panic in CVSS v3 scoring from malformed OSV openeuler advisory
Description
Clair v4.9.0 (claircore v1.5.48, toolkit v1.3.0) panics during the OSV update cycle when processing advisories from the openeuler ecosystem that contain malformed CVSS v3 vectors.
Panic Output
panic: programmer error: invalid vector constructed
goroutine 2500 [running]:
github.com/quay/claircore/toolkit/types/cvss.(*V3).Score(0xc017bf3848)
github.com/quay/claircore/[email protected]/types/cvss/cvss_v3_score.go:47 +0x565
github.com/quay/claircore/toolkit/types/cvss.QualitativeScore[...](0xc018201890?)
github.com/quay/claircore/[email protected]/types/cvss/cvss.go:226 +0x19
github.com/quay/claircore/updater/osv.(*ecs).Insert(0xc000051b10, {0x18e6070, 0xc0182377a0}, 0xc000051a98, {0xc018ab7aa0, 0x9}, 0xc01826d900)
github.com/quay/[email protected]/updater/osv/osv.go:529 +0x3dd
github.com/quay/claircore/updater/osv.(*updater).Parse(0xc00098d860, {0x18e6070?, 0xc000c08ab0?}, {0x18dca70, 0xc000306570})
github.com/quay/[email protected]/updater/osv/osv.go:437 +0x1298
github.com/quay/claircore/libvuln/updates.(*Manager).driveUpdater(0xc000316050, {0x18e6070, 0xc000c08ab0}, {0x18e2fd0, 0xc00098d860})
github.com/quay/[email protected]/libvuln/updates/manager.go:376 +0x775Steps to Reproduce
- Deploy Clair v4.9.0 in combo mode with default updater configuration (all OSV ecosystems enabled)
- Wait for the update cycle to begin
- The
osv/openeulerupdater fetches and parses advisory data - Clair panics when it encounters an advisory with an invalid CVSS v3 vector string
Expected Behavior
Clair should log a warning for the malformed vector and skip the advisory (or assign a default severity), not panic.
Actual Behavior
The process panics and crashes. Since this happens on every update cycle, Clair enters a crash loop (CrashLoopBackOff in Kubernetes).
Workaround
Use the OSV allowlist config option to exclude the openeuler ecosystem:
updaters:
config:
osv:
allowlist:
- npm
- pypi
- go
- crates.io
- maven
# ... other ecosystems, excluding openeulerEnvironment
- Clair v4.9.0 (
quay.io/projectquay/clair:4.9.0) - claircore v1.5.48
- toolkit v1.3.0
- Deployed on OpenShift (ROSA) in combo mode
- Observed: 2026-08-14
Analysis
The root cause is in toolkit/types/cvss/cvss_v3_score.go:47 where (*V3).Score() calls panic() instead of returning an error when it encounters an invalid vector. The invalid vector originates from upstream OSV data for the openeuler ecosystem.
The fix should either:
- Validate CVSS vectors before scoring and return an error for malformed ones
- Handle the error in
updater/osv/osv.go:529((*ecs).Insert) so a single bad advisory doesn't crash the entire process
Source: quay/clair