Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions classes/debian-cve-check.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,46 @@
DEBIAN_CVE_CHECK_DB_DIR ?= "${CVE_CHECK_DB_DIR}/DEBIAN"
DEBIAN_CODENAME ?= "${DISTRO_CODENAME}"
DEBIAN_SECRUTY_TRACKER_JSON_URL ??= "https://deb.freexian.com/extended-lts/tracker/data/json"
CVE_CHECK_ERROR_ON_FAILURE ??= "0"

# CVE database update interval, in seconds. By default: once a day (24*60*60).
# Use 0 to force the update
# Use a negative value to skip the update
CVE_DB_UPDATE_INTERVAL ??= "86400"

python debian_cve_check () {
"""
Check CVE in Debian source
"""
from datetime import datetime, date

debian_src_uri = d.getVar("DEBIAN_SRC_URI", True)
if debian_src_uri is None:
bb.note("%s dosen't use debian source" % d.getVar("BPN"))
return

json_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True),"dst.json")
dst_data = load_json(json_path)
json_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True), "dst.json")
cve_check_error = True
if os.path.isfile(json_path):
try:
update_interval = int(d.getVar("CVE_DB_UPDATE_INTERVAL"))
except ValueError:
update_interval = 0
if update_interval == 0:
update_interval = 86400
if ((update_interval < 0) or
(time.time() - os.path.getmtime(json_path) < update_interval)):
dst_data = load_json(json_path)
if dst_data is not None:
cve_check_error = False

if cve_check_error:
if d.getVar("CVE_CHECK_ERROR_ON_FAILURE") == "0":
d.setVar("CVE_CHECK_DB_FILE", "")
bb.note("debian_cve_check: No DST database found, skipping CVE check")
else:
bb.fatal("debian_cve_check: No DST database found")
return

# get package name from DEBIAN_SRC_URI
for _pkg_uri in debian_src_uri.split():
Expand Down Expand Up @@ -52,15 +80,22 @@ python update_dst () {
from datetime import datetime, date

json_urls = d.getVar("DEBIAN_SECRUTY_TRACKER_JSON_URL", "").split(" ")
dist_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True),"dst.json")
dist_path = os.path.join(d.getVar("DEBIAN_CVE_CHECK_DB_DIR", True), "dst.json")
dist_dir = os.path.dirname(dist_path)

if not os.path.isdir(dist_dir):
os.mkdir(dist_dir)

if os.path.isfile(dist_path):
timestamp = datetime.fromtimestamp(os.path.getmtime(dist_path))
if timestamp.date() == date.today():
try:
update_interval = int(d.getVar("CVE_DB_UPDATE_INTERVAL"))
except ValueError:
update_interval = 0
if update_interval < 0:
bb.note("DST database update skipped")
return
if time.time() - os.path.getmtime(dist_path) < update_interval:
bb.note("DST database recently updated, skipping")
return

for json_url in json_urls:
Expand All @@ -79,7 +114,7 @@ python update_dst () {
time.sleep(10 + (attempt * 10))
continue
else:
bb.error("DST database received error")
bb.warn("DST database download failed")
return
}

Expand All @@ -90,11 +125,12 @@ def load_json(path):
Load json file.
"""
import json
if not os.path.isfile(path):
bb.error("%s dosen't exist" % path)
try:
with open(path, 'r') as f:
return json.load(f)
except Exception as e:
bb.debug(2, "%s json.load: %s" % (path, e))
return
with open(path, 'r') as f:
return json.load(f)

def deb_check_cves(d, pkg_data):
"""
Expand Down Expand Up @@ -132,8 +168,8 @@ def compare_versions(current_version, fixed_version):
"""
import subprocess

ret = subprocess.run(["/usr/bin/dpkg","--compare-versions", current_version,
"ge",fixed_version]).returncode
ret = subprocess.run(["/usr/bin/dpkg", "--compare-versions", current_version,
"ge", fixed_version]).returncode
if ret == 0:
return True
else:
Expand Down
6 changes: 6 additions & 0 deletions doc/7.cve-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ Replace URL:
DEBIAN_SECRUTY_TRACKER_JSON_URL = "http://localhost:8000/dst.json"
```

- CVE\_CHECK\_ERROR\_ON\_FAILURE

If the Debian security tracker json (dst.json) cannot be downloaded or file is invalid, the CVE check cannot be performed.
In this case, set ```CVE_CHECK_ERROR_ON_FAILURE``` to "1" to make bitbake return fatal ERROR.
The default for this variable is "0" to skip the CVE check and continue with bitbake.