Add a privsep context only for link commands

This new context will have only two capabilities: CAP_NET_ADMIN
and CAP_SYS_ADMIN (for operations inside namespaces).

Change-Id: If9273db1a7ccdce3a81f68fce78408830e9c3d42
This commit is contained in:
Rodolfo Alonso Hernandez 2021-07-13 16:37:15 +00:00
parent 474f5d700b
commit 899953de6b
4 changed files with 23 additions and 11 deletions

View File

@ -62,3 +62,12 @@ conntrack_cmd = priv_context.PrivContext(
pypath=__name__ + '.conntrack_cmd',
capabilities=[caps.CAP_NET_ADMIN]
)
link_cmd = priv_context.PrivContext(
__name__,
cfg_section='privsep_link',
pypath=__name__ + '.link_cmd',
capabilities=[caps.CAP_NET_ADMIN,
caps.CAP_SYS_ADMIN]
)

View File

@ -340,43 +340,43 @@ def interface_exists(ifname, namespace):
raise
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def set_link_flags(device, namespace, flags):
link = _run_iproute_link("get", device, namespace)[0]
new_flags = flags | link['flags']
return _run_iproute_link("set", device, namespace, flags=new_flags)
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def set_link_attribute(device, namespace, **attributes):
return _run_iproute_link("set", device, namespace, **attributes)
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def set_link_vf_feature(device, namespace, vf_config):
return _run_iproute_link("set", device, namespace=namespace, vf=vf_config)
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def set_link_bridge_forward_delay(device, forward_delay, namespace=None):
return _run_iproute_link('set', device, namespace=namespace,
kind='bridge', br_forward_delay=forward_delay)
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def set_link_bridge_stp(device, stp, namespace=None):
return _run_iproute_link('set', device, namespace=namespace,
kind='bridge', br_stp_state=stp)
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def set_link_bridge_master(device, bridge, namespace=None):
bridge_idx = get_link_id(bridge, namespace) if bridge else 0
return _run_iproute_link('set', device, namespace=namespace,
master=bridge_idx)
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def get_link_attributes(device, namespace):
link = _run_iproute_link("get", device, namespace)[0]
return {
@ -392,7 +392,7 @@ def get_link_attributes(device, namespace):
}
@privileged.default.entrypoint
@privileged.link_cmd.entrypoint
def get_link_vfs(device, namespace):
link = _run_iproute_link('get', device, namespace=namespace, ext_mask=1)[0]
num_vfs = link.get_attr('IFLA_NUM_VF')

View File

@ -50,7 +50,10 @@ class LinuxbridgeCleanupTest(base.BaseSudoTestCase):
},
'privsep': {
'helper_command': ' '.join(['sudo', '-E', privsep_helper]),
}
},
'privsep_link': {
'helper_command': ' '.join(['sudo', '-E', privsep_helper]),
},
})
config.update({'VXLAN': {'enable_vxlan': 'False'}})

View File

@ -227,7 +227,7 @@ class IpLibTestCase(base.BaseTestCase):
self.assertEqual(errno.EINVAL, e.errno)
def _clean(self, client_mode):
priv_lib.privileged.default.client_mode = client_mode
priv_lib.privileged.link_cmd.client_mode = client_mode
def test_get_link_vfs(self):
# NOTE(ralonsoh): there should be a functional test checking this
@ -249,7 +249,7 @@ class IpLibTestCase(base.BaseTestCase):
value.setvalue({'attrs': [('IFLA_NUM_VF', 3),
('IFLA_VFINFO_LIST', vfinfo_list)]})
client_mode = priv_lib.privileged.default.client_mode
priv_lib.privileged.default.client_mode = False
priv_lib.privileged.link_cmd.client_mode = False
self.addCleanup(self._clean, client_mode)
with mock.patch.object(priv_lib, '_run_iproute_link') as mock_iplink:
mock_iplink.return_value = [value]