feat: read what a Linux kernel has built and loaded, once for every driver #4

Merged
christianmanivong merged 1 commits from feat/kernel-facts into main 2026-10-05 04:36:43 +00:00
Owner

netOrk's KB precondition vocabulary asks kernel_module and kernel_config (netOrk #268). Reading the answer is identical on every Linux host, so it lives here once:

  • KERNEL_FACTS_COMMAND: one read-only POSIX sh line, no privileges. It reads the release, /proc/modules, modules.builtin, modules.dep and the build configuration (/boot/config-* or /proc/config.gz). The report is framed, gzipped and base64-encoded. Nothing in it can then look like a prompt to a screen-scraping transport, and a distribution kernel's configuration (~300 kB) crosses as a fifth of that. Measured on an Ubuntu 7.0 kernel: 145 kB on the wire, 250 loaded, 306 built-in, 6 899 shipped modules, 10 284 options.
  • parse_kernel_facts(): a section the command could not print comes back None, never empty. Downstream, "could not read" and "read, and nothing there" lead to different verdicts.
  • module_name(): no path, no .ko* suffix, - folded to _, as the kernel itself does.
  • KernelFactsMixin uses the README's template form: get_kernel_facts() is concrete, and _run_kernel_facts_command() is the driver's hook. Drivers mix it in themselves; OSDriver does not carry it. A Windows host is an OS driver too, and hasattr(driver, "get_kernel_facts") has to stay truthful.
  • KernelFactsDict in models.py; version 2.1.0; README updated.

Tests: 213 pass, including one that runs the command against the test host and parses the result.

napalm-linux and napalm-proxmox PRs depend on this.

netOrk's KB precondition vocabulary asks `kernel_module` and `kernel_config` (netOrk #268). Reading the answer is identical on every Linux host, so it lives here once: - **`KERNEL_FACTS_COMMAND`**: one read-only POSIX `sh` line, no privileges. It reads the release, `/proc/modules`, `modules.builtin`, `modules.dep` and the build configuration (`/boot/config-*` or `/proc/config.gz`). The report is framed, gzipped and base64-encoded. Nothing in it can then look like a prompt to a screen-scraping transport, and a distribution kernel's configuration (~300 kB) crosses as a fifth of that. Measured on an Ubuntu 7.0 kernel: 145 kB on the wire, 250 loaded, 306 built-in, 6 899 shipped modules, 10 284 options. - **`parse_kernel_facts()`**: a section the command could not print comes back `None`, never empty. Downstream, "could not read" and "read, and nothing there" lead to different verdicts. - **`module_name()`**: no path, no `.ko*` suffix, `-` folded to `_`, as the kernel itself does. - **`KernelFactsMixin`** uses the README's template form: `get_kernel_facts()` is concrete, and `_run_kernel_facts_command()` is the driver's hook. Drivers mix it in themselves; `OSDriver` does not carry it. A Windows host is an OS driver too, and `hasattr(driver, "get_kernel_facts")` has to stay truthful. - `KernelFactsDict` in `models.py`; version **2.1.0**; README updated. Tests: 213 pass, including one that runs the command against the test host and parses the result. napalm-linux and napalm-proxmox PRs depend on this.
christianmanivong added 1 commit 2026-10-05 04:17:49 +00:00
A kernel CVE's exploitability often hangs on code that is not there: a module
neither loaded nor shipped, an option the kernel was built without. netOrk's
KB precondition vocabulary asks exactly that (kernel_module, kernel_config).

Reading it is the same on every Linux host, so the command and its parse live
here and a driver supplies only the transport:

- KERNEL_FACTS_COMMAND: one read-only POSIX sh line, no privileges. Release,
  /proc/modules, modules.builtin, modules.dep and the build configuration
  (/boot/config-* or /proc/config.gz). The report is framed, gzipped and
  base64-encoded, so nothing in it can look like a shell prompt to a
  screen-scraping transport, and ~300 kB of configuration crosses as a fifth.
- parse_kernel_facts(): a section the command could not print comes back None,
  never empty -- "could not read" and "read, and nothing there" must stay apart.
- module_name(): no path, no .ko suffix, "-" folded to "_", as the kernel does.
- KernelFactsMixin, in the template form: get_kernel_facts() is concrete,
  _run_kernel_facts_command() is the driver's hook. Mixed in by the drivers
  that can, not by OSDriver -- a Windows host is an OS driver too, and
  hasattr(driver, "get_kernel_facts") has to stay truthful.
- KernelFactsDict in models.py. Version 2.1.0.
christianmanivong merged commit d55b036a8e into main 2026-10-05 04:36:43 +00:00
christianmanivong deleted branch feat/kernel-facts 2026-10-05 04:36:43 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: NAPALM/napalm-device-types#4