From patchwork Fri Nov 8 18:02:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Graves X-Patchwork-Id: 70142 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 9C25727BBEA; Fri, 8 Nov 2024 18:06:05 +0000 (GMT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE, SPF_HELO_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id DD42C27BBE2 for ; Fri, 8 Nov 2024 18:06:04 +0000 (GMT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t9TL8-0005y4-5C; Fri, 08 Nov 2024 13:04:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t9TL1-0005fL-QR for guix-patches@gnu.org; Fri, 08 Nov 2024 13:04:05 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t9TL1-0002IK-BB for guix-patches@gnu.org; Fri, 08 Nov 2024 13:04:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:References:In-Reply-To:Date:From:To:Subject; bh=OUOgP/7kgRVujDzjN1Lo3ponAQb4lfRBWeJo4gkx490=; b=qlSYJ4DTEMeT8s/evUvyGcE4NaX8TOEZHZbRbfXGIfy/c/s0ea532wP9TlIi0vqZDojf6yP5Lw5Kt6nZ/sBbcXs5kuhyEvH7MWaP5UtfvUHF3voq3zxcvXKGnqRwzTTG4TZa+O0Jj2iuhFejsEoR/tzKL6QsqecucAeTXcEANnlZeX5upLZLSl7Nu0fCGQdtClNtaqbJFz76DeiHhRlYLOjQlnbwrbXjtfTeYWPWRfn8DqRTtA7Th7MLeR6FzGNOFI2tjvnee31BIy10VGd+HZ3h5+ISnu18APeSiQSyxiqSoK19PrYPBUROQUUowUeujyNQCfvB4mmCKAICBoHcIw==; Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1t9TL1-0002Mw-4H for guix-patches@gnu.org; Fri, 08 Nov 2024 13:04:03 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#74034] [PATCH v3 02/17] cve: Separate vendor and string. Resent-From: Nicolas Graves Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Fri, 08 Nov 2024 18:04:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74034 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 74034@debbugs.gnu.org Cc: Nicolas Graves Received: via spool by 74034-submit@debbugs.gnu.org id=B74034.17310890278978 (code B ref 74034); Fri, 08 Nov 2024 18:04:03 +0000 Received: (at 74034) by debbugs.gnu.org; 8 Nov 2024 18:03:47 +0000 Received: from localhost ([127.0.0.1]:51997 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t9TKk-0002KY-QN for submit@debbugs.gnu.org; Fri, 08 Nov 2024 13:03:47 -0500 Received: from 5.mo582.mail-out.ovh.net ([46.105.54.31]:51517) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t9TKg-0002Ju-5y for 74034@debbugs.gnu.org; Fri, 08 Nov 2024 13:03:43 -0500 Received: from director7.ghost.mail-out.ovh.net (unknown [10.108.25.209]) by mo582.mail-out.ovh.net (Postfix) with ESMTP id 4XlRdR62BVz1SXQ for <74034@debbugs.gnu.org>; Fri, 8 Nov 2024 18:03:39 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-bb4g9 (unknown [10.110.188.168]) by director7.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 192F61FD47; Fri, 8 Nov 2024 18:03:38 +0000 (UTC) Received: from ngraves.fr ([37.59.142.99]) by ghost-submission-5b5ff79f4f-bb4g9 with ESMTPSA id f+ooLnpSLmewfQEAHalyRQ (envelope-from ); Fri, 08 Nov 2024 18:03:38 +0000 Authentication-Results: garm.ovh; auth=pass (GARM-99G00397de699d-ff50-4885-bb86-e3b50bf9c060, B410E14B5436B49C86B8ABDE07A7D070408E1A9F) smtp.auth=ngraves@ngraves.fr X-OVh-ClientIp: 80.215.133.26 Date: Fri, 8 Nov 2024 19:02:25 +0100 Message-ID: <20241108180330.18126-2-ngraves@ngraves.fr> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20241108180330.18126-1-ngraves@ngraves.fr> References: <20241108180330.18126-1-ngraves@ngraves.fr> MIME-Version: 1.0 X-Ovh-Tracer-Id: 5943344134285943522 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefuddrtdeigddutdegucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefpihgtohhlrghsucfirhgrvhgvshcuoehnghhrrghvvghssehnghhrrghvvghsrdhfrheqnecuggftrfgrthhtvghrnhepleffjeetueethfefkeffffefvddukeejkefgleduiedthfekvefhiedvhfffgeegnecukfhppeduvdejrddtrddtrddupdektddrvdduhedrudeffedrvdeipdefjedrheelrddugedvrdelleenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepnhhgrhgrvhgvshesnhhgrhgrvhgvshdrfhhrpdhnsggprhgtphhtthhopedupdhrtghpthhtohepjeegtdefgeesuggvsggsuhhgshdrghhnuhdrohhrghdpoffvtefjohhsthepmhhoheekvdgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=OUOgP/7kgRVujDzjN1Lo3ponAQb4lfRBWeJo4gkx490=; c=relaxed/relaxed; d=ngraves.fr; h=From; s=ovhmo4487190-selector1; t=1731089020; v=1; b=p9GPS29lcUNLCGnImigJz/jYHPR2W2tGsD0ycr6aT694qabHGPWwVoYqjjXK5/JzIIxCcPCn c7nhUSxqqj34VzTJxvC8ZAw5JEAYhjG1D+SF3wW7KwmxfkfS9jriSZ3K8x8JRwQx8xkJITRu0oW zFNpsLkKFObFdLC0/TK86twWAu2MR+j6FG0JX1f3txoNBtQeoq9kQb3XF42Lacm8VAjFjQauENa PxD57moXQ/si4Q0BNU/6Udg/VLhKyNWAEi8C3nfRo8mzTo3lOvje7hvGeOrgACpiUxBf4dn/wyb 1TmWK5nwe5BCWO7B3IMfpYuNY68jns1SSqqI1sfJRElOA== X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Nicolas Graves X-ACL-Warn: , Nicolas Graves via Guix-patches X-Patchwork-Original-From: Nicolas Graves via Guix-patches via From: Nicolas Graves Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches --- guix/cve.scm | 111 +++++++++++++++++++++++++------------------------- tests/cve.scm | 14 +++---- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/guix/cve.scm b/guix/cve.scm index f7984be0ad..4f410ccc5e 100644 --- a/guix/cve.scm +++ b/guix/cve.scm @@ -25,11 +25,11 @@ (define-module (guix cve) #:use-module (web uri) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) - #:use-module (srfi srfi-11) #:use-module (srfi srfi-19) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (srfi srfi-35) + #:use-module (srfi srfi-71) #:use-module (ice-9 match) #:use-module (ice-9 regex) #:use-module (ice-9 vlist) @@ -106,7 +106,7 @@ (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-identifier cpe) "Converts the Common Platform Enumeration (CPE) string CPE to a package @@ -117,18 +117,19 @@ (define (cpe->package-identifier cpe) => (lambda (matches) (values (match:substring matches 1) - (match (match:substring matches 2) + (match:substring matches 2) + (match (match:substring matches 3) ("*" '_) (version (string-append version - (match (match:substring matches 3) + (match (match:substring matches 4) ("" "") (patch-level ;; Drop the colon from things like ;; "cpe:2.3:a:openbsd:openssh:6.8:p1". (string-drop patch-level 1))))))))) (else - (values #f #f)))) + (values #f #f #f)))) (define (cpe-match->cve-configuration alist) "Convert ALIST, a \"cpe_match\" alist, into an sexp representing the package @@ -142,17 +143,18 @@ (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-identifier cpe))) + (let ((vendor package version (cpe->package-identifier cpe))) (and package - `(,package - ,(cond ((and (or starti starte) (or endi ende)) - `(and ,(if starti `(>= ,starti) `(> ,starte)) - ,(if endi `(<= ,endi) `(< ,ende)))) - (starti `(>= ,starti)) - (starte `(> ,starte)) - (endi `(<= ,endi)) - (ende `(< ,ende)) - (else version)))))))) + `(,vendor + ,package + ,(cond ((and (or starti starte) (or endi ende)) + `(and ,(if starti `(>= ,starti) `(> ,starte)) + ,(if endi `(<= ,endi) `(< ,ende)))) + (starti `(>= ,starti)) + (starte `(> ,starte)) + (endi `(<= ,endi)) + (ende `(< ,ende)) + (else version)))))))) (define (configuration-data->cve-configurations alist) "Given ALIST, a JSON dictionary for the baroque \"configurations\" @@ -232,18 +234,12 @@ (define (vulnerability-matches? vuln vendor hidden-vendors) "Checks if a VENDOR matches at least one of 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 (($ id packages) (any (match-lambda - (((? vendor-matches? vendor+name) . _) #t) - (_ #f)) + (((? (cut string=? <> vendor)) _) #t) + (((? (cut member <> hidden-vendors)) _) #t) + (_ #f)) packages)))) @@ -290,39 +286,47 @@ (define sexp->vulnerability (vulnerability id packages)))) (define (cve-configuration->package-list config) - "Parse CONFIG, a config sexp, and return a list of the form (P SEXP) -where P is a package name and SEXP expresses constraints on the matching -versions." + "Parse CONFIG, a config sexp, and return a list of the form (V P SEXP) +where V is a CPE vendor, P is a package name and SEXP expresses constraints on +the matching versions." (let loop ((config config) - (packages '())) + (vendor+package-list '())) (match config (('or configs ...) - (fold loop packages configs)) - (('and config _ ...) ;XXX - (loop config packages)) - (((? string? package) '_) ;any version - (cons `(,package _) - (alist-delete package packages))) - (((? string? package) sexp) - (let ((previous (assoc-ref packages package))) - (if previous - (cons `(,package (or ,sexp ,@previous)) - (alist-delete package packages)) - (cons `(,package ,sexp) packages))))))) + (fold loop vendor+package-list configs)) + (('and config _ ...) ;XXX + (loop config vendor+package-list)) + (((? string? vendor) (? string? package) sexp) + (let ((filtered-list (filter (match-lambda + ((vendor package _) #f) + (otherwise otherwise)) + vendor+package-list))) + (match sexp + ('_ ;any version + (cons `(,vendor ,package _) filtered-list)) + (_ + (match (assoc-ref (assoc-ref vendor+package-list vendor) package) + ((previous) + (cons `(,vendor ,package (or ,sexp ,previous)) filtered-list)) + (_ + (cons `(,vendor ,package ,sexp) vendor+package-list)))))))))) (define (merge-package-lists lst) - "Merge the list in LST, each of which has the form (p sexp), where P -is the name of a package and SEXP is an sexp that constrains matching -versions." + "Merge the list in LST, each of which has the form (V P SEXP), where V is a +CPE vendor, P is the name of a package and SEXP is an sexp that constrains +matching versions." (fold (lambda (plist result) ;XXX: quadratic (fold (match-lambda* - (((package version) result) - (match (assoc-ref result package) - (#f - (cons `(,package ,version) result)) - ((previous) - (cons `(,package (or ,version ,previous)) - (alist-delete package result)))))) + (((vendor package version) result) + (match (assoc-ref result vendor) + (((? (cut string=? package <>)) previous) + (cons `(,vendor ,package (or ,version ,previous)) + (filter (match-lambda + ((vendor package _) #f) + (otherwise otherwise)) + result))) + (_ + (cons `(,vendor ,package ,version) result))))) result plist)) '() @@ -422,11 +426,8 @@ (define table (($ id packages) (fold (lambda (package table) (match package - ((vendor+name . versions) - (vhash-cons (match (string-split vendor+name #\:) - ((vendor name) name) - ((name) name)) - (cons vuln versions) + ((vendor name versions) + (vhash-cons name (cons vuln `(,versions)) table)))) table packages)))) diff --git a/tests/cve.scm b/tests/cve.scm index 6567d73c69..90ada2b647 100644 --- a/tests/cve.scm +++ b/tests/cve.scm @@ -34,19 +34,19 @@ (define %expected-vulnerabilities (vulnerability "CVE-2019-0001" ;; Only the "a" CPE configurations are kept; the "o" ;; configurations are discarded. - '(("juniper:junos" (or "18.21-s4" (or "18.21-s3" "18.2"))))) + '(("juniper" "junos" (or "18.2" (or "18.21-s3" "18.21-s4"))))) (vulnerability "CVE-2019-0005" - '(("juniper:junos" (or "18.11" "18.1")))) + '(("juniper" "junos" (or "18.1" "18.11")))) ;; CVE-2019-0005 has no "a" configurations. (vulnerability "CVE-2019-14811" - '(("artifex:ghostscript" (< "9.28")))) + '(("artifex" "ghostscript" (< "9.28")))) (vulnerability "CVE-2019-17365" - '(("nixos:nix" (<= "2.3")))) + '(("nixos" "nix" (<= "2.3")))) (vulnerability "CVE-2019-1010180" - '(("gnu:gdb" _))) ;any version + '(("gnu" "gdb" _))) ;any version (vulnerability "CVE-2019-1010204" - '(("gnu:binutils" (and (>= "2.21") (<= "2.31.1"))) - ("gnu: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. ))