summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorNiko Mauno <niko.mauno@vaisala.com>2025-11-04 08:33:31 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-11-07 13:15:35 +0000
commit085208eb70daec4a936d4f58ee6b7e9ef0988f41 (patch)
treeb9d53ded45063311133d901c066d7c790e133757 /meta
parent35f915165ac023333cb5cae46dc48c8d47f75923 (diff)
downloadpoky-085208eb70daec4a936d4f58ee6b7e9ef0988f41.tar.gz
cve-update: Drop obsolete NVD1 support
Since enabling NVD1 as NVD_DB_VERSION nowadays leads to BitBake failure WARNING: cve-update-db-native-1.0-r0 do_fetch: Failed to fetch CVE data (HTTP Error 403: Forbidden) WARNING: cve-update-db-native-1.0-r0 do_fetch: Host IPs are 172.65.90.26, 172.65.90.25, 172.65.90.24, 172.65.90.27, 2606:4700:78::90:0:180, 2606:4700:78::90:0:183, 2606:4700:78::90:0:181, 2606:4700:78::90:0:182 WARNING: cve-update-db-native-1.0-r0 do_fetch: CVE database update failed ERROR: cve-update-db-native-1.0-r0 do_unpack: Error executing a python function in exec_func_python() autogenerated: Remove the support for obsolete NVD1. (From OE-Core rev: 9cd19f0dc1629086ab1dd18d969e0b4e9acac3ea) Signed-off-by: Niko Mauno <niko.mauno@vaisala.com> Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes/cve-check.bbclass8
-rw-r--r--meta/recipes-core/meta/cve-update-db-native.bb87
2 files changed, 15 insertions, 80 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index c63ebd56e1..259c699af2 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -31,11 +31,11 @@
31CVE_PRODUCT ??= "${BPN}" 31CVE_PRODUCT ??= "${BPN}"
32CVE_VERSION ??= "${PV}" 32CVE_VERSION ??= "${PV}"
33 33
34# Possible database sources: NVD1, NVD2, FKIE 34# Possible database sources: NVD2, FKIE
35NVD_DB_VERSION ?= "FKIE" 35NVD_DB_VERSION ?= "FKIE"
36 36
37# Use different file names for each database source, as they synchronize at different moments, so may be slightly different 37# Use different file names for each database source, as they synchronize at different moments, so may be slightly different
38CVE_CHECK_DB_FILENAME ?= "${@'nvdcve_2-2.db' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'nvdcve_1-3.db' if d.getVar('NVD_DB_VERSION') == 'NVD1' else 'nvdfkie_1-1.db'}" 38CVE_CHECK_DB_FILENAME ?= "${@'nvdcve_2-2.db' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'nvdfkie_1-1.db'}"
39CVE_CHECK_DB_FETCHER ?= "${@'cve-update-nvd2-native' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'cve-update-db-native'}" 39CVE_CHECK_DB_FETCHER ?= "${@'cve-update-nvd2-native' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'cve-update-db-native'}"
40CVE_CHECK_DB_DIR ?= "${STAGING_DIR}/CVE_CHECK" 40CVE_CHECK_DB_DIR ?= "${STAGING_DIR}/CVE_CHECK"
41CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/${CVE_CHECK_DB_FILENAME}" 41CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/${CVE_CHECK_DB_FILENAME}"
@@ -108,8 +108,8 @@ python () {
108 extend_cve_status(d) 108 extend_cve_status(d)
109 109
110 nvd_database_type = d.getVar("NVD_DB_VERSION") 110 nvd_database_type = d.getVar("NVD_DB_VERSION")
111 if nvd_database_type not in ("NVD1", "NVD2", "FKIE"): 111 if nvd_database_type not in ("NVD2", "FKIE"):
112 bb.erroronce("Malformed NVD_DB_VERSION, must be one of: NVD1, NVD2, FKIE. Defaulting to NVD2") 112 bb.erroronce("Malformed NVD_DB_VERSION, must be one of: NVD2, FKIE. Defaulting to NVD2")
113 d.setVar("NVD_DB_VERSION", "NVD2") 113 d.setVar("NVD_DB_VERSION", "NVD2")
114} 114}
115 115
diff --git a/meta/recipes-core/meta/cve-update-db-native.bb b/meta/recipes-core/meta/cve-update-db-native.bb
index 3a6dc95580..4423216be5 100644
--- a/meta/recipes-core/meta/cve-update-db-native.bb
+++ b/meta/recipes-core/meta/cve-update-db-native.bb
@@ -11,7 +11,6 @@ deltask do_compile
11deltask do_install 11deltask do_install
12deltask do_populate_sysroot 12deltask do_populate_sysroot
13 13
14NVDCVE_URL ?= "https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-"
15FKIE_URL ?= "https://github.com/fkie-cad/nvd-json-data-feeds/releases/latest/download/CVE-" 14FKIE_URL ?= "https://github.com/fkie-cad/nvd-json-data-feeds/releases/latest/download/CVE-"
16 15
17# CVE database update interval, in seconds. By default: once a day (23*60*60). 16# CVE database update interval, in seconds. By default: once a day (23*60*60).
@@ -108,30 +107,12 @@ def cleanup_db_download(db_tmp_file):
108 if os.path.exists(db_tmp_file): 107 if os.path.exists(db_tmp_file):
109 os.remove(db_tmp_file) 108 os.remove(db_tmp_file)
110 109
111def db_file_names(d, year, is_nvd): 110def db_file_names(d, year):
112 if is_nvd:
113 year_url = d.getVar('NVDCVE_URL') + str(year)
114 meta_url = year_url + ".meta"
115 json_url = year_url + ".json.gz"
116 return json_url, meta_url
117 year_url = d.getVar('FKIE_URL') + str(year) 111 year_url = d.getVar('FKIE_URL') + str(year)
118 meta_url = year_url + ".meta" 112 meta_url = year_url + ".meta"
119 json_url = year_url + ".json.xz" 113 json_url = year_url + ".json.xz"
120 return json_url, meta_url 114 return json_url, meta_url
121 115
122def host_db_name(d, is_nvd):
123 if is_nvd:
124 return "nvd.nist.gov"
125 return "github.com"
126
127def db_decompress(d, data, is_nvd):
128 import gzip, lzma
129
130 if is_nvd:
131 return gzip.decompress(data).decode('utf-8')
132 # otherwise
133 return lzma.decompress(data)
134
135def update_db_file(db_tmp_file, d): 116def update_db_file(db_tmp_file, d):
136 """ 117 """
137 Update the given database file 118 Update the given database file
@@ -139,12 +120,12 @@ def update_db_file(db_tmp_file, d):
139 import bb.progress 120 import bb.progress
140 import bb.utils 121 import bb.utils
141 from datetime import date 122 from datetime import date
123 import lzma
142 import sqlite3 124 import sqlite3
143 import urllib 125 import urllib
144 126
145 YEAR_START = 2002 127 YEAR_START = 2002
146 cve_socket_timeout = int(d.getVar("CVE_SOCKET_TIMEOUT")) 128 cve_socket_timeout = int(d.getVar("CVE_SOCKET_TIMEOUT"))
147 is_nvd = d.getVar("NVD_DB_VERSION") == "NVD1"
148 129
149 # Connect to database 130 # Connect to database
150 conn = sqlite3.connect(db_tmp_file) 131 conn = sqlite3.connect(db_tmp_file)
@@ -155,7 +136,7 @@ def update_db_file(db_tmp_file, d):
155 for i, year in enumerate(range(YEAR_START, date.today().year + 1)): 136 for i, year in enumerate(range(YEAR_START, date.today().year + 1)):
156 bb.note("Updating %d" % year) 137 bb.note("Updating %d" % year)
157 ph.update((float(i + 1) / total_years) * 100) 138 ph.update((float(i + 1) / total_years) * 100)
158 json_url, meta_url = db_file_names(d, year, is_nvd) 139 json_url, meta_url = db_file_names(d, year)
159 140
160 # Retrieve meta last modified date 141 # Retrieve meta last modified date
161 try: 142 try:
@@ -164,7 +145,7 @@ def update_db_file(db_tmp_file, d):
164 cve_f.write('Warning: CVE db update error, Unable to fetch CVE data.\n\n') 145 cve_f.write('Warning: CVE db update error, Unable to fetch CVE data.\n\n')
165 bb.warn("Failed to fetch CVE data (%s)" % e) 146 bb.warn("Failed to fetch CVE data (%s)" % e)
166 import socket 147 import socket
167 result = socket.getaddrinfo(host_db_name(d, is_nvd), 443, proto=socket.IPPROTO_TCP) 148 result = socket.getaddrinfo("github.com", 443, proto=socket.IPPROTO_TCP)
168 bb.warn("Host IPs are %s" % (", ".join(t[4][0] for t in result))) 149 bb.warn("Host IPs are %s" % (", ".join(t[4][0] for t in result)))
169 return False 150 return False
170 151
@@ -192,7 +173,7 @@ def update_db_file(db_tmp_file, d):
192 try: 173 try:
193 response = urllib.request.urlopen(json_url, timeout=cve_socket_timeout) 174 response = urllib.request.urlopen(json_url, timeout=cve_socket_timeout)
194 if response: 175 if response:
195 update_db(d, conn, db_decompress(d, response.read(), is_nvd)) 176 update_db(conn, lzma.decompress(response.read()))
196 conn.execute("insert or replace into META values (?, ?)", [year, last_modified]).close() 177 conn.execute("insert or replace into META values (?, ?)", [year, last_modified]).close()
197 except urllib.error.URLError as e: 178 except urllib.error.URLError as e:
198 cve_f.write('Warning: CVE db update error, CVE data is outdated.\n\n') 179 cve_f.write('Warning: CVE db update error, CVE data is outdated.\n\n')
@@ -224,17 +205,14 @@ def initialize_db(conn):
224 205
225 c.close() 206 c.close()
226 207
227def parse_node_and_insert(conn, node, cveId, is_nvd): 208def parse_node_and_insert(conn, node, cveId):
228 # Parse children node if needed 209 # Parse children node if needed
229 for child in node.get('children', ()): 210 for child in node.get('children', ()):
230 parse_node_and_insert(conn, child, cveId, is_nvd) 211 parse_node_and_insert(conn, child, cveId)
231 212
232 def cpe_generator(is_nvd): 213 def cpe_generator():
233 match_string = "cpeMatch" 214 match_string = "cpeMatch"
234 cpe_string = 'criteria' 215 cpe_string = 'criteria'
235 if is_nvd:
236 match_string = "cpe_match"
237 cpe_string = 'cpe23Uri'
238 216
239 for cpe in node.get(match_string, ()): 217 for cpe in node.get(match_string, ()):
240 if not cpe['vulnerable']: 218 if not cpe['vulnerable']:
@@ -290,44 +268,7 @@ def parse_node_and_insert(conn, node, cveId, is_nvd):
290 # Save processing by representing as -. 268 # Save processing by representing as -.
291 yield [cveId, vendor, product, '-', '', '', ''] 269 yield [cveId, vendor, product, '-', '', '', '']
292 270
293 conn.executemany("insert into PRODUCTS values (?, ?, ?, ?, ?, ?, ?)", cpe_generator(is_nvd)).close() 271 conn.executemany("insert into PRODUCTS values (?, ?, ?, ?, ?, ?, ?)", cpe_generator()).close()
294
295def update_db_nvdjson(conn, jsondata):
296 import json
297 root = json.loads(jsondata)
298
299 for elt in root['CVE_Items']:
300 if not elt['impact']:
301 continue
302
303 accessVector = None
304 vectorString = None
305 cvssv2 = 0.0
306 cvssv3 = 0.0
307 cvssv4 = 0.0
308 cveId = elt['cve']['CVE_data_meta']['ID']
309 cveDesc = elt['cve']['description']['description_data'][0]['value']
310 date = elt['lastModifiedDate']
311 try:
312 accessVector = elt['impact']['baseMetricV2']['cvssV2']['accessVector']
313 vectorString = elt['impact']['baseMetricV2']['cvssV2']['vectorString']
314 cvssv2 = elt['impact']['baseMetricV2']['cvssV2']['baseScore']
315 except KeyError:
316 cvssv2 = 0.0
317 try:
318 accessVector = accessVector or elt['impact']['baseMetricV3']['cvssV3']['attackVector']
319 vectorString = vectorString or elt['impact']['baseMetricV3']['cvssV3']['vectorString']
320 cvssv3 = elt['impact']['baseMetricV3']['cvssV3']['baseScore']
321 except KeyError:
322 accessVector = accessVector or "UNKNOWN"
323 cvssv3 = 0.0
324
325 conn.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?, ?, ?)",
326 [cveId, cveDesc, cvssv2, cvssv3, cvssv4, date, accessVector, vectorString]).close()
327
328 configurations = elt['configurations']['nodes']
329 for config in configurations:
330 parse_node_and_insert(conn, config, cveId, True)
331 272
332def get_metric_entry(metric): 273def get_metric_entry(metric):
333 primaries = [c for c in metric if c['type'] == "Primary"] 274 primaries = [c for c in metric if c['type'] == "Primary"]
@@ -338,7 +279,7 @@ def get_metric_entry(metric):
338 return secondaries[0] 279 return secondaries[0]
339 return None 280 return None
340 281
341def update_db_fkie(conn, jsondata): 282def update_db(conn, jsondata):
342 import json 283 import json
343 root = json.loads(jsondata) 284 root = json.loads(jsondata)
344 285
@@ -403,13 +344,7 @@ def update_db_fkie(conn, jsondata):
403 for config in elt['configurations']: 344 for config in elt['configurations']:
404 # This is suboptimal as it doesn't handle AND/OR and negate, but is better than nothing 345 # This is suboptimal as it doesn't handle AND/OR and negate, but is better than nothing
405 for node in config.get("nodes") or []: 346 for node in config.get("nodes") or []:
406 parse_node_and_insert(conn, node, cveId, False) 347 parse_node_and_insert(conn, node, cveId)
407
408def update_db(d, conn, jsondata):
409 if (d.getVar("NVD_DB_VERSION") == "FKIE"):
410 return update_db_fkie(conn, jsondata)
411 else:
412 return update_db_nvdjson(conn, jsondata)
413 348
414do_fetch[nostamp] = "1" 349do_fetch[nostamp] = "1"
415 350