summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoffrey GIRY <geoffrey.giry@smile.fr>2023-03-28 12:23:49 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-03-30 12:30:38 +0100
commit81740facf458a5a3326c0cfca20ebf75d8fe91d0 (patch)
tree7fd393837325a5d81c8fc38eeb5911c45c751ab2
parente8693364c59e627bf667c5ecc790beb2a59b6dd8 (diff)
downloadpoky-81740facf458a5a3326c0cfca20ebf75d8fe91d0.tar.gz
cve-check: Fix false negative version issue
NVD DB store version and update in the same value, separated by '_'. The proposed patch check if the version from NVD DB contains a "_", ie 9.2.0_p1 is convert to 9.2.0p1 before version comparison. [YOCTO #14127] Reviewed-by: Yoann CONGAL <yoann.congal@smile.fr> (From OE-Core rev: 7d00f6ec578084a0a0e5caf36241d53036d996c4) Signed-off-by: Geoffrey GIRY <geoffrey.giry@smile.fr> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/classes/cve-check.bbclass5
-rw-r--r--meta/lib/oe/cve_check.py39
-rw-r--r--meta/lib/oeqa/selftest/cases/cve_check.py19
3 files changed, 62 insertions, 1 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index 41fdf8363f..5e2da56046 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -260,7 +260,7 @@ def check_cves(d, patched_cves):
260 """ 260 """
261 Connect to the NVD database and find unpatched cves. 261 Connect to the NVD database and find unpatched cves.
262 """ 262 """
263 from oe.cve_check import Version 263 from oe.cve_check import Version, convert_cve_version
264 264
265 pn = d.getVar("PN") 265 pn = d.getVar("PN")
266 real_pv = d.getVar("PV") 266 real_pv = d.getVar("PV")
@@ -324,6 +324,9 @@ def check_cves(d, patched_cves):
324 if cve in cve_ignore: 324 if cve in cve_ignore:
325 ignored = True 325 ignored = True
326 326
327 version_start = convert_cve_version(version_start)
328 version_end = convert_cve_version(version_end)
329
327 if (operator_start == '=' and pv == version_start) or version_start == '-': 330 if (operator_start == '=' and pv == version_start) or version_start == '-':
328 vulnerable = True 331 vulnerable = True
329 else: 332 else:
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
index 4f1d80f050..dbaa0b373a 100644
--- a/meta/lib/oe/cve_check.py
+++ b/meta/lib/oe/cve_check.py
@@ -179,3 +179,42 @@ def update_symlinks(target_path, link_path):
179 if os.path.exists(os.path.realpath(link_path)): 179 if os.path.exists(os.path.realpath(link_path)):
180 os.remove(link_path) 180 os.remove(link_path)
181 os.symlink(os.path.basename(target_path), link_path) 181 os.symlink(os.path.basename(target_path), link_path)
182
183
184def convert_cve_version(version):
185 """
186 This function converts from CVE format to Yocto version format.
187 eg 8.3_p1 -> 8.3p1, 6.2_rc1 -> 6.2-rc1
188
189 Unless it is redefined using CVE_VERSION in the recipe,
190 cve_check uses the version in the name of the recipe (${PV})
191 to check vulnerabilities against a CVE in the database downloaded from NVD.
192
193 When the version has an update, i.e.
194 "p1" in OpenSSH 8.3p1,
195 "-rc1" in linux kernel 6.2-rc1,
196 the database stores the version as version_update (8.3_p1, 6.2_rc1).
197 Therefore, we must transform this version before comparing to the
198 recipe version.
199
200 In this case, the parameter of the function is 8.3_p1.
201 If the version uses the Release Candidate format, "rc",
202 this function replaces the '_' by '-'.
203 If the version uses the Update format, "p",
204 this function removes the '_' completely.
205 """
206 import re
207
208 matches = re.match('^([0-9.]+)_((p|rc)[0-9]+)$', version)
209
210 if not matches:
211 return version
212
213 version = matches.group(1)
214 update = matches.group(2)
215
216 if matches.group(3) == "rc":
217 return version + '-' + update
218
219 return version + update
220
diff --git a/meta/lib/oeqa/selftest/cases/cve_check.py b/meta/lib/oeqa/selftest/cases/cve_check.py
index ac47af1990..9534c9775c 100644
--- a/meta/lib/oeqa/selftest/cases/cve_check.py
+++ b/meta/lib/oeqa/selftest/cases/cve_check.py
@@ -54,6 +54,25 @@ class CVECheck(OESelftestTestCase):
54 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'") 54 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'")
55 55
56 56
57 def test_convert_cve_version(self):
58 from oe.cve_check import convert_cve_version
59
60 # Default format
61 self.assertEqual(convert_cve_version("8.3"), "8.3")
62 self.assertEqual(convert_cve_version(""), "")
63
64 # OpenSSL format version
65 self.assertEqual(convert_cve_version("1.1.1t"), "1.1.1t")
66
67 # OpenSSH format
68 self.assertEqual(convert_cve_version("8.3_p1"), "8.3p1")
69 self.assertEqual(convert_cve_version("8.3_p22"), "8.3p22")
70
71 # Linux kernel format
72 self.assertEqual(convert_cve_version("6.2_rc8"), "6.2-rc8")
73 self.assertEqual(convert_cve_version("6.2_rc31"), "6.2-rc31")
74
75
57 def test_recipe_report_json(self): 76 def test_recipe_report_json(self):
58 config = """ 77 config = """
59INHERIT += "cve-check" 78INHERIT += "cve-check"