@@ -106,22 +106,22 @@ (define (reference-data->cve-references alist)
(define %cpe-package-rx
;; For applications: "cpe:2.3:a:VENDOR:PACKAGE:VERSION", or sometimes
;; "cpe:2.3:a:VENDOR:PACKAGE:VERSION:PATCH-LEVEL".
- (make-regexp "^cpe:2\\.3:a:([^:]+):([^:]+):([^:]+):([^:]+):"))
+ (make-regexp "^cpe:2\\.3:a:([^:]+:[^:]+):([^:]+):([^:]+):"))
-(define (cpe->package-name cpe)
+(define (cpe->package-identifier cpe)
"Converts the Common Platform Enumeration (CPE) string CPE to a package
-name, in a very naive way. Return two values: the package name, and its
-version string. Return #f and #f if CPE does not look like an application CPE
-string."
+identifier, in a very naive way. Return two values: the package identifier
+(composed from the CPE vendor and the package name), and its version string.
+Return #f and #f if CPE does not look like an application CPE string."
(cond ((regexp-exec %cpe-package-rx cpe)
=>
(lambda (matches)
- (values (match:substring matches 2)
- (match (match:substring matches 3)
+ (values (match:substring matches 1)
+ (match (match:substring matches 2)
("*" '_)
(version
(string-append version
- (match (match:substring matches 4)
+ (match (match:substring matches 3)
("" "")
(patch-level
;; Drop the colon from things like
@@ -142,7 +142,7 @@ (define (cpe-match->cve-configuration alist)
;; Normally "cpe23Uri" is here in each "cpe_match" item, but CVE-2020-0534
;; has a configuration that lacks it.
(and cpe
- (let-values (((package version) (cpe->package-name cpe)))
+ (let-values (((package version) (cpe->package-identifier cpe)))
(and package
`(,package
,(cond ((and (or starti starte) (or endi ende))
@@ -228,6 +228,24 @@ (define (version-matches? version sexp)
(('>= min)
(version>=? version min))))
+(define (vulnerability-matches? vuln vendor hidden-vendors)
+ "Checks if a VENDOR matches at least one of <vulnerability> VULN
+packages. When VENDOR is #f, ignore packages that have a vendor among
+HIDDEN-VENDORS."
+ (define (vendor-matches? vendor+name)
+ (if vendor
+ (string-prefix? (string-append vendor ":") vendor+name)
+ (or (null? hidden-vendors)
+ (not (any (cut string-prefix? (string-append <> ":") vendor+name)
+ hidden-vendors)))))
+
+ (match vuln
+ (($ <vulnerability> id packages)
+ (any (match-lambda
+ (((? vendor-matches? vendor+name) . _) #t)
+ (_ #f))
+ packages))))
+
;;;
;;; High-level interface.
@@ -404,28 +422,29 @@ (define table
(($ <vulnerability> id packages)
(fold (lambda (package table)
(match package
- ((name . versions)
- (vhash-cons name (cons vuln versions)
+ ((vendor+name . versions)
+ (vhash-cons (match (string-split vendor+name #\:)
+ ((vendor name) name)
+ ((name) name))
+ (cons vuln versions)
table))))
table
packages))))
vlist-null
vulnerabilities))
- (lambda* (package #:optional version)
- (vhash-fold* (if version
- (lambda (pair result)
- (match pair
- ((vuln sexp)
- (if (version-matches? version sexp)
- (cons vuln result)
- result))))
- (lambda (pair result)
- (match pair
- ((vuln . _)
- (cons vuln result)))))
- '()
- package table)))
+ (lambda* (package #:optional version #:key (vendor #f) (hidden-vendors '()))
+ (vhash-fold*
+ (lambda (pair result)
+ (match pair
+ ((vuln sexp)
+ (if (and (or (and (not vendor) (null? hidden-vendors))
+ (vulnerability-matches? vuln vendor hidden-vendors))
+ (or (not version) (version-matches? version sexp)))
+ (cons vuln result)
+ result))))
+ '()
+ package table)))
;;; cve.scm ends here
@@ -1551,8 +1551,14 @@ (define package-vulnerabilities
(package-name package)))
(version (or (assoc-ref (package-properties package)
'cpe-version)
- (package-version package))))
- ((force lookup) name version)))))
+ (package-version package)))
+ (vendor (assoc-ref (package-properties package)
+ 'cpe-vendor))
+ (hidden-vendors (assoc-ref (package-properties package)
+ 'lint-hidden-cpe-vendors)))
+ ((force lookup) name version
+ #:vendor vendor
+ #:hidden-vendors hidden-vendors)))))
;; Prevent Guile 3 from inlining this procedure so we can mock it in tests.
(set! package-vulnerabilities package-vulnerabilities)
@@ -34,19 +34,19 @@ (define %expected-vulnerabilities
(vulnerability "CVE-2019-0001"
;; Only the "a" CPE configurations are kept; the "o"
;; configurations are discarded.
- '(("junos" (or "18.21-s4" (or "18.21-s3" "18.2")))))
+ '(("juniper:junos" (or "18.21-s4" (or "18.21-s3" "18.2")))))
(vulnerability "CVE-2019-0005"
- '(("junos" (or "18.11" "18.1"))))
+ '(("juniper:junos" (or "18.11" "18.1"))))
;; CVE-2019-0005 has no "a" configurations.
(vulnerability "CVE-2019-14811"
- '(("ghostscript" (< "9.28"))))
+ '(("artifex:ghostscript" (< "9.28"))))
(vulnerability "CVE-2019-17365"
- '(("nix" (<= "2.3"))))
+ '(("nixos:nix" (<= "2.3"))))
(vulnerability "CVE-2019-1010180"
- '(("gdb" _))) ;any version
+ '(("gnu:gdb" _))) ;any version
(vulnerability "CVE-2019-1010204"
- '(("binutils" (and (>= "2.21") (<= "2.31.1")))
- ("binutils_gold" (and (>= "1.11") (<= "1.16")))))
+ '(("gnu:binutils" (and (>= "2.21") (<= "2.31.1")))
+ ("gnu:binutils_gold" (and (>= "1.11") (<= "1.16")))))
;; CVE-2019-18192 has no associated configurations.
))