Add resolved-in-version override for CVE-2025-63389 on Ollama (#48525)

**Related issue:** Resolves #44800
This commit is contained in:
Dante Catalfamo
2026-07-07 16:24:41 -04:00
committed by GitHub
parent 0b9ca60e73
commit 57dc28991a
3 changed files with 76 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
- Fixed missing `resolved_in_version` for CVE-2025-63389 on Ollama (resolved in v0.12.4), which was absent because the NVD record only provides a `versionEndIncluding` constraint.
@@ -553,6 +553,23 @@ func transformVuln(year int, item nvdapi.CVEItem) nvdapi.CVEItem {
}
}
// NVD lists ollama as vulnerable through (and including) v0.12.3 via versionEndIncluding with no
// versionEndExcluding, so resolved_in_version comes back empty. The fix shipped in the next
// release, v0.12.4. Supply versionEndExcluding here so Fleet reports the resolved version.
// See https://github.com/fleetdm/fleet/issues/44800.
if item.CVE.ID != nil && *item.CVE.ID == "CVE-2025-63389" {
for configID := range item.CVE.Configurations {
for nodeID := range item.CVE.Configurations[configID].Nodes {
for matchID := range item.CVE.Configurations[configID].Nodes[nodeID].CPEMatch {
match := &item.CVE.Configurations[configID].Nodes[nodeID].CPEMatch[matchID]
if strings.Contains(match.Criteria, ":ollama:ollama:") && match.VersionEndExcluding == nil {
match.VersionEndExcluding = new("0.12.4")
}
}
}
}
}
return item
}
@@ -30,6 +30,64 @@ var (
api20CVEDir = filepath.Join("testdata", "cve", "api_2.0")
)
func TestTransformVuln(t *testing.T) {
t.Parallel()
// makeItem builds a minimal CVEItem with a single CPE match carrying the given criteria and
// versionEndIncluding/versionEndExcluding constraints.
makeItem := func(cveID, criteria string, endIncluding, endExcluding *string) nvdapi.CVEItem {
return nvdapi.CVEItem{
CVE: nvdapi.CVE{
ID: &cveID,
Configurations: []nvdapi.Config{
{
Nodes: []nvdapi.Node{
{
CPEMatch: []nvdapi.CVECPEMatch{
{
Vulnerable: true,
Criteria: criteria,
VersionEndIncluding: endIncluding,
VersionEndExcluding: endExcluding,
},
},
},
},
},
},
},
}
}
endExcludingOf := func(item nvdapi.CVEItem) *string {
return item.CVE.Configurations[0].Nodes[0].CPEMatch[0].VersionEndExcluding
}
const ollamaCPE = "cpe:2.3:a:ollama:ollama:*:*:*:*:*:*:*:*"
t.Run("CVE-2025-63389 gets a resolved version when NVD provides only versionEndIncluding", func(t *testing.T) {
got := transformVuln(2025, makeItem("CVE-2025-63389", ollamaCPE, new("0.12.3"), nil))
require.NotNil(t, endExcludingOf(got))
require.Equal(t, "0.12.4", *endExcludingOf(got))
})
t.Run("CVE-2025-63389 does not clobber an existing versionEndExcluding", func(t *testing.T) {
got := transformVuln(2025, makeItem("CVE-2025-63389", ollamaCPE, new("0.12.3"), new("0.12.9")))
require.NotNil(t, endExcludingOf(got))
require.Equal(t, "0.12.9", *endExcludingOf(got))
})
t.Run("CVE-2025-63389 override does not apply to other products", func(t *testing.T) {
got := transformVuln(2025, makeItem("CVE-2025-63389", "cpe:2.3:a:acme:widget:*:*:*:*:*:*:*:*", new("0.12.3"), nil))
require.Nil(t, endExcludingOf(got))
})
t.Run("unrelated CVE is left unchanged", func(t *testing.T) {
got := transformVuln(2025, makeItem("CVE-2025-00000", ollamaCPE, new("0.12.3"), nil))
require.Nil(t, endExcludingOf(got))
})
}
func TestStoreCVEsLegacyFormat(t *testing.T) {
t.Parallel()
year := 2023