Compare commits

..

2 Commits

Author SHA1 Message Date
Paul Barker
265fe4e664 cve-update: Avoid NFS caching issues
When moving the updated CVE database file to the downloads directory,
ensure that it has a different inode number to the previous version of
this file.

We have seen "sqlite3.DatabaseError: database disk image is malformed"
exceptions on our autobuilder when trying to read the CVE database in
do_cve_check tasks. The context here is that the downloads directory
(where the updated database file is copied to) is shared between workers
as an NFS mount. Different autobuilder workers were seeing different
checksums for the database file, which indicates that a mix of both new
and stale data was being read. Forcing each new version of the database
file to have a different inode number will prevent stale data from being
read from local caches.

This should fix [YOCTO #16086].

(From OE-Core rev: 1e668895f80725cb4102d000c879d57464757cc1)

Signed-off-by: Paul Barker <paul@pbarker.dev>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit f63622bbec1cfaca6d0b3e05e11466e4c10fa86e)
[YC: Fixing [YOCTO #15660] ]
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2026-07-31 17:28:23 +01:00
Richard Purdie
83a78bea91 cve_check: Use a local copy of the database during builds
Rtaher than trying to use a sqlite database over NFS from DL_DIR, work from
a local copy in STAGING DIR after fetching.

(From OE-Core rev: d7f74cd94e4916e4d93252328f8484d13a877554)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit 03596904392d257572a905a182b92c780d636744)
[YC: Fixing [YOCTO #15660] ]
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2026-07-31 17:28:23 +01:00
3 changed files with 31 additions and 12 deletions

View File

@@ -25,8 +25,9 @@
CVE_PRODUCT ??= "${BPN}"
CVE_VERSION ??= "${PV}"
CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK"
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_2.db"
CVE_CHECK_DB_FILENAME ?= "nvdcve_2.db"
CVE_CHECK_DB_DIR ?= "${STAGING_DIR}/CVE_CHECK"
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/${CVE_CHECK_DB_FILENAME}"
CVE_CHECK_DB_FILE_LOCK ?= "${CVE_CHECK_DB_FILE}.lock"
CVE_CHECK_LOG ?= "${T}/cve.log"
@@ -156,7 +157,7 @@ python do_cve_check () {
}
addtask cve_check before do_build
do_cve_check[depends] = "cve-update-nvd2-native:do_fetch"
do_cve_check[depends] = "cve-update-nvd2-native:do_unpack"
do_cve_check[nostamp] = "1"
python cve_check_cleanup () {

View File

@@ -63,8 +63,13 @@ python do_fetch() {
shutil.copy2(db_file, db_tmp_file)
if update_db_file(db_tmp_file, d) == True:
# Update downloaded correctly, can swap files
shutil.move(db_tmp_file, db_file)
# Update downloaded correctly, we can swap files. To avoid potential
# NFS caching issues, ensure that the destination file has a new inode
# number. We do this in two steps as the downloads directory may be on
# a different filesystem to tmpdir we're working in.
new_file = "%s.new" % (db_file)
shutil.move(db_tmp_file, new_file)
os.rename(new_file, db_file)
else:
# Update failed, do not modify the database
bb.note("CVE database update failed")

View File

@@ -8,7 +8,6 @@ INHIBIT_DEFAULT_DEPS = "1"
inherit native
deltask do_unpack
deltask do_patch
deltask do_configure
deltask do_compile
@@ -35,7 +34,9 @@ CVE_DB_INCR_UPDATE_AGE_THRES ?= "10368000"
# Number of attempts for each http query to nvd server before giving up
CVE_DB_UPDATE_ATTEMPTS ?= "5"
CVE_DB_TEMP_FILE ?= "${CVE_CHECK_DB_DIR}/temp_nvdcve_2.db"
CVE_CHECK_DB_DLDIR_FILE ?= "${DL_DIR}/CVE_CHECK/${CVE_CHECK_DB_FILENAME}"
CVE_CHECK_DB_DLDIR_LOCK ?= "${CVE_CHECK_DB_DLDIR_FILE}.lock"
CVE_CHECK_DB_TEMP_FILE ?= "${CVE_CHECK_DB_FILE}.tmp"
python () {
if not bb.data.inherits_class("cve-check", d):
@@ -52,9 +53,9 @@ python do_fetch() {
bb.utils.export_proxies(d)
db_file = d.getVar("CVE_CHECK_DB_FILE")
db_file = d.getVar("CVE_CHECK_DB_DLDIR_FILE")
db_dir = os.path.dirname(db_file)
db_tmp_file = d.getVar("CVE_DB_TEMP_FILE")
db_tmp_file = d.getVar("CVE_CHECK_DB_TEMP_FILE")
cleanup_db_download(db_file, db_tmp_file)
# By default let's update the whole database (since time 0)
@@ -77,22 +78,34 @@ python do_fetch() {
pass
bb.utils.mkdirhier(db_dir)
bb.utils.mkdirhier(os.path.dirname(db_tmp_file))
if os.path.exists(db_file):
shutil.copy2(db_file, db_tmp_file)
if update_db_file(db_tmp_file, d, database_time) == True:
# Update downloaded correctly, can swap files
shutil.move(db_tmp_file, db_file)
# Update downloaded correctly, we can swap files. To avoid potential
# NFS caching issues, ensure that the destination file has a new inode
# number. We do this in two steps as the downloads directory may be on
# a different filesystem to tmpdir we're working in.
new_file = "%s.new" % (db_file)
shutil.move(db_tmp_file, new_file)
os.rename(new_file, db_file)
else:
# Update failed, do not modify the database
bb.warn("CVE database update failed")
os.remove(db_tmp_file)
}
do_fetch[lockfiles] += "${CVE_CHECK_DB_FILE_LOCK}"
do_fetch[lockfiles] += "${CVE_CHECK_DB_DLDIR_LOCK}"
do_fetch[file-checksums] = ""
do_fetch[vardeps] = ""
python do_unpack() {
import shutil
shutil.copyfile(d.getVar("CVE_CHECK_DB_DLDIR_FILE"), d.getVar("CVE_CHECK_DB_FILE"))
}
do_unpack[lockfiles] += "${CVE_CHECK_DB_DLDIR_LOCK} ${CVE_CHECK_DB_FILE_LOCK}"
def cleanup_db_download(db_file, db_tmp_file):
"""
Cleanup the download space from possible failed downloads