Commit Graph

6 Commits

Author SHA1 Message Date
leviathan 2b1e96336e core/host: in_range helper + 13-module migration + 12 more tests (29 total)
Three coordinated changes that build on the host_kernel_at_least
landed in 1571b88:

1. core/host gains skeletonkey_host_kernel_in_range(h, lo..., hi...)
   — a [lo, hi) bounded-interval check for modules that want the
   'vulnerable window' semantics directly. Implemented in terms of
   host_kernel_at_least (so the comparison logic stays in one place).
   No module uses it yet; available for new modules that want it.

2. 13 modules migrated off the manual
        if (v->major < X || (v->major == X && v->minor < Y)) { ... }
   pattern onto
        if (!skeletonkey_host_kernel_at_least(ctx->host, X, Y, 0)) { ... }
   One-line replacements, mechanical, no behavior change.

   Migrated: af_packet2, dirty_pipe, fuse_legacy, netfilter_xtcompat,
   nf_tables, nft_fwd_dup, nft_payload, nft_set_uaf, overlayfs,
   overlayfs_setuid, ptrace_traceme, stackrot, vmwgfx. The repo now
   has zero manual 'v->major < X' patterns — every predates-check
   reads the same way.

3. tests/test_detect.c expanded from 17 to 29 cases. Adds:

   Above-fix coverage on h_kernel_6_12 (10 modules previously
   untested): af_packet, af_packet2, af_unix_gc, netfilter_xtcompat,
   nft_set_uaf, nft_fwd_dup, nft_payload, stackrot, sequoia, vmwgfx.

   Ancient-kernel predates coverage on h_kernel_4_4 (2 more cases):
   nft_set_uaf (introduced 5.1), stackrot (introduced 6.1).

   Detect-path test coverage now spans most of the corpus that
   has a testable host-fingerprint gate. Untested modules from
   here on are either userspace bugs whose detect() doesn't gate
   on host fields (pwnkit, sudo_samedit, sudoedit_editor),
   entrybleed (sysfs-direct, no host gate), or the copy_fail_family
   bridge (no ctx->host integration yet).

Verification: Linux (docker gcc:latest, non-root user): 29/29 pass.
macOS (local): 31-module build clean, suite reports 'skipped —
Linux-only' as designed.
2026-05-22 23:58:38 -04:00
leviathan 36814f272d modules: migrate remaining 22 modules to ctx->host fingerprint
Completes the host-fingerprint refactor that started in c00c3b4. Every
module now consults the shared ctx->host (populated once at startup
by core/host.c) instead of re-doing uname / geteuid / /etc/os-release
parsing / fork+unshare(CLONE_NEWUSER) probes per detect().

Migrations applied per module (mechanical, no exploit logic touched):

1. #include "../../core/host.h" inside each module's #ifdef __linux__.
2. kernel_version_current(&v) -> ctx->host->kernel (with the
   v -> v-> arrow-vs-dot fix for all later usage). Drops ~20 redundant
   uname() calls across the corpus.
3. geteuid() == 0 (the 'already root, nothing to escalate' gate) ->
   bool is_root = ctx->host ? ctx->host->is_root : (geteuid() == 0);
   This is the key change that lets the unit test suite construct
   non-root fingerprints regardless of the test process's actual euid.
4. Per-detect fork+unshare(CLONE_NEWUSER) probe helpers (named
   can_unshare_userns / can_unshare_userns_mount across the corpus)
   are removed wholesale; their call sites now consult
   ctx->host->unprivileged_userns_allowed, which was probed once at
   startup. Removes ~10 per-scan fork()s.

Modules touched by this commit (22):

  Batch A (7): dirty_pipe, dirty_cow, ptrace_traceme, pwnkit,
               cgroup_release_agent, overlayfs_setuid, and entrybleed
               (no migration target — KPTI gate stays as direct sysfs
               read; documented as 'no applicable pattern').

  Batch B (7): nf_tables, cls_route4, netfilter_xtcompat, af_packet,
               af_packet2, af_unix_gc, fuse_legacy.

  Batch C (8): stackrot, nft_set_uaf, nft_fwd_dup, nft_payload,
               sudo_samedit, sequoia, sudoedit_editor, vmwgfx.

Combined with the 4 modules already migrated (dirtydecrypt, fragnesia,
pack2theroot, overlayfs) and the 5-module copy_fail_family bridge,
the entire registered corpus now goes through ctx->host. The 4
'fork+unshare per detect()' helpers that existed across nf_tables,
cls_route4, netfilter_xtcompat, af_packet, af_packet2, fuse_legacy,
nft_set_uaf, nft_fwd_dup, nft_payload, sequoia,
cgroup_release_agent, and overlayfs_setuid are now gone — replaced by
the single startup probe in core/host.c.

Verification:
- Linux (docker gcc:latest + libglib2.0-dev): full clean build links
  31 modules; tests/test_detect.c: 8/8 pass.
- macOS (local): full clean build links 31 modules (Mach-O, 172KB);
  test suite reports skipped as designed on non-Linux.

Subsequent commits can add more EXPECT_DETECT cases in
tests/test_detect.c — the host-fingerprint paths in every module are
now uniformly testable via synthetic struct skeletonkey_host instances.
2026-05-22 23:43:20 -04:00
leviathan 9593d90385 rename: IAMROOT → SKELETONKEY across the entire project
release / build (arm64) (push) Waiting to run
release / build (x86_64) (push) Waiting to run
release / release (push) Blocked by required conditions
Breaking change. Tool name, binary name, function/type names,
constant names, env vars, header guards, file paths, and GitHub
repo URL all rebrand IAMROOT → SKELETONKEY.

Changes:
  - All "IAMROOT" → "SKELETONKEY" (constants, env vars, enum
    values, docs, comments)
  - All "iamroot" → "skeletonkey" (functions, types, paths, CLI)
  - iamroot.c → skeletonkey.c
  - modules/*/iamroot_modules.{c,h} → modules/*/skeletonkey_modules.{c,h}
  - tools/iamroot-fleet-scan.sh → tools/skeletonkey-fleet-scan.sh
  - Binary "iamroot" → "skeletonkey"
  - GitHub URL KaraZajac/IAMROOT → KaraZajac/SKELETONKEY
  - .gitignore now expects build output named "skeletonkey"
  - /tmp/iamroot-* tmpfiles → /tmp/skeletonkey-*
  - Env vars IAMROOT_MODPROBE_PATH etc. → SKELETONKEY_*

New ASCII skeleton-key banner (horizontal key icon + ANSI Shadow
SKELETONKEY block letters) replaces the IAMROOT banner in
skeletonkey.c and README.md.

VERSION: 0.3.1 → 0.4.0 (breaking).

Build clean on Debian 6.12.86. `skeletonkey --version` → 0.4.0.
All 24 modules still register; no functional code changes — pure
rename + banner refresh.
2026-05-16 22:43:49 -04:00
leviathan 9d88b475c1 v0.3.1: --dump-offsets tool + NOTICE.md per module
release / build (arm64) (push) Waiting to run
release / build (x86_64) (push) Waiting to run
release / release (push) Blocked by required conditions
The README has been claiming "each module credits the original CVE
reporter and PoC author in its NOTICE.md" since v0.1.0, but only
copy_fail_family actually shipped one. Fixed.

  modules/<name>/NOTICE.md (×19 new + 1 existing): per-module
    research credit covering CVE ID, discoverer, original advisory
    URL where public, upstream fix commit, IAMROOT's role.

  iamroot.c: new --dump-offsets subcommand. Resolves kernel offsets
    via the existing core/offsets.c four-source chain (env →
    /proc/kallsyms → /boot/System.map → embedded table), then emits
    a ready-to-paste C struct entry for kernel_table[]. Run once
    as root on a target kernel build; upstream via PR. Eliminates
    fabricating offsets — every shipped entry traces back to a
    `iamroot --dump-offsets` invocation on a real kernel.

  docs/OFFSETS.md: documents the --dump-offsets workflow.
  CVES.md: notes the NOTICE.md convention + offset dump tool.

  iamroot.c: bump IAMROOT_VERSION 0.3.0 → 0.3.1.
2026-05-16 22:33:43 -04:00
leviathan 5a808e3583 modules: 4 new CVE modules — nft_set_uaf + af_unix_gc + nft_fwd_dup + nft_payload
Each module: detect with branch-backport ranges + userns reach +
hand-rolled trigger + msg_msg cross-cache groom + slabinfo witness
+ /tmp/iamroot-<name>.log breadcrumb + auditd rules + --full-chain
finisher (FALLBACK depth, sentinel-arbitrated).

  nft_set_uaf (CVE-2023-32233, +1033): anonymous-set UAF
                (Sondej+Krysiuk). 5.1 → 6.4. nfnetlink batch:
                NEWTABLE → NEWCHAIN → NEWSET(ANON|EVAL) →
                NEWRULE(lookup) → DELSET → DELRULE; cg-512 spray.

  af_unix_gc (CVE-2023-4622, +813): GC race UAF (Lin Ma). ~2.0 → 6.5
                — widest range of any module. Two-thread race driver
                (SCM_RIGHTS cycle vs unix_gc trigger) + kmalloc-512
                spray. No userns needed.

  nft_fwd_dup (CVE-2022-25636, +1024): nft_fwd_dup_netdev_offload
                heap OOB (Aaron Adams). 5.4 → 5.17. NFT_CHAIN_HW_OFFLOAD
                chain + 16 immediates + fwd to overrun action.entries[].

  nft_payload (CVE-2023-0179, +1136): set-id memory corruption
                (Davide Ornaghi). 5.4 → 6.2. NFTA_SET_DESC variable
                element + NFTA_SET_ELEM_EXPRESSIONS with payload-set
                whose verdict.code drives the regs->data[] OOB.

All 4 honor verified-vs-claimed: trigger fires, primitive grooms, no
fabricated offsets. EXPLOIT_OK only via empirical setuid-bash sentinel.

Build clean on Debian 6.12.86; all 4 refuse cleanly on both default
and --full-chain paths via the existing patched-kernel detect gate.
2026-05-16 22:24:15 -04:00
leviathan 6a0a7d8718 scaffold: 4 new module dirs + registry/Makefile wiring (stubs)
Pre-scaffolding for the next batch (CVE-2023-32233, CVE-2023-4622,
CVE-2022-25636, CVE-2023-0179). Each module ships as a 21-line
stub returning PRECOND_FAIL; parallel agents fill in the real
detect/exploit/--full-chain implementations.

This commit keeps registry.h / iamroot.c / Makefile in one place
so the 4 parallel agents don't collide on shared-file edits — they
each own a single iamroot_modules.c.

Build clean on Debian 6.12.86; --list shows all 24 modules
including the 4 new stubs.
2026-05-16 22:17:47 -04:00