Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[device/celestica] Mitigation for command injection vulnerability #11740

Merged
merged 30 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
956da45
Improve command injection in subprocess and eval
maipbui Aug 15, 2022
8811f7a
Use literal_evals instead of eval
maipbui Aug 15, 2022
652921f
Add sanitize command input
maipbui Aug 15, 2022
c24eec3
Remove globals()
maipbui Aug 15, 2022
9ca1d96
Fix syntax error
maipbui Aug 15, 2022
ca56944
Fix command in subprocess
maipbui Aug 16, 2022
ba61fd4
Change data structure and fix static input in subprocess
maipbui Aug 17, 2022
cebc440
Remove unnecessary parameters
maipbui Aug 18, 2022
0a5d46a
Fix static subprocess
maipbui Aug 18, 2022
dada9ae
Remove os.system and subprocess shell=True
maipbui Sep 1, 2022
91781fe
Fix lgtm
maipbui Sep 1, 2022
6647f81
Fix lgtm
maipbui Sep 1, 2022
35aedce
Remove unused funcs and fix subprocess cmd
maipbui Sep 6, 2022
a7b8055
Remove brackets
maipbui Sep 6, 2022
ec603a0
Add p1 returncod checkere
maipbui Sep 7, 2022
3166477
Replace unsafe functions in platform directory
maipbui Sep 15, 2022
edd4aec
Fix command
maipbui Sep 16, 2022
2d5d44c
Fix command
maipbui Sep 16, 2022
7460c9f
Fix command
maipbui Sep 16, 2022
8ac59ab
Use common lib function
maipbui Sep 18, 2022
f1365f5
Fix PR comments
maipbui Sep 21, 2022
96bc208
Change sp run to call and add \n
maipbui Sep 21, 2022
552abed
Replace shell=True
maipbui Sep 21, 2022
65b4300
fix bug
maipbui Sep 21, 2022
0ce54ef
Add universal_newliness for py3
maipbui Sep 21, 2022
a971633
Merge remote-tracking branch 'upstream/master' into celestica_e1031_s…
maipbui Oct 5, 2022
bba06ff
Revert solution
maipbui Oct 6, 2022
92147d7
Revert deleted line
maipbui Oct 6, 2022
22bad5e
Address PR comments
maipbui Dec 8, 2022
34991a5
Address PR comments
maipbui Dec 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions device/celestica/x86_64-cel_e1031-r0/sonic_platform/common.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import os
import ast
import imp
import yaml
import subprocess

from shlex import split
from sonic_py_common import device_info


Expand Down Expand Up @@ -47,7 +48,7 @@ def run_command(self, command):
output = ""
try:
p = subprocess.Popen(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
split(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if p.returncode == 0:
status, output = True, raw_data.strip()
Expand All @@ -67,7 +68,7 @@ def _clean_input(self, input, config):
cleaned_input = input_translator.get(input)

elif type(input_translator) is str:
cleaned_input = eval(input_translator.format(input))
cleaned_input = ast.literal_eval(input_translator.format(input))

return cleaned_input

Expand All @@ -77,9 +78,9 @@ def _clean_output(self, index, output, config):
if type(output_translator) is dict:
output = output_translator.get(output)
elif type(output_translator) is str:
output = eval(output_translator.format(output))
output = ast.literal_eval(output_translator.format(output))
elif type(output_translator) is list:
output = eval(output_translator[index].format(output))
output = ast.literal_eval(output_translator[index].format(output))

return output

Expand Down Expand Up @@ -195,7 +196,8 @@ def write_txt_file(self, file_path, value):
return True

def is_host(self):
return os.system(self.HOST_CHK_CMD) == 0
command = split(self.HOST_CHK_CMD)
return subprocess.run(command).returncode == 0
maipbui marked this conversation as resolved.
Show resolved Hide resolved

def load_json_file(self, path):
"""
Expand Down
10 changes: 5 additions & 5 deletions device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
try:
import os.path
import shutil
import shlex
import subprocess
from shlex import split
from sonic_platform_base.component_base import ComponentBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
Expand Down Expand Up @@ -40,7 +40,7 @@ def __run_command(self, command):
# Run bash command and print output to stdout
try:
process = subprocess.Popen(
shlex.split(command), universal_newlines=True, stdout=subprocess.PIPE)
split(command), universal_newlines=True, stdout=subprocess.PIPE)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
Expand All @@ -65,7 +65,7 @@ def get_register_value(self, register):
# Retrieves the cpld register value
cmd = "echo {1} > {0}; cat {0}".format(GETREG_PATH, register)
p = subprocess.Popen(
cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
split(cmd), universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if err is not '':
return None
Expand All @@ -76,11 +76,11 @@ def __get_cpld_version(self):
cpld_version = dict()
with open(SMC_CPLD_PATH, 'r') as fd:
smc_cpld_version = fd.read()
smc_cpld_version = 'None' if smc_cpld_version is 'None' else "{}.{}".format(
smc_cpld_version = 'None' if smc_cpld_version == 'None' else "{}.{}".format(
int(smc_cpld_version[2], 16), int(smc_cpld_version[3], 16))

mmc_cpld_version = self.get_register_value(MMC_CPLD_ADDR)
mmc_cpld_version = 'None' if mmc_cpld_version is 'None' else "{}.{}".format(
mmc_cpld_version = 'None' if mmc_cpld_version == 'None' else "{}.{}".format(
int(mmc_cpld_version[2], 16), int(mmc_cpld_version[3], 16))

cpld_version["SMC_CPLD"] = smc_cpld_version
Expand Down
25 changes: 10 additions & 15 deletions device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,15 @@
PSU_LED_GREEN_CMD = "0x01"
PSU_LED_AMBER_CMD = "0x02"

PSU1_VOUT_SS_ID = "0x36"
PSU1_COUT_SS_ID = "0x37"
PSU1_POUT_SS_ID = "0x38"
PSU1_STATUS_REG = "0x39"

PSU2_VOUT_SS_ID = "0x40"
PSU2_COUT_SS_ID = "0x41"
PSU2_POUT_SS_ID = "0x42"
PSU2_STATUS_REG = "0x2f"

PSU1_FRU_ID = 3

SS_READ_OFFSET = 0

PSU_VOUT_SS_ID = {"PSU1_VOUT_SS_ID": "0x36", "PSU2_VOUT_SS_ID": "0x40"}
maipbui marked this conversation as resolved.
Show resolved Hide resolved
PSU_COUT_SS_ID = {"PSU1_COUT_SS_ID": "0x37", "PSU2_COUT_SS_ID": "0x41"}
PSU_POUT_SS_ID = {"PSU1_POUT_SS_ID": "0x38", "PSU2_POUT_SS_ID": "0x42"}
PSU_STATUS_REG = {"PSU1_STATUS_REG": "0x39", "PSU2_STATUS_REG": "0x2f"}


class Psu(PsuBase):
"""Platform-specific Psu class"""
Expand All @@ -71,7 +66,7 @@ def get_voltage(self):
e.g. 12.1
"""
psu_voltage = 0.0
psu_vout_key = globals()['PSU{}_VOUT_SS_ID'.format(self.index+1)]
psu_vout_key = PSU_VOUT_SS_ID['PSU{}_VOUT_SS_ID'.format(self.index+1)]
status, raw_ss_read = self._api_helper.ipmi_raw(
IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_vout_key))
ss_read = raw_ss_read.split()[SS_READ_OFFSET]
Expand All @@ -87,7 +82,7 @@ def get_current(self):
A float number, the electric current in amperes, e.g 15.4
"""
psu_current = 0.0
psu_cout_key = globals()['PSU{}_COUT_SS_ID'.format(self.index+1)]
psu_cout_key = PSU_COUT_SS_ID['PSU{}_COUT_SS_ID'.format(self.index+1)]
status, raw_ss_read = self._api_helper.ipmi_raw(
IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_cout_key))
ss_read = raw_ss_read.split()[SS_READ_OFFSET]
Expand All @@ -103,7 +98,7 @@ def get_power(self):
A float number, the power in watts, e.g. 302.6
"""
psu_power = 0.0
psu_pout_key = globals()['PSU{}_POUT_SS_ID'.format(self.index+1)]
psu_pout_key = PSU_POUT_SS_ID['PSU{}_POUT_SS_ID'.format(self.index+1)]
status, raw_ss_read = self._api_helper.ipmi_raw(
IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pout_key))
ss_read = raw_ss_read.split()[SS_READ_OFFSET]
Expand Down Expand Up @@ -176,7 +171,7 @@ def get_presence(self):
bool: True if PSU is present, False if not
"""
psu_presence = False
psu_pstatus_key = globals()['PSU{}_STATUS_REG'.format(self.index+1)]
psu_pstatus_key = PSU_STATUS_REG['PSU{}_STATUS_REG'.format(self.index+1)]
status, raw_status_read = self._api_helper.ipmi_raw(
IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pstatus_key))
status_byte = self.find_value(raw_status_read)
Expand Down Expand Up @@ -228,7 +223,7 @@ def get_status(self):
A boolean value, True if device is operating properly, False if not
"""
psu_status = False
psu_pstatus_key = globals()['PSU{}_STATUS_REG'.format(self.index+1)]
psu_pstatus_key = PSU_STATUS_REG['PSU{}_STATUS_REG'.format(self.index+1)]
status, raw_status_read = self._api_helper.ipmi_raw(
IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pstatus_key))
status_byte = self.find_value(raw_status_read)
Expand Down