Skip to content

Commit 2f6b34a

Browse files
authored
[device/juniper] Mitigation for security vulnerability (#11838)
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 `commands` module is not secure command injection in `getstatusoutput` being used without a static string #### How I did it Eliminate `commands` module, use `subprocess` module only Convert Python 2 to Python 3
1 parent 283de9a commit 2f6b34a

File tree

8 files changed

+151
-136
lines changed

8 files changed

+151
-136
lines changed

device/juniper/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py

+11-13
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,9 @@
3434

3535
import binascii
3636
import os
37-
import sys
37+
import subprocess
3838
from sonic_eeprom import eeprom_tlvinfo
39-
40-
if sys.version_info[0] < 3:
41-
import commands
42-
else:
43-
import subprocess as commands
39+
from sonic_py_common.general import getstatusoutput_noshell
4440

4541

4642
def fantype_detect():
@@ -56,9 +52,7 @@ def fantype_detect():
5652
for filename in os.listdir(refpgaTMC_path):
5753
if filename.endswith('_type'):
5854
fantype_path = os.path.join(refpgaTMC_path, filename)
59-
cat_string = "cat "
60-
fantype_string = cat_string + fantype_path
61-
status, fan_type = commands.getstatusoutput(fantype_string)
55+
status, fan_type = getstatusoutput_noshell(['cat', fantype_path])
6256
if ((fan_type == AFO) or (fan_type == AFI)):
6357
return fan_type
6458
else:
@@ -176,17 +170,21 @@ def main():
176170
eeprom_file.write("Main board eeprom (0x57)\r\n")
177171
eeprom_file.write("===============================\r\n")
178172

179-
MainEepromCreate = 'sudo echo 24c02 0x57 > /sys/bus/i2c/devices/i2c-0/new_device'
173+
MainEepromCreate = '24c02 0x57'
174+
out_file = '/sys/bus/i2c/devices/i2c-0/new_device'
180175
# Write the contents of Main Board EEPROM to file
181176
try:
182-
os.system(MainEepromCreate)
177+
with open(out_file, 'w') as file:
178+
file.write(MainEepromCreate)
183179
except OSError:
184180
print('Error: Execution of "%s" failed', MainEepromCreate)
185181
return False
186182

187-
MainEepromFileCmd = 'cat /sys/bus/i2c/devices/i2c-0/0-0057/eeprom > /etc/init.d/MainEeprom_qfx5200_ascii'
183+
MainEepromFileCmd = ['cat', '/sys/bus/i2c/devices/i2c-0/0-0057/eeprom']
184+
out_file = '/etc/init.d/MainEeprom_qfx5200_ascii'
188185
try:
189-
os.system(MainEepromFileCmd)
186+
with open(out_file, 'w') as file:
187+
subprocess.call(MainEepromFileCmd, universal_newlines=True, stdout=file)
190188
except OSError:
191189
print('Error: Execution of "%s" failed', MainEepromFileCmd)
192190
return False

device/juniper/x86_64-juniper_qfx5210-r0/plugins/qfx5210_eeprom_data.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
# components is subject to the terms and conditions of the respective license
3333
# as noted in the Third-Party source code file.
3434

35-
import os
3635
import binascii
36+
import subprocess
3737
from sonic_eeprom import eeprom_tlvinfo
3838

3939

@@ -81,10 +81,12 @@ def main():
8181
eeprom_file.write("Vendor Name=%s\r\n" % eeprom_qfx5210.vendor_name_str())
8282
eeprom_file.write("Manufacture Name=%s\r\n" % eeprom_qfx5210.manufacture_name_str())
8383

84-
CPUeepromFileCmd = 'cat /sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom > /etc/init.d/eeprom_qfx5210_ascii'
84+
CPUeepromFileCmd = ['cat', '/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom']
8585
# Write the contents of CPU EEPROM to file
86+
out_file = '/etc/init.d/eeprom_qfx5210_ascii'
8687
try:
87-
os.system(CPUeepromFileCmd)
88+
with open(out_file, 'w') as file:
89+
subprocess.call(CPUeepromFileCmd, universal_newlines=True, stdout=file)
8890
except OSError:
8991
print('Error: Execution of "%s" failed', CPUeepromFileCmd)
9092
return False

platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_monitor.py

+18-16
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@
3434

3535
try:
3636
import os
37-
import commands
3837
import subprocess
3938
import logging
4039
import logging.config
4140
import logging.handlers
4241
import time
4342
import glob
4443
import re
44+
from sonic_py_common.general import getstatusoutput_noshell
4545
except ImportError as e:
4646
raise ImportError('%s - required module not found' % str(e))
4747

@@ -172,24 +172,27 @@ def get_fan_dutycycle(self):
172172
pwm_value = 0
173173
pwm_value1 = 0
174174
device_path = self._pwm_input_path_mapping[x]
175-
cmd = ("sudo cat %s" %(device_path))
176-
status, pwm_value = commands.getstatusoutput(cmd)
175+
cmd = ["sudo", "cat", device_path]
176+
status, pwm_value = getstatusoutput_noshell(cmd)
177177
pwm_value1 = int(pwm_value)
178178
time.sleep(0.25)
179179
if int(pwm_value1) > 0:
180180
ret_value = fan_speed.get(int(pwm_value))
181181
break
182182

183183
return int(ret_value)
184+
185+
def write_file(self, text, file):
186+
with open(file, 'w') as f:
187+
f.write(text + '\n')
184188

185189
def set_fan_dutycycle(self, val):
186190
fan_speed = {35: 86, 55: 139, 75: 192, 90: 230,100: 255}
187191
for x in range(self.PWMINPUT_NUM):
188192
device_path = self._pwm_input_path_mapping[x]
189193
pwm_value = fan_speed.get(val)
190194
pwm_value1 = str(pwm_value)
191-
cmd = ("sudo echo %s > %s" %(pwm_value1,device_path))
192-
os.system(cmd)
195+
self.write_file(pwm_value1,device_path)
193196
time.sleep(0.25)
194197
logging.debug('Setting PWM value: %s to all fans', pwm_value1)
195198
return True
@@ -198,8 +201,8 @@ def get_check_fan_dutycycle(self):
198201
pwm_str = ''
199202
for x in range(self.PWMINPUT_NUM):
200203
device_path = self._pwm_input_path_mapping[x]
201-
cmd = ("sudo cat %s" %(device_path))
202-
status, pwm_value = commands.getstatusoutput(cmd)
204+
cmd = ["sudo", "cat", device_path]
205+
status, pwm_value = getstatusoutput_noshell(cmd)
203206
pwm_str += pwm_value
204207
if (x != self.PWMINPUT_NUM -1):
205208
pwm_str += ', '
@@ -495,8 +498,8 @@ def getSensorTemp(self):
495498
else:
496499
proc = subprocess.Popen("bcmcmd \"show temp\" | grep \"maximum peak temperature\" | awk '{ print $5 }' > /var/log/asic_value 2>&1 & ",shell=True)
497500
time.sleep(2)
498-
cmd = "kill -9 %s"%(proc.pid)
499-
commands.getstatusoutput(cmd)
501+
cmd = ["kill", "-9", proc.pid]
502+
getstatusoutput_noshell(cmd)
500503

501504
if os.stat("/var/log/asic_value").st_size == 0:
502505
value = PrevASICValue
@@ -568,7 +571,7 @@ def getSensorTemp(self):
568571
or SensorFlag[8][11] or SensorFlag[9][11] or SensorFlag[10][11] or SensorFlag[11][11]):
569572

570573
logging.debug('Fire Threshold reached: System is going to shutdown now')
571-
os.system("echo 'CRITICAL: Fire Threshold reached: System is going to shutdown now' > /dev/console")
574+
self.write_file('CRITICAL: Fire Threshold reached: System is going to shutdown now', "/dev/console")
572575

573576

574577
logging.debug('Executing poweroff command')
@@ -583,8 +586,8 @@ def getSensorTemp(self):
583586

584587
monitorlog_file.close()
585588

586-
cmd = "poweroff"
587-
os.system(cmd)
589+
cmd = ["poweroff"]
590+
subprocess.call(cmd)
588591

589592
# CHECK IF ANY TEMPERATURE SENSORS is running at RED warning , IF YES, SET THE ALARM LED TO 'RED'
590593
elif (SensorFlag[0][10] or SensorFlag[1][10] or SensorFlag[2][10] or SensorFlag[3][10] or SensorFlag[4][10] or SensorFlag[5][10] or SensorFlag[6][10] or SensorFlag[7][10]
@@ -878,8 +881,7 @@ def set_Default_fan_dutycycle(self, val):
878881
pwm_value = fan_speed.get(val)
879882
pwm_value1 = str(pwm_value)
880883
time.sleep(0.25)
881-
cmd = ("sudo echo %s > %s" %(pwm_value1,device_path))
882-
os.system(cmd)
884+
self.write_file(pwm_value1, device_path)
883885

884886
logging.debug('Setting Default PWM value: 86 to all fans')
885887
return True
@@ -888,8 +890,8 @@ def get_Initial_fan_dutycycle(self):
888890
pwm_str = ''
889891
for x in range(self.PWMINPUT_NUM):
890892
device_path = self._pwm_input_path_mapping[x]
891-
cmd = ("sudo cat %s" %(device_path))
892-
status, pwm_value = commands.getstatusoutput(cmd)
893+
cmd = ["sudo", "cat", device_path]
894+
status, pwm_value = getstatusoutput_noshell(cmd)
893895
pwm_str += pwm_value
894896
if (x != self.PWMINPUT_NUM -1):
895897
pwm_str += ', '

platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/juniper_qfx5200_util.py

+37-30
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@
2323
import sys
2424
import logging
2525
import time
26+
import subprocess
27+
from sonic_py_common.general import getstatusoutput_noshell
2628

2729
PROJECT_NAME = 'QFX5200-32C'
2830
verbose = False
2931
DEBUG = False
3032
FORCE = 0
3133

3234
if DEBUG == True:
33-
print sys.argv[0]
34-
print 'ARGV :', sys.argv[1:]
35+
print(sys.argv[0])
36+
print('ARGV :', sys.argv[1:])
3537

3638
i2c_prefix = '/sys/bus/i2c/devices/'
3739

@@ -70,7 +72,7 @@
7072

7173
def my_log(txt):
7274
if DEBUG == True:
73-
print txt
75+
print(txt)
7476
return
7577

7678
def log_os_system(cmd, show):
@@ -83,6 +85,10 @@ def log_os_system(cmd, show):
8385
if show:
8486
print('Failed :'+cmd)
8587
return status, output
88+
89+
def write_file(text, file):
90+
with open(file, 'w') as f:
91+
f.write(text + '\n')
8692

8793
def driver_install():
8894
global FORCE
@@ -106,7 +112,7 @@ def device_install():
106112
for i in range(0,len(mknod)):
107113
status, output = log_os_system(mknod[i], 1)
108114
if status:
109-
print output
115+
print(output)
110116
if FORCE == 0:
111117
return status
112118

@@ -123,7 +129,7 @@ def do_install():
123129
if FORCE == 0:
124130
return status
125131
else:
126-
print PROJECT_NAME.upper()+" devices detected...."
132+
print(PROJECT_NAME.upper()+" devices detected....")
127133
return
128134

129135
def main():
@@ -139,70 +145,71 @@ def main():
139145

140146

141147
# Enabling REFPGA
142-
EnableREFFGACmd = 'busybox devmem 0xFED50011 8 0x53'
148+
EnableREFFGACmd = ['busybox', 'devmem', '0xFED50011', '8', '0x53']
143149
try:
144-
os.system(EnableREFFGACmd)
150+
subprocess.call(EnableREFFGACmd)
145151
except OSError:
146-
print 'Error: Execution of "%s" failed', EnableREFFGACmd
152+
print('Error: Execution of "%s" failed', EnableREFFGACmd)
147153
return False
148154

149155
time.sleep(2)
150156

151157
# Create CPU Board EEPROM device
152-
CreateEEPROMdeviceCmd = 'sudo echo 24c02 0x51 > /sys/bus/i2c/devices/i2c-0/new_device'
158+
CreateEEPROMdeviceCmd = '24c02 0x51'
159+
file = '/sys/bus/i2c/devices/i2c-0/new_device'
153160
try:
154-
os.system(CreateEEPROMdeviceCmd)
161+
write_file(CreateEEPROMdeviceCmd, file)
155162
except OSError:
156-
print 'Error: Execution of "%s" failed', CreateEEPROMdeviceCmd
163+
print('Error: Execution of "%s" failed', CreateEEPROMdeviceCmd)
157164
return False
158165

159166
time.sleep(1)
160167

161168
#Retrieve the Base MAC Address from EEPROM
162-
status, macAddress = commands.getstatusoutput("decode-syseeprom -m 0x24")
169+
status, macAddress = getstatusoutput_noshell(["decode-syseeprom", "-m", "0x24"])
163170
if status:
164-
print 'Error: Could not retrieve BASE MAC Address from EEPROM'
171+
print('Error: Could not retrieve BASE MAC Address from EEPROM')
165172
return False
166173

167174
#Make eth0 interface down
168-
status, eth0Down = commands.getstatusoutput("ifconfig eth0 down")
175+
status, eth0Down = getstatusoutput_noshell(["ifconfig", "eth0", "down"])
169176
if status:
170-
print 'Error: Could not make eth0 interface down'
177+
print('Error: Could not make eth0 interface down')
171178
return False
172179

173180
#Assign BASE MAC ADDRESS retieved from CPU board EEPROM to eth0 interface
174-
mac_address_prog = "ifconfig eth0 hw ether " + str(macAddress)
181+
mac_address_prog = ["ifconfig", "eth0", "hw", "ether", str(macAddress)]
175182

176-
status, MACAddressProg = commands.getstatusoutput(mac_address_prog)
183+
status, MACAddressProg = getstatusoutput_noshell(mac_address_prog)
177184
if status:
178-
print 'Error: Could not set up "macAddress" for eth0 interface'
185+
print('Error: Could not set up "macAddress" for eth0 interface')
179186
return False
180187

181188
#Make eth0 interface up
182-
status, eth0UP = commands.getstatusoutput("ifconfig eth0 up")
189+
status, eth0UP = getstatusoutput_noshell(["ifconfig", "eth0", "up"])
183190
if status:
184-
print 'Error: Could not make eth0 interface up'
191+
print('Error: Could not make eth0 interface up')
185192
return False
186193

187194
# Juniper QFX5200 platform drivers install
188195
do_install()
189196
time.sleep(2)
190197

191198
# Juniper SFP Intialization
192-
JuniperSFPInitCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py'
199+
JuniperSFPInitCmd = ['python', '/usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_sfp_init.py']
193200
try:
194-
os.system(JuniperSFPInitCmd)
201+
subprocess.call(JuniperSFPInitCmd)
195202
except OSError:
196-
print 'Error: Execution of "%s" failed', JuniperSFPInitCmd
203+
print('Error: Execution of "%s" failed', JuniperSFPInitCmd)
197204
return False
198205

199206
time.sleep(1)
200207
# Invoking the script which retrieves the data from CPU Board and Main Board EEPROM and storing in file
201-
EEPROMDataCmd = 'python /usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py'
208+
EEPROMDataCmd = ['python', '/usr/share/sonic/device/x86_64-juniper_qfx5200-r0/plugins/qfx5200_eeprom_data.py']
202209
try:
203-
os.system(EEPROMDataCmd)
210+
subprocess.call(EEPROMDataCmd)
204211
except OSError:
205-
print 'Error: Execution of "%s" failed', EEPROMDataCmd
212+
print('Error: Execution of "%s" failed', EEPROMDataCmd)
206213
return False
207214

208215
for x in range(PWMINPUT_NUM):
@@ -218,16 +225,16 @@ def main():
218225
hwmon_dir)
219226
device_path = pwm_input_path_mapping[x]
220227
time.sleep(1)
221-
cmd = ("sudo echo 22500 > %s" %device_path)
222-
os.system(cmd)
228+
cmd = "22500"
229+
write_file(cmd, device_path)
223230

224231
numsensors_input_path_mapping[x] = NUMSENSORS_PATH.format(
225232
hwmon_input_node_mapping[x],
226233
hwmon_dir)
227234
numsensors_path = numsensors_input_path_mapping[x]
228235
time.sleep(1)
229-
cmd = ("sudo echo 0 > %s" %numsensors_path)
230-
os.system(cmd)
236+
cmd = "0"
237+
write_file(cmd, numsensors_path)
231238

232239
return True
233240

platform/broadcom/sonic-platform-modules-juniper/qfx5200/utils/show_thresholds

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22
import os
3-
import commands
3+
from sonic_py_common.general import getstatusoutput_noshell
44

55
def fantype_detect():
66

@@ -15,9 +15,8 @@ def fantype_detect():
1515
for filename in os.listdir(refpgaTMC_path):
1616
if filename.endswith('_type'):
1717
fantype_path = os.path.join(refpgaTMC_path, filename)
18-
cat_string = "cat "
19-
fantype_string = cat_string + fantype_path
20-
status,fan_type=commands.getstatusoutput(fantype_string)
18+
fantype_string = ["cat", fantype_path]
19+
status, fan_type = getstatusoutput_noshell(fantype_string)
2120
if ((fan_type == AFO) or (fan_type == AFI)):
2221
return fan_type
2322
else:

0 commit comments

Comments
 (0)