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/toolkit@v1.3.0/types/cvss/cvss_v3_score.go:47 +0x565
github.com/quay/claircore/toolkit/types/cvss.QualitativeScore[...](0xc018201890?)
github.com/quay/claircore/toolkit@v1.3.0/types/cvss/cvss.go:226 +0x19
github.com/quay/claircore/updater/osv.(*ecs).Insert(0xc000051b10, {0x18e6070, 0xc0182377a0}, 0xc000051a98, {0xc018ab7aa0, 0x9}, 0xc01826d900)
github.com/quay/claircore@v1.5.48/updater/osv/osv.go:529 +0x3dd
github.com/quay/claircore/updater/osv.(*updater).Parse(0xc00098d860, {0x18e6070?, 0xc000c08ab0?}, {0x18dca70, 0xc000306570})
github.com/quay/claircore@v1.5.48/updater/osv/osv.go:437 +0x1298
github.com/quay/claircore/libvuln/updates.(*Manager).driveUpdater(0xc000316050, {0x18e6070, 0xc000c08ab0}, {0x18e2fd0, 0xc00098d860})
github.com/quay/claircore@v1.5.48/libvuln/updates/manager.go:376 +0x775
Steps 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/openeuler updater 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 openeuler
Environment
- 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
Description
Clair v4.9.0 (claircore v1.5.48, toolkit v1.3.0) panics during the OSV update cycle when processing advisories from the
openeulerecosystem that contain malformed CVSS v3 vectors.Panic Output
Steps to Reproduce
osv/openeulerupdater fetches and parses advisory dataExpected 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
allowlistconfig option to exclude theopeneulerecosystem:Environment
quay.io/projectquay/clair:4.9.0)Analysis
The root cause is in
toolkit/types/cvss/cvss_v3_score.go:47where(*V3).Score()callspanic()instead of returning an error when it encounters an invalid vector. The invalid vector originates from upstream OSV data for theopeneulerecosystem.The fix should either:
updater/osv/osv.go:529((*ecs).Insert) so a single bad advisory doesn't crash the entire process