summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/selftest/cases/cve_check.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/selftest/cases/cve_check.py')
-rw-r--r--meta/lib/oeqa/selftest/cases/cve_check.py186
1 files changed, 185 insertions, 1 deletions
diff --git a/meta/lib/oeqa/selftest/cases/cve_check.py b/meta/lib/oeqa/selftest/cases/cve_check.py
index 3f343a2841..22ffeffd29 100644
--- a/meta/lib/oeqa/selftest/cases/cve_check.py
+++ b/meta/lib/oeqa/selftest/cases/cve_check.py
@@ -1,9 +1,13 @@
1from oe.cve_check import Version 1import json
2import os
2from oeqa.selftest.case import OESelftestTestCase 3from oeqa.selftest.case import OESelftestTestCase
4from oeqa.utils.commands import bitbake, get_bb_vars
3 5
4class CVECheck(OESelftestTestCase): 6class CVECheck(OESelftestTestCase):
5 7
6 def test_version_compare(self): 8 def test_version_compare(self):
9 from oe.cve_check import Version
10
7 result = Version("100") > Version("99") 11 result = Version("100") > Version("99")
8 self.assertTrue( result, msg="Failed to compare version '100' > '99'") 12 self.assertTrue( result, msg="Failed to compare version '100' > '99'")
9 result = Version("2.3.1") > Version("2.2.3") 13 result = Version("2.3.1") > Version("2.2.3")
@@ -34,3 +38,183 @@ class CVECheck(OESelftestTestCase):
34 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' < '1.0r'") 38 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' < '1.0r'")
35 result = Version("1.0b","alphabetical") > Version("1.0","alphabetical") 39 result = Version("1.0b","alphabetical") > Version("1.0","alphabetical")
36 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' > '1.0'") 40 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' > '1.0'")
41
42 # consider the trailing "p" and "patch" as patched released when comparing
43 result = Version("1.0","patch") < Version("1.0p1","patch")
44 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0' < '1.0p1'")
45 result = Version("1.0p2","patch") > Version("1.0p1","patch")
46 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0p2' > '1.0p1'")
47 result = Version("1.0_patch2","patch") < Version("1.0_patch3","patch")
48 self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'")
49
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
70 def test_recipe_report_json(self):
71 config = """
72INHERIT += "cve-check"
73CVE_CHECK_FORMAT_JSON = "1"
74"""
75 self.write_config(config)
76
77 vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
78 summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
79 recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json")
80
81 try:
82 os.remove(summary_json)
83 os.remove(recipe_json)
84 except FileNotFoundError:
85 pass
86
87 bitbake("m4-native -c cve_check")
88
89 def check_m4_json(filename):
90 with open(filename) as f:
91 report = json.load(f)
92 self.assertEqual(report["version"], "1")
93 self.assertEqual(len(report["package"]), 1)
94 package = report["package"][0]
95 self.assertEqual(package["name"], "m4-native")
96 found_cves = { issue["id"]: issue["status"] for issue in package["issue"]}
97 self.assertIn("CVE-2008-1687", found_cves)
98 self.assertEqual(found_cves["CVE-2008-1687"], "Patched")
99
100 self.assertExists(summary_json)
101 check_m4_json(summary_json)
102 self.assertExists(recipe_json)
103 check_m4_json(recipe_json)
104
105
106 def test_image_json(self):
107 config = """
108INHERIT += "cve-check"
109CVE_CHECK_FORMAT_JSON = "1"
110"""
111 self.write_config(config)
112
113 vars = get_bb_vars(["CVE_CHECK_DIR", "CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
114 report_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
115 print(report_json)
116 try:
117 os.remove(report_json)
118 except FileNotFoundError:
119 pass
120
121 bitbake("core-image-minimal-initramfs")
122 self.assertExists(report_json)
123
124 # Check that the summary report lists at least one package
125 with open(report_json) as f:
126 report = json.load(f)
127 self.assertEqual(report["version"], "1")
128 self.assertGreater(len(report["package"]), 1)
129
130 # Check that a random recipe wrote a recipe report to deploy/cve/
131 recipename = report["package"][0]["name"]
132 recipe_report = os.path.join(vars["CVE_CHECK_DIR"], recipename + "_cve.json")
133 self.assertExists(recipe_report)
134 with open(recipe_report) as f:
135 report = json.load(f)
136 self.assertEqual(report["version"], "1")
137 self.assertEqual(len(report["package"]), 1)
138 self.assertEqual(report["package"][0]["name"], recipename)
139
140
141 def test_recipe_report_json_unpatched(self):
142 config = """
143INHERIT += "cve-check"
144CVE_CHECK_FORMAT_JSON = "1"
145CVE_CHECK_REPORT_PATCHED = "0"
146"""
147 self.write_config(config)
148
149 vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
150 summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
151 recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json")
152
153 try:
154 os.remove(summary_json)
155 os.remove(recipe_json)
156 except FileNotFoundError:
157 pass
158
159 bitbake("m4-native -c cve_check")
160
161 def check_m4_json(filename):
162 with open(filename) as f:
163 report = json.load(f)
164 self.assertEqual(report["version"], "1")
165 self.assertEqual(len(report["package"]), 1)
166 package = report["package"][0]
167 self.assertEqual(package["name"], "m4-native")
168 #m4 had only Patched CVEs, so the issues array will be empty
169 self.assertEqual(package["issue"], [])
170
171 self.assertExists(summary_json)
172 check_m4_json(summary_json)
173 self.assertExists(recipe_json)
174 check_m4_json(recipe_json)
175
176
177 def test_recipe_report_json_ignored(self):
178 config = """
179INHERIT += "cve-check"
180CVE_CHECK_FORMAT_JSON = "1"
181CVE_CHECK_REPORT_PATCHED = "1"
182"""
183 self.write_config(config)
184
185 vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
186 summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"])
187 recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "logrotate_cve.json")
188
189 try:
190 os.remove(summary_json)
191 os.remove(recipe_json)
192 except FileNotFoundError:
193 pass
194
195 bitbake("logrotate -c cve_check")
196
197 def check_m4_json(filename):
198 with open(filename) as f:
199 report = json.load(f)
200 self.assertEqual(report["version"], "1")
201 self.assertEqual(len(report["package"]), 1)
202 package = report["package"][0]
203 self.assertEqual(package["name"], "logrotate")
204 found_cves = { issue["id"]: issue["status"] for issue in package["issue"]}
205 # m4 CVE should not be in logrotate
206 self.assertNotIn("CVE-2008-1687", found_cves)
207 # logrotate has both Patched and Ignored CVEs
208 self.assertIn("CVE-2011-1098", found_cves)
209 self.assertEqual(found_cves["CVE-2011-1098"], "Patched")
210 self.assertIn("CVE-2011-1548", found_cves)
211 self.assertEqual(found_cves["CVE-2011-1548"], "Ignored")
212 self.assertIn("CVE-2011-1549", found_cves)
213 self.assertEqual(found_cves["CVE-2011-1549"], "Ignored")
214 self.assertIn("CVE-2011-1550", found_cves)
215 self.assertEqual(found_cves["CVE-2011-1550"], "Ignored")
216
217 self.assertExists(summary_json)
218 check_m4_json(summary_json)
219 self.assertExists(recipe_json)
220 check_m4_json(recipe_json)