Skip to content

Commit 6f67a3a

Browse files
authored
[device/quanta] Mitigation for security vulnerability (#11867)
Signed-off-by: maipbui <maibui@microsoft.com> Dependency: [https://github.com/sonic-net/sonic-buildimage/pull/12065](https://github.com/sonic-net/sonic-buildimage/pull/12065) #### Why I did it `shell=True` is dangerous because this call will spawn the command using a shell process `os` - not secure against maliciously constructed input and dangerous if used to evaluate dynamic content. #### How I did it `os` - use with `subprocess` Use `shell=False` with shell features - redirection: [https://stackoverflow.com/questions/4965159/how-to-redirect-output-with-subprocess-in-python/6482200#6482200?newreg=53afb91b3ebd47c5930be627fcdf2930](https://stackoverflow.com/questions/4965159/how-to-redirect-output-with-subprocess-in-python/6482200#6482200?newreg=53afb91b3ebd47c5930be627fcdf2930) - `|` operator: [https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline](https://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline)
1 parent ef0559c commit 6f67a3a

File tree

20 files changed

+266
-167
lines changed

20 files changed

+266
-167
lines changed

device/quanta/x86_64-quanta_ix1b_rglbmc-r0/plugins/psuutil.py

+21-17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os.path
88
import subprocess
99
import logging
10+
from sonic_py_common.general import check_output_pipe
1011

1112
try:
1213
from sonic_psu.psu_base import PsuBase
@@ -22,11 +23,13 @@ def show_log(txt):
2223
return
2324

2425

25-
def exec_cmd(cmd, show):
26+
def exec_cmd(cmd_args, out_file, show):
27+
cmd = ' '.join(cmd_args) + ' > ' + out_file
2628
logging.info('Run :'+cmd)
2729
try:
28-
output = subprocess.check_output(cmd, shell=True, universal_newlines=True)
29-
show_log(cmd + "output:"+str(output))
30+
with open(out_file, 'w') as f:
31+
output = subprocess.check_output(cmd_args, stdout=f, universal_newlines=True)
32+
show_log(cmd + "output:"+str(output))
3033
except subprocess.CalledProcessError as e:
3134
logging.info("Failed :"+cmd)
3235
if show:
@@ -40,12 +43,13 @@ def my_log(txt):
4043
return
4144

4245

43-
def log_os_system(cmd, show):
46+
def log_os_system(cmd1_args, cmd2_args, show):
47+
cmd = ' '.join(cmd1_args) + ' | ' + ' '.join(cmd2_args)
4448
logging.info('Run :'+cmd)
4549
status = 1
4650
output = ""
4751
try:
48-
output = subprocess.check_output(cmd, shell=True, universal_newlines=True)
52+
output = check_output_pipe(cmd1_args, cmd2_args)
4953
my_log(cmd + "output:"+str(output))
5054
except subprocess.CalledProcessError as e:
5155
logging.info('Failed :'+cmd)
@@ -55,28 +59,28 @@ def log_os_system(cmd, show):
5559

5660

5761
def gpio16_exist():
58-
ls = log_os_system("ls /sys/class/gpio/ | grep gpio16", 0)
62+
ls = log_os_system(["ls", "/sys/class/gpio/"], ["grep", "gpio16"], 0)
5963
logging.info('mods:'+ls)
6064
if len(ls) == 0:
6165
return False
6266

6367

6468
def gpio17_exist():
65-
ls = log_os_system("ls /sys/class/gpio/ | grep gpio17", 0)
69+
ls = log_os_system(["ls", "/sys/class/gpio/"], ["grep", "gpio17"], 0)
6670
logging.info('mods:'+ls)
6771
if len(ls) == 0:
6872
return False
6973

7074

7175
def gpio19_exist():
72-
ls = log_os_system("ls /sys/class/gpio/ | grep gpio19", 0)
76+
ls = log_os_system(["ls", "/sys/class/gpio/"], ["grep", "gpio19"], 0)
7377
logging.info('mods:'+ls)
7478
if len(ls) == 0:
7579
return False
7680

7781

7882
def gpio20_exist():
79-
ls = log_os_system("ls /sys/class/gpio/ | grep gpio20", 0)
83+
ls = log_os_system(["ls", "/sys/class/gpio/"], ["grep", "gpio20"], 0)
8084
logging.info('mods:'+ls)
8185
if len(ls) == 0:
8286
return False
@@ -95,20 +99,20 @@ def __init__(self):
9599
PsuBase.__init__(self)
96100

97101
if gpio16_exist() == False:
98-
output = exec_cmd("echo 16 > /sys/class/gpio/export ", 1)
99-
output = exec_cmd("echo in > /sys/class/gpio/gpio16/direction ", 1)
102+
output = exec_cmd(["echo", "16"], "/sys/class/gpio/export", 1)
103+
output = exec_cmd(["echo", "in"], "/sys/class/gpio/gpio16/direction", 1)
100104

101105
if gpio17_exist() == False:
102-
output = exec_cmd("echo 17 > /sys/class/gpio/export ", 1)
103-
output = exec_cmd("echo in > /sys/class/gpio/gpio17/direction ", 1)
106+
output = exec_cmd(["echo", "17"], "/sys/class/gpio/export", 1)
107+
output = exec_cmd(["echo", "in"], "/sys/class/gpio/gpio17/direction", 1)
104108

105109
if gpio19_exist() == False:
106-
output = exec_cmd("echo 19 > /sys/class/gpio/export ", 1)
107-
output = exec_cmd("echo in > /sys/class/gpio/gpio19/direction ", 1)
110+
output = exec_cmd(["echo", "19"], "/sys/class/gpio/export", 1)
111+
output = exec_cmd(["echo", "in"], "/sys/class/gpio/gpio19/direction", 1)
108112

109113
if gpio20_exist() == False:
110-
output = exec_cmd("echo 20 > /sys/class/gpio/export ", 1)
111-
output = exec_cmd("echo in > /sys/class/gpio/gpio20/direction ", 1)
114+
output = exec_cmd(["echo", "20"], "/sys/class/gpio/export", 1)
115+
output = exec_cmd(["echo", "in"], "/sys/class/gpio/gpio20/direction", 1)
112116

113117
# Get sysfs attribute
114118
def get_attr_value(self, attr_path):

platform/broadcom/sonic-platform-modules-quanta/ix1b-32x/utils/quanta_ix1b_util.py

+18-19
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,19 @@
2727
clean : uninstall drivers and remove related sysfs nodes
2828
"""
2929

30-
import os
3130
import commands
3231
import sys, getopt
3332
import logging
34-
import re
3533
import time
36-
from collections import namedtuple
3734

3835
DEBUG = False
3936
args = []
4037
FORCE = 0
4138
i2c_prefix = '/sys/bus/i2c/devices/'
4239

4340
if DEBUG == True:
44-
print sys.argv[0]
45-
print 'ARGV :', sys.argv[1:]
41+
print(sys.argv[0])
42+
print('ARGV :', sys.argv[1:])
4643

4744
def main():
4845
global DEBUG
@@ -56,10 +53,10 @@ def main():
5653
'debug',
5754
'force',
5855
])
59-
if DEBUG == True:
60-
print options
61-
print args
62-
print len(sys.argv)
56+
if DEBUG is True:
57+
print(options)
58+
print(args)
59+
print(len(sys.argv))
6360

6461
for opt, arg in options:
6562
if opt in ('-h', '--help'):
@@ -83,12 +80,12 @@ def main():
8380
return 0
8481

8582
def show_help():
86-
print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
83+
print(__doc__ % {'scriptName' : sys.argv[0].split("/")[-1]})
8784
sys.exit(0)
8885

8986
def show_log(txt):
90-
if DEBUG == True:
91-
print "[IX1B-32X]" + txt
87+
if DEBUG is True:
88+
print("[IX1B-32X]" + txt)
9289

9390
return
9491

@@ -165,7 +162,7 @@ def system_install():
165162
status, output = exec_cmd("modprobe " + drivers[i], 1)
166163

167164
if status:
168-
print output
165+
print(output)
169166
if FORCE == 0:
170167
return status
171168

@@ -174,7 +171,7 @@ def system_install():
174171
status, output = exec_cmd(instantiate[i], 1)
175172

176173
if status:
177-
print output
174+
print(output)
178175
if FORCE == 0:
179176
return status
180177

@@ -184,7 +181,9 @@ def system_install():
184181
#QSFP for 1~32 port
185182
for port_number in range(1, 33):
186183
bus_number = port_number + 31
187-
os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number))
184+
file = "/sys/bus/i2c/devices/%d-0050/port_name" % bus_number
185+
with open(file, 'w') as f:
186+
f.write(str(port_number) + '\n')
188187

189188
#Set system LED to green
190189
status, output = exec_cmd("echo 1 > /sys/class/leds/sysled_green/brightness", 1)
@@ -199,14 +198,14 @@ def system_ready():
199198

200199
def install():
201200
if not device_found():
202-
print "No device, installing...."
201+
print("No device, installing....")
203202
status = system_install()
204203

205204
if status:
206205
if FORCE == 0:
207206
return status
208207
else:
209-
print " ix1b driver already installed...."
208+
print(" ix1b driver already installed....")
210209

211210
return
212211

@@ -215,10 +214,10 @@ def uninstall():
215214

216215
#uninstall drivers
217216
for i in range(len(drivers) - 1, -1, -1):
218-
status, output = exec_cmd("rmmod " + drivers[i], 1)
217+
status, output = exec_cmd("rmmod " + drivers[i], 1)
219218

220219
if status:
221-
print output
220+
print(output)
222221
if FORCE == 0:
223222
return status
224223

platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/component.py

+22-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import subprocess
1515
from sonic_platform_base.component_base import ComponentBase
1616
from collections import namedtuple
17+
from sonic_py_common.general import getstatusoutput_noshell_pipe
1718
except ImportError as e:
1819
raise ImportError(str(e) + "- required module not found")
1920

@@ -47,7 +48,7 @@ def _get_command_result(cmdline):
4748
try:
4849
proc = subprocess.Popen(cmdline,
4950
stdout=subprocess.PIPE,
50-
shell=True, stderr=subprocess.STDOUT,
51+
stderr=subprocess.STDOUT,
5152
universal_newlines=True)
5253
stdout = proc.communicate()[0]
5354
rc = proc.wait()
@@ -60,12 +61,24 @@ def _get_command_result(cmdline):
6061

6162
return result
6263

64+
@staticmethod
65+
def _get_command_result_pipe(cmd1, cmd2):
66+
try:
67+
rc, result = getstatusoutput_noshell_pipe(cmd1, cmd2)
68+
if rc != [0, 0]:
69+
raise RuntimeError("Failed to execute command {} {}, return code {}, {}".format(cmd1, cmd2, rc, result))
70+
71+
except OSError as e:
72+
raise RuntimeError("Failed to execute command {} {} due to {}".format(cmd1, cmd2, repr(e)))
73+
74+
return result
75+
6376

6477
class ComponentBIOS(Component):
6578
COMPONENT_NAME = 'BIOS'
6679
COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System'
6780

68-
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s bios-version"
81+
BIOS_QUERY_VERSION_COMMAND = ["dmidecode", "-s", "bios-version"]
6982

7083
def __init__(self):
7184
super(ComponentBIOS, self).__init__()
@@ -90,7 +103,8 @@ def get_firmware_version(self):
90103
class ComponentBMC(Component):
91104
COMPONENT_NAME = 'BMC'
92105
COMPONENT_DESCRIPTION = 'BMC - Board Management Controller'
93-
BMC_QUERY_VERSION_COMMAND = "ipmitool mc info | grep 'Firmware Revision'"
106+
BMC_QUERY_VERSION_COMMAND1 = ["ipmitool", "mc", "info"]
107+
BMC_QUERY_VERSION_COMMAND2 = ["grep", 'Firmware Revision']
94108

95109
def __init__(self):
96110
super(ComponentBMC, self).__init__()
@@ -105,7 +119,7 @@ def get_firmware_version(self):
105119
Returns:
106120
A string containing the firmware version of the component
107121
"""
108-
bmc_ver = self._get_command_result(self.BMC_QUERY_VERSION_COMMAND)
122+
bmc_ver = self._get_command_result_pipe(self.BMC_QUERY_VERSION_COMMAND1, self.BMC_QUERY_VERSION_COMMAND2)
109123
if not bmc_ver:
110124
return 'ERR'
111125
else:
@@ -159,7 +173,7 @@ def get_firmware_version(self):
159173
Returns:
160174
A string containing the firmware version of the component
161175
"""
162-
res = self._get_command_result("ipmitool raw 0x32 0xff 0x02 {}".format(self.cplds[self.index].cmd_index))
176+
res = self._get_command_result(["ipmitool", "raw", "0x32", "0xff", "0x02", str(self.cplds[self.index].cmd_index)])
163177
if not res:
164178
return 'ERR'
165179
else:
@@ -179,7 +193,8 @@ def get_component_list(cls):
179193
class ComponentPCIE(Component):
180194
COMPONENT_NAME = 'PCIe'
181195
COMPONENT_DESCRIPTION = 'ASIC PCIe Firmware'
182-
PCIE_QUERY_VERSION_COMMAND = "bcmcmd 'pciephy fw version' | grep 'FW version'"
196+
PCIE_QUERY_VERSION_COMMAND1 = ["bcmcmd", 'pciephy fw version']
197+
PCIE_QUERY_VERSION_COMMAND2 = ["grep", 'FW version']
183198

184199
def __init__(self):
185200
super(ComponentPCIE, self).__init__()
@@ -194,7 +209,7 @@ def get_firmware_version(self):
194209
Returns:
195210
A string containing the firmware version of the component
196211
"""
197-
version = self._get_command_result(self.PCIE_QUERY_VERSION_COMMAND)
212+
version = self._get_command_result_pipe(self.PCIE_QUERY_VERSION_COMMAND1, self.PCIE_QUERY_VERSION_COMMAND2)
198213
if not version:
199214
return 'ERR'
200215
else:

platform/broadcom/sonic-platform-modules-quanta/ix7-32x/sonic_platform/sfp.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@
88
#
99
#############################################################################
1010

11-
import os
1211
import time
12+
import subprocess
1313
from ctypes import create_string_buffer
1414

1515
try:
16-
from sonic_platform_base.sfp_base import SfpBase
17-
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
18-
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
19-
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
20-
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
21-
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
16+
from sonic_platform_base.sfp_base import SfpBase
17+
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
18+
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
19+
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
20+
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
21+
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
2222
except ImportError as e:
2323
raise ImportError(str(e) + "- required module not found")
2424

@@ -163,7 +163,7 @@ class Sfp(SfpBase):
163163
# Path to QSFP sysfs
164164
PLATFORM_ROOT_PATH = "/usr/share/sonic/device"
165165
PMON_HWSKU_PATH = "/usr/share/sonic/hwsku"
166-
HOST_CHK_CMD = "docker > /dev/null 2>&1"
166+
HOST_CHK_CMD = ["docker"]
167167

168168
PLATFORM = "x86_64-quanta_ix7_rglbmc-r0"
169169
HWSKU = "Quanta-IX7-32X"
@@ -259,7 +259,7 @@ def _convert_string_to_num(self, value_str):
259259
return 'N/A'
260260

261261
def __is_host(self):
262-
return os.system(self.HOST_CHK_CMD) == 0
262+
return subprocess.call(self.HOST_CHK_CMD) == 0
263263

264264
def __get_path_to_port_config_file(self):
265265
platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM])

platform/broadcom/sonic-platform-modules-quanta/ix7-32x/utils/quanta_ix7_util.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
clean : uninstall drivers and remove related sysfs nodes
2828
"""
2929

30-
import os
3130
import subprocess
3231
import sys, getopt
3332
import logging
@@ -54,7 +53,7 @@ def main():
5453
'debug',
5554
'force',
5655
])
57-
if DEBUG == True:
56+
if DEBUG is True:
5857
print(options)
5958
print(args)
6059
print(len(sys.argv))
@@ -84,7 +83,7 @@ def show_help():
8483
sys.exit(0)
8584

8685
def show_log(txt):
87-
if DEBUG == True:
86+
if DEBUG is True:
8887
print("[IX7-32X]" + txt)
8988
return
9089

@@ -204,7 +203,9 @@ def system_install():
204203
#QSFP for 1~32 port
205204
for port_number in range(1, 33):
206205
bus_number = port_number + 16
207-
os.system("echo %d >/sys/bus/i2c/devices/%d-0050/port_name" % (port_number, bus_number))
206+
file = "/sys/bus/i2c/devices/%d-0050/port_name" % bus_number
207+
with open(file, 'w') as f:
208+
f.write(str(port_number) + '\n')
208209
return
209210

210211

0 commit comments

Comments
 (0)