summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoffrey GIRY <geoffrey.giry@smile.fr>2023-03-28 12:23:49 +0200
committerSteve Sakoman <steve@sakoman.com>2023-04-14 05:44:12 -1000
commitd8057ae9aa73616d2383e5d10d2125d1912b0a13 (patch)
tree6ef95d877a3a68197b2c5bf71d621c7e68b864cb
parent5150ad7fcb320964dc215866a1943d4732b49e98 (diff)
downloadpoky-d8057ae9aa73616d2383e5d10d2125d1912b0a13.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: eb439b1283b60e6665694ff28c89fbd633eda6b0) 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>
-rw-r--r--meta/classes/cve-check.bbclass5
-rw-r--r--meta/lib/oe/cve_check.py37
-rw-r--r--meta/lib/oeqa/selftest/cases/cve_check.py19
3 files changed, 60 insertions, 1 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index 87a59d5c6d..05b9cb47dc 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -253,7 +253,7 @@ def check_cves(d, patched_cves):
253 """ 253 """
254 Connect to the NVD database and find unpatched cves. 254 Connect to the NVD database and find unpatched cves.
255 """ 255 """
256 from oe.cve_check import Version 256 from oe.cve_check import Version, convert_cve_version
257 257
258 pn = d.getVar("PN") 258 pn = d.getVar("PN")
259 real_pv = d.getVar("PV") 259 real_pv = d.getVar("PV")
@@ -317,6 +317,9 @@ def check_cves(d, patched_cves):
317 if cve in cve_whitelist: 317 if cve in cve_whitelist:
318 ignored = True 318 ignored = True
319 319
320 version_start = convert_cve_version(version_start)
321 version_end = convert_cve_version(version_end)
322
320 if (operator_start == '=' and pv == version_start) or version_start == '-': 323 if (operator_start == '=' and pv == version_start) or version_start == '-':
321 vulnerable = True 324 vulnerable = True
322 else: 325 else:
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
index 67f0644889..c508865738 100644
--- a/meta/lib/oe/cve_check.py
+++ b/meta/lib/oe/cve_check.py
@@ -172,3 +172,40 @@ def get_cpe_ids(cve_product, version):
172 cpe_ids.append(cpe_id) 172 cpe_ids.append(cpe_id)
173 173
174 return cpe_ids 174 return cpe_ids
175
176def convert_cve_version(version):
177 """
178 This function converts from CVE format to Yocto version format.
179 eg 8.3_p1 -> 8.3p1, 6.2_rc1 -> 6.2-rc1
180
181 Unless it is redefined using CVE_VERSION in the recipe,
182 cve_check uses the version in the name of the recipe (${PV})
183 to check vulnerabilities against a CVE in the database downloaded from NVD.
184
185 When the version has an update, i.e.
186 "p1" in OpenSSH 8.3p1,
187 "-rc1" in linux kernel 6.2-rc1,
188 the database stores the version as version_update (8.3_p1, 6.2_rc1).
189 Therefore, we must transform this version before comparing to the
190 recipe version.
191
192 In this case, the parameter of the function is 8.3_p1.
193 If the version uses the Release Candidate format, "rc",
194 this function replaces the '_' by '-'.
195 If the version uses the Update format, "p",
196 this function removes the '_' completely.
197 """
198 import re
199
200 matches = re.match('^([0-9.]+)_((p|rc)[0-9]+)$', version)
201
202 if not matches:
203 return version
204
205 version = matches.group(1)
206 update = matches.group(2)
207
208 if matches.group(3) == "rc":
209 return version + '-' + update
210
211 return version + update
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"