diff -ruN neutron-bak/agent/linux/ipset_manager.py neutron/agent/linux/ipset_manager.py --- neutron-bak/agent/linux/ipset_manager.py? 2022-02-16 15:11:40.419016919 +0800 +++ neutron/agent/linux/ipset_manager.py??????? 2022-02-16 15:17:02.328133786 +0800 @@ -146,7 +146,7 @@ ???????????? cmd_ns.extend(['ip', 'netns', 'exec', self.namespace]) ???????? cmd_ns.extend(cmd) ???????? self.execute(cmd_ns, run_as_root=True, process_input=input, -???? ????????????????check_exit_code=fail_on_errors) +???????????????????? check_exit_code=fail_on_errors, privsep_exec=True) ? ???? def _get_new_set_ips(self, set_name, expected_ips): ???????? new_member_ips = (set(expected_ips) - diff -ruN neutron-bak/agent/linux/iptables_manager.py neutron/agent/linux/iptables_manager.py --- neutron-bak/agent/linux/iptables_manager.py????? 2022-02-16 15:05:53.853147520 +0800 +++ neutron/agent/linux/iptables_manager.py?? 2021-07-07 14:59:16.000000000 +0800 @@ -475,12 +475,15 @@ ???? ????args = ['iptables-save', '-t', table] ???????? if self.namespace: ???????????? args = ['ip', 'netns', 'exec', self.namespace] + args -??????? return self.execute(args, run_as_root=True).split('\n') +??????? #return self.execute(args, run_as_root=True).split('\n') +??????? return self.execute(args, run_as_root=True, +??????????????????????????? privsep_exec=True).split('\n') ? ???? def _get_version(self): ???????? # Output example is 'iptables v1.6.2' ???????? args = ['iptables', '--version'] -??????? version = str(self.execute(args, run_as_root=True).split()[1][1:]) +??????? #version = str(self.execute(args, run_as_root=True).split()[1][1:]) +??????? version = str(self.execute(args, run_as_root=True, privsep_exec=True).split()[1][1:]) ???????? LOG.debug('IPTables version installed: %s', version) ???????? return version ? @@ -505,8 +508,10 @@ ???????????? args += ['-w', self.xlock_wait_time, '-W', XLOCK_WAIT_INTERVAL] ???????? try: ???????????? kwargs = {} if lock else {'log_fail_as_error': False} +?????? ?????#self.execute(args, process_input='\n'.join(commands), +??????????? #???????????? run_as_root=True, **kwargs) ???????????? self.execute(args, process_input='\n'.join(commands), -???????????????????????? run_as_root=True, **kwargs) +?????????????????? ??????run_as_root=True, privsep_exec=True, **kwargs) ???????? except RuntimeError as error: ???????????? return error ? @@ -568,7 +573,8 @@ ???????????? if self.namespace: ???????????????? args = ['ip', 'netns', 'exec', self.namespace] + args ???????????? try: -??????????????? save_output = self.execute(args, run_as_root=True) +??????????????? #save_output = self.execute(args, run_as_root=True) +??????????????? save_output = self.execute(args, run_as_root=True, privsep_exec=True) ???????????? except RuntimeError: ???????????????? # We could be racing with a cron job deleting namespaces. ???????????????? # It is useless to try to apply iptables rules over and @@ -769,7 +775,8 @@ ???????????????? args.append('-Z') ???????????? if self.namespace: ????????????? ???args = ['ip', 'netns', 'exec', self.namespace] + args -??????????? current_table = self.execute(args, run_as_root=True) +??????????? #current_table = self.execute(args, run_as_root=True) +??????????? current_table = self.execute(args, run_as_root=True, privsep_exec=True) ???????????? current_lines = current_table.split('\n') ? ???????????? for line in current_lines[2:]: diff -ruN neutron-bak/agent/linux/utils.py neutron/agent/linux/utils.py --- neutron-bak/agent/linux/utils.py 2022-02-16 15:06:03.133090388 +0800 +++ neutron/agent/linux/utils.py?????? 2021-07-08 09:34:12.000000000 +0800 @@ -38,6 +38,7 @@ ?from neutron.agent.linux import xenapi_root_helper ?from neutron.common import utils ?from neutron.conf.agent import common as config +from neutron.privileged.agent.linux import utils as priv_utils ?from neutron import wsgi ? ? @@ -85,13 +86,24 @@ ???? if run_as_root: ???????? cmd = shlex.split(config.get_root_helper(cfg.CONF)) + cmd ???? LOG.debug('Running command: %s', cmd) -??? obj = utils.subprocess_popen(cmd, shell=False, -???????????????????????????????? stdin=subprocess.PIPE, -???????????????????????????????? stdout=subprocess.PIPE, -???????????????????????????????? stderr=subprocess.PIPE) +??? #obj = utils.subprocess_popen(cmd, shell=False, +??? #??????? ?????????????????????stdin=subprocess.PIPE, +??? #???????????????????????????? stdout=subprocess.PIPE, +??? #???????????????????????????? stderr=subprocess.PIPE) +??? obj = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, +??????????????????????? ???stdout=subprocess.PIPE, stderr=subprocess.PIPE) ? ???? return obj, cmd ? +def _execute_process(cmd, _process_input, addl_env, run_as_root): +??? obj, cmd = create_process(cmd, run_as_root=run_as_root, addl_env=addl_env) +??? _stdout, _stderr = obj.communicate(_process_input) +??? returncode = obj.returncode +??? obj.stdin.close() +??? _stdout = helpers.safe_decode_utf8(_stdout) +??? _stderr = helpers.safe_decode_utf8(_stderr) +??? return _stdout, _stderr, returncode + ? ?def execute_rootwrap_daemon(cmd, process_input, addl_env): ???? cmd = list(map(str, addl_env_args(addl_env) + cmd)) @@ -103,31 +115,45 @@ ???? LOG.debug('Running command (rootwrap daemon): %s', cmd) ???? client = RootwrapDaemonHelper.get_client() ???? try: -??????? return client.execute(cmd, process_input) +??????? #return client.execute(cmd, process_input) +??????? returncode, __stdout, _stderr =? client.execute(cmd, process_input) ???? except Exception: ???????? with excutils.save_and_reraise_exception(): ???????????? LOG.error('Rootwrap error running command: %s', cmd) +??? _stdout = helpers.safe_decode_utf8(_stdout) +??? _stderr = helpers.safe_decode_utf8(_stderr) +??? return _stdout, _stderr, returncode ? ? ?def execute(cmd, process_input=None, addl_env=None, ???????????? check_exit_code=True, return_stderr=False, log_fail_as_error=True, -??????????? extra_ok_codes=None, run_as_root=False): +??????????? extra_ok_codes=None, run_as_root=False, privsep_exec=False): ???? try: ???????? if process_input is not None: ???????????? _process_input = encodeutils.to_utf8(process_input) ???????? else: ???????????? _process_input = None -??????? if run_as_root and cfg.CONF.AGENT.root_helper_daemon: -??????????? returncode, _stdout, _stderr = ( -??????????????? execute_rootwrap_daemon(cmd, process_input, addl_env)) +??????? #if run_as_root and cfg.CONF.AGENT.root_helper_daemon: +??????? #??? returncode, _stdout, _stderr = ( +??????? #??????? execute_rootwrap_daemon(cmd, process_input, addl_env)) +??????? #else: +??????? #??? obj, cmd = create_process(cmd, run_as_root=run_as_root, +??????? #????????????????????????????? addl_env=addl_env) +??????? #??? _stdout, _stderr = obj.communicate(_process_input) +??????? #??? returncode = obj.returncode +??????? #??? obj.stdin.close() +??????? #_stdout = helpers.safe_decode_utf8(_stdout) +??????? #_stderr = helpers.safe_decode_utf8(_stderr) + +??????? if run_as_root and privsep_exec: +??????????? _stdout, _stderr, returncode = priv_utils.execute_process( +??????????????? cmd, _process_input, addl_env) +??????? elif run_as_root and cfg.CONF.AGENT.root_helper_daemon: +??????????? _stdout, _stderr, returncode = execute_rootwarp_daemon( +??????????????? cmd, process_input, addl_env) ???????? else: -??????????? obj, cmd = create_process(cmd, run_as_root=run_as_root, -?? ???????????????????????????????????addl_env=addl_env) -??????????? _stdout, _stderr = obj.communicate(_process_input) -??????????? returncode = obj.returncode -??????????? obj.stdin.close() -??????? _stdout = helpers.safe_decode_utf8(_stdout) -??????? _stderr = helpers.safe_decode_utf8(_stderr) +??????????? _stdout, _stderr, returncode = _execute_process( +??????????????? cmd, _process_input, addl_env, run_as_root) ? ???????? extra_ok_codes = extra_ok_codes or [] ???????? if returncode and returncode not in extra_ok_codes: diff -ruN neutron-bak/cmd/ipset_cleanup.py neutron/cmd/ipset_cleanup.py --- neutron-bak/cmd/ipset_cleanup.py????? 2022-02-16 15:18:00.727786180 +0800 +++ neutron/cmd/ipset_cleanup.py?? 2021-07-07 15:00:03.000000000 +0800 @@ -38,7 +38,8 @@ ?def remove_iptables_reference(ipset): ???? # Remove any iptables reference to this IPset ???? cmd = ['iptables-save'] if 'IPv4' in ipset else ['ip6tables-save'] -??? iptables_save = utils.execute(cmd, run_as_root=True) +??? #iptables_save = utils.execute(cmd, run_as_root=True) +??? iptables_save = utils.execute(cmd, run_as_root=True, privsep_exec=True) ? ???? if ipset in iptables_save: ???????? cmd = ['iptables'] if 'IPv4' in ipset else ['ip6tables'] @@ -50,7 +51,8 @@ ? ???????????????params = rule.split() ???????????????? params[0] = '-D' ???????????????? try: -??????????????????? utils.execute(cmd + params, run_as_root=True) +??????????????????? #utils.execute(cmd + params, run_as_root=True) +??????????????????? utils.execute(cmd + params, run_as_root=True, privsep_exec=True) ???????????????? except Exception: ???????????????????? LOG.exception('Error, unable to remove iptables rule ' ?????????????????????????????????? 'for IPset: %s', ipset) @@ -65,7 +67,8 @@ ???? LOG.info('Destroying IPset: %s', ipset) ???? cmd = ['ipset', 'destroy', ipset] ???? try: -??????? utils.execute(cmd, run_as_root=True) +??????? #utils.execute(cmd, run_as_root=True) +??????? utils.execute(cmd, run_as_root=True, privsep_exec=True) ???? except Exception: ???????? LOG.exception('Error, unable to destroy IPset: %s', ipset) ? @@ -75,7 +78,8 @@ ???? LOG.info('Destroying IPsets with prefix: %s', conf.prefix) ? ???? cmd = ['ipset', '-L', '-n'] -??? ipsets = utils.execute(cmd, run_as_root=True) +??? #ipsets = utils.execute(cmd, run_as_root=True) +??? ipsets = utils.execute(cmd, run_as_root=True, privsep_exec=True) ???? for ipset in ipsets.split('\n'): ???????? if conf.allsets or ipset.startswith(conf.prefix): ???????????? destroy_ipset(conf, ipset) diff -ruN neutron-bak/privileged/agent/linux/utils.py neutron/privileged/agent/linux/utils.py --- neutron-bak/privileged/agent/linux/utils.py? 1970-01-01 08:00:00.000000000 +0800 +++ neutron/privileged/agent/linux/utils.py??????? 2021-07-07 14:58:21.000000000 +0800 @@ -0,0 +1,82 @@ +# Copyright 2020 Red Hat, Inc. +# +#??? Licensed under the Apache License, Version 2.0 (the 'License'); you may +#??? not use this file except in compliance with the License. You may obtain +#??? a copy of the License at +# +#???????? http://www.apache.org/licenses/LICENSE-2.0 +# +#??? Unless required by applicable law or agreed to in writing, software +#??? distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT +#??? WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +#??? License for the specific language governing permissions and limitations +#??? under the License. + +import os +import re + +from eventlet.green import subprocess +from neutron_lib.utils import helpers +from oslo_concurrency import processutils +from oslo_utils import fileutils + +from neutron import privileged + + +NETSTAT_PIDS_REGEX = re.compile(r'.* (?P\d{2,6})/.*') + + +@privileged.default.entrypoint +def find_listen_pids_namespace(namespace): +??? return _find_listen_pids_namespace(namespace) + + +def _find_listen_pids_namespace(namespace): +??? '''Retrieve a list of pids of listening processes within the given netns +??? This method is implemented separately to allow unit testing. +??? ''' +??? pids = set() +??? cmd = ['ip', 'netns', 'exec', namespace, 'netstat', '-nlp'] +??? output = processutils.execute(*cmd) +??? for line in output[0].splitlines(): +??????? m = NETSTAT_PIDS_REGEX.match(line) +??????? if m: +??????????? pids.add(m.group('pid')) +??? return list(pids) + + +@privileged.default.entrypoint +def delete_if_exists(path, remove=os.unlink): +??? fileutils.delete_if_exists(path, remove=remove) + + +@privileged.default.entrypoint +def execute_process(cmd, _process_input, addl_env): +??? obj, cmd = _create_process(cmd, addl_env=addl_env) +??? _stdout, _stderr = obj.communicate(_process_input) +??? returncode = obj.returncode +??? obj.stdin.close() +??? _stdout = helpers.safe_decode_utf8(_stdout) +??? _stderr = helpers.safe_decode_utf8(_stderr) +??? return _stdout, _stderr, returncode + + +def _addl_env_args(addl_env): +??? '''Build arguments for adding additional environment vars with env''' + +??? # NOTE (twilson) If using rootwrap, an EnvFilter should be set up for the +??? # command instead of a CommandFilter. +??? if addl_env is None: +??????? return [] +??? return ['env'] + ['%s=%s' % pair for pair in addl_env.items()] + + +def _create_process(cmd, addl_env=None): +??? '''Create a process object for the given command. +??? The return value will be a tuple of the process object and the +??? list of command arguments used to create it. +??? ''' +??? cmd = list(map(str, _addl_env_args(addl_env) + list(cmd))) +??? obj = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE, +?????????????????????????? stdout=subprocess.PIPE, stderr=subprocess.PIPE) +??? return obj, cmd |