blob: ac47af1990b3c82999dd9b0055c36cc2d30eb047 [file] [log] [blame]
Patrick Williams92b42cb2022-09-03 06:53:57 -05001#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
Andrew Geisslerd5838332022-05-27 11:33:10 -05007import json
8import os
Andrew Geisslerd1e89492021-02-12 15:35:20 -06009from oeqa.selftest.case import OESelftestTestCase
Andrew Geisslerd5838332022-05-27 11:33:10 -050010from oeqa.utils.commands import bitbake, get_bb_vars
Andrew Geisslerd1e89492021-02-12 15:35:20 -060011
12class CVECheck(OESelftestTestCase):
13
14 def test_version_compare(self):
Andrew Geisslerd5838332022-05-27 11:33:10 -050015 from oe.cve_check import Version
16
Andrew Geisslerd1e89492021-02-12 15:35:20 -060017 result = Version("100") > Version("99")
18 self.assertTrue( result, msg="Failed to compare version '100' > '99'")
19 result = Version("2.3.1") > Version("2.2.3")
20 self.assertTrue( result, msg="Failed to compare version '2.3.1' > '2.2.3'")
21 result = Version("2021-01-21") > Version("2020-12-25")
22 self.assertTrue( result, msg="Failed to compare version '2021-01-21' > '2020-12-25'")
23 result = Version("1.2-20200910") < Version("1.2-20200920")
24 self.assertTrue( result, msg="Failed to compare version '1.2-20200910' < '1.2-20200920'")
25
26 result = Version("1.0") >= Version("1.0beta")
27 self.assertTrue( result, msg="Failed to compare version '1.0' >= '1.0beta'")
28 result = Version("1.0-rc2") > Version("1.0-rc1")
29 self.assertTrue( result, msg="Failed to compare version '1.0-rc2' > '1.0-rc1'")
30 result = Version("1.0.alpha1") < Version("1.0")
31 self.assertTrue( result, msg="Failed to compare version '1.0.alpha1' < '1.0'")
32 result = Version("1.0_dev") <= Version("1.0")
33 self.assertTrue( result, msg="Failed to compare version '1.0_dev' <= '1.0'")
34
35 # ignore "p1" and "p2", so these should be equal
36 result = Version("1.0p2") == Version("1.0p1")
37 self.assertTrue( result ,msg="Failed to compare version '1.0p2' to '1.0p1'")
38 # ignore the "b" and "r"
39 result = Version("1.0b") == Version("1.0r")
40 self.assertTrue( result ,msg="Failed to compare version '1.0b' to '1.0r'")
41
42 # consider the trailing alphabet as patched level when comparing
43 result = Version("1.0b","alphabetical") < Version("1.0r","alphabetical")
44 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' < '1.0r'")
45 result = Version("1.0b","alphabetical") > Version("1.0","alphabetical")
46 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' > '1.0'")
Andrew Geissler95ac1b82021-03-31 14:34:31 -050047
48 # consider the trailing "p" and "patch" as patched released when comparing
49 result = Version("1.0","patch") < Version("1.0p1","patch")
50 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0' < '1.0p1'")
51 result = Version("1.0p2","patch") > Version("1.0p1","patch")
52 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0p2' > '1.0p1'")
53 result = Version("1.0_patch2","patch") < Version("1.0_patch3","patch")
54 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'")
Andrew Geisslerd5838332022-05-27 11:33:10 -050055
56
57 def test_recipe_report_json(self):
58 config = """
59INHERIT += "cve-check"
60CVE_CHECK_FORMAT_JSON = "1"
61"""
62 self.write_config(config)
63
64 vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
65 summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
66 recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json")
67
68 try:
69 os.remove(summary_json)
70 os.remove(recipe_json)
71 except FileNotFoundError:
72 pass
73
74 bitbake("m4-native -c cve_check")
75
76 def check_m4_json(filename):
77 with open(filename) as f:
78 report = json.load(f)
79 self.assertEqual(report["version"], "1")
80 self.assertEqual(len(report["package"]), 1)
81 package = report["package"][0]
82 self.assertEqual(package["name"], "m4-native")
83 found_cves = { issue["id"]: issue["status"] for issue in package["issue"]}
84 self.assertIn("CVE-2008-1687", found_cves)
85 self.assertEqual(found_cves["CVE-2008-1687"], "Patched")
86
87 self.assertExists(summary_json)
88 check_m4_json(summary_json)
89 self.assertExists(recipe_json)
90 check_m4_json(recipe_json)
91
92
93 def test_image_json(self):
94 config = """
95INHERIT += "cve-check"
96CVE_CHECK_FORMAT_JSON = "1"
97"""
98 self.write_config(config)
99
100 vars = get_bb_vars(["CVE_CHECK_DIR", "CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
101 report_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
102 print(report_json)
103 try:
104 os.remove(report_json)
105 except FileNotFoundError:
106 pass
107
108 bitbake("core-image-minimal-initramfs")
109 self.assertExists(report_json)
110
111 # Check that the summary report lists at least one package
112 with open(report_json) as f:
113 report = json.load(f)
114 self.assertEqual(report["version"], "1")
115 self.assertGreater(len(report["package"]), 1)
116
117 # Check that a random recipe wrote a recipe report to deploy/cve/
118 recipename = report["package"][0]["name"]
119 recipe_report = os.path.join(vars["CVE_CHECK_DIR"], recipename + "_cve.json")
120 self.assertExists(recipe_report)
121 with open(recipe_report) as f:
122 report = json.load(f)
123 self.assertEqual(report["version"], "1")
124 self.assertEqual(len(report["package"]), 1)
125 self.assertEqual(report["package"][0]["name"], recipename)
Andrew Geissler615f2f12022-07-15 14:00:58 -0500126
127
128 def test_recipe_report_json_unpatched(self):
129 config = """
130INHERIT += "cve-check"
131CVE_CHECK_FORMAT_JSON = "1"
132CVE_CHECK_REPORT_PATCHED = "0"
133"""
134 self.write_config(config)
135
136 vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
137 summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
138 recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json")
139
140 try:
141 os.remove(summary_json)
142 os.remove(recipe_json)
143 except FileNotFoundError:
144 pass
145
146 bitbake("m4-native -c cve_check")
147
148 def check_m4_json(filename):
149 with open(filename) as f:
150 report = json.load(f)
151 self.assertEqual(report["version"], "1")
152 self.assertEqual(len(report["package"]), 1)
153 package = report["package"][0]
154 self.assertEqual(package["name"], "m4-native")
155 #m4 had only Patched CVEs, so the issues array will be empty
156 self.assertEqual(package["issue"], [])
157
158 self.assertExists(summary_json)
159 check_m4_json(summary_json)
160 self.assertExists(recipe_json)
161 check_m4_json(recipe_json)
162
163
164 def test_recipe_report_json_ignored(self):
165 config = """
166INHERIT += "cve-check"
167CVE_CHECK_FORMAT_JSON = "1"
168CVE_CHECK_REPORT_PATCHED = "1"
169"""
170 self.write_config(config)
171
172 vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
173 summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
174 recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "logrotate_cve.json")
175
176 try:
177 os.remove(summary_json)
178 os.remove(recipe_json)
179 except FileNotFoundError:
180 pass
181
182 bitbake("logrotate -c cve_check")
183
184 def check_m4_json(filename):
185 with open(filename) as f:
186 report = json.load(f)
187 self.assertEqual(report["version"], "1")
188 self.assertEqual(len(report["package"]), 1)
189 package = report["package"][0]
190 self.assertEqual(package["name"], "logrotate")
191 found_cves = { issue["id"]: issue["status"] for issue in package["issue"]}
192 # m4 CVE should not be in logrotate
193 self.assertNotIn("CVE-2008-1687", found_cves)
194 # logrotate has both Patched and Ignored CVEs
195 self.assertIn("CVE-2011-1098", found_cves)
196 self.assertEqual(found_cves["CVE-2011-1098"], "Patched")
197 self.assertIn("CVE-2011-1548", found_cves)
198 self.assertEqual(found_cves["CVE-2011-1548"], "Ignored")
199 self.assertIn("CVE-2011-1549", found_cves)
200 self.assertEqual(found_cves["CVE-2011-1549"], "Ignored")
201 self.assertIn("CVE-2011-1550", found_cves)
202 self.assertEqual(found_cves["CVE-2011-1550"], "Ignored")
203
204 self.assertExists(summary_json)
205 check_m4_json(summary_json)
206 self.assertExists(recipe_json)
207 check_m4_json(recipe_json)