]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
cve-update: Keep mtime stamp in the database itself
authorNiko Mauno <niko.mauno@vaisala.com>
Tue, 4 Nov 2025 08:33:33 +0000 (08:33 +0000)
committerMathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Fri, 7 Nov 2025 05:47:27 +0000 (06:47 +0100)
This should help to avoid problems that will occur if the modification
time of database file itself is altered e.g. by unassociated
process(es) on the file system which hosts the database file.

Since this change updates the database structure by adding a new table,
bump the 'minor' version number in database file names to enforce full
database fetch. This should also iron out e.g. situation where the
database might have inconspicuously omitted entries due to way in which
the mtime of database file itself was relied upon.

Signed-off-by: Niko Mauno <niko.mauno@vaisala.com>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
meta/classes/cve-check.bbclass
meta/recipes-core/meta/cve-update-db-native.bb
meta/recipes-core/meta/cve-update-native.inc
meta/recipes-core/meta/cve-update-nvd2-native.bb

index 259c699af287a74ce8ce7572f69c05e6f9739dde..7252c4ecdc0f8ce2169befd38561ac12d0e4fe83 100644 (file)
@@ -35,7 +35,7 @@ CVE_VERSION ??= "${PV}"
 NVD_DB_VERSION ?= "FKIE"
 
 # Use different file names for each database source, as they synchronize at different moments, so may be slightly different
-CVE_CHECK_DB_FILENAME ?= "${@'nvdcve_2-2.db' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'nvdfkie_1-1.db'}"
+CVE_CHECK_DB_FILENAME ?= "${@'nvdcve_2-3.db' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'nvdfkie_1-2.db'}"
 CVE_CHECK_DB_FETCHER ?= "${@'cve-update-nvd2-native' if d.getVar('NVD_DB_VERSION') == 'NVD2' else 'cve-update-db-native'}"
 CVE_CHECK_DB_DIR ?= "${STAGING_DIR}/CVE_CHECK"
 CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/${CVE_CHECK_DB_FILENAME}"
index ca83c80958532a56a40772cd73c90ea9509b4e1a..c1db67ce55322665e69a2be9a6bcc3dd008237e0 100644 (file)
@@ -18,6 +18,7 @@ def update_db_file(db_tmp_file, d, *_):
     """
     import bb.progress
     import bb.utils
+    import datetime
     from datetime import date
     import lzma
     import sqlite3
@@ -31,6 +32,7 @@ def update_db_file(db_tmp_file, d, *_):
     initialize_db(conn)
 
     with bb.progress.ProgressHandler(d) as ph, open(os.path.join(d.getVar("TMPDIR"), 'cve_check'), 'a') as cve_f:
+        pre_update_utc_timestamp = datetime.datetime.now().astimezone(tz=datetime.timezone.utc)
         total_years = date.today().year + 1 - YEAR_START
         for i, year in enumerate(range(YEAR_START, date.today().year + 1)):
             bb.note("Updating %d" % year)
@@ -82,6 +84,7 @@ def update_db_file(db_tmp_file, d, *_):
                 bb.debug(2, "Already up to date (last modified %s)" % last_modified)
             # Update success, set the date to cve_check file.
             if year == date.today().year:
+                conn.execute("insert into MTIME values (?)", [pre_update_utc_timestamp.isoformat()]).close()
                 cve_f.write('CVE database update : %s\n\n' % date.today())
 
         conn.commit()
index 298c89b498f984c487d5b11e65560176bfb438e5..47cfb6a4633539c09b2311f1881d47ec9b59b78f 100644 (file)
@@ -33,6 +33,7 @@ python do_fetch() {
     import bb.utils
     import bb.progress
     import shutil
+    import time
 
     bb.utils.export_proxies(d)
 
@@ -46,16 +47,16 @@ python do_fetch() {
 
     # The NVD database changes once a day, so no need to update more frequently
     # Allow the user to force-update
-    try:
-        import time
-        update_interval = int(d.getVar("CVE_DB_UPDATE_INTERVAL"))
-        if update_interval < 0:
-            bb.note("CVE database update skipped")
-            if not os.path.exists(db_file):
-                bb.error("CVE database %s not present, database fetch/update skipped" % db_file)
-            return
+    update_interval = int(d.getVar("CVE_DB_UPDATE_INTERVAL"))
+    if update_interval < 0:
+        bb.note("CVE database update skipped")
+        if not os.path.exists(db_file):
+            bb.error("CVE database %s not present, database fetch/update skipped" % db_file)
+        return
+
+    if os.path.exists(db_file):
+        database_time = get_mtime_timestamp_from(db_file)
         curr_time = time.time()
-        database_time = os.path.getmtime(db_file)
         bb.note("Current time: %s; DB time: %s" % (time.ctime(curr_time), time.ctime(database_time)))
         if curr_time < database_time:
             bb.warn("Database time is in the future, force DB update")
@@ -64,9 +65,6 @@ python do_fetch() {
             bb.note("CVE database recently updated, skipping")
             return
 
-    except OSError:
-        pass
-
     if bb.utils.to_boolean(d.getVar("BB_NO_NETWORK")):
         bb.error("BB_NO_NETWORK attempted to disable fetch, this recipe uses CVE_DB_UPDATE_INTERVAL to control download, set to '-1' to disable fetch or update")
 
@@ -107,10 +105,30 @@ def cleanup_db_download(db_tmp_file):
         os.remove(db_tmp_file)
 
 
+def get_mtime_timestamp_from(db_file):
+    """
+    Resolve the time when the CVE database was previously updated
+    """
+    import datetime
+    import sqlite3
+
+    conn = sqlite3.connect(db_file)
+    curs = conn.cursor()
+    res = curs.execute("select TIMESTAMP from MTIME order by TIMESTAMP desc limit 1;")
+    latest = res.fetchone()[0]
+    latest = datetime.datetime.strptime(latest, '%Y-%m-%dT%H:%M:%S.%f+00:00')
+    latest = latest.astimezone(tz=datetime.timezone.utc)
+    curs.close()
+    conn.close()
+    return latest.timestamp()
+
+
 def initialize_db(conn):
     with conn:
         c = conn.cursor()
 
+        c.execute("CREATE TABLE IF NOT EXISTS MTIME (TIMESTAMP INT)")
+
         c.execute("CREATE TABLE IF NOT EXISTS META (YEAR INTEGER UNIQUE, DATE TEXT)")
 
         c.execute("CREATE TABLE IF NOT EXISTS NVD (ID TEXT UNIQUE, SUMMARY TEXT, \
index 01d3e8e7541a48398352022fa2d7874b8a8b29b8..77d7408b164aeee9134337227b581aa50e9b0be0 100644 (file)
@@ -72,6 +72,8 @@ def update_db_file(db_tmp_file, d, database_time):
     import sqlite3
     import json
 
+    pre_update_utc_timestamp = datetime.datetime.now().astimezone(tz=datetime.timezone.utc)
+
     # Connect to database
     conn = sqlite3.connect(db_tmp_file)
     initialize_db(conn)
@@ -141,6 +143,7 @@ def update_db_file(db_tmp_file, d, database_time):
 
         # Update success, set the date to cve_check file.
         cve_f.write('CVE database update : %s\n\n' % datetime.date.today())
+        conn.execute("insert into MTIME values (?)", [pre_update_utc_timestamp.isoformat()]).close()
 
     conn.commit()
     conn.close()