Skip to content

Commit 37a36a4

Browse files
committed
debian-cve-check: Improve error handling when dst.json download fails
If the Debian Security Tracker json (dst.json) download fails or file is invalid, the CVE check cannot be performed. In this case, output backtrace [1] because there is insufficient error checking. So improve to error handling. When cve-check cannot be performed, there are two ways of thinking depending on the purpose of bitbake: 1. The purpose is build, want to continue to build e.g. `bitbake core-image-minimal` 2. The purpose is cve-check, want to immediately terminate with an error e.g. `bitbake bash -c cve_check` Add "CVE_CHECK_ERROR_ON_FAILURE" variable to satisfy these wants. - Set "0" (is default): skip the CVE check and continue with build of bitbake By disabling "CVE_CHECK_DB_FILE" variable, CVE check will be skipped in Poky's do_cve_check() function. This is the same behavior as if the NVD database download failed in Poky, skip the CVE check and continue with build. - Set "1": bitbake return fatal error immediately Immediately exit with bb.fatal(). In summary, the following changes in this commit: - Add exception handling to load_json() Delete file exist check as they are handled by exception handling. - Add check of the dst.json file (Even if the dst.json download fails,) A successfully downloaded dst.json file may still exist, so if the timestamp is today, it is considered a valid file. - Add error handling logic for "CVE_CHECK_ERROR_ON_FAILURE" variable Change the log output lebel to match behavior of this variable. - Some code style fixes Add spaces after comma. [1] ``` File: '<path-to>/meta-debian/classes/debian-cve-check.bbclass', lineno: 33, function: debian_cve_check 0029: _pkg_file_name = os.path.basename(_pkg_uri) 0030: pkgname = _pkg_file_name.split(";")[0].split("_")[0] 0031: break 0032: *** 0033: if pkgname not in dst_data.keys(): 0034: bb.note("%s is not found in Debian Security Tracker." % pkgname) 0035: return 0036: 0037: deb_patched, deb_unpatched = deb_check_cves(d, dst_data[pkgname]) Exception: AttributeError: 'NoneType' object has no attribute 'keys' ``` Signed-off-by: Takahiro Terada <[email protected]>
1 parent c0e0ebe commit 37a36a4

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

classes/debian-cve-check.bbclass

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,35 @@
1010
DEBIAN_CVE_CHECK_DB_DIR ?= "${CVE_CHECK_DB_DIR}/DEBIAN"
1111
DEBIAN_CODENAME ?= "${DISTRO_CODENAME}"
1212
DEBIAN_SECRUTY_TRACKER_JSON_URL ??= "https://deb.freexian.com/extended-lts/tracker/data/json"
13+
CVE_CHECK_ERROR_ON_FAILURE ??= "0"
1314

1415
python debian_cve_check () {
1516
"""
1617
Check CVE in Debian source
1718
"""
19+
from datetime import datetime, date
20+
1821
debian_src_uri = d.getVar("DEBIAN_SRC_URI", True)
1922
if debian_src_uri is None:
2023
bb.note("%s dosen't use debian source" % d.getVar("BPN"))
2124
return
2225

23-
json_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True),"dst.json")
24-
dst_data = load_json(json_path)
26+
json_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True), "dst.json")
27+
cve_check_error = True
28+
if os.path.isfile(json_path):
29+
timestamp = datetime.fromtimestamp(os.path.getmtime(json_path))
30+
if timestamp.date() == date.today():
31+
dst_data = load_json(json_path)
32+
if dst_data is not None:
33+
cve_check_error = False
34+
35+
if cve_check_error:
36+
if d.getVar("CVE_CHECK_ERROR_ON_FAILURE") == "0":
37+
d.setVar("CVE_CHECK_DB_FILE", "")
38+
bb.note("debian_cve_check: No DST database found, skipping CVE check")
39+
else:
40+
bb.fatal("debian_cve_check: No DST database found")
41+
return
2542

2643
# get package name from DEBIAN_SRC_URI
2744
for _pkg_uri in debian_src_uri.split():
@@ -52,7 +69,7 @@ python update_dst () {
5269
from datetime import datetime, date
5370

5471
json_urls = d.getVar("DEBIAN_SECRUTY_TRACKER_JSON_URL", "").split(" ")
55-
dist_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True),"dst.json")
72+
dist_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True), "dst.json")
5673
dist_dir = os.path.dirname(dist_path)
5774

5875
if not os.path.isdir(dist_dir):
@@ -79,7 +96,7 @@ python update_dst () {
7996
time.sleep(10 + (attempt * 10))
8097
continue
8198
else:
82-
bb.error("DST database received error")
99+
bb.warn("DST database download failed")
83100
return
84101
}
85102

@@ -90,11 +107,12 @@ def load_json(path):
90107
Load json file.
91108
"""
92109
import json
93-
if not os.path.isfile(path):
94-
bb.error("%s dosen't exist" % path)
110+
try:
111+
with open(path, 'r') as f:
112+
return json.load(f)
113+
except Exception as e:
114+
bb.debug(2, "%s json.load: %s" % (path, e))
95115
return
96-
with open(path, 'r') as f:
97-
return json.load(f)
98116

99117
def deb_check_cves(d, pkg_data):
100118
"""
@@ -132,8 +150,8 @@ def compare_versions(current_version, fixed_version):
132150
"""
133151
import subprocess
134152

135-
ret = subprocess.run(["/usr/bin/dpkg","--compare-versions", current_version,
136-
"ge",fixed_version]).returncode
153+
ret = subprocess.run(["/usr/bin/dpkg", "--compare-versions", current_version,
154+
"ge", fixed_version]).returncode
137155
if ret == 0:
138156
return True
139157
else:

doc/7.cve-check.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ Replace URL:
2222
DEBIAN_SECRUTY_TRACKER_JSON_URL = "http://localhost:8000/dst.json"
2323
```
2424

25+
- CVE\_CHECK\_ERROR\_ON\_FAILURE
26+
27+
If the Debian security tracker json (dst.json) cannot be downloaded or file is invalid, the CVE check cannot be performed.
28+
In this case, set ```CVE_CHECK_ERROR_ON_FAILURE``` to "1" to make bitbake return fatal ERROR.
29+
The default for this variable is "0" to skip the CVE check and continue with bitbake.
30+

0 commit comments

Comments
 (0)