From patchwork Thu Nov 27 11:00:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamel Bouhara X-Patchwork-Id: 75461 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D015D116F5 for ; Thu, 27 Nov 2025 11:00:36 +0000 (UTC) Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.16161.1764241226556605539 for ; Thu, 27 Nov 2025 03:00:26 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=GNKF4n1l; spf=pass (domain: bootlin.com, ip: 185.246.84.56, mailfrom: kamel.bouhara@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 0ED5C1A1DB7; Thu, 27 Nov 2025 11:00:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D94C96068C; Thu, 27 Nov 2025 11:00:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id A8C99102F275A; Thu, 27 Nov 2025 12:00:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1764241224; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=v3jQfxdOJ6tOxcQiXUmfIB2+hxDREoTnnjB7VOypO2U=; b=GNKF4n1lgdQyBWzG7uBwxYsoZyQg9e+/ZgSJ6XvHVlPWX6Xio1xH1/SHD8Cdxo7e44kmDG yPcWQRx8ztZiCmDzgsSvNsTIoe5F5fWpEoqxxFuNqAUuG02CU8ZTYaFarcYlvPkyd0Q4jN wJHzp9IEFJ5c/3zg0aPnzxl08DFHR9XlpFOlmis7PZOVcLUROQQjz7atigrFec5DSRG3ej ojxQ1j9Ri8Xc+3G+MFbbwcfo66T8PYo+i29JOmC81T05rKYnuBOlPtPaG1A1Y80xl19M23 s1FGrMA0nZHfPhLoRpzryqPEnxW35ptSMWIUQLSZFhMY3kc6VbO2ZJ19ZajxKw== From: Kamel Bouhara To: openembedded-core@lists.openembedded.org Cc: JPEWhacker@gmail.com, thomas.petazzoni@bootlin.com, Miquel Raynal , mathieu.dubois-briand@bootlin.com, antonin.godard@bootlin.com, Pascal Eberhard , "Kamel Bouhara (Schneider Electric)" Subject: [PATCH v4 1/3] kernel.bbclass: Add task to export kernel configuration to SPDX Date: Thu, 27 Nov 2025 12:00:16 +0100 Message-ID: <20251127110018.183232-2-kamel.bouhara@bootlin.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251127110018.183232-1-kamel.bouhara@bootlin.com> References: <20251127110018.183232-1-kamel.bouhara@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 27 Nov 2025 11:00:36 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/226834 From: "Kamel Bouhara (Schneider Electric)" Introduce a new bitbake task do_create_kernel_config_spdx that extracts the kernel configuration from ${B}/.config and exports it into the recipe's SPDX document as a separate build_Build object. The kernel config parameters are stored as SPDX DictionaryEntry objects and linked to the main kernel build using an ancestorOf relationship. This enables the kernel build's configuration to be explicitly captured in the SPDX document for compliance, auditing, and reproducibility. The task is gated by SPDX_INCLUDE_KERNEL_CONFIG (default = "0"). Reviewed-by: Joshua Watt Signed-off-by: Kamel Bouhara (Schneider Electric) --- meta/classes-recipe/kernel.bbclass | 64 ++++++++++++++++++++++++++++ meta/classes/create-spdx-3.0.bbclass | 6 +++ 2 files changed, 70 insertions(+) diff --git a/meta/classes-recipe/kernel.bbclass b/meta/classes-recipe/kernel.bbclass index 003a155e79..f989b31c47 100644 --- a/meta/classes-recipe/kernel.bbclass +++ b/meta/classes-recipe/kernel.bbclass @@ -864,5 +864,69 @@ addtask deploy after do_populate_sysroot do_packagedata EXPORT_FUNCTIONS do_deploy +python __anonymous() { + inherits = (d.getVar("INHERIT") or "") + if "create-spdx" in inherits: + bb.build.addtask('do_create_kernel_config_spdx', 'do_populate_lic do_deploy', 'do_create_spdx', d) +} + +python do_create_kernel_config_spdx() { + if d.getVar("SPDX_INCLUDE_KERNEL_CONFIG", True) == "1": + import oe.spdx30 + import oe.spdx30_tasks + from pathlib import Path + from datetime import datetime, timezone + + pkg_arch = d.getVar("SSTATE_PKGARCH") + deploydir = Path(d.getVar("SPDXDEPLOY")) + pn = d.getVar("PN") + + config_path = d.expand("${B}/.config") + kernel_params = [] + if not os.path.exists(config_path): + bb.warn(f"SPDX: Kernel config file not found at: {config_path}") + return + + try: + with open(config_path, 'r') as f: + for line in f: + line = line.strip() + if not line or line.startswith("#"): + continue + if "=" in line: + key, value = line.split("=", 1) + kernel_params.append(oe.spdx30.DictionaryEntry( + key=key, + value=value.strip('"') + )) + bb.note(f"Parsed {len(kernel_params)} kernel config entries from {config_path}") + except Exception as e: + bb.error(f"Failed to parse kernel config file: {e}") + + build, build_objset = oe.sbom30.find_root_obj_in_jsonld( + d, "recipes", f"recipe-{pn}", oe.spdx30.build_Build + ) + + kernel_build = build_objset.add_root( + oe.spdx30.build_Build( + _id=build_objset.new_spdxid("kernel-config"), + creationInfo=build_objset.doc.creationInfo, + build_buildType="https://openembedded.org/kernel-configuration", + build_parameter=kernel_params + ) + ) + + oe.spdx30_tasks.set_timestamp_now(d, kernel_build, "build_buildStartTime") + + build_objset.new_relationship( + [build], + oe.spdx30.RelationshipType.ancestorOf, + [kernel_build] + ) + + oe.sbom30.write_jsonld_doc(d, build_objset, deploydir / pkg_arch / "recipes" / f"recipe-{pn}.spdx.json") +} +do_create_kernel_config_spdx[depends] = "virtual/kernel:do_configure" + # Add using Device Tree support inherit kernel-devicetree diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass index a6d2d44e34..f4f7a77d86 100644 --- a/meta/classes/create-spdx-3.0.bbclass +++ b/meta/classes/create-spdx-3.0.bbclass @@ -50,6 +50,12 @@ SPDX_INCLUDE_TIMESTAMPS[doc] = "Include time stamps in SPDX output. This is \ useful if you want to know when artifacts were produced and when builds \ occurred, but will result in non-reproducible SPDX output" +SPDX_INCLUDE_KERNEL_CONFIG ??= "0" +SPDX_INCLUDE_KERNEL_CONFIG[doc] = "If set to '1', the .config file for the kernel will be parsed \ +and each CONFIG_* value will be included in the Build.build_parameter list as DictionaryEntry \ +items. Set to '0' to disable exporting kernel configuration to improve performance or reduce \ +SPDX document size." + SPDX_IMPORTS ??= "" SPDX_IMPORTS[doc] = "SPDX_IMPORTS is the base variable that describes how to \ reference external SPDX ids. Each import is defined as a key in this \ From patchwork Thu Nov 27 11:00:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamel Bouhara X-Patchwork-Id: 75462 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16F9ED11183 for ; Thu, 27 Nov 2025 11:00:36 +0000 (UTC) Received: from smtpout-04.galae.net (smtpout-04.galae.net [185.171.202.116]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.16120.1764241228984244921 for ; Thu, 27 Nov 2025 03:00:30 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=IGXMMxZs; spf=pass (domain: bootlin.com, ip: 185.171.202.116, mailfrom: kamel.bouhara@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-04.galae.net (Postfix) with ESMTPS id 3E4ADC16A1C; Thu, 27 Nov 2025 11:00:03 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 14CC96068C; Thu, 27 Nov 2025 11:00:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F333A102F2762; Thu, 27 Nov 2025 12:00:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1764241225; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=jDkgXyFNVyxiQimf9b1KajbNW8olcUZ7E4uMdguqVdY=; b=IGXMMxZsfakZpp9AcsaBHKbE+dI1dIyt/U9wx9mZG9wLwt9IwxPVGpBdSE5iRj3HwCn2Ah kQUePWuZAt1nhllzuPduWdLDQmzRCebjbRwYY6JX+m1D8cpnG884kXGo+h0nPY5opCW5Gb zOqJbxRGyOdyYDoEurCATjLpHG6UVo8pRyJIB6RwzXxUp2/LK8/u1W9dbLU5/Ktz50s8L+ SdCdJwtKYoolB0QKZxYh/iOQI+9Y32vzeT+FOh4kBsm93EznUfoxovXfA0GhxKZpk+npch qlpVR86M9OVFDOq2Low16eMmoeUEXzrnVr0HSpHGLRiiCZ954+pE3qbaEwpL1g== From: Kamel Bouhara To: openembedded-core@lists.openembedded.org Cc: JPEWhacker@gmail.com, thomas.petazzoni@bootlin.com, Miquel Raynal , mathieu.dubois-briand@bootlin.com, antonin.godard@bootlin.com, Pascal Eberhard , "Kamel Bouhara (Schneider Electric)" Subject: [PATCH v4 2/3] spdx30_tasks: Add support for exporting PACKAGECONFIG to SPDX Date: Thu, 27 Nov 2025 12:00:17 +0100 Message-ID: <20251127110018.183232-3-kamel.bouhara@bootlin.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251127110018.183232-1-kamel.bouhara@bootlin.com> References: <20251127110018.183232-1-kamel.bouhara@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 27 Nov 2025 11:00:36 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/226835 From: "Kamel Bouhara (Schneider Electric)" Introduce the SPDX_INCLUDE_PACKAGECONFIG variable, which when enabled causes PACKAGECONFIG features to be recorded in the SPDX document as build parameters. Each feature is recorded as a DictionaryEntry with key PACKAGECONFIG: and value enabled or disabled, depending on whether the feature is active in the current build. This makes the build-time configuration more transparent in SPDX output and improves reproducibility tracking. This makes the build-time configuration more transparent in SPDX output and improves reproducibility tracking. In particular, it allows consumers of the SBOM to identify enabled/disabled features that may affect security posture or feature set. Reviewed-by: Joshua Watt Signed-off-by: Kamel Bouhara (Schneider Electric) --- meta/classes/create-spdx-3.0.bbclass | 5 +++++ meta/lib/oe/spdx30_tasks.py | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass index f4f7a77d86..96c0b9722b 100644 --- a/meta/classes/create-spdx-3.0.bbclass +++ b/meta/classes/create-spdx-3.0.bbclass @@ -56,6 +56,11 @@ and each CONFIG_* value will be included in the Build.build_parameter list as Di items. Set to '0' to disable exporting kernel configuration to improve performance or reduce \ SPDX document size." +SPDX_INCLUDE_PACKAGECONFIG ??= "0" +SPDX_INCLUDE_PACKAGECONFIG[doc] = "If set to '1', each PACKAGECONFIG feature is recorded in the \ +build_Build object's build_parameter list as a DictionaryEntry with key \ +'PACKAGECONFIG:' and value 'enabled' or 'disabled'" + SPDX_IMPORTS ??= "" SPDX_IMPORTS[doc] = "SPDX_IMPORTS is the base variable that describes how to \ reference external SPDX ids. Each import is defined as a key in this \ diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index f2f133005d..63aeabf5a4 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py @@ -815,6 +815,26 @@ def create_spdx(d): sorted(list(build_inputs)) + sorted(list(debug_source_ids)), ) + if d.getVar("SPDX_INCLUDE_PACKAGECONFIG", True) != "0": + packageconfig = (d.getVar("PACKAGECONFIG") or "").split() + all_features = (d.getVarFlags("PACKAGECONFIG") or {}).keys() + + if all_features: + enabled = set(packageconfig) + all_features_set = set(all_features) + disabled = all_features_set - enabled + + for feature in sorted(all_features): + status = "enabled" if feature in enabled else "disabled" + build.build_parameter.append( + oe.spdx30.DictionaryEntry( + key=f"PACKAGECONFIG:{feature}", + value=status + ) + ) + + bb.note(f"Added PACKAGECONFIG entries: {len(enabled)} enabled, {len(disabled)} disabled") + oe.sbom30.write_recipe_jsonld_doc(d, build_objset, "recipes", deploydir) From patchwork Thu Nov 27 11:00:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamel Bouhara X-Patchwork-Id: 75460 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07C72CFD2F6 for ; Thu, 27 Nov 2025 11:00:36 +0000 (UTC) Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) by mx.groups.io with SMTP id smtpd.msgproc02-g2.16121.1764241229334541396 for ; Thu, 27 Nov 2025 03:00:30 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="dkim: body hash did not verify" header.i=@bootlin.com header.s=dkim header.b=InUa7Zdp; spf=pass (domain: bootlin.com, ip: 185.246.85.4, mailfrom: kamel.bouhara@bootlin.com) Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 5B0194E4190A; Thu, 27 Nov 2025 11:00:27 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 3009F6068C; Thu, 27 Nov 2025 11:00:27 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 41CA0102F2753; Thu, 27 Nov 2025 12:00:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1764241226; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=XoEUWAQFVGSJAltU7IZlWxtmE9UfWltG0Oyr+aly36A=; b=InUa7ZdpLSUMQnfliD3EltK4uYVz0rEZyk6VB40fNrX0JGIOm6GI/IuD+ULg9QYWYm9pe5 40HBIEsmWIxf1uRzIruaaxHhGyN1O7/lMyq69TwLlnNG0EJ2D/6iFXtU8cq5DoN8UQoP7D yaXzn211ORDVDgsLy+410s5mp11g10r2i3rTq1efAaL5+2DRvVVsrg3SHllsQSqQRsOzcv T483Vyc8whkDlU7A4MXkHDuYeci5I3pFT+G6ugXoAH465MnwHxII5cWflI5xEzZQxbQweE UYifdmjldEo+5XA/PSh49N4m5pjbARkEbB4RxBfBTGomrd9oXcWJyiBUcx9EMQ== From: Kamel Bouhara To: openembedded-core@lists.openembedded.org Cc: JPEWhacker@gmail.com, thomas.petazzoni@bootlin.com, Miquel Raynal , mathieu.dubois-briand@bootlin.com, antonin.godard@bootlin.com, Pascal Eberhard , "Kamel Bouhara (Schneider Electric)" Subject: [PATCH v4 3/3] oeqa/selftest: oe-selftest: Add SPDX tests for kernel config and PACKAGECONFIG Date: Thu, 27 Nov 2025 12:00:18 +0100 Message-ID: <20251127110018.183232-4-kamel.bouhara@bootlin.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251127110018.183232-1-kamel.bouhara@bootlin.com> References: <20251127110018.183232-1-kamel.bouhara@bootlin.com> MIME-Version: 1.0 X-Last-TLS-Session-Version: TLSv1.3 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Thu, 27 Nov 2025 11:00:36 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/226836 From: "Kamel Bouhara (Schneider Electric)" Add test_kernel_config_spdx and test_packageconfig_spdx to verify SPDX document generation includes kernel configuration and package feature metadata when enabled. Signed-off-by: Kamel Bouhara (Schneider Electric) --- meta/lib/oeqa/selftest/cases/spdx.py | 57 ++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/meta/lib/oeqa/selftest/cases/spdx.py b/meta/lib/oeqa/selftest/cases/spdx.py index 8cd4e83ca2..035f3fe336 100644 --- a/meta/lib/oeqa/selftest/cases/spdx.py +++ b/meta/lib/oeqa/selftest/cases/spdx.py @@ -286,3 +286,60 @@ class SPDX30Check(SPDX3CheckBase, OESelftestTestCase): break else: self.assertTrue(False, "Unable to find imported Host SpdxID") + + def test_kernel_config_spdx(self): + kernel_recipe = get_bb_var("PREFERRED_PROVIDER_virtual/kernel") + spdx_file = f"recipe-{kernel_recipe}.spdx.json" + spdx_path = f"{{DEPLOY_DIR_SPDX}}/{{SSTATE_PKGARCH}}/recipes/{spdx_file}" + + # Make sure kernel is configured first + bitbake(f"-c configure {kernel_recipe}") + + objset = self.check_recipe_spdx( + kernel_recipe, + spdx_path, + task="do_create_kernel_config_spdx", + extraconf="""\ + INHERIT += "create-spdx" + SPDX_INCLUDE_KERNEL_CONFIG = "1" + """, + ) + + # Check that at least one CONFIG_* entry exists + found_kernel_config = False + for build_obj in objset.foreach_type(oe.spdx30.build_Build): + if getattr(build_obj, "build_buildType", "") == "https://openembedded.org/kernel-configuration": + found_kernel_config = True + self.assertTrue( + len(getattr(build_obj, "build_parameter", [])) > 0, + "Kernel configuration build_Build has no CONFIG_* entries" + ) + break + + self.assertTrue(found_kernel_config, "Kernel configuration build_Build not found in SPDX output") + + def test_packageconfig_spdx(self): + objset = self.check_recipe_spdx( + "tar", + "{DEPLOY_DIR_SPDX}/{SSTATE_PKGARCH}/recipes/recipe-tar.spdx.json", + extraconf="""\ + SPDX_INCLUDE_PACKAGECONFIG = "1" + """, + ) + + found_entries = [] + for build_obj in objset.foreach_type(oe.spdx30.build_Build): + for param in getattr(build_obj, "build_parameter", []): + if param.key.startswith("PACKAGECONFIG:"): + found_entries.append((param.key, param.value)) + + self.assertTrue( + found_entries, + "No PACKAGECONFIG entries found in SPDX output for 'tar'" + ) + + for key, value in found_entries: + self.assertIn( + value, ["enabled", "disabled"], + f"Unexpected PACKAGECONFIG value '{value}' for {key}" + )