[sonic-py-common] Remove subprocess with shell=True (#12562)
Signed-off-by: maipbui <maibui@microsoft.com> #### Why I did it `subprocess` is used with `shell=True`, which is very dangerous for shell injection. #### How I did it remove `shell=True`, use `shell=False` #### How to verify it Manual test Pass UT
This commit is contained in:
parent
7fb8bf7012
commit
b522b7762f
@ -6,7 +6,7 @@ import subprocess
|
|||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from natsort import natsorted
|
from natsort import natsorted
|
||||||
|
from sonic_py_common.general import getstatusoutput_noshell_pipe
|
||||||
from swsscommon.swsscommon import ConfigDBConnector, SonicV2Connector
|
from swsscommon.swsscommon import ConfigDBConnector, SonicV2Connector
|
||||||
|
|
||||||
USR_SHARE_SONIC_PATH = "/usr/share/sonic"
|
USR_SHARE_SONIC_PATH = "/usr/share/sonic"
|
||||||
@ -531,7 +531,27 @@ def _valid_mac_address(mac):
|
|||||||
return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac))
|
return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac))
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(cmd):
|
||||||
|
proc = subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
(out, err) = proc.communicate()
|
||||||
|
return (out, err)
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_pipe(cmd0, cmd1, cmd2):
|
||||||
|
exitcodes, out = getstatusoutput_noshell_pipe(cmd0, cmd1, cmd2)
|
||||||
|
if exitcodes == [0, 0, 0]:
|
||||||
|
err = None
|
||||||
|
else:
|
||||||
|
err = out
|
||||||
|
return (out, err)
|
||||||
|
|
||||||
|
|
||||||
def get_system_mac(namespace=None):
|
def get_system_mac(namespace=None):
|
||||||
|
hw_mac_entry_outputs = []
|
||||||
|
syseeprom_cmd = ["sudo", "decode-syseeprom", "-m"]
|
||||||
|
iplink_cmd0 = ["ip", 'link', 'show', 'eth0']
|
||||||
|
iplink_cmd1 = ['grep', 'ether']
|
||||||
|
iplink_cmd2 = ['awk', '{print $2}']
|
||||||
version_info = get_sonic_version_info()
|
version_info = get_sonic_version_info()
|
||||||
|
|
||||||
if (version_info['asic_type'] == 'mellanox'):
|
if (version_info['asic_type'] == 'mellanox'):
|
||||||
@ -548,36 +568,51 @@ def get_system_mac(namespace=None):
|
|||||||
if _valid_mac_address(mac):
|
if _valid_mac_address(mac):
|
||||||
return mac
|
return mac
|
||||||
|
|
||||||
hw_mac_entry_cmds = [ "sudo decode-syseeprom -m" ]
|
(mac, err) = run_command(syseeprom_cmd)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
elif (version_info['asic_type'] == 'marvell'):
|
elif (version_info['asic_type'] == 'marvell'):
|
||||||
# Try valid mac in eeprom, else fetch it from eth0
|
# Try valid mac in eeprom, else fetch it from eth0
|
||||||
platform = get_platform()
|
platform = get_platform()
|
||||||
machine_key = "onie_machine"
|
machine_key = "onie_machine"
|
||||||
machine_vars = get_machine_info()
|
machine_vars = get_machine_info()
|
||||||
|
(mac, err) = run_command(syseeprom_cmd)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
if machine_vars is not None and machine_key in machine_vars:
|
if machine_vars is not None and machine_key in machine_vars:
|
||||||
hwsku = machine_vars[machine_key]
|
hwsku = machine_vars[machine_key]
|
||||||
profile_cmd = 'cat ' + HOST_DEVICE_PATH + '/' + platform + '/' + hwsku + '/profile.ini | grep switchMacAddress | cut -f2 -d='
|
profile_cmd0 = ['cat', HOST_DEVICE_PATH + '/' + platform + '/' + hwsku + '/profile.ini']
|
||||||
|
profile_cmd1 = ['grep', 'switchMacAddress']
|
||||||
|
profile_cmd2 = ['cut', '-f2', '-d', '=']
|
||||||
|
(mac, err) = run_command_pipe(profile_cmd0, profile_cmd1, profile_cmd2)
|
||||||
else:
|
else:
|
||||||
profile_cmd = "false"
|
profile_cmd = ["false"]
|
||||||
hw_mac_entry_cmds = ["sudo decode-syseeprom -m", profile_cmd, "ip link show eth0 | grep ether | awk '{print $2}'"]
|
(mac, err) = run_command(profile_cmd)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
|
(mac, err) = run_command_pipe(iplink_cmd0, iplink_cmd1, iplink_cmd2)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
elif (version_info['asic_type'] == 'cisco-8000'):
|
elif (version_info['asic_type'] == 'cisco-8000'):
|
||||||
# Try to get valid MAC from profile.ini first, else fetch it from syseeprom or eth0
|
# Try to get valid MAC from profile.ini first, else fetch it from syseeprom or eth0
|
||||||
platform = get_platform()
|
platform = get_platform()
|
||||||
if namespace is not None:
|
if namespace is not None:
|
||||||
profile_cmd = 'cat ' + HOST_DEVICE_PATH + '/' + platform + '/profile.ini | grep ' + namespace + 'switchMacAddress | cut -f2 -d='
|
profile_cmd0 = ['cat', HOST_DEVICE_PATH + '/' + platform + '/profile.ini']
|
||||||
|
profile_cmd1 = ['grep', str(namespace)+'switchMacAddress']
|
||||||
|
profile_cmd2 = ['cut', '-f2', '-d', '=']
|
||||||
|
(mac, err) = run_command_pipe(profile_cmd0, profile_cmd1, profile_cmd2)
|
||||||
else:
|
else:
|
||||||
profile_cmd = "false"
|
profile_cmd = ["false"]
|
||||||
hw_mac_entry_cmds = [profile_cmd, "sudo decode-syseeprom -m", "ip link show eth0 | grep ether | awk '{print $2}'"]
|
(mac, err) = run_command(profile_cmd)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
|
(mac, err) = run_command(syseeprom_cmd)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
|
(mac, err) = run_command_pipe(iplink_cmd0, iplink_cmd1, iplink_cmd2)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
else:
|
else:
|
||||||
mac_address_cmd = "cat /sys/class/net/eth0/address"
|
mac_address_cmd = ["cat", "/sys/class/net/eth0/address"]
|
||||||
if namespace is not None:
|
if namespace is not None:
|
||||||
mac_address_cmd = "sudo ip netns exec {} {}".format(namespace, mac_address_cmd)
|
mac_address_cmd = ['sudo', 'ip', 'netns', 'exec', str(namespace)] + mac_address_cmd
|
||||||
|
(mac, err) = run_command(mac_address_cmd)
|
||||||
|
hw_mac_entry_outputs.append((mac, err))
|
||||||
|
|
||||||
hw_mac_entry_cmds = [mac_address_cmd]
|
for (mac, err) in hw_mac_entry_outputs:
|
||||||
|
|
||||||
for get_mac_cmd in hw_mac_entry_cmds:
|
|
||||||
proc = subprocess.Popen(get_mac_cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
(mac, err) = proc.communicate()
|
|
||||||
if err:
|
if err:
|
||||||
continue
|
continue
|
||||||
mac = mac.strip()
|
mac = mac.strip()
|
||||||
@ -602,17 +637,14 @@ def get_system_routing_stack():
|
|||||||
Returns:
|
Returns:
|
||||||
A string containing the name of the routing stack in use on the device
|
A string containing the name of the routing stack in use on the device
|
||||||
"""
|
"""
|
||||||
command = "sudo docker ps | grep bgp | awk '{print$2}' | cut -d'-' -f3 | cut -d':' -f1"
|
cmd0 = ['sudo', 'docker', 'ps']
|
||||||
|
cmd1 = ['grep', 'bgp']
|
||||||
|
cmd2 = ['awk', '{print$2}']
|
||||||
|
cmd3 = ['cut', '-d', '-', '-f3']
|
||||||
|
cmd4 = ['cut', '-d', ':', '-f1']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
proc = subprocess.Popen(command,
|
_, result = getstatusoutput_noshell_pipe(cmd0, cmd1, cmd2, cmd3, cmd4)
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
shell=True,
|
|
||||||
universal_newlines=True,
|
|
||||||
stderr=subprocess.STDOUT)
|
|
||||||
stdout = proc.communicate()[0]
|
|
||||||
proc.wait()
|
|
||||||
result = stdout.rstrip('\n')
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise OSError("Cannot detect routing stack")
|
raise OSError("Cannot detect routing stack")
|
||||||
|
|
||||||
@ -644,8 +676,8 @@ def is_warm_restart_enabled(container_name):
|
|||||||
# Check if System fast reboot is enabled.
|
# Check if System fast reboot is enabled.
|
||||||
def is_fast_reboot_enabled():
|
def is_fast_reboot_enabled():
|
||||||
fb_system_state = 0
|
fb_system_state = 0
|
||||||
cmd = 'sonic-db-cli STATE_DB get "FAST_REBOOT|system"'
|
cmd = ['sonic-db-cli', 'STATE_DB', 'get', "FAST_REBOOT|system"]
|
||||||
proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE)
|
proc = subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE)
|
||||||
(stdout, stderr) = proc.communicate()
|
(stdout, stderr) = proc.communicate()
|
||||||
|
|
||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
|
@ -157,10 +157,9 @@ def get_current_namespace(pid=None):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
net_namespace = None
|
net_namespace = None
|
||||||
command = ["sudo /bin/ip netns identify {}".format(os.getpid() if not pid else pid)]
|
command = ["sudo", '/bin/ip', 'netns', 'identify', "{}".format(os.getpid() if not pid else pid)]
|
||||||
proc = subprocess.Popen(command,
|
proc = subprocess.Popen(command,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
shell=True,
|
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
try:
|
try:
|
||||||
|
Reference in New Issue
Block a user