Understanding CVE Database Management¶
Why meta-tolomeo actively manages the NVD CVE database, and the strategy behind it.
The problem¶
cve-check scans every recipe against a local copy of the NVD database.
The stock cve-update-nvd2-native recipe keeps that copy in ${DL_DIR}/CVE_CHECK and, on later
builds, either skips the update (when the file is younger than CVE_DB_UPDATE_INTERVAL) or performs
a fast incremental update covering only the days since the last fetch.
The weak point is the first fetch: a full download is slow and, because the public NVD API is rate-limited and occasionally unavailable, it can hang or fail. This happens on every build that starts from an empty downloads directory — CI feature-branch pipelines (which use a one-shot, workspace-local cache) and fresh local checkouts.
meta-tolomeo addresses this with two cooperating mechanisms plus a per-branch policy.
Backup seed¶
A .bbappend for cve-update-nvd2-native seeds the database from CVE_DB_BACKUP_FILE before the
stock fetch runs. When the local database is missing, the backup is copied into place, so the fetch
finds a database and only needs a quick incremental update — or skips entirely.
The seed is deliberately conservative:
- It copies only when the local database is missing, never clobbering an already-cached copy.
- When the backup path is the build's own database (stable/production builds that write the shared cache), the seed is skipped and the stock update runs in place — the backup is never tainted.
- If the backup is absent, the build logs a warning and falls back to the normal fetch.
The copy preserves the backup's modification time, so the stock recipe still sees the true age of the data when choosing between skip, incremental, and full re-download.
Scheduled refresh¶
A seed is only as fresh as its backup. A dedicated CI job refreshes the shared database on a
schedule, independent of build cadence, by running the fetch against the shared cache with
CVE_DB_UPDATE_INTERVAL=0. Because the shared cache is exactly the default CVE_DB_BACKUP_FILE,
every other build seeds from an up-to-date database.
Per-branch update policy¶
With the shared database kept fresh, each build type chooses how much work to do at build time:
| Build type | CVE_DB_UPDATE_INTERVAL |
Rationale |
|---|---|---|
| Scheduled refresh | 0 |
Force an incremental refresh of the shared database every run. |
| Feature build | -1 |
Seed and skip the update — zero network, CVEs still evaluated against the fresh seed. |
| Production / stable | default (86400) |
Update the shared database in place — a self-healing safety net if the schedule lags. |
Feature builds get fast, fresh CVE evaluation with no NVD traffic, while production builds never
depend solely on the schedule. Skipping (-1) requires a database to be present; if both the seed
source and the local database are missing, the build fails rather than scanning against no data.
See also
- Manage the CVE Database — task guide
- CVE Database reference — variables, paths, and CI refresh job