From c3c37f46ef48168179df1a59881d2348a7a00a81 Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Wed, 30 Nov 2022 03:06:28 -0500 Subject: [PATCH] [device/marvell] Mitigation for security vulnerability (#11876) #### Why I did it `os` and `commands` modules are not secure against maliciously constructed input `getstatusoutput` is detected without a static string, uses `shell=True` #### How I did it Eliminate the use of `os` and `commands` Use `subprocess` instead --- .../plugins/sfputil.py | 21 ++++++++----------- .../plugins/sfputil.py | 21 ++++++++----------- .../plugins/psuutil.py | 13 +++--------- .../plugins/sfputil.py | 18 +++++++--------- .../plugins/sfputil.py | 21 ++++++++----------- .../plugins/sfputil.py | 21 ++++++++----------- 6 files changed, 46 insertions(+), 69 deletions(-) diff --git a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py index 4463e687e6..500bdda8f2 100644 --- a/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py +++ b/device/marvell/arm64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py @@ -1,17 +1,13 @@ try: import os import time - import sys import re + import subprocess from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_py_common.general import getstatusoutput_noshell except ImportError as e: raise ImportError(str(e) + "- required module not found") -if sys.version_info[0] < 3: - import commands -else: - import subprocess as commands - smbus_present = 1 try: @@ -31,9 +27,10 @@ class SfpUtil(SfpUtilBase): _qsfp_ports = list(range(_port_start, ports_in_block + 1)) def __init__(self): - os.system("modprobe i2c-dev") + subprocess.call(["modprobe", "i2c-dev"]) if not os.path.exists("/sys/bus/i2c/devices/0-0050"): - os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + with open("/sys/bus/i2c/devices/i2c-0/new_device", 'w') as file: + file.write("optoe2 0x50") eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' # for x in range(self.port _start, self.port_end +1): @@ -74,8 +71,8 @@ class SfpUtil(SfpUtilBase): def i2c_get(self, device_addr, offset): status = 0 if smbus_present == 0: - x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) - cmdstatus, status = commands.getstatusoutput(x) + x = ["i2cget", "-y", "0", hex(device_addr), hex(offset)] + cmdstatus, status = getstatusoutput_noshell(x) if cmdstatus != 0: return cmdstatus status = int(status, 16) @@ -86,8 +83,8 @@ class SfpUtil(SfpUtilBase): def i2c_set(self, device_addr, offset, value): if smbus_present == 0: - cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) - os.system(cmd) + cmd = ["i2cset", "-y", "0", hex(device_addr), hex(offset), hex(value)] + subprocess.call(cmd) else: bus = smbus.SMBus(0) bus.write_byte_data(device_addr, offset, value) diff --git a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py index b3d1ea3714..280593c60b 100644 --- a/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py +++ b/device/marvell/arm64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py @@ -1,17 +1,13 @@ try: import os import time - import sys import re + import subprocess from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_py_common.general import getstatusoutput_noshell except ImportError as e: raise ImportError(str(e) + "- required module not found") -if sys.version_info[0] < 3: - import commands -else: - import subprocess as commands - smbus_present = 1 try: @@ -31,9 +27,10 @@ class SfpUtil(SfpUtilBase): _qsfp_ports = list(range(_port_start, ports_in_block + 1)) def __init__(self): - os.system("modprobe i2c-dev") + subprocess.call(["modprobe", "i2c-dev"]) if not os.path.exists("/sys/bus/i2c/devices/0-0050"): - os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + with open("/sys/bus/i2c/devices/i2c-0/new_device", 'w') as file: + file.write("optoe2 0x50") eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' # for x in range(self.port _start, self.port_end +1): @@ -74,8 +71,8 @@ class SfpUtil(SfpUtilBase): def i2c_get(self, device_addr, offset): status = 0 if smbus_present == 0: - x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) - cmdstatus, status = commands.getstatusoutput(x) + x = ["i2cget", "-y", "0", hex(device_addr), hex(offset)] + cmdstatus, status = getstatusoutput_noshell(x) if cmdstatus != 0: return cmdstatus status = int(status, 16) @@ -86,8 +83,8 @@ class SfpUtil(SfpUtilBase): def i2c_set(self, device_addr, offset, value): if smbus_present == 0: - cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) - os.system(cmd) + cmd = ["i2cset", "-y", "0", hex(device_addr), hex(offset), hex(value)] + subprocess.call(cmd) else: bus = smbus.SMBus(0) bus.write_byte_data(device_addr, offset, value) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py index ab6aeff2b2..a75832ee4d 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/psuutil.py @@ -1,9 +1,4 @@ -import sys -import os.path -if sys.version_info[0] < 3: - import commands -else: - import subprocess as commands +from sonic_py_common.general import getstatusoutput_noshell smbus_present = 1 try: @@ -32,8 +27,7 @@ class PsuUtil(PsuBase): if index is None: return False if smbus_present == 0: - cmdstatus, psustatus = commands.getstatusoutput( - 'i2cget -y 0 0x41 0xa') # need to verify the cpld register logic + cmdstatus, psustatus = getstatusoutput_noshell(["i2cget", "-y", "0", "0x41", "0xa"]) psustatus = int(psustatus, 16) else: bus = smbus.SMBus(0) @@ -56,8 +50,7 @@ class PsuUtil(PsuBase): return False if smbus_present == 0: - cmdstatus, psustatus = commands.getstatusoutput( - 'i2cget -y 0 0x41 0xa') # need to verify the cpld register logic + cmdstatus, psustatus = getstatusoutput_noshell(["i2cget", "-y", "0", "0x41", "0xa"]) psustatus = int(psustatus, 16) else: bus = smbus.SMBus(0) diff --git a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py index 39d5db4ce7..a160becb6f 100755 --- a/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py +++ b/device/marvell/armhf-marvell_et6448m_52x-r0/plugins/sfputil.py @@ -2,17 +2,13 @@ try: import os import time import re - import sys import glob + import subprocess from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_py_common.general import getstatusoutput_noshell except ImportError as e: raise ImportError(str(e) + "- required module not found") -if sys.version_info[0] < 3: - import commands -else: - import subprocess as commands - smbus_present = 1 try: @@ -43,7 +39,7 @@ class SfpUtil(SfpUtilBase): # Enable optical SFP Tx if smbus_present == 0: - os.system("i2cset -y -m 0x0f 0 0x41 0x5 0x00") + subprocess.call(["i2cset", "-y", "-m", "0x0f", "0", "0x41", "0x5", "0x00"]) else: bus = smbus.SMBus(0) DEVICE_ADDRESS = 0x41 @@ -66,8 +62,9 @@ class SfpUtil(SfpUtilBase): port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) #print port_eeprom_path if not os.path.exists(port_eeprom_path): - bus_dev_path = bus_path.format(self.port_to_i2c_mapping[x]) - os.system("echo optoe2 0x50 > " + bus_dev_path + "/new_device") + bus_dev_path = bus_path.format(self.port_to_i2c_mapping[x]) + "/new_device" + with open(bus_dev_path, 'w') as f: + f.write("optoe2 0x50") self.port_to_eeprom_mapping[x] = port_eeprom_path self._port_to_eeprom_mapping[x] = port_eeprom_path SfpUtilBase.__init__(self) @@ -113,8 +110,7 @@ class SfpUtil(SfpUtilBase): pos = [1, 2, 4, 8] bit_pos = pos[prt] if smbus_present == 0: - cmdstatus, sfpstatus = commands.getstatusoutput( - 'i2cget -y 0 0x41 0x3') # need to verify the cpld register logic + cmdstatus, sfpstatus = getstatusoutput_noshell(['i2cget', '-y', '0', '0x41', '0x3']) sfpstatus = int(sfpstatus, 16) else: bus = smbus.SMBus(0) diff --git a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py index 4463e687e6..500bdda8f2 100644 --- a/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py +++ b/device/marvell/x86_64-marvell_db98cx8580_16cd-r0/plugins/sfputil.py @@ -1,17 +1,13 @@ try: import os import time - import sys import re + import subprocess from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_py_common.general import getstatusoutput_noshell except ImportError as e: raise ImportError(str(e) + "- required module not found") -if sys.version_info[0] < 3: - import commands -else: - import subprocess as commands - smbus_present = 1 try: @@ -31,9 +27,10 @@ class SfpUtil(SfpUtilBase): _qsfp_ports = list(range(_port_start, ports_in_block + 1)) def __init__(self): - os.system("modprobe i2c-dev") + subprocess.call(["modprobe", "i2c-dev"]) if not os.path.exists("/sys/bus/i2c/devices/0-0050"): - os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + with open("/sys/bus/i2c/devices/i2c-0/new_device", 'w') as file: + file.write("optoe2 0x50") eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' # for x in range(self.port _start, self.port_end +1): @@ -74,8 +71,8 @@ class SfpUtil(SfpUtilBase): def i2c_get(self, device_addr, offset): status = 0 if smbus_present == 0: - x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) - cmdstatus, status = commands.getstatusoutput(x) + x = ["i2cget", "-y", "0", hex(device_addr), hex(offset)] + cmdstatus, status = getstatusoutput_noshell(x) if cmdstatus != 0: return cmdstatus status = int(status, 16) @@ -86,8 +83,8 @@ class SfpUtil(SfpUtilBase): def i2c_set(self, device_addr, offset, value): if smbus_present == 0: - cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) - os.system(cmd) + cmd = ["i2cset", "-y", "0", hex(device_addr), hex(offset), hex(value)] + subprocess.call(cmd) else: bus = smbus.SMBus(0) bus.write_byte_data(device_addr, offset, value) diff --git a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py index b3d1ea3714..280593c60b 100644 --- a/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py +++ b/device/marvell/x86_64-marvell_db98cx8580_32cd-r0/plugins/sfputil.py @@ -1,17 +1,13 @@ try: import os import time - import sys import re + import subprocess from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_py_common.general import getstatusoutput_noshell except ImportError as e: raise ImportError(str(e) + "- required module not found") -if sys.version_info[0] < 3: - import commands -else: - import subprocess as commands - smbus_present = 1 try: @@ -31,9 +27,10 @@ class SfpUtil(SfpUtilBase): _qsfp_ports = list(range(_port_start, ports_in_block + 1)) def __init__(self): - os.system("modprobe i2c-dev") + subprocess.call(["modprobe", "i2c-dev"]) if not os.path.exists("/sys/bus/i2c/devices/0-0050"): - os.system("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-0/new_device") + with open("/sys/bus/i2c/devices/i2c-0/new_device", 'w') as file: + file.write("optoe2 0x50") eeprom_path = '/sys/bus/i2c/devices/0-0050/eeprom' # for x in range(self.port _start, self.port_end +1): @@ -74,8 +71,8 @@ class SfpUtil(SfpUtilBase): def i2c_get(self, device_addr, offset): status = 0 if smbus_present == 0: - x = "i2cget -y 0 " + hex(device_addr) + " " + hex(offset) - cmdstatus, status = commands.getstatusoutput(x) + x = ["i2cget", "-y", "0", hex(device_addr), hex(offset)] + cmdstatus, status = getstatusoutput_noshell(x) if cmdstatus != 0: return cmdstatus status = int(status, 16) @@ -86,8 +83,8 @@ class SfpUtil(SfpUtilBase): def i2c_set(self, device_addr, offset, value): if smbus_present == 0: - cmd = "i2cset -y 0 " + hex(device_addr) + " " + hex(offset) + " " + hex(value) - os.system(cmd) + cmd = ["i2cset", "-y", "0", hex(device_addr), hex(offset), hex(value)] + subprocess.call(cmd) else: bus = smbus.SMBus(0) bus.write_byte_data(device_addr, offset, value)