release v0.9.0: 5 gap-fillers — every year 2016 → 2026 now covered

Five new modules close the 2018 gap entirely and thicken
2019 / 2020 / 2024. All five carry the full 4-format detection-rule
corpus + opsec_notes + arch_support + register helpers.

CVE-2018-14634 — mutagen_astronomy (Qualys, closes 2018)
  create_elf_tables() int wrap → SUID-execve stack corruption.
  CISA KEV-listed Jan 2026 despite the bug's age; legacy RHEL 7 /
  CentOS 7 / Debian 8 fleets still affected. 🟡 PRIMITIVE.
  arch_support: x86_64+unverified-arm64.

CVE-2019-14287 — sudo_runas_neg1 (Joe Vennix)
  sudo -u#-1 → uid_t underflow → root despite (ALL,!root) blacklist.
  Pure userspace logic bug; the famous Apple Information Security
  finding. detect() looks for a (ALL,!root) grant in sudo -ln output;
  PRECOND_FAIL when no such grant exists for the invoking user.
  arch_support: any (4 -> 5 userspace 'any' modules).

CVE-2020-29661 — tioscpgrp (Jann Horn / Project Zero)
  TTY TIOCSPGRP ioctl race on PTY pairs → struct pid UAF in
  kmalloc-256. Affects everything through Linux 5.9.13. 🟡 PRIMITIVE
  (race-driver + msg_msg groom). Public PoCs from grsecurity /
  spender + Maxime Peterlin.

CVE-2024-50264 — vsock_uaf (a13xp0p0v / Pwnie Award 2025 winner)
  AF_VSOCK connect-race UAF in kmalloc-96. Pwn2Own 2024 + Pwnie
  2025 winner. Reachable as plain unprivileged user (no userns
  required — unusual). Two public exploit paths: @v4bel+@qwerty
  kernelCTF (BPF JIT spray + SLUBStick) and Alexander Popov / PT
  SWARM (msg_msg). 🟡 PRIMITIVE.

CVE-2024-26581 — nft_pipapo (Notselwyn II, 'Flipping Pages')
  nft_set_pipapo destroy-race UAF. Sibling to nf_tables
  (CVE-2024-1086) from the same Notselwyn paper. Distinct bug in
  the pipapo set substrate. Same family signature. 🟡 PRIMITIVE.

Plumbing changes:

  core/registry.h + registry_all.c — 5 new register declarations
    + calls.
  Makefile — 5 new MUT/SRN/TIO/VSK/PIP module groups in MODULE_OBJS.
  tests/test_detect.c — 7 new test rows covering the new modules
    (above-fix OK, predates-the-bug OK, sudo-no-grant PRECOND_FAIL).
  tools/verify-vm/targets.yaml — verifier entries for all 5 with
    honest 'expect_detect' values based on what Vagrant boxes can
    realistically reach (mutagen_astronomy gets OK on stock 18.04
    since 4.15.0-213 is post-fix; sudo_runas_neg1 gets PRECOND_FAIL
    because no (ALL,!root) grant on default vagrant user; tioscpgrp
    + nft_pipapo VULNERABLE with kernel pins; vsock_uaf flagged
    manual because vsock module rarely available on CI runners).
  tools/refresh-cve-metadata.py — added curl fallback for the CISA
    KEV CSV fetch (urlopen times out intermittently against CISA's
    HTTP/2 endpoint).

Corpus growth across v0.8.0 + v0.9.0:

                v0.7.1    v0.8.0    v0.9.0
  Modules          31        34        39
  Distinct CVEs    26        29        34
  KEV-listed       10        10        11 (mutagen_astronomy)
  arch 'any'        4         6         7 (sudo_runas_neg1)
  Years 2016-2026:  10/11     10/11     **11/11**

Year-by-year coverage:

  2016: 1   2017: 1   2018: 1   2019: 2   2020: 2
  2021: 5   2022: 5   2023: 8   2024: 3   2025: 2   2026: 4

CVE-2018 gap → CLOSED. Every year from 2016 through 2026 now has
at least one module.

Surfaces updated:
  - README.md: badge → 22 VM-verified / 34, Status section refreshed
  - docs/index.html: hero eyebrow + footer → v0.9.0, hero tagline
    'every year 2016 → 2026', stats chips → 39 / 22 / 11 / 151
  - docs/RELEASE_NOTES.md: v0.9.0 entry added on top with year
    coverage matrix + per-module breakdown; v0.8.0 + v0.7.1 entries
    preserved below
  - docs/og.svg + og.png: regenerated with new numbers + 'Every
    year 2016 → 2026' tagline

CVE metadata refresh (tools/refresh-cve-metadata.py) deferred to
follow-up — CISA KEV CSV + NVD CVE API were timing out during the
v0.9.0 push window. The 5 new CVEs will return NULL from
cve_metadata_lookup() until the refresh runs (—module-info simply
skips the WEAKNESS/THREAT INTEL header for them; no functional
impact). Re-run 'tools/refresh-cve-metadata.py' when network
cooperates.

Tests: macOS local 33/33 kernel_range pass; detect-test stubs (88
total) build clean; ASan/UBSan + clang-tidy CI jobs still green
from the v0.7.x setup.
This commit is contained in:
2026-05-23 22:15:44 -04:00
parent 4af82b82d9
commit d84b3b0033
28 changed files with 2850 additions and 34 deletions
+86
View File
@@ -60,6 +60,14 @@ extern const struct skeletonkey_module dirty_frag_rxrpc_module;
extern const struct skeletonkey_module sudo_samedit_module;
extern const struct skeletonkey_module sudoedit_editor_module;
extern const struct skeletonkey_module pwnkit_module;
extern const struct skeletonkey_module sudo_chwoot_module;
extern const struct skeletonkey_module udisks_libblockdev_module;
extern const struct skeletonkey_module pintheft_module;
extern const struct skeletonkey_module mutagen_astronomy_module;
extern const struct skeletonkey_module sudo_runas_neg1_module;
extern const struct skeletonkey_module tioscpgrp_module;
extern const struct skeletonkey_module vsock_uaf_module;
extern const struct skeletonkey_module nft_pipapo_module;
static int g_pass = 0;
static int g_fail = 0;
@@ -630,6 +638,84 @@ static void run_all(void)
SKELETONKEY_PRECOND_FAIL);
#endif
/* ── new v0.8.0 modules ──────────────────────────────────────── */
/* sudo_chwoot: vulnerable sudo version range [1.9.14, 1.9.17p0].
* Vulnerability is independent of kernel — pure version gate.
* Test fingerprints below the range, in the range, and above. */
struct skeletonkey_host h_sudo_chwoot_vuln = h_kernel_6_12;
strcpy(h_sudo_chwoot_vuln.sudo_version, "1.9.16");
run_one("sudo_chwoot: sudo 1.9.16 (in range) → VULNERABLE",
&sudo_chwoot_module, &h_sudo_chwoot_vuln,
SKELETONKEY_VULNERABLE);
struct skeletonkey_host h_sudo_chwoot_fixed = h_kernel_6_12;
strcpy(h_sudo_chwoot_fixed.sudo_version, "1.9.17p1");
run_one("sudo_chwoot: sudo 1.9.17p1 (fixed) → OK",
&sudo_chwoot_module, &h_sudo_chwoot_fixed,
SKELETONKEY_OK);
struct skeletonkey_host h_sudo_chwoot_old = h_kernel_6_12;
strcpy(h_sudo_chwoot_old.sudo_version, "1.9.13p1");
run_one("sudo_chwoot: sudo 1.9.13p1 (pre-chroot feature) → OK",
&sudo_chwoot_module, &h_sudo_chwoot_old,
SKELETONKEY_OK);
/* udisks_libblockdev: detect gates on udisksd binary + dbus
* socket presence + active polkit session. On CI / test containers
* udisksd is rarely installed → PRECOND_FAIL. */
run_one("udisks_libblockdev: udisksd absent in CI → PRECOND_FAIL",
&udisks_libblockdev_module, &h_kernel_6_12,
SKELETONKEY_PRECOND_FAIL);
/* pintheft: AF_RDS socket() in CI/container is almost never
* reachable (RDS module blacklisted on every common distro except
* Arch) → detect returns OK ("bug exists in kernel but unreachable
* from userland here"). */
run_one("pintheft: AF_RDS unreachable on CI runner → OK",
&pintheft_module, &h_kernel_6_12,
SKELETONKEY_OK);
/* ── v0.9.0 modules ────────────────────────────────────────── */
/* mutagen_astronomy: kernel 6.12 is above the 4.18.8 fix → OK */
run_one("mutagen_astronomy: kernel 6.12 above 4.18.8 fix → OK",
&mutagen_astronomy_module, &h_kernel_6_12,
SKELETONKEY_OK);
/* sudo_runas_neg1: fixed sudo (1.9.13p1) → OK */
run_one("sudo_runas_neg1: sudo 1.9.13p1 above 1.8.28 fix → OK",
&sudo_runas_neg1_module, &h_fixed_sudo,
SKELETONKEY_OK);
/* sudo_runas_neg1: vuln sudo 1.8.31 (in range), but no (ALL,!root)
* grant for this test user → PRECOND_FAIL. The CI runner has no
* sudoers entry of that shape, so find_runas_blacklist_grant()
* returns false. */
run_one("sudo_runas_neg1: vuln sudo, no (ALL,!root) grant → PRECOND_FAIL",
&sudo_runas_neg1_module, &h_vuln_sudo,
SKELETONKEY_PRECOND_FAIL);
/* tioscpgrp: kernel 6.12 above the 5.10 mainline fix → OK */
run_one("tioscpgrp: kernel 6.12 above 5.10 fix → OK",
&tioscpgrp_module, &h_kernel_6_12,
SKELETONKEY_OK);
/* vsock_uaf: kernel 6.12 above 6.11 mainline fix → OK */
run_one("vsock_uaf: kernel 6.12 above 6.11 fix → OK",
&vsock_uaf_module, &h_kernel_6_12,
SKELETONKEY_OK);
/* nft_pipapo: kernel 6.12 above 6.8 mainline fix → OK */
run_one("nft_pipapo: kernel 6.12 above 6.8 fix → OK",
&nft_pipapo_module, &h_kernel_6_12,
SKELETONKEY_OK);
/* nft_pipapo: kernel 5.4 predates the pipapo set type (5.6+) → OK */
run_one("nft_pipapo: kernel 4.4 predates pipapo (5.6+) → OK",
&nft_pipapo_module, &h_kernel_4_4,
SKELETONKEY_OK);
/* ── coverage report ─────────────────────────────────────────
* Iterate the runtime registry (populated by skeletonkey_register_*
* calls in main()) and warn for any module that was not touched