From patchwork Wed Apr 23 15:29:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFwaGHDq2wgTcOpbG90dGU=?= X-Patchwork-Id: 2076240 Return-Path: X-Original-To: incoming-buildroot@patchwork.ozlabs.org Delivered-To: patchwork-incoming-buildroot@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=buildroot.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=buildroot-bounces@buildroot.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZjNLl71N7z1yMZ for ; Thu, 24 Apr 2025 01:29:19 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 31115611D1; Wed, 23 Apr 2025 15:29:35 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 5aTatXUF01qo; Wed, 23 Apr 2025 15:29:33 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.166.142; helo=lists1.osuosl.org; envelope-from=buildroot-bounces@buildroot.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org F24816103B Received: from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142]) by smtp3.osuosl.org (Postfix) with ESMTP id F24816103B; Wed, 23 Apr 2025 15:29:32 +0000 (UTC) X-Original-To: buildroot@buildroot.org Delivered-To: buildroot@buildroot.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists1.osuosl.org (Postfix) with ESMTP id EAE7F1A0 for ; Wed, 23 Apr 2025 15:29:31 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D0F3883026 for ; Wed, 23 Apr 2025 15:29:31 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Q7qBOg9RgNm8 for ; Wed, 23 Apr 2025 15:29:31 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2a00:1450:4864:20::42f; helo=mail-wr1-x42f.google.com; envelope-from=raphael.melotte@essensium.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 8D55383183 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 8D55383183 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by smtp1.osuosl.org (Postfix) with ESMTPS id 8D55383183 for ; Wed, 23 Apr 2025 15:29:29 +0000 (UTC) Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-39c31e4c3e5so4545893f8f.0 for ; Wed, 23 Apr 2025 08:29:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745422168; x=1746026968; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=9DA65l8GSD577fv7r6lRnquQvv7294ZBWJWtejyczmQ=; b=Wv4eFIgXWHexQf4UhxIqpduipjjbg0b12s1TGMtL5wdittIu3s5+r8rFkPu+8z4VzL 2rr733i/MNFokEx5y5NkzKUlO+CQQbWUyrXkabtkK7a/7uooRrKy6oQTiVuYxC6yrpYr R3dek0IjykWC1iEb8zSwK9/FHMrjTb4BMbqO0YYLojSwjY6fS6c0O6N4nOMZPK05ynWH X85fCKQXsNm3uaU8Cl5r4AEmtJOin1ZvRF9XsUCGRZ+3OFFZV3BnnFgOKuN48cFBv49n 7H/ID8ojuhAwuEbKuuY1mUg4dFptddoce1Rib6JwWld/GokJyKIqmfCFiWlak6osap0z egug== X-Gm-Message-State: AOJu0Yw/BzncSjTxUwNUteneaNlU+aW/tpZ8i1YRIaUwpwsgFQ9L/DsX IKWgOpMeKFFyA7hF6TCtcGkbe24nkMST6QKnHqe8NtV0+qnMNquX5S92XXvqmFTsK4V7/JovoIV W X-Gm-Gg: ASbGncs0+UONRKbyOxX0tsvSS3X/ehK/EhsijAIEwGt/3pHxir0VYfI2+noD5q/qSA+ 9uAbvXYrUTMcItE/4ZJ9IkDcncofXaKlXA7GAS+NHKC8ik2jpYK5G/LNC7Rpuas50/2HD+qhFs5 r5G8oigr/QaAQmwvrNfxpNk05GIhY5rjWoA8coEk7VNRV2862PJD7MS36P+3yCGiE8dlRz3OMTM n+OTuUAGcMZqifX8yi2nu7GLePHqlm8xxVQCgvwqhih3p8f2E2LiGyE5TFSRxm8S1UhgFBjEkCW AmWJAsnSP1/Gl83H8WqJFZ7rnRqMxYEspuxKFVoWrsv1OrvkrB5FNvmSRTZntrWUxf+SME9Vm8t AYHtkrK7c18xIhYUKO3IHJTflETSoo0XIaATQ X-Google-Smtp-Source: AGHT+IHdVnBmqZObZSCnLihxig9g44ocV2ZAj6d1/eswI/7RmrubjrrqHrf60taK0MXCSr92+CqxqA== X-Received: by 2002:a05:6000:2405:b0:39a:c9ed:8555 with SMTP id ffacd0b85a97d-39efba52eb0mr15339723f8f.23.1745422167744; Wed, 23 Apr 2025 08:29:27 -0700 (PDT) Received: from debian-hp-1.local.essensium.com (ip-94-140-185-241.reverse.destiny.be. [94.140.185.241]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-39efa4930e4sm19194887f8f.73.2025.04.23.08.29.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Apr 2025 08:29:27 -0700 (PDT) To: buildroot@buildroot.org Cc: =?utf-8?b?UmFwaGHDq2wgTcOpbG90dGU=?= , Sen Hastings Date: Wed, 23 Apr 2025 17:29:05 +0200 Message-ID: <20250423152906.1017522-1-raphael.melotte@mind.be> X-Mailer: git-send-email 2.49.0 MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mind.be; s=google; t=1745422168; x=1746026968; darn=buildroot.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=9DA65l8GSD577fv7r6lRnquQvv7294ZBWJWtejyczmQ=; b=JMAxHkMi9wR6/tEo2nB7UHVcumpXTYfbu2w9peHP9OW+IBFCPS3H7rgt5a6+mkk1ac W20xGEYcBtbA/dSx98G6LkR4AkpbnPtFu3+aUA8gT4VO0S07SOLOYoMpvQIfEi3NSCtX GlBXfuVXUh5oaXMfleAwlCQgkSiN8ay1DTMadmqmo2Fiqs6OV+9Rt+4CUs/HNRHV8Kyj jbYlydYUC193Zy5R3EQKqvKJHXMYfxagNr0vGAFpE8omkhCfZ3Mf9aV0nkW1cNh+LksW 7YhGpJjbjXpa3u4HxVqgQ0OVhfA+MDbB7fKHO5mzLUO1nbp6rEI8FtVdAfOcbGjNoLhi Kt1w== X-Mailman-Original-Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=mind.be X-Mailman-Original-Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key) header.d=mind.be header.i=@mind.be header.a=rsa-sha256 header.s=google header.b=JMAxHkMi Subject: [Buildroot] [RFC PATCH 1/1] support/scripts/pkg-stats: add support for reporting stale CVE entries X-BeenThere: buildroot@buildroot.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: =?utf-8?q?Rapha=C3=ABl_M=C3=A9lotte_via_buildroot?= From: =?utf-8?b?UmFwaGHDq2wgTcOpbG90dGU=?= Reply-To: =?utf-8?b?UmFwaGHDq2wgTcOpbG90dGU=?= Errors-To: buildroot-bounces@buildroot.org Sender: "buildroot" The NVD database contains some CPEs that are wrongly not associated with any version number. They are for example sometimes associated with very old CVEs. Those CPEs are annoying, because they pollute our pkg-stat CVE results with CVE entries which actually don't affect us. The proper way to solve it is, and should remain, to fix the NVD database by reporting these issues. Having to deal with a lot of CVEs/CPEs, the NVD database is however slow to be updated. To reduce the noise in our pkg-stats results in the meantime, one possibility is to add entries for those CVEs. This however comes with the downside that even once the NVD database gets fixed, those ignored entries risk remaining in Buildroot forever because they are undetected. This commit tries to address this downside by checking for and reporting CVEs that are ignored in Buildroot, but where the NVD reports our package version as unaffected. Those CVEs will appear in the 'CVEs Ignored' column as '(stale)', and the cell will be colored the same way warnings are. This should allow us to detect and remove those entries. It can be tested for example by adding the following variable to the apache package (for a CVE that was recently fixed in the NVD database): APACHE_IGNORE_CVES = CVE-1999-0236 Signed-off-by: Raphaël Mélotte --- support/scripts/cve.py | 4 +--- support/scripts/pkg-stats | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/support/scripts/cve.py b/support/scripts/cve.py index 5af6e0c43f..fe2e3f7712 100755 --- a/support/scripts/cve.py +++ b/support/scripts/cve.py @@ -190,13 +190,11 @@ class CVE: """The set of CPE products referred by this CVE definition""" return set(cpe_product(p['id']) for p in self.each_cpe()) - def affects(self, name, version, cve_ignore_list, cpeid=None): + def affects(self, name, version, cpeid=None): """ True if the Buildroot Package object passed as argument is affected by this CVE. """ - if self.identifier in cve_ignore_list: - return self.CVE_DOESNT_AFFECT pkg_version = distutils.version.LooseVersion(version) if not hasattr(pkg_version, "version"): diff --git a/support/scripts/pkg-stats b/support/scripts/pkg-stats index c134e1ec06..ac8472167e 100755 --- a/support/scripts/pkg-stats +++ b/support/scripts/pkg-stats @@ -122,6 +122,7 @@ class Package: self.cves = list() self.ignored_cves = list() self.unsure_cves = list() + self.stale_cve_ignores = list() self.latest_version = {'status': RM_API_STATUS_ERROR, 'version': None, 'id': None} self.status = {} @@ -638,7 +639,18 @@ def check_package_cve_affects(cve, cpe_product_pkgs): if product not in cpe_product_pkgs: continue for pkg in cpe_product_pkgs[product]: - cve_status = cve.affects(pkg.name, pkg.current_version, pkg.ignored_cves, pkg.cpeid) + cve_status = cve.affects(pkg.name, pkg.current_version, pkg.cpeid) + + if cve.identifier in pkg.ignored_cves: + if cve_status == cve.CVE_DOESNT_AFFECT: + # We have an ignore entry for a CVE which is + # already reported as 'not affected'. This might + # happen for example when the NVD database doesn't + # initially include version numbers for a CPE, and + # later fixes it. Store it so that we can report + # it. + pkg.stale_cve_ignores.append(cve.identifier) + cve_status = cve.CVE_DOESNT_AFFECT if cve_status == cve.CVE_AFFECTS: pkg.cves.append(cve.identifier) elif cve_status == cve.CVE_UNKNOWN: @@ -670,6 +682,8 @@ def check_package_cves(nvd_path, packages): if 'cve' not in pkg.status: if pkg.cves or pkg.unsure_cves: pkg.status['cve'] = ("error", "affected by CVEs") + elif pkg.stale_cve_ignores: + pkg.status['cve'] = ("warning", "has stale CVE ignores") else: pkg.status['cve'] = ("ok", "not affected by CVEs") @@ -712,10 +726,13 @@ def calculate_stats(packages): stats["patches"] += pkg.patch_count stats["total-cves"] += len(pkg.cves) stats["total-unsure-cves"] += len(pkg.unsure_cves) + stats["total-stale-cve-ignores"] += len(pkg.stale_cve_ignores) if len(pkg.cves) != 0: stats["pkg-cves"] += 1 if len(pkg.unsure_cves) != 0: stats["pkg-unsure-cves"] += 1 + if len(pkg.stale_cve_ignores) != 0: + stats["pkg-stale-cve-ignores"] += 1 if pkg.cpeid: stats["cpe-id"] += 1 else: @@ -867,7 +884,7 @@ function expandField(fieldId){ .wrong, .lotsofpatches, .invalid_url, .version-needs-update, .cpe-nok, .cve-nok { background: #ff9a69; } - .somepatches, .somewarnings, .missing_url, .version-unknown, .cpe-unknown, .cve-unknown { + .somepatches, .somewarnings, .missing_url, .version-unknown, .cpe-unknown, .cve-unknown, .cve-stale { background: #ffd870; } .cve_ignored, .version-error { @@ -1080,10 +1097,17 @@ def dump_html_pkg(f, pkg): div_class = ["centered data ignored_cves"] div_class.append(f'_{pkg_css_class}') if pkg.ignored_cves: - div_class.append("cve_ignored") + if pkg.stale_cve_ignores: + div_class.append("cve-stale") + else: + div_class.append("cve_ignored") f.write(f'
\n') for ignored_cve in pkg.ignored_cves: - f.write(f' {ignored_cve}
\n') + if ignored_cve in pkg.stale_cve_ignores: + f.write(f""" {ignored_cve}""" + """(stale)
\n""") + else: + f.write(f' {ignored_cve}
\n') f.write("
\n") # CPE ID @@ -1193,6 +1217,10 @@ def dump_html_stats(f, stats): stats["pkg-unsure-cves"]) f.write('
Total number of unsure CVEs affecting all packages
%s
\n' % stats["total-unsure-cves"]) + f.write('
Packages with stale CVE ignores
%s
\n' % + stats["pkg-stale-cve-ignores"]) + f.write('
Total number of stale CVE ignores affecting all packages
%s
\n' % + stats["total-stale-cve-ignores"]) f.write('
Packages with CPE ID
%s
\n' % stats["cpe-id"]) f.write('
Packages without CPE ID
%s
\n' %