summaryrefslogtreecommitdiffstats
path: root/meta
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-04-11 11:31:52 +0100
commit8064466b45668bb188bd16a6a49f7f085672749d (patch)
treee39f022d89a8d1488a1b29cfa52c36db606e37f5 /meta
parentfd78b2c6ac8a952154c1eebd412d271af6ec6805 (diff)
downloadpoky-8064466b45668bb188bd16a6a49f7f085672749d.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: f331c80df6c447d3073ebe3f00102c78ced242f3) Signed-off-by: Geoffrey GIRY <geoffrey.giry@smile.fr> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> (cherry picked from commit 7d00f6ec578084a0a0e5caf36241d53036d996c4) Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-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 b9c0bfd6d8..3c922b27af 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -254,7 +254,7 @@ def check_cves(d, patched_cves):
254 """ 254 """
255 Connect to the NVD database and find unpatched cves. 255 Connect to the NVD database and find unpatched cves.
256 """ 256 """
257 from oe.cve_check import Version 257 from oe.cve_check import Version, convert_cve_version
258 258
259 pn = d.getVar("PN") 259 pn = d.getVar("PN")
260 real_pv = d.getVar("PV") 260 real_pv = d.getVar("PV")
@@ -318,6 +318,9 @@ def check_cves(d, patched_cves):
318 if cve in cve_ignore: 318 if cve in cve_ignore:
319 ignored = True 319 ignored = True
320 320
321 version_start = convert_cve_version(version_start)
322 version_end = convert_cve_version(version_end)
323
321 if (operator_start == '=' and pv == version_start) or version_start == '-': 324 if (operator_start == '=' and pv == version_start) or version_start == '-':
322 vulnerable = True 325 vulnerable = True
323 else: 326 else:
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
index f40f16d7ab..42a77872e9 100644
--- a/meta/lib/oe/cve_check.py
+++ b/meta/lib/oe/cve_check.py
@@ -173,3 +173,42 @@ def update_symlinks(target_path, link_path):
173 if os.path.exists(os.path.realpath(link_path)): 173 if os.path.exists(os.path.realpath(link_path)):
174 os.remove(link_path) 174 os.remove(link_path)
175 os.symlink(os.path.basename(target_path), link_path) 175 os.symlink(os.path.basename(target_path), link_path)
176
177
178def convert_cve_version(version):
179 """
180 This function converts from CVE format to Yocto version format.
181 eg 8.3_p1 -> 8.3p1, 6.2_rc1 -> 6.2-rc1
182
183 Unless it is redefined using CVE_VERSION in the recipe,
184 cve_check uses the version in the name of the recipe (${PV})
185 to check vulnerabilities against a CVE in the database downloaded from NVD.
186
187 When the version has an update, i.e.
188 "p1" in OpenSSH 8.3p1,
189 "-rc1" in linux kernel 6.2-rc1,
190 the database stores the version as version_update (8.3_p1, 6.2_rc1).
191 Therefore, we must transform this version before comparing to the
192 recipe version.
193
194 In this case, the parameter of the function is 8.3_p1.
195 If the version uses the Release Candidate format, "rc",
196 this function replaces the '_' by '-'.
197 If the version uses the Update format, "p",
198 this function removes the '_' completely.
199 """
200 import re
201
202 matches = re.match('^([0-9.]+)_((p|rc)[0-9]+)$', version)
203
204 if not matches:
205 return version
206
207 version = matches.group(1)
208 update = matches.group(2)
209
210 if matches.group(3) == "rc":
211 return version + '-' + update
212
213 return version + update
214
diff --git a/meta/lib/oeqa/selftest/cases/cve_check.py b/meta/lib/oeqa/selftest/cases/cve_check.py
index d0b2213703..22ffeffd29 100644
--- a/meta/lib/oeqa/selftest/cases/cve_check.py
+++ b/meta/lib/oeqa/selftest/cases/cve_check.py
@@ -48,6 +48,25 @@ class CVECheck(OESelftestTestCase):
48 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'") 48 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'")
49 49
50 50
51 def test_convert_cve_version(self):
52 from oe.cve_check import convert_cve_version
53
54 # Default format
55 self.assertEqual(convert_cve_version("8.3"), "8.3")
56 self.assertEqual(convert_cve_version(""), "")
57
58 # OpenSSL format version
59 self.assertEqual(convert_cve_version("1.1.1t"), "1.1.1t")
60
61 # OpenSSH format
62 self.assertEqual(convert_cve_version("8.3_p1"), "8.3p1")
63 self.assertEqual(convert_cve_version("8.3_p22"), "8.3p22")
64
65 # Linux kernel format
66 self.assertEqual(convert_cve_version("6.2_rc8"), "6.2-rc8")
67 self.assertEqual(convert_cve_version("6.2_rc31"), "6.2-rc31")
68
69
51 def test_recipe_report_json(self): 70 def test_recipe_report_json(self):
52 config = """ 71 config = """
53INHERIT += "cve-check" 72INHERIT += "cve-check"