Skip to content

Ubuntu: CVEs fixed by an installed ESM (esm-apps/esm-infra) build are still reported as notFixedYet/needed (plain <release> segment wins over esm-apps/<release>) #2645

Description

@AllanElleuch

What did you do? (required. The issue will be closed when not provided.)

Scanned an Ubuntu 24.04 (noble) host that is attached to Ubuntu Pro with esm-apps + esm-infra enabled and fully up to date, using vuls scan (fast mode) + vuls report with the Vuls2 DB (ghcr.io/vulsio/vuls-nightly-db:0, fetched 2026-08-20).

Many installed packages are ESM builds, e.g. freeglut 3.4.0-1ubuntu0.1~esm1, ffmpeg 7:6.1.1-3ubuntu5+esm10, openexr 3.1.5-5.1ubuntu0.1~esm1, python-pip 24.0+dfsg-1ubuntu1.3+esm3, cjson 1.7.17-1ubuntu0.1~esm3, mbedtls 2.28.8-1ubuntu0.1~esm1.

What did you expect to happen?

CVEs whose fix was published in the esm-apps / esm-infra pocket and whose fixed version is already installed should not be reported as notFixedYet: true, fixState: needed.

Ground truth from Canonical for one example (freeglut, CVE-2024-24258):

$ pro fix --dry-run CVE-2024-24258
CVE-2024-24258: Freeglut vulnerabilities
1 affected source package is installed: freeglut
(1/1) freeglut:
A fix is available in Ubuntu Pro: ESM Apps.
The update is already installed.
✔ CVE-2024-24258 is resolved.

and https://ubuntu.com/security/cves/CVE-2024-24258.json for noble: status: released, fixed version 3.4.0-1ubuntu0.1~esm1, pocket: esm-apps.

What happened instead?

  • Current Output

The report marks the CVE as unfixed, sourced from the plain noble_medium segment of the ubuntu-cve-tracker:

"CVE-2024-24258": {
  "affectedPackages": [
    {"name": "libglut-dev",  "notFixedYet": true, "fixState": "needed"},
    {"name": "libglut3.12",  "notFixedYet": true, "fixState": "needed"}
  ],
  "cveContents": {"ubuntu_api": [{"type": "ubuntu_api",
     "optional": {"vuls2-sources": "[{\"root_id\":\"CVE-2024-24258\",\"source_id\":\"ubuntu-cve-tracker\",\"segment\":{\"ecosystem\":\"ubuntu:24.04\",\"tag\":\"noble_medium\"}}]"}}]}
}
"packages": {"libglut3.12": {"name": "libglut3.12", "version": "3.4.0-1ubuntu0.1~esm1"}}
"SrcPackages": {"freeglut": {"name": "freeglut", "version": "3.4.0-1ubuntu0.1~esm1", "binaryNames": ["libglut3.12", "libglut-dev"]}}

Scale of the problem on this host: of 266 "open" userspace CVE×source-package entries in the report, 60 are already fixed by an installed ESM build (checked against the Ubuntu CVE tracker JSON, noble status released, pocket esm-*, fixed version <= installed source version with dpkg --compare-versions): ffmpeg 34 of 38 reported CVEs, mbedtls 5, zvbi 5, cjson 4, openexr 3, python-pip 3, freeglut 2, qtwebengine-opensource-src 1, qtdeclarative-opensource-src 1, gst-plugins-bad1.0 1, wheel 1.

Why (as far as I can tell from the code)

In the ubuntu-cve-tracker data there are two segments per release for such packages: the plain noble_<prio> segment, where the status is needed (the ~esm build is not available to non-Pro users), and the esm-apps/noble_<prio> segment, where the status is released (3.4.0-1ubuntu0.1~esm1).

detector/vuls2/vuls2.go (walkVulnerabilityDetections) evaluates every segment independently and records the match per source{RootID, SourceID, Segment}. The esm-apps/noble segment does not match (installed >= fixed), the plain noble segment matches with an unfixed needed status, so the CVE surfaces as open. ignoreCriterion in detector/vuls2/vendor.go only drops non-ESM /-prefixed tags (fips, …) and keeps both the plain and the ESM segment; compareTag additionally prefers the plain tag (!strings.Contains(tag, "/") → 2) over the ESM one when choosing contents. Nothing ties the two segments of the same package together, and the scanner does not know/care whether the host is Pro-attached.

Proposal

For ecosystem ubuntu:*, source ubuntu-cve-tracker: when a package is detected as unfixed in the plain <release>_* segment but the same source package has a released status in an esm-apps/<release>_* / esm-infra/<release>_* (or esm, *-legacy, ros-esm) segment whose fixed version is <= the installed version, drop the plain-segment match (the fix is installed). Cheap heuristics that would already cover the real world: the installed version string contains esm (~esmN / +esmN), or the host has /etc/apt/sources.list.d/ubuntu-esm-apps.sources / pro status reports esm-apps: enabled (could be collected at scan time like other host facts). Conversely, for a non-Pro host the ESM released status could be surfaced as "fix available in Ubuntu Pro" instead of being invisible.

Steps to reproduce the behaviour

  1. Ubuntu 24.04 host, pro attach …, pro enable esm-apps, apt install libglut3.12 (gets 3.4.0-1ubuntu0.1~esm1).
  2. vuls scan (fast mode is enough), vuls report -format-json with the Vuls2 nightly DB.
  3. CVE-2024-24258 / CVE-2024-24259 are reported with notFixedYet: true, fixState: needed for libglut3.12, while pro fix --dry-run CVE-2024-24258 says the fix is already installed.

Configuration (MUST fill this out):

  • Go version (go version): n/a (official image vuls/vuls:v0.40.1)

  • Go environment (go env): n/a

  • Vuls environment:

Hash : vuls-v0.40.1-build-20260730_021743_e6624e9 (vuls -v)

  • config.toml:
[vuls2]
path = "/vuls/db/vuls.db"
repository = "ghcr.io/vulsio/vuls-nightly-db:0"
skipUpdate = true

[default]
port = "22"
user = "vuls-scan"
keyPath = "/vuls/ssh/id_ed25519"
scanMode = ["fast"]
scanModules = ["ospkg"]

[servers]
[servers.host]
host = ""
  • command:
vuls scan   -config /vuls/config.toml -results-dir /vuls/results
vuls report -config /vuls/config.toml -results-dir /vuls/results -to-localfile -format-json -format-full-text -format-list -lang=en

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions