From 110ae398bfd974a3b16dbc20dce0a53af60d1d39 Mon Sep 17 00:00:00 2001 From: rabbitali Date: Sun, 4 Feb 2024 10:50:46 +0800 Subject: [PATCH 1/1] fix cve-2021-33633 --- ceres/function/util.py | 11 +++++---- ceres/manages/collect_manage.py | 18 +++++++-------- ceres/manages/list_file_manage.py | 2 +- ceres/manages/plugin_manage.py | 8 +++---- ceres/manages/resource_manage.py | 4 ++-- ceres/manages/vulnerability_manage.py | 32 +++++++++++++-------------- 6 files changed, 36 insertions(+), 39 deletions(-) diff --git a/ceres/function/util.py b/ceres/function/util.py index 433db09..1d3d9e3 100644 --- a/ceres/function/util.py +++ b/ceres/function/util.py @@ -15,7 +15,7 @@ import json import os import shlex import subprocess -from typing import Any, Tuple, NoReturn +from typing import Any, Tuple, NoReturn, Sequence from libconf import load, ConfigParseError, AttrDict from jsonschema import validate, ValidationError @@ -63,12 +63,12 @@ def validate_data(data: Any, schema: dict) -> bool: return False -def execute_shell_command(command: str, **kwargs) -> Tuple[int, str, str]: +def execute_shell_command(commands: Sequence[str], **kwargs) -> Tuple[int, str, str]: """ execute shell commands Args: - command(str): shell command which needs to execute + command(Sequence[str]): Multiple shell commands that need to be executed continuously **kwargs: keyword arguments, it is used to create Popen object.supported options: env, cwd, bufsize, group and so on. you can see more options information in annotation of Popen obejct. @@ -77,11 +77,10 @@ def execute_shell_command(command: str, **kwargs) -> Tuple[int, str, str]: a tuple containing three elements (return code, standard output, standard error). Example usage: - >>> return_code, stdout, stderr = execute_shell_command("ls -al|wc -l", **{"env": {"LANG": "en_US.utf-8"}}) + >>> return_code, stdout, stderr = execute_shell_command(["ls -al", "wc -l"], **{"env": {"LANG": "en_US.utf-8"}}) >>> print(return_code, stdout, stderr) 0, 42, "" """ - commands = command.split('|') process = None stdout_data = "" stderr_data = "" @@ -153,7 +152,7 @@ def plugin_status_judge(plugin_name: str) -> str: if service_name is None: LOGGER.warning(f"Fail to get service name about {plugin_name}") return "" - return_code, stdout, _ = execute_shell_command(f"systemctl status {service_name}|grep Active") + return_code, stdout, _ = execute_shell_command([f"systemctl status {service_name}", "grep Active"]) if return_code == CommandExitCode.SUCCEED: return stdout diff --git a/ceres/manages/collect_manage.py b/ceres/manages/collect_manage.py index ffc82e3..d499cfd 100644 --- a/ceres/manages/collect_manage.py +++ b/ceres/manages/collect_manage.py @@ -104,7 +104,7 @@ class Collect: Returns: str: e.g openEuler 21.09 """ - _, stdout, _ = execute_shell_command("cat /etc/os-release") + _, stdout, _ = execute_shell_command(["cat /etc/os-release"]) res = re.search('(?=PRETTY_NAME=).+', stdout) if res: @@ -138,7 +138,7 @@ class Collect: Returns: str """ - _, stdout, _ = execute_shell_command("dmidecode -t bios") + _, stdout, _ = execute_shell_command(["dmidecode -t bios"]) res = re.search('(?=Version:).+', stdout) if res: @@ -154,7 +154,7 @@ class Collect: Returns: str """ - _, stdout, _ = execute_shell_command("uname -r") + _, stdout, _ = execute_shell_command(["uname -r"]) res = re.search(r'[\d\.]+-[\d\.]+[\d]', stdout) if res: @@ -180,7 +180,7 @@ class Collect: "l3_cache": string } """ - _, stdout, _ = execute_shell_command("lscpu", **{"env": {"LANG": "en_US.utf-8"}}) + _, stdout, _ = execute_shell_command(["lscpu"], **{"env": {"LANG": "en_US.utf-8"}}) info_list = re.findall('.+:.+', stdout) @@ -213,7 +213,7 @@ class Collect: Returns: str: memory size """ - _, stdout, _ = execute_shell_command("lsmem") + _, stdout, _ = execute_shell_command(["lsmem"]) res = re.search("(?=Total online memory:).+", stdout) if res: @@ -244,7 +244,7 @@ class Collect: """ res = {'size': self.__get_total_online_memory() or None, "total": None, "info": []} - code, memory_data, _ = execute_shell_command("dmidecode -t memory") + code, memory_data, _ = execute_shell_command(["dmidecode -t memory"]) # dmidecode -t memory # e.g @@ -305,7 +305,7 @@ class Collect: } ] """ - code, stdout, _ = execute_shell_command("lshw -xml -c disk") + code, stdout, _ = execute_shell_command(["lshw -xml -c disk"]) if code != CommandExitCode.SUCCEED: LOGGER.error(stdout) return [] @@ -383,7 +383,7 @@ class Collect: Returns: uuid(str) """ - code, stdout, _ = execute_shell_command("dmidecode|grep UUID") + code, stdout, _ = execute_shell_command(["dmidecode", "grep UUID"]) if code == CommandExitCode.SUCCEED: return stdout.replace("-", "").split(':')[1].strip() return "" @@ -419,7 +419,7 @@ class Collect: }] """ - code, source_name_info, _ = execute_shell_command("rpm -qai|grep .src.rpm") + code, source_name_info, _ = execute_shell_command(["rpm -qai", "grep .src.rpm"]) if code != CommandExitCode.SUCCEED: LOGGER.error("Failed to query installed packages.") return [] diff --git a/ceres/manages/list_file_manage.py b/ceres/manages/list_file_manage.py index 3d7fd21..dab55e6 100644 --- a/ceres/manages/list_file_manage.py +++ b/ceres/manages/list_file_manage.py @@ -40,7 +40,7 @@ class ListFileManage: """ file_list_res = [] try: - command = "ls -l " + directory_path + " | awk '{print $9}'" + command = [f"ls -l {directory_path}", "awk '{print $9}'"] _, stdout, _ = execute_shell_command(command) file_list = stdout.split("\n") for file in file_list: diff --git a/ceres/manages/plugin_manage.py b/ceres/manages/plugin_manage.py index ed7b2ab..fb06220 100644 --- a/ceres/manages/plugin_manage.py +++ b/ceres/manages/plugin_manage.py @@ -52,7 +52,7 @@ class Plugin: if "running" in plugin_status: return SUCCESS - code, _, _ = execute_shell_command(f"systemctl start {self.rpm_name}") + code, _, _ = execute_shell_command([f"systemctl start {self.rpm_name}"]) if code != CommandExitCode.SUCCEED: return FAIL return SUCCESS @@ -68,7 +68,7 @@ class Plugin: if "inactive" in plugin_status: return SUCCESS - code, _, _ = execute_shell_command(f"systemctl stop {self.rpm_name}") + code, _, _ = execute_shell_command([f"systemctl stop {self.rpm_name}"]) if code != CommandExitCode.SUCCEED: return FAIL return SUCCESS @@ -100,7 +100,7 @@ class Plugin: str: dead or running """ - code, stdout, _ = execute_shell_command(f"systemctl status {self.rpm_name}|grep Active") + code, stdout, _ = execute_shell_command([f"systemctl status {self.rpm_name}", "grep Active"]) if code == CommandExitCode.SUCCEED: return re.search(r':.+\(', stdout).group()[1:-1].strip() LOGGER.error(f'Failed to get service {self.rpm_name} status!') @@ -114,7 +114,7 @@ class Plugin: Returns: The str type of main process id """ - code, main_pid_info, _ = execute_shell_command(f"systemctl status {rpm_name}|grep Main") + code, main_pid_info, _ = execute_shell_command([f"systemctl status {rpm_name}", "grep Main"]) if code == CommandExitCode.SUCCEED: return re.search("[0-9]+[0-9]", main_pid_info).group() LOGGER.error(f"Failed to get {rpm_name} pid") diff --git a/ceres/manages/resource_manage.py b/ceres/manages/resource_manage.py index 5766744..e9c6256 100644 --- a/ceres/manages/resource_manage.py +++ b/ceres/manages/resource_manage.py @@ -32,7 +32,7 @@ class Resource: Returns: str:The memory value which has used """ - code, stdout, _ = execute_shell_command(f"cat /proc/{pid}/status|grep VmRSS") + code, stdout, _ = execute_shell_command([f"cat /proc/{pid}/status", "grep VmRSS"]) if code == CommandExitCode.SUCCEED: return stdout.split(":")[1].strip() LOGGER.error(f'Failed to get memory info of process {pid}!') @@ -80,7 +80,7 @@ class Resource: Returns: str: cpu usage """ - code, stdout, _ = execute_shell_command(f"ps -aux|grep -w {rpm_name}|grep {pid}|awk {{print$3}}") + code, stdout, _ = execute_shell_command(["ps -aux", f"grep -w {rpm_name}", f"grep {pid}", f"awk {{print$3}}"]) if code == CommandExitCode.SUCCEED: return f'{stdout.strip()}%' LOGGER.error(f'Failed to get plugin cpu info about {rpm_name}.') diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py index 23ae2ce..16fc2d7 100644 --- a/ceres/manages/vulnerability_manage.py +++ b/ceres/manages/vulnerability_manage.py @@ -71,7 +71,7 @@ class VulnerabilityManage: Returns: bool """ - code, _, _ = execute_shell_command(f"yum repoinfo --repo {repo_id}") + code, _, _ = execute_shell_command([f"yum repoinfo --repo {repo_id}"]) return code == CommandExitCode.SUCCEED def cve_scan(self, cve_scan_args: dict) -> Tuple[str, dict]: @@ -157,9 +157,7 @@ class VulnerabilityManage: # powertop:powertop-2.9-12.oe1.x86_64 # libusbx:libusbx-1.0.23-1.oe1.x86_64 code, stdout, _ = execute_shell_command( - """ - rpm -qa --queryformat '%{NAME}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' - """ + ["rpm -qa --queryformat '%{NAME}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n'"] ) if code != CommandExitCode.SUCCEED or not stdout: LOGGER.error("query installed packages info failed!") @@ -190,7 +188,7 @@ class VulnerabilityManage: # kernel-debuginfo.x86_64 5.10.0-60.105.0.132.oe2203 update # kernel-debugsource.x86_64 5.10.0-60.105.0.132.oe2203 update # kernel-devel.x86_64 5.10.0-60.105.0.132.oe2203 update - code, stdout, stderr = execute_shell_command("dnf list available|grep -v '.src'") + code, stdout, stderr = execute_shell_command(["dnf list available", "grep -v '.src'"]) if code != CommandExitCode.SUCCEED: LOGGER.error(stderr) return result @@ -232,7 +230,7 @@ class VulnerabilityManage: # CVE-2021-45469 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64 # CVE-2021-44733 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64 unfixed_cves = [] - code, stdout, stderr = execute_shell_command("dnf updateinfo list cves") + code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves"]) if code != CommandExitCode.SUCCEED: LOGGER.error("query unfixed cve info failed by dnf!") LOGGER.error(stderr) @@ -295,7 +293,7 @@ class VulnerabilityManage: # CVE-2021-42574 Important/Sec. binutils-2.34-19.oe1.x86_64 - # CVE-2023-1513 Important/Sec. kernel-4.19.90-2304.1.0.0196.oe1.x86_64 patch-kernel-4.19.90-2112... cve_info_list = [] - code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves") + code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves"]) if code != CommandExitCode.SUCCEED: LOGGER.error("query unfixed cve info failed by dnf!") LOGGER.error(stderr) @@ -357,7 +355,7 @@ class VulnerabilityManage: # CVE-2021-45469 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64 # CVE-2021-44733 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64 fixed_cves = [] - code, stdout, stderr = execute_shell_command("dnf updateinfo list cves --installed") + code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves --installed"]) if code != CommandExitCode.SUCCEED: LOGGER.error("query fixed cve info failed!") LOGGER.error(stderr) @@ -395,7 +393,7 @@ class VulnerabilityManage: # CVE-2021-42574 Important/Sec. binutils-2.34-19.oe1.x86_64 - # CVE-2023-1513 Important/Sec. kernel-4.19.90-2304.1.0.0196.oe1.x86_64 patch-kernel-4.19.90-2112... - code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves --installed") + code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves --installed"]) if code != CommandExitCode.SUCCEED: LOGGER.error("query unfixed cve info failed by dnf!") LOGGER.error(stderr) @@ -461,7 +459,7 @@ class VulnerabilityManage: # CVE-2023-1111 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED # CVE-2023-1112 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED result = {} - code, stdout, stderr = execute_shell_command("dnf hotpatch --list cves") + code, stdout, stderr = execute_shell_command(["dnf hotpatch --list cves"]) if code != CommandExitCode.SUCCEED: LOGGER.error("query applied hotpatch info failed!") LOGGER.error(stderr) @@ -620,7 +618,7 @@ class VulnerabilityManage: Tuple[str, str] a tuple containing two elements (update result, log). """ - code, stdout, stderr = execute_shell_command(f"dnf upgrade-en {rpm_name} -y") + code, stdout, stderr = execute_shell_command([f"dnf upgrade-en {rpm_name} -y"]) log = stdout + stderr if code != CommandExitCode.SUCCEED: return TaskExecuteRes.FAIL, log @@ -641,9 +639,9 @@ class VulnerabilityManage: a tuple containing two elements (update result, log). """ if self.takeover: - update_command = f"dnf hotupgrade {hotpatch_pkg} --takeover -y" + update_command = [f"dnf hotupgrade {hotpatch_pkg} --takeover -y"] else: - update_command = f"dnf hotupgrade {hotpatch_pkg} -y" + update_command = [f"dnf hotupgrade {hotpatch_pkg} -y"] code, stdout, stderr = execute_shell_command(update_command) log = stdout + stderr @@ -692,7 +690,7 @@ class VulnerabilityManage: # Last metadata expiration check: 3:25:24 ago on Wed 13 Sep 2023 08:16:17 AM CST. # Gonna accept this hot patch: kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1 # accept hot patch 'kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1' failed, remain original status - code, stdout, stderr = execute_shell_command(f"dnf hotpatch --{operation} {wait_to_remove_patch}") + code, stdout, stderr = execute_shell_command([f"dnf hotpatch --{operation} {wait_to_remove_patch}"]) if code != CommandExitCode.SUCCEED or 'failed' in stdout: LOGGER.error(f"hotpatch {hotpatch} set status failed!") return False, stdout + stderr @@ -807,7 +805,7 @@ class VulnerabilityManage: "CVE-XXXX-XXX": {"patch 1", "patch 2"} } """ - code, stdout, _ = execute_shell_command(f"dnf hot-updateinfo list cves --installed|grep patch") + code, stdout, _ = execute_shell_command([f"dnf hot-updateinfo list cves --installed", "grep patch"]) if code != CommandExitCode.SUCCEED: LOGGER.error(f"Failed to hotpatch list cve.") return None @@ -841,7 +839,7 @@ class VulnerabilityManage: Args: hotpatch: hotpatch package which needs to remove """ - cmd = f"dnf remove {hotpatch} -y" + cmd = [f"dnf remove {hotpatch} -y"] _, stdout, stderr = execute_shell_command(cmd) return True, f"Command:{cmd}\n\n{stdout}\n{stderr}\n" @@ -876,7 +874,7 @@ class VulnerabilityManage: # description: (none) # patch: # 31fc7544 0001-Prevent-unauthenticated-client-from-easily-consuming.patch - code, stdout, _ = execute_shell_command(f"syscare info {base_pkg_hotpatch}") + code, stdout, _ = execute_shell_command([f"syscare info {base_pkg_hotpatch}"]) hotpatch_release_info = dict() if code != CommandExitCode.SUCCEED: -- 2.33.0