Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ __pycache__
roots.txt
sbom*.spdx.json
sbom.used-files.txt
dist/
build/
*.egg-info/
2 changes: 1 addition & 1 deletion sbom/Makefile → Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ $(SBOM_TARGETS) &: $(SBOM_DEPS)
sed 's/\.o$$/.ko/' $(objtree)/modules.order >> $(SBOM_ROOTS_FILE); \
fi

$(Q)$(PYTHON3) $(srctree)/scripts/sbom/sbom.py \
$(Q)kernel-sbom \
--src-tree $(abspath $(srctree)) \
--obj-tree $(abspath $(objtree)) \
--roots-file $(SBOM_ROOTS_FILE) \
Expand Down
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ flowchart TD
- `sbom/`
- `sbom.py` - The main script responsible for generating the SBOM
- `sbom/sbom/` - Library modules used by the main script
- `sbom/tests/` - Unit tests for the library modules
- `tests/` - Unit and integration tests
- `sbom_analysis/` - Additional scripts for analyzing the outputs produced by the main script.
- [sbom_analysis/cmd_graph_based_kernel_build/](sbom_analysis/cmd_graph_based_kernel_build/README.md) - Validation of cmd graph completeness by rebuilding the linux kernel only with files referenced in the cmd graph.
- [sbom_analysis/cmd_graph_visualization/](sbom_analysis/cmd_graph_visualization/README.md) - Interactive visualization of the cmd graph
Expand All @@ -271,19 +271,32 @@ Activate the venv and install build dependencies:
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
pip install pre-commit reuse ruff
pre-commit install
```

When committing, `reuse lint` is run as a pre-commit hook to ensure all files have compliant license headers.

## Run tests
Unit tests can be found in `sbom/tests`. These are designed to be contributed upstream to the `linux` kernel repository.
Integration tests are located in `sbom_integration_tests`. These tests are not intended for inclusion in the kernel repository, as they require a larger number of additional files.
Unit tests can be found in `tests`. These are designed to be contributed upstream to the `linux` kernel repository.
Integration tests are located in `tests/integration`. These tests are not intended for inclusion in the kernel repository, as they require a larger number of additional files.

```bash
python3 -m tests
```

Run unit + integration tests:

```bash
SRCARCH=x86 python3 -m tests --integration
```

Or explicitly:

```bash
# Run unit tests
python3 -m unittest discover -v -s sbom -p "test_*.py"
python3 -m unittest discover -v -s tests -p "test_*.py"
# Run integration tests
python3 -m unittest discover -v -s sbom_integration_tests -p "test_*.py"
python3 -m unittest discover -v -s tests/integration -p "test_*.py"
```
17 changes: 8 additions & 9 deletions sbom/sbom.rst → docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ KernelSbom
Introduction
------------

KernelSbom is a Python script ``scripts/sbom/sbom.py`` that can be
executed after a successful kernel build. When invoked, KernelSbom
analyzes all files involved in the build and generates Software Bill of
Materials (SBOM) documents in SPDX 3.0.1 format.
KernelSbom is a tool ``kernel-sbom`` that can be executed after a successful
kernel build. When invoked, KernelSbom analyzes all files involved in the build
and generates Software Bill of Materials (SBOM) documents in SPDX 3.0.1 format.
The generated SBOM documents capture:

* **Final output artifacts**, typically the kernel image and modules
Expand Down Expand Up @@ -67,12 +66,12 @@ Instead, source files are included in the build SBOM.
Standalone Usage
----------------

KernelSbom can also be used as a standalone script to generate
KernelSbom can also be used as a standalone tool to generate
SPDX documents for specific build outputs. For example, after a
successful x86 kernel build, KernelSbom can generate SPDX documents
for the ``bzImage`` kernel image::

$ SRCARCH=x86 python3 scripts/sbom/sbom.py \
$ SRCARCH=x86 kernel-sbom \
--src-tree . \
--obj-tree ./kernel_build \
--roots arch/x86/boot/bzImage \
Expand All @@ -89,7 +88,7 @@ architecture for which the build was performed.

For a full list of command-line options, run::

$ python3 scripts/sbom/sbom.py --help
$ kernel-sbom --help

Output Format
-------------
Expand Down Expand Up @@ -134,7 +133,7 @@ from multiple sources:
Parsing these files is considered too complex for the scope of this
project. Instead, the remaining gaps of the graph are filled using a
list of manually defined dependencies, see
``scripts/sbom/sbom/cmd_graph/hardcoded_dependencies.py``. This list is
``kernel_sbom/cmd_graph/hardcoded_dependencies.py``. This list is
known to be incomplete. However, analysis of the cmd graph indicates a
~99% completeness. For more information about the completeness analysis,
see `KernelSbom #95 <https://github.com/TNG/KernelSbom/issues/95>`_.
Expand Down Expand Up @@ -171,7 +170,7 @@ For example::

Then use the generated roots file::

$ SRCARCH=x86 python3 scripts/sbom/sbom.py \
$ SRCARCH=x86 kernel-sbom \
--src-tree . \
--obj-tree ./kernel_build \
--roots-file sbom-roots.txt \
Expand Down
4 changes: 4 additions & 0 deletions kernel_sbom/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only OR MIT
# Copyright (C) 2025 TNG Technology Consulting GmbH

__version__ = "0.3.0a0"
15 changes: 7 additions & 8 deletions sbom/sbom.py → kernel_sbom/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
import sys
import time
import uuid
import sbom.sbom_logging as sbom_logging
from sbom.config import get_config
from sbom.path_utils import is_relative_to
from sbom.spdx import JsonLdSpdxDocument, SpdxIdGenerator
from sbom.spdx.core import CreationInfo, SpdxDocument
from sbom.spdx_graph import SpdxIdGeneratorCollection, build_spdx_graphs
from sbom.cmd_graph import CmdGraph
import kernel_sbom.sbom_logging as sbom_logging
from kernel_sbom.config import get_config
from kernel_sbom.path_utils import is_relative_to
from kernel_sbom.spdx import JsonLdSpdxDocument, SpdxIdGenerator
from kernel_sbom.spdx.core import CreationInfo, SpdxDocument
from kernel_sbom.spdx_graph import SpdxIdGeneratorCollection, build_spdx_graphs
from kernel_sbom.cmd_graph import CmdGraph


def main():
Expand Down Expand Up @@ -124,6 +124,5 @@ def main():
sys.exit(1)


# Call main method
if __name__ == "__main__":
main()
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import os
import re
from dataclasses import dataclass, field
from sbom.cmd_graph.deps_parser import parse_cmd_file_deps
from sbom.cmd_graph.savedcmd_parser import parse_inputs_from_commands
import sbom.sbom_logging as sbom_logging
from sbom.path_utils import PathStr
from kernel_sbom.cmd_graph.deps_parser import parse_cmd_file_deps
from kernel_sbom.cmd_graph.savedcmd_parser import parse_inputs_from_commands
import kernel_sbom.sbom_logging as sbom_logging
from kernel_sbom.path_utils import PathStr

SAVEDCMD_PATTERN = re.compile(r"^(saved)?cmd_.*?:=\s*(?P<full_command>.+)$")
SOURCE_PATTERN = re.compile(r"^source.*?:=\s*(?P<source_file>.+)$")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from dataclasses import dataclass, field
from typing import Iterator

from sbom.cmd_graph.cmd_graph_node import CmdGraphNode, CmdGraphNodeConfig
from sbom.path_utils import PathStr
from kernel_sbom.cmd_graph.cmd_graph_node import CmdGraphNode, CmdGraphNodeConfig
from kernel_sbom.path_utils import PathStr


@dataclass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import os
from typing import Iterator, Protocol

from sbom import sbom_logging
from sbom.cmd_graph.cmd_file import CmdFile
from sbom.cmd_graph.hardcoded_dependencies import get_hardcoded_dependencies
from sbom.cmd_graph.incbin_parser import parse_incbin_statements
from sbom.path_utils import PathStr, is_relative_to
from kernel_sbom import sbom_logging
from kernel_sbom.cmd_graph.cmd_file import CmdFile
from kernel_sbom.cmd_graph.hardcoded_dependencies import get_hardcoded_dependencies
from kernel_sbom.cmd_graph.incbin_parser import parse_incbin_statements
from kernel_sbom.path_utils import PathStr, is_relative_to


@dataclass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Copyright (C) 2025 TNG Technology Consulting GmbH

import re
import sbom.sbom_logging as sbom_logging
from sbom.path_utils import PathStr
import kernel_sbom.sbom_logging as sbom_logging
from kernel_sbom.path_utils import PathStr

# Match dependencies on config files
# Example match: "$(wildcard include/config/CONFIG_SOMETHING)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

import os
from typing import Callable
import sbom.sbom_logging as sbom_logging
from sbom.path_utils import PathStr, is_relative_to
from sbom.environment import Environment
import kernel_sbom.sbom_logging as sbom_logging
from kernel_sbom.path_utils import PathStr, is_relative_to
from kernel_sbom.environment import Environment

HARDCODED_DEPENDENCIES: dict[str, list[str]] = {
# defined in linux/Kbuild
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import dataclass
import re

from sbom.path_utils import PathStr
from kernel_sbom.path_utils import PathStr

INCBIN_PATTERN = re.compile(r'\s*\.incbin\s+"(?P<path>[^"]+)"')
"""Regex pattern for matching `.incbin "<path>"` statements."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import shlex
from dataclasses import dataclass
from typing import Any, Callable, Union
import sbom.sbom_logging as sbom_logging
from sbom.path_utils import PathStr
import kernel_sbom.sbom_logging as sbom_logging
from kernel_sbom.path_utils import PathStr


class CmdParsingError(Exception):
Expand Down
2 changes: 1 addition & 1 deletion sbom/sbom/config.py → kernel_sbom/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from enum import Enum
import os
from typing import Any
from sbom.path_utils import PathStr
from kernel_sbom.path_utils import PathStr


class KernelSpdxDocumentKind(Enum):
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion sbom/sbom/spdx/build.py → kernel_sbom/spdx/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copyright (C) 2025 TNG Technology Consulting GmbH

from dataclasses import dataclass, field
from sbom.spdx.core import DictionaryEntry, Element, Hash
from kernel_sbom.spdx.core import DictionaryEntry, Element, Hash


@dataclass(kw_only=True)
Expand Down
2 changes: 1 addition & 1 deletion sbom/sbom/spdx/core.py → kernel_sbom/spdx/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Any, Literal
from sbom.spdx.spdxId import SpdxId
from kernel_sbom.spdx.spdxId import SpdxId

SPDX_SPEC_VERSION = "3.0.1"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import json
from typing import Any
from sbom.path_utils import PathStr
from sbom.spdx.core import SPDX_SPEC_VERSION, SpdxDocument, SpdxObject
from kernel_sbom.path_utils import PathStr
from kernel_sbom.spdx.core import SPDX_SPEC_VERSION, SpdxDocument, SpdxObject


class JsonLdSpdxDocument:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copyright (C) 2025 TNG Technology Consulting GmbH

from dataclasses import dataclass, field
from sbom.spdx.core import Element
from kernel_sbom.spdx.core import Element


@dataclass(kw_only=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from dataclasses import dataclass, field
from typing import Literal
from sbom.spdx.core import Artifact, ElementCollection, IntegrityMethod
from kernel_sbom.spdx.core import Artifact, ElementCollection, IntegrityMethod


SbomType = Literal["source", "build"]
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
from typing import Protocol

import logging
from sbom.config import KernelSpdxDocumentKind
from sbom.cmd_graph import CmdGraph
from sbom.path_utils import PathStr
from sbom.spdx_graph.kernel_file import KernelFileCollection
from sbom.spdx_graph.spdx_graph_model import SpdxGraph, SpdxIdGeneratorCollection
from sbom.spdx_graph.shared_spdx_elements import SharedSpdxElements
from sbom.spdx_graph.spdx_source_graph import SpdxSourceGraph
from sbom.spdx_graph.spdx_build_graph import SpdxBuildGraph
from sbom.spdx_graph.spdx_output_graph import SpdxOutputGraph
from kernel_sbom.config import KernelSpdxDocumentKind
from kernel_sbom.cmd_graph import CmdGraph
from kernel_sbom.path_utils import PathStr
from kernel_sbom.spdx_graph.kernel_file import KernelFileCollection
from kernel_sbom.spdx_graph.spdx_graph_model import SpdxGraph, SpdxIdGeneratorCollection
from kernel_sbom.spdx_graph.shared_spdx_elements import SharedSpdxElements
from kernel_sbom.spdx_graph.spdx_source_graph import SpdxSourceGraph
from kernel_sbom.spdx_graph.spdx_build_graph import SpdxBuildGraph
from kernel_sbom.spdx_graph.spdx_output_graph import SpdxOutputGraph


class SpdxGraphConfig(Protocol):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import hashlib
import os
import re
from sbom.cmd_graph import CmdGraph
from sbom.path_utils import PathStr, is_relative_to
from sbom.spdx import SpdxId, SpdxIdGenerator
from sbom.spdx.core import Hash
from sbom.spdx.software import ContentIdentifier, File, SoftwarePurpose
import sbom.sbom_logging as sbom_logging
from sbom.spdx_graph.spdx_graph_model import SpdxIdGeneratorCollection
from kernel_sbom.cmd_graph import CmdGraph
from kernel_sbom.path_utils import PathStr, is_relative_to
from kernel_sbom.spdx import SpdxId, SpdxIdGenerator
from kernel_sbom.spdx.core import Hash
from kernel_sbom.spdx.software import ContentIdentifier, File, SoftwarePurpose
import kernel_sbom.sbom_logging as sbom_logging
from kernel_sbom.spdx_graph.spdx_graph_model import SpdxIdGeneratorCollection


class KernelFileLocation(Enum):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from dataclasses import dataclass
from datetime import datetime
from sbom.spdx.core import CreationInfo, SoftwareAgent
from sbom.spdx.spdxId import SpdxIdGenerator
from kernel_sbom.spdx.core import CreationInfo, SoftwareAgent
from kernel_sbom.spdx.spdxId import SpdxIdGenerator


@dataclass(frozen=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

from dataclasses import dataclass
from typing import Mapping
from sbom.cmd_graph import CmdGraph
from sbom.path_utils import PathStr
from sbom.spdx import SpdxIdGenerator
from sbom.spdx.build import Build
from sbom.spdx.core import ExternalMap, NamespaceMap, Relationship, SpdxDocument
from sbom.spdx.software import File, Sbom
from sbom.spdx_graph.kernel_file import KernelFileCollection
from sbom.spdx_graph.shared_spdx_elements import SharedSpdxElements
from sbom.spdx_graph.spdx_graph_model import SpdxGraph, SpdxIdGeneratorCollection
from sbom.spdx_graph.spdx_source_graph import source_file_license_elements
from kernel_sbom.cmd_graph import CmdGraph
from kernel_sbom.path_utils import PathStr
from kernel_sbom.spdx import SpdxIdGenerator
from kernel_sbom.spdx.build import Build
from kernel_sbom.spdx.core import ExternalMap, NamespaceMap, Relationship, SpdxDocument
from kernel_sbom.spdx.software import File, Sbom
from kernel_sbom.spdx_graph.kernel_file import KernelFileCollection
from kernel_sbom.spdx_graph.shared_spdx_elements import SharedSpdxElements
from kernel_sbom.spdx_graph.spdx_graph_model import SpdxGraph, SpdxIdGeneratorCollection
from kernel_sbom.spdx_graph.spdx_source_graph import source_file_license_elements


@dataclass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
# Copyright (C) 2025 TNG Technology Consulting GmbH

from dataclasses import dataclass
from sbom.spdx.core import CreationInfo, SoftwareAgent, SpdxDocument, SpdxObject
from sbom.spdx.software import Sbom
from sbom.spdx.spdxId import SpdxIdGenerator
from kernel_sbom.spdx.core import CreationInfo, SoftwareAgent, SpdxDocument, SpdxObject
from kernel_sbom.spdx.software import Sbom
from kernel_sbom.spdx.spdxId import SpdxIdGenerator


@dataclass
Expand Down
Loading