-
Notifications
You must be signed in to change notification settings - Fork 42
Description
Problem Summary
RPM packages with OS release-specific suffixes (e.g., el7eap, el8eap, el9eap) are incorrectly matched across different OS release lines because the version comparison function treats them as a linear version progression rather than distinct product lines.
Current Behavior
When querying for vulnerabilities affecting a PURL like:
pkg:rpm/redhat/eap7-bouncycastle@1.76.0-4.redhat_00001.1.el8eap?arch=noarch
The system incorrectly matches it against purl_status records that have version ranges targeting different OS releases:
| Version Range | Status | Expected Match | Actual Match |
|---|---|---|---|
[el8eap, el8eap] |
fixed | Yes | Yes |
(null, el9eap) |
affected | No | Yes |
The el8eap purl incorrectly matches the range < el9eap because rpmver_cmp() compares the release suffixes as 8 < 9.
Root Cause
The rpmver_cmp() function correctly implements RPM version comparison per the RPM spec:
-- Splits version into segments: 1.76.0-4.redhat_00001.1.el8eap
-- becomes: [1, 76, 0, 4, redhat, 00001, 1, el, 8, eap]
a_segments := array(select (regexp_matches(a, '(\d+|[a-zA-Z]+|[~^])', 'g'))[1]);When comparing el8eap vs el9eap:
- Both split into segments:
[el, 8, eap]vs[el, 9, eap] el=el(equal)8<9(numeric comparison)- Result:
el8eap < el9eap
This is technically correct per RPM ordering, but semantically wrong for vulnerability correlation:
el7,el8,el9represent different RHEL major versions- They are parallel product lines, not version progressions
- A vulnerability fixed in
el9eappackages does NOT meanel8eappackages are affected
Affected Endpoints
| Endpoint | Method | Impact |
|---|---|---|
/api/v2/vulnerability/analyze |
POST | Returns incorrect vulnerabilities for el8/el9 RPMs |
/api/v3/vulnerability/analyze |
POST | Same as above, plus incorrect remediations |
/api/v3/purl/recommend |
POST | May recommend wrong versions |
/api/v2/purl/{key} |
GET | Shows incorrect vulnerability status |
/api/v2/sbom/{id}/advisory |
GET | Lists wrong advisories for SBOM packages |
/api/v2/vulnerability/{id} |
GET | Shows incorrect affected packages |
Reproduction Steps
-
Ingest a Red Hat CSAF advisory that contains products for multiple RHEL versions:
curl -X POST http://localhost:8080/api/v2/advisory \ -H "Content-Type: application/json" \ -d @etc/test-data/csaf/cve-2023-33201.json -
Query for an
el8eappackage:curl -X POST http://localhost:8080/api/v3/vulnerability/analyze \ -H "Content-Type: application/json" \ -d '{"purls": ["pkg:rpm/redhat/eap7-bouncycastle@1.76.0-4.redhat_00001.1.el8eap?arch=noarch"]}'
-
Observe that the response includes vulnerability status and remediations from
el9eapproducts.
Test Cases
Tests documenting this issue:
Branch: test/rpm-os-release-suffix-matching
Test file: modules/ingestor/tests/version/rpmver.rs
| Test Name | Purpose |
|---|---|
test_rpmver_cmp_release_suffix_different_os |
Documents that el7 < el8 < el9 per RPM spec |
test_rpmver_version_matches_cross_os_release_bug |
Documents the bug: el8eap matches range < el9eap |
test_rpmver_same_version_different_os_releases |
Shows all OS suffixes are treated as linear progression |
test_rpmver_version_matches_exact_with_os_suffix |
Verifies exact matching works correctly |
test_rpmver_version_matches_same_os_release |
Verifies matching within same OS release works |
Run the tests with:
cargo test -p trustify-module-ingestor --test ingestor test_rpmverPotential Solutions
Option 1: Enhanced Version Range Matching
Modify rpmver_version_matches to detect and handle OS release suffixes:
CREATE FUNCTION extract_rpm_os_release(version text) RETURNS text AS $$
BEGIN
RETURN (regexp_match(version, '\.el(\d+)'))[1];
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- In rpmver_version_matches, add check:
IF extract_rpm_os_release(version_p) != extract_rpm_os_release(range_p.high_version) THEN
RETURN false;
END IF;Pros: Targeted fix, minimal changes
Cons: RPM-specific, may miss edge cases
Option 2: Normalize OS Release in Base PURL
Extract OS release into PURL namespace during ingestion.
Option 3: Add OS Release Qualifier
Store OS release as a qualifier and include it in matching.
Option 4: Separate Version and Release Fields
Store RPM version and release separately in the database.
Related
- Discovered during review of feat: CSAF remediation support in api/v3/purl/recommend and api/v2/vulnerability/analyze endpoints #2234 (CSAF Remediation Support)
- The remediation linking is correct; this exposes a pre-existing version matching issue
- PR comment: feat: CSAF remediation support in api/v3/purl/recommend and api/v2/vulnerability/analyze endpoints #2234 (comment)
References
- RPM Version Comparison
- CSAF test file:
etc/test-data/csaf/cve-2023-33201.json
Metadata
Metadata
Assignees
Labels
Type
Projects
Status