guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Dealing with CVEs that apply to unspecified package versions


From: Ludovic Courtès
Subject: Dealing with CVEs that apply to unspecified package versions
Date: Mon, 06 Mar 2017 22:36:48 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)

Hi!

A couple of weeks ago you mentioned that CVE-2016-10165 (for lcms) is
not reported by ‘guix lint -c cve’.  This is due to the fact that the
CVE does not specify the lcms version number it applies to, and thus
(guix cve) ignores it.

The attached patch fixes (guix cve) to honor CVEs with an unspecified
version number.

Unfortunately, there’s no way to know whether such CVEs are actually
fixed at a specific package version or not, and they’re not uncommon.
Consequently, ‘guix lint -c cve’ would now report old CVEs that possibly
no longer apply to our package versions.

In the patch, I added the ability to specify a ‘patched-vulnerabilities’
property to work around that (with Coreutils as an example).  The
downside is that we’d have to maintain these lists by ourselves, which
is not great, but might still be better than the status quo.

Thoughts?

Ludo’.

diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index c75e03828..c84571c21 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <address@hidden>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès 
<address@hidden>
 ;;; Copyright © 2014 Andreas Enge <address@hidden>
 ;;; Copyright © 2012 Nikita Karetnikov <address@hidden>
 ;;; Copyright © 2014, 2015, 2016 Mark H Weaver <address@hidden>
@@ -320,6 +320,7 @@ used to apply commands with arbitrarily long arguments.")
                       (("#!/bin/sh")
                        (format #f "#!~a/bin/sh" bash)))))
                 %standard-phases)))
+   (properties '((patched-vulnerabilities "CVE-2016-2781"))) ;really?
    (synopsis "Core GNU utilities (file, text, shell)")
    (description
     "GNU Coreutils includes all of the basic command-line tools that are
diff --git a/guix/cve.scm b/guix/cve.scm
index 088e39837..771b82d05 100644
--- a/guix/cve.scm
+++ b/guix/cve.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015, 2016 Ludovic Courtès <address@hidden>
+;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <address@hidden>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -88,9 +88,17 @@
         (close-port port)))))
 
 (define %cpe-package-rx
+  ;; The CPE syntax as defined in the CPE 2.2 specs from
+  ;; <https://cpe.mitre.org/specification/2.2/cpe-specification_2.2.pdf>.
+  ;;
   ;; For applications: "cpe:/a:VENDOR:PACKAGE:VERSION", or sometimes
-  ;; "cpe/a:VENDOR:PACKAGE:VERSION:PATCH-LEVEL".
-  (make-regexp "^cpe:/a:([^:]+):([^:]+):([^:]+)((:.+)?)"))
+  ;; "cpe/a:VENDOR:PACKAGE:VERSION:PATCH-LEVEL"; in some cases, simply
+  ;; "cpe:/a:VENDOR:PACKAGE", meaning that the affected versions are not
+  ;; specified.
+  (make-regexp "^c[pP][eE]:/[aA]:([^:]+):(.*)"))
+
+(define %not-colon
+  (char-set-complement (char-set #\:)))
 
 (define (cpe->package-name cpe)
   "Converts the Common Platform Enumeration (CPE) string CPE to a package
@@ -99,15 +107,17 @@ version string.  Return #f and #f if CPE does not look 
like an application CPE
 string."
   (cond ((regexp-exec %cpe-package-rx (string-trim-both cpe))
          =>
-         (lambda (matches)
-           (values (match:substring matches 2)
-                   (string-append (match:substring matches 3)
-                                  (match (match:substring matches 4)
-                                    ("" "")
-                                    (patch-level
-                                     ;; Drop the colon from things like
-                                     ;; "cpe:/a:openbsd:openssh:6.8:p1".
-                                     (string-drop patch-level 1)))))))
+         (lambda (rx-match)
+           (match (string-tokenize (match:substring rx-match 2)
+                                   %not-colon)
+             ((package)
+              ;; No version component, as in
+              ;; "cpe:/a:littlecms:little_cms_color_engine".
+              (values package 'any))
+             ((package version _ ...)
+              ;; Ignore the "patch level" part if there is one, as in
+              ;; "cpe:/a:openbsd:openssh:6.8:p1".
+              (values package version)))))
         (else
          (values #f #f))))
 
@@ -119,6 +129,11 @@ applications listed in PRODUCTS, with names converted to 
package names:
     '(\"cpe:/a:gnu:libtasn1:4.7\" \"cpe:/a:gnu:libtasn1:4.6\" 
\"cpe:/a:gnu:cpio:2.11\"))
   => ((\"libtasn1\" \"4.7\" \"4.6\") (\"cpio\" \"2.11\"))
 "
+  (define (version-cons v lst)
+    (cond ((eq? v 'any) 'any)
+          ((eq? lst 'any) 'any)
+          (else (cons v lst))))
+
   (fold (lambda (product result)
           (let-values (((name version) (cpe->package-name product)))
             (if name
@@ -126,10 +141,10 @@ applications listed in PRODUCTS, with names converted to 
package names:
                   (((previous . versions) . tail)
                    ;; Attempt to coalesce NAME and PREVIOUS.
                    (if (string=? name previous)
-                       (alist-cons name (cons version versions) tail)
-                       (alist-cons name (list version) result)))
+                       (alist-cons name (version-cons version versions) tail)
+                       (alist-cons name (version-cons version '()) result)))
                   (()
-                   (alist-cons name (list version) result)))
+                   (alist-cons name (version-cons version '()) result)))
                 result)))
         '()
         (sort products string<?)))
@@ -282,6 +297,8 @@ vulnerabilities affecting the given package version."
     (vhash-fold* (if version
                      (lambda (pair result)
                        (match pair
+                         ((vuln . 'any)
+                          (cons vuln result))
                          ((vuln . versions)
                           (if (member version versions)
                               (cons vuln result)
diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm
index 776e7332c..ca96b9a73 100644
--- a/guix/scripts/lint.scm
+++ b/guix/scripts/lint.scm
@@ -790,10 +790,15 @@ from ~s: ~a (~s)~%")
                                      (or (and=> (package-source package)
                                                 origin-patches)
                                          '())))
+              (patched   (or (assoc-ref (package-properties package)
+                                        'patched-vulnerabilities)
+                             '()))
               (unpatched (remove (lambda (vuln)
-                                   (find (cute string-contains
-                                           <> (vulnerability-id vuln))
-                                         patches))
+                                   (or (member (vulnerability-id vuln)
+                                               patched)
+                                       (find (cute string-contains
+                                               <> (vulnerability-id vuln))
+                                             patches)))
                                  vulnerabilities)))
          (unless (null? unpatched)
            (emit-warning package
diff --git a/tests/cve-sample.xml b/tests/cve-sample.xml
index ce158490f..78b2e302b 100644
--- a/tests/cve-sample.xml
+++ b/tests/cve-sample.xml
@@ -613,4 +613,68 @@
     </vuln:references>
     <vuln:summary>The PCo agent in SAP Plant Connectivity (PCo) allows remote 
attackers to cause a denial of service (memory corruption and agent crash) via 
crafted xMII requests, aka SAP Security Note 2238619.</vuln:summary>
   </entry>
+  <entry id="CVE-2016-10165">
+    <vuln:vulnerable-configuration id="http://nvd.nist.gov/";>
+      <cpe-lang:logical-test operator="OR" negate="false">
+        <cpe-lang:fact-ref name="cpe:/a:littlecms:little_cms_color_engine"/>
+      </cpe-lang:logical-test>
+    </vuln:vulnerable-configuration>
+    <vuln:vulnerable-configuration id="http://nvd.nist.gov/";>
+      <cpe-lang:logical-test operator="OR" negate="false">
+        <cpe-lang:fact-ref name="cpe:/o:debian:debian_linux:8.0"/>
+      </cpe-lang:logical-test>
+    </vuln:vulnerable-configuration>
+    <vuln:vulnerable-configuration id="http://nvd.nist.gov/";>
+      <cpe-lang:logical-test operator="OR" negate="false">
+        <cpe-lang:fact-ref name="cpe:/o:novell:leap:42.1"/>
+      </cpe-lang:logical-test>
+    </vuln:vulnerable-configuration>
+    <vuln:vulnerable-software-list>
+      <vuln:product>cpe:/o:debian:debian_linux:8.0</vuln:product>
+      <vuln:product>cpe:/a:littlecms:little_cms_color_engine</vuln:product>
+      <vuln:product>cpe:/o:novell:leap:42.1</vuln:product>
+    </vuln:vulnerable-software-list>
+    <vuln:cve-id>CVE-2016-10165</vuln:cve-id>
+    
<vuln:published-datetime>2017-02-03T14:59:00.177-05:00</vuln:published-datetime>
+    
<vuln:last-modified-datetime>2017-02-09T10:05:10.670-05:00</vuln:last-modified-datetime>
+    <vuln:cvss>
+      <cvss:base_metrics>
+        <cvss:score>5.8</cvss:score>
+        <cvss:access-vector>NETWORK</cvss:access-vector>
+        <cvss:access-complexity>MEDIUM</cvss:access-complexity>
+        <cvss:authentication>NONE</cvss:authentication>
+        <cvss:confidentiality-impact>PARTIAL</cvss:confidentiality-impact>
+        <cvss:integrity-impact>NONE</cvss:integrity-impact>
+        <cvss:availability-impact>PARTIAL</cvss:availability-impact>
+        <cvss:source>http://nvd.nist.gov</cvss:source>
+        
<cvss:generated-on-datetime>2017-02-08T12:23:39.653-05:00</cvss:generated-on-datetime>
+      </cvss:base_metrics>
+    </vuln:cvss>
+    <vuln:cwe id="CWE-125"/>
+    <vuln:references xml:lang="en" reference_type="VENDOR_ADVISORY">
+      <vuln:source>SUSE</vuln:source>
+      <vuln:reference 
href="http://lists.opensuse.org/opensuse-updates/2017-01/msg00174.html"; 
xml:lang="en">openSUSE-SU-2017:0336</vuln:reference>
+    </vuln:references>
+    <vuln:references xml:lang="en" reference_type="VENDOR_ADVISORY">
+      <vuln:source>DEBIAN</vuln:source>
+      <vuln:reference href="http://www.debian.org/security/2017/dsa-3774"; 
xml:lang="en">DSA-3774</vuln:reference>
+    </vuln:references>
+    <vuln:references xml:lang="en" reference_type="VENDOR_ADVISORY">
+      <vuln:source>MLIST</vuln:source>
+      <vuln:reference 
href="http://www.openwall.com/lists/oss-security/2017/01/23/1"; 
xml:lang="en">[oss-security] 20170125 Re: CVE MLIST:[oss-security] 20170123 CVE 
request: lcms2 heap OOB read parsing crafted ICC profile</vuln:reference>
+    </vuln:references>
+    <vuln:references xml:lang="en" reference_type="VENDOR_ADVISORY">
+      <vuln:source>MLIST</vuln:source>
+      <vuln:reference 
href="http://www.openwall.com/lists/oss-security/2017/01/25/14"; 
xml:lang="en">[oss-security] 20170125 Re: CVE request: lcms2 heap OOB read 
parsing crafted ICC profile</vuln:reference>
+    </vuln:references>
+    <vuln:references xml:lang="en" reference_type="VENDOR_ADVISORY">
+      <vuln:source>BID</vuln:source>
+      <vuln:reference href="http://www.securityfocus.com/bid/95808"; 
xml:lang="en">95808</vuln:reference>
+    </vuln:references>
+    <vuln:references xml:lang="en" reference_type="VENDOR_ADVISORY">
+      <vuln:source>CONFIRM</vuln:source>
+      <vuln:reference 
href="https://github.com/mm2/Little-CMS/commit/5ca71a7bc18b6897ab21d815d15e218e204581e2";
 
xml:lang="en">https://github.com/mm2/Little-CMS/commit/5ca71a7bc18b6897ab21d815d15e218e204581e2</vuln:reference>
+    </vuln:references>
+    <vuln:summary>The Type_MLU_Read function in cmstypes.c in Little CMS (aka 
lcms2) allows remote attackers to obtain sensitive information or cause a 
denial of service via an image with a crafted ICC profile, which triggers an 
out-of-bounds heap read.</vuln:summary>
+  </entry>
 </nvd>
diff --git a/tests/cve.scm b/tests/cve.scm
index 3fbb22d3c..d4d9ba5f8 100644
--- a/tests/cve.scm
+++ b/tests/cve.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015, 2016 Ludovic Courtès <address@hidden>
+;;; Copyright © 2015, 2016, 2017 Ludovic Courtès <address@hidden>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -31,12 +31,13 @@
   ;; What we should get when reading %SAMPLE.
   (list
    ;; CVE-2003-0001 has no "/a" in its product list so it is omitted.
-   ;; CVE-2004-0230 lists "tcp" as an application, but lacks a version number.
+   (vulnerability "CVE-2004-0230" '(("tcp" . any)))
    (vulnerability "CVE-2008-2335" '(("phpvid" "1.2" "1.1")))
    (vulnerability "CVE-2008-3522" '(("enterprise_virtualization" "3.5")
                                     ("jasper" "1.900.1")))
    (vulnerability "CVE-2009-3301" '(("openoffice.org" "2.3.0" "2.2.1" 
"2.1.0")))
    ;; CVE-2015-8330 has no software list.
+   (vulnerability "CVE-2016-10165" '(("little_cms_color_engine" . any)))
    ))
 

@@ -47,17 +48,27 @@
   (call-with-input-file %sample xml->vulnerabilities))
 
 (test-equal "vulnerabilities->lookup-proc"
-  (list (list (first %expected-vulnerabilities))
+  (list (list (second %expected-vulnerabilities))
         '()
         '()
-        (list (second %expected-vulnerabilities))
-        (list (third %expected-vulnerabilities)))
+        (list (third %expected-vulnerabilities))
+        (list (fourth %expected-vulnerabilities))
+
+        (list (fifth %expected-vulnerabilities))
+        (list (fifth %expected-vulnerabilities))
+        (list (fifth %expected-vulnerabilities)))
   (let* ((vulns  (call-with-input-file %sample xml->vulnerabilities))
          (lookup (vulnerabilities->lookup-proc vulns)))
     (list (lookup "phpvid")
           (lookup "jasper" "2.0")
           (lookup "foobar")
           (lookup "jasper" "1.900.1")
-          (lookup "openoffice.org" "2.3.0"))))
+          (lookup "openoffice.org" "2.3.0")
+
+          ;; The 'littlecms' vulnerability has no version specifier so it
+          ;; should always match.
+          (lookup "little_cms_color_engine")
+          (lookup "little_cms_color_engine" "1.2.3")
+          (lookup "little_cms_color_engine" "42"))))
 
 (test-end "cve")
diff --git a/tests/lint.scm b/tests/lint.scm
index 3a9b89fe9..64bbc18b5 100644
--- a/tests/lint.scm
+++ b/tests/lint.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Cyril Roelandt <address@hidden>
 ;;; Copyright © 2014, 2015, 2016 Eric Bavier <address@hidden>
-;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <address@hidden>
+;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <address@hidden>
 ;;; Copyright © 2015, 2016 Mathieu Lirzin <address@hidden>
 ;;; Copyright © 2016 Hartmut Goebel <address@hidden>
 ;;;
@@ -598,6 +598,21 @@
                              (patches
                               (list "/a/b/pi-CVE-2015-1234.patch"))))))))))
 
+(test-assert "cve: one patched vulnerability in properties"
+  (mock ((guix scripts lint) package-vulnerabilities
+         (lambda (package)
+           (list (make-struct (@@ (guix cve) <vulnerability>) 0
+                              "CVE-2015-1234"
+                              (list (cons (package-name package)
+                                          (package-version package)))))))
+        (string-null?
+         (with-warnings
+           (check-vulnerabilities
+            (dummy-package "pi"
+                           (version "3.14")
+                           (properties
+                            '((patched-vulnerabilities "CVE-2015-1234")))))))))
+
 (test-assert "cve: vulnerability fixed in replacement version"
   (mock ((guix scripts lint) package-vulnerabilities
          (lambda (package)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]