aops-ceres/0003-update-method-of-querying-fixed-cves-by-dnf-plugin.patch
rabbitali b514a7ffa6 update method of querying fixed cves by dnf plugin
(cherry picked from commit 03db33a126cccd30d06c4958cd27121a48aa9173)
2023-09-19 10:41:21 +08:00

154 lines
7.0 KiB
Diff

From f947f2b46c52bc453858bf4e030ec9388c29b52d Mon Sep 17 00:00:00 2001
From: rabbitali <shusheng.wen@outlook.com>
Date: Mon, 18 Sep 2023 17:31:06 +0800
Subject: [PATCH 1/1] update method of querying fixed cves by dnf plugin
---
ceres/manages/vulnerability_manage.py | 80 ++++++++++++++++++++-------
1 file changed, 60 insertions(+), 20 deletions(-)
diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py
index ab4b41c..ab10381 100644
--- a/ceres/manages/vulnerability_manage.py
+++ b/ceres/manages/vulnerability_manage.py
@@ -132,7 +132,7 @@ class VulnerabilityManage:
{
"check_items": items_check_log,
"unfixed_cves": self._query_unfixed_cves_by_dnf_plugin() or self._query_unfixed_cves_by_dnf(),
- "fixed_cves": self._query_fixed_cves(),
+ "fixed_cves": self._query_fixed_cves_by_dnf_plugin() or self._query_fixed_cves_by_dnf(),
}
)
return SUCCESS, cve_scan_result
@@ -339,7 +339,7 @@ class VulnerabilityManage:
return cve_info_list
- def _query_fixed_cves(self) -> list:
+ def _query_fixed_cves_by_dnf(self) -> list:
"""
parse the fixed kernel vulnerability info by dnf
@@ -348,7 +348,6 @@ class VulnerabilityManage:
list: cve info e.g
[
{"cve_id": "CVE-XXXX-XXXX","installed_rpm": "kernel-version-release.arch", "fix_way":"coldpatch"},
- {"cve_id": "CVE-XXXX-XXXX","installed_rpm": "xxxx", "fix_way": "hotpatch", "hp_status": "ACCEPTED"}
]
"""
@@ -380,17 +379,70 @@ class VulnerabilityManage:
fixed_cves.append(
{"cve_id": cve_id, "installed_rpm": self.installed_rpm_info.get(rpm_name), "fix_way": "coldpatch"}
)
- fixed_cves.extend(self._query_applied_hotpatch())
return fixed_cves
- def _query_applied_hotpatch(self) -> list:
+ def _query_fixed_cves_by_dnf_plugin(self) -> list:
"""
- parse kernel hotpatch info which has been applied by dnf hotpatch plugin (hotpatch)
+ parse the fixed kernel vulnerability info by dnf plugin
Return:
list: hotpatch info list. e.g
[{"cve_id": "CVE-XXXX-XXXX", "fix_way": "hotpatch", "hp_status": "ACCEPTED", "installed_rpm":"xxxx"}]
+ """
+ # Example of command execution result:
+ # Last metadata expiration check: 0:31:50 ago on Mon 07 Aug 2023 10:26:32 AM CST.
+ # CVE-2023-1981 Moderate/Sec. avahi-libs-0.8-9.oe1.x86_64 -
+ # 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")
+ if code != CommandExitCode.SUCCEED:
+ LOGGER.error("query unfixed cve info failed by dnf!")
+ LOGGER.error(stderr)
+ return []
+
+ # Example of regex matching result:
+ # [
+ # ("CVE-2023-1513", "Important/Sec.", "kernel-4.19.90-2304.1.0.0196.oe1.x86_64", "patch-kernel-4.19.90-2112.."),
+ # ("CVE-2021-xxxx", "Important/Sec.", "-", "patch-redis-6.2.5-1-SGL_CVE_2023_1111_CVE_2023_1112-1-1.x86_64")
+ # ]
+ hotpatch_status = self._query_applied_hotpatch_status()
+ all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel\S+|-)\s+(patch-kernel\S+|-)", stdout)
+
+ cve_info_fixed_by_coldpatch, cve_info_fixed_by_hotpatch, hotpatch_dic = [], [], defaultdict(str)
+ for cve_id, _, coldpatch, hotpatch in all_cve_info:
+ if hotpatch == "-":
+ cve_info_fixed_by_coldpatch.append(
+ {
+ "cve_id": cve_id,
+ "installed_rpm": self.installed_rpm_info.get(coldpatch.rsplit("-", 2)[0]),
+ "fix_way": "coldpatch",
+ }
+ )
+ else:
+ cve_info_fixed_by_hotpatch.append({"cve_id": cve_id, "fix_way": "hotpatch", "installed_rpm": hotpatch})
+
+ hotpatch_dic_key = hotpatch.rsplit("-", 2)[0]
+ if hotpatch_dic_key.endswith("ACC"):
+ hotpatch_dic[hotpatch_dic_key] = max(hotpatch, hotpatch_dic.get(hotpatch_dic_key, hotpatch))
+
+ for cve_info in cve_info_fixed_by_hotpatch:
+ hotpatch_dic_key = cve_info["installed_rpm"].rsplit("-", 2)[0]
+
+ if hotpatch_dic_key in hotpatch_dic:
+ cve_info["installed_rpm"] = hotpatch_dic[hotpatch_dic_key]
+ cve_info["hp_status"] = hotpatch_status.get(cve_info["installed_rpm"].rsplit(".", 1)[0], "")
+
+ return cve_info_fixed_by_coldpatch + cve_info_fixed_by_hotpatch
+
+ def _query_applied_hotpatch_status(self) -> Dict[str, str]:
+ """
+ query applied hotpatch with its status
+
+ Return:
+ dict: key is hotpatch name, value is its status. e.g {"patch-redis-6.2.5-1-ACC-1-3": "ACTIVED"}
+
"""
# Example of command execution result:
# Last metadata expiration check: 0:28:36 ago on Mon 07 Aug 2023 10:26:32 AM CST.
@@ -409,7 +461,7 @@ class VulnerabilityManage:
# CVE-2023-1112 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-cli NOT-APPLIED
# 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 = []
+ result = {}
code, stdout, stderr = execute_shell_command("dnf hotpatch --list cves")
if code != CommandExitCode.SUCCEED:
LOGGER.error("query applied hotpatch info failed!")
@@ -426,11 +478,6 @@ class VulnerabilityManage:
if not applied_hotpatch_info_list:
return result
- code, arch, _ = execute_shell_command("uname -m")
- if code != CommandExitCode.SUCCEED:
- LOGGER.debug("Failed to query host arch info!")
- arch = "unknown_arch"
-
record_key_set = set()
for cve_id, patch_name, hotpatch_status in applied_hotpatch_info_list:
rpm = patch_name.split("-", 1)[0]
@@ -445,14 +492,7 @@ class VulnerabilityManage:
and (hotpatch_status in ("ACTIVED", "ACCEPTED"))
and record_key not in record_key_set
):
- result.append(
- {
- "cve_id": cve_id,
- "installed_rpm": f"patch-{patch_name.rsplit('/',1)[0].replace('/','-')}.{arch}",
- "fix_way": "hotpatch",
- "hp_status": hotpatch_status,
- }
- )
+ result[f"patch-{patch_name.rsplit('/',1)[0].replace('/','-')}"] = hotpatch_status
record_key_set.add(record_key)
return result
--
2.33.1.windows.1