diff options
Diffstat (limited to 'meta/lib/oeqa/selftest/cases/cve_check.py')
-rw-r--r-- | meta/lib/oeqa/selftest/cases/cve_check.py | 256 |
1 files changed, 255 insertions, 1 deletions
diff --git a/meta/lib/oeqa/selftest/cases/cve_check.py b/meta/lib/oeqa/selftest/cases/cve_check.py index 60cecd1328..511e4b81b4 100644 --- a/meta/lib/oeqa/selftest/cases/cve_check.py +++ b/meta/lib/oeqa/selftest/cases/cve_check.py | |||
@@ -72,6 +72,259 @@ class CVECheck(OESelftestTestCase): | |||
72 | self.assertEqual(convert_cve_version("6.2_rc8"), "6.2-rc8") | 72 | self.assertEqual(convert_cve_version("6.2_rc8"), "6.2-rc8") |
73 | self.assertEqual(convert_cve_version("6.2_rc31"), "6.2-rc31") | 73 | self.assertEqual(convert_cve_version("6.2_rc31"), "6.2-rc31") |
74 | 74 | ||
75 | def test_product_match(self): | ||
76 | from oe.cve_check import has_cve_product_match | ||
77 | |||
78 | status = {} | ||
79 | status["detail"] = "ignored" | ||
80 | status["vendor"] = "*" | ||
81 | status["product"] = "*" | ||
82 | status["description"] = "" | ||
83 | status["mapping"] = "" | ||
84 | |||
85 | self.assertEqual(has_cve_product_match(status, "some_vendor:some_product"), True) | ||
86 | self.assertEqual(has_cve_product_match(status, "*:*"), True) | ||
87 | self.assertEqual(has_cve_product_match(status, "some_product"), True) | ||
88 | self.assertEqual(has_cve_product_match(status, "glibc"), True) | ||
89 | self.assertEqual(has_cve_product_match(status, "glibca"), True) | ||
90 | self.assertEqual(has_cve_product_match(status, "aglibc"), True) | ||
91 | self.assertEqual(has_cve_product_match(status, "*"), True) | ||
92 | self.assertEqual(has_cve_product_match(status, "aglibc glibc test:test"), True) | ||
93 | |||
94 | status["product"] = "glibc" | ||
95 | self.assertEqual(has_cve_product_match(status, "some_vendor:some_product"), False) | ||
96 | # The CPE in the recipe must be defined, no * accepted | ||
97 | self.assertEqual(has_cve_product_match(status, "*:*"), False) | ||
98 | self.assertEqual(has_cve_product_match(status, "*"), False) | ||
99 | self.assertEqual(has_cve_product_match(status, "some_product"), False) | ||
100 | self.assertEqual(has_cve_product_match(status, "glibc"), True) | ||
101 | self.assertEqual(has_cve_product_match(status, "glibca"), False) | ||
102 | self.assertEqual(has_cve_product_match(status, "aglibc"), False) | ||
103 | self.assertEqual(has_cve_product_match(status, "some_vendor:glibc"), True) | ||
104 | self.assertEqual(has_cve_product_match(status, "some_vendor:glibc test"), True) | ||
105 | self.assertEqual(has_cve_product_match(status, "test some_vendor:glibc"), True) | ||
106 | |||
107 | status["vendor"] = "glibca" | ||
108 | status["product"] = "glibc" | ||
109 | self.assertEqual(has_cve_product_match(status, "some_vendor:some_product"), False) | ||
110 | # The CPE in the recipe must be defined, no * accepted | ||
111 | self.assertEqual(has_cve_product_match(status, "*:*"), False) | ||
112 | self.assertEqual(has_cve_product_match(status, "*"), False) | ||
113 | self.assertEqual(has_cve_product_match(status, "some_product"), False) | ||
114 | self.assertEqual(has_cve_product_match(status, "glibc"), False) | ||
115 | self.assertEqual(has_cve_product_match(status, "glibca"), False) | ||
116 | self.assertEqual(has_cve_product_match(status, "aglibc"), False) | ||
117 | self.assertEqual(has_cve_product_match(status, "some_vendor:glibc"), False) | ||
118 | self.assertEqual(has_cve_product_match(status, "glibca:glibc"), True) | ||
119 | self.assertEqual(has_cve_product_match(status, "test:test glibca:glibc"), True) | ||
120 | self.assertEqual(has_cve_product_match(status, "test glibca:glibc"), True) | ||
121 | self.assertEqual(has_cve_product_match(status, "glibca:glibc test"), True) | ||
122 | |||
123 | def test_parse_cve_from_patch_filename(self): | ||
124 | from oe.cve_check import parse_cve_from_filename | ||
125 | |||
126 | # Patch filename without CVE ID | ||
127 | self.assertEqual(parse_cve_from_filename("0001-test.patch"), "") | ||
128 | |||
129 | # Patch with single CVE ID | ||
130 | self.assertEqual( | ||
131 | parse_cve_from_filename("CVE-2022-12345.patch"), "CVE-2022-12345" | ||
132 | ) | ||
133 | |||
134 | # Patch with multiple CVE IDs | ||
135 | self.assertEqual( | ||
136 | parse_cve_from_filename("CVE-2022-41741-CVE-2022-41742.patch"), | ||
137 | "CVE-2022-41742", | ||
138 | ) | ||
139 | |||
140 | # Patches with CVE ID and appended text | ||
141 | self.assertEqual( | ||
142 | parse_cve_from_filename("CVE-2023-3019-0001.patch"), "CVE-2023-3019" | ||
143 | ) | ||
144 | self.assertEqual( | ||
145 | parse_cve_from_filename("CVE-2024-21886-1.patch"), "CVE-2024-21886" | ||
146 | ) | ||
147 | |||
148 | # Patch with CVE ID and prepended text | ||
149 | self.assertEqual( | ||
150 | parse_cve_from_filename("grep-CVE-2012-5667.patch"), "CVE-2012-5667" | ||
151 | ) | ||
152 | self.assertEqual( | ||
153 | parse_cve_from_filename("0001-CVE-2012-5667.patch"), "CVE-2012-5667" | ||
154 | ) | ||
155 | |||
156 | # Patch with CVE ID and both prepended and appended text | ||
157 | self.assertEqual( | ||
158 | parse_cve_from_filename( | ||
159 | "0001-tpm2_import-fix-fixed-AES-key-CVE-2021-3565-0001.patch" | ||
160 | ), | ||
161 | "CVE-2021-3565", | ||
162 | ) | ||
163 | |||
164 | # Only grab the last CVE ID in the filename | ||
165 | self.assertEqual( | ||
166 | parse_cve_from_filename("CVE-2012-5667-CVE-2012-5668.patch"), | ||
167 | "CVE-2012-5668", | ||
168 | ) | ||
169 | |||
170 | # Test invalid CVE ID with incorrect length (must be at least 4 digits) | ||
171 | self.assertEqual( | ||
172 | parse_cve_from_filename("CVE-2024-001.patch"), | ||
173 | "", | ||
174 | ) | ||
175 | |||
176 | # Test valid CVE ID with very long length | ||
177 | self.assertEqual( | ||
178 | parse_cve_from_filename("CVE-2024-0000000000000000000000001.patch"), | ||
179 | "CVE-2024-0000000000000000000000001", | ||
180 | ) | ||
181 | |||
182 | def test_parse_cve_from_patch_contents(self): | ||
183 | import textwrap | ||
184 | from oe.cve_check import parse_cves_from_patch_contents | ||
185 | |||
186 | # Standard patch file excerpt without any patches | ||
187 | self.assertEqual( | ||
188 | parse_cves_from_patch_contents( | ||
189 | textwrap.dedent("""\ | ||
190 | remove "*" for root since we don't have a /etc/shadow so far. | ||
191 | |||
192 | Upstream-Status: Inappropriate [configuration] | ||
193 | |||
194 | Signed-off-by: Scott Garman <scott.a.garman@intel.com> | ||
195 | |||
196 | --- base-passwd/passwd.master~nobash | ||
197 | +++ base-passwd/passwd.master | ||
198 | @@ -1,4 +1,4 @@ | ||
199 | -root:*:0:0:root:/root:/bin/sh | ||
200 | +root::0:0:root:/root:/bin/sh | ||
201 | daemon:*:1:1:daemon:/usr/sbin:/bin/sh | ||
202 | bin:*:2:2:bin:/bin:/bin/sh | ||
203 | sys:*:3:3:sys:/dev:/bin/sh | ||
204 | """) | ||
205 | ), | ||
206 | set(), | ||
207 | ) | ||
208 | |||
209 | # Patch file with multiple CVE IDs (space-separated) | ||
210 | self.assertEqual( | ||
211 | parse_cves_from_patch_contents( | ||
212 | textwrap.dedent("""\ | ||
213 | There is an assertion in function _cairo_arc_in_direction(). | ||
214 | |||
215 | CVE: CVE-2019-6461 CVE-2019-6462 | ||
216 | Upstream-Status: Pending | ||
217 | Signed-off-by: Ross Burton <ross.burton@intel.com> | ||
218 | |||
219 | diff --git a/src/cairo-arc.c b/src/cairo-arc.c | ||
220 | index 390397bae..1bde774a4 100644 | ||
221 | --- a/src/cairo-arc.c | ||
222 | +++ b/src/cairo-arc.c | ||
223 | @@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr, | ||
224 | if (cairo_status (cr)) | ||
225 | return; | ||
226 | |||
227 | - assert (angle_max >= angle_min); | ||
228 | + if (angle_max < angle_min) | ||
229 | + return; | ||
230 | |||
231 | if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { | ||
232 | angle_max = fmod (angle_max - angle_min, 2 * M_PI); | ||
233 | """), | ||
234 | ), | ||
235 | {"CVE-2019-6461", "CVE-2019-6462"}, | ||
236 | ) | ||
237 | |||
238 | # Patch file with multiple CVE IDs (comma-separated w/ both space and no space) | ||
239 | self.assertEqual( | ||
240 | parse_cves_from_patch_contents( | ||
241 | textwrap.dedent("""\ | ||
242 | There is an assertion in function _cairo_arc_in_direction(). | ||
243 | |||
244 | CVE: CVE-2019-6461,CVE-2019-6462, CVE-2019-6463 | ||
245 | Upstream-Status: Pending | ||
246 | Signed-off-by: Ross Burton <ross.burton@intel.com> | ||
247 | |||
248 | diff --git a/src/cairo-arc.c b/src/cairo-arc.c | ||
249 | index 390397bae..1bde774a4 100644 | ||
250 | --- a/src/cairo-arc.c | ||
251 | +++ b/src/cairo-arc.c | ||
252 | @@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr, | ||
253 | if (cairo_status (cr)) | ||
254 | return; | ||
255 | |||
256 | - assert (angle_max >= angle_min); | ||
257 | + if (angle_max < angle_min) | ||
258 | + return; | ||
259 | |||
260 | if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { | ||
261 | angle_max = fmod (angle_max - angle_min, 2 * M_PI); | ||
262 | |||
263 | """), | ||
264 | ), | ||
265 | {"CVE-2019-6461", "CVE-2019-6462", "CVE-2019-6463"}, | ||
266 | ) | ||
267 | |||
268 | # Patch file with multiple CVE IDs (&-separated) | ||
269 | self.assertEqual( | ||
270 | parse_cves_from_patch_contents( | ||
271 | textwrap.dedent("""\ | ||
272 | There is an assertion in function _cairo_arc_in_direction(). | ||
273 | |||
274 | CVE: CVE-2019-6461 & CVE-2019-6462 | ||
275 | Upstream-Status: Pending | ||
276 | Signed-off-by: Ross Burton <ross.burton@intel.com> | ||
277 | |||
278 | diff --git a/src/cairo-arc.c b/src/cairo-arc.c | ||
279 | index 390397bae..1bde774a4 100644 | ||
280 | --- a/src/cairo-arc.c | ||
281 | +++ b/src/cairo-arc.c | ||
282 | @@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr, | ||
283 | if (cairo_status (cr)) | ||
284 | return; | ||
285 | |||
286 | - assert (angle_max >= angle_min); | ||
287 | + if (angle_max < angle_min) | ||
288 | + return; | ||
289 | |||
290 | if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { | ||
291 | angle_max = fmod (angle_max - angle_min, 2 * M_PI); | ||
292 | """), | ||
293 | ), | ||
294 | {"CVE-2019-6461", "CVE-2019-6462"}, | ||
295 | ) | ||
296 | |||
297 | # Patch file with multiple lines with CVE IDs | ||
298 | self.assertEqual( | ||
299 | parse_cves_from_patch_contents( | ||
300 | textwrap.dedent("""\ | ||
301 | There is an assertion in function _cairo_arc_in_direction(). | ||
302 | |||
303 | CVE: CVE-2019-6461 & CVE-2019-6462 | ||
304 | |||
305 | CVE: CVE-2019-6463 & CVE-2019-6464 | ||
306 | Upstream-Status: Pending | ||
307 | Signed-off-by: Ross Burton <ross.burton@intel.com> | ||
308 | |||
309 | diff --git a/src/cairo-arc.c b/src/cairo-arc.c | ||
310 | index 390397bae..1bde774a4 100644 | ||
311 | --- a/src/cairo-arc.c | ||
312 | +++ b/src/cairo-arc.c | ||
313 | @@ -186,7 +186,8 @@ _cairo_arc_in_direction (cairo_t *cr, | ||
314 | if (cairo_status (cr)) | ||
315 | return; | ||
316 | |||
317 | - assert (angle_max >= angle_min); | ||
318 | + if (angle_max < angle_min) | ||
319 | + return; | ||
320 | |||
321 | if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { | ||
322 | angle_max = fmod (angle_max - angle_min, 2 * M_PI); | ||
323 | |||
324 | """), | ||
325 | ), | ||
326 | {"CVE-2019-6461", "CVE-2019-6462", "CVE-2019-6463", "CVE-2019-6464"}, | ||
327 | ) | ||
75 | 328 | ||
76 | def test_recipe_report_json(self): | 329 | def test_recipe_report_json(self): |
77 | config = """ | 330 | config = """ |
@@ -217,9 +470,10 @@ CVE_CHECK_REPORT_PATCHED = "1" | |||
217 | # m4 CVE should not be in logrotate | 470 | # m4 CVE should not be in logrotate |
218 | self.assertNotIn("CVE-2008-1687", found_cves) | 471 | self.assertNotIn("CVE-2008-1687", found_cves) |
219 | # logrotate has both Patched and Ignored CVEs | 472 | # logrotate has both Patched and Ignored CVEs |
473 | detail = "version-not-in-range" | ||
220 | self.assertIn("CVE-2011-1098", found_cves) | 474 | self.assertIn("CVE-2011-1098", found_cves) |
221 | self.assertEqual(found_cves["CVE-2011-1098"]["status"], "Patched") | 475 | self.assertEqual(found_cves["CVE-2011-1098"]["status"], "Patched") |
222 | self.assertEqual(len(found_cves["CVE-2011-1098"]["detail"]), 0) | 476 | self.assertEqual(found_cves["CVE-2011-1098"]["detail"], detail) |
223 | self.assertEqual(len(found_cves["CVE-2011-1098"]["description"]), 0) | 477 | self.assertEqual(len(found_cves["CVE-2011-1098"]["description"]), 0) |
224 | detail = "not-applicable-platform" | 478 | detail = "not-applicable-platform" |
225 | description = "CVE is debian, gentoo or SUSE specific on the way logrotate was installed/used" | 479 | description = "CVE is debian, gentoo or SUSE specific on the way logrotate was installed/used" |