all modules: wrap Linux-only code in #ifdef __linux__ — full macOS build works

Every kernel-LPE module that uses Linux-only headers (splice, posix_fadvise,
linux/netlink.h, sys/ptrace.h, etc.) now follows the same #ifdef __linux__
pattern the new modules already used: Linux body in the ifdef, stub
detect/exploit/cleanup returning SKELETONKEY_PRECOND_FAIL on non-Linux,
platform-neutral rule strings + module struct + register fn left outside.

14 modules wrapped:
  dirty_pipe (already done above), af_packet, af_packet2,
  cgroup_release_agent, cls_route4, dirty_cow, fuse_legacy,
  netfilter_xtcompat, nf_tables, nft_fwd_dup, nft_payload,
  overlayfs, overlayfs_setuid, ptrace_traceme.

Several modules previously had ad-hoc partial stubs (af_packet2 faked
SIOCSIFFLAGS/MAP_LOCKED, netfilter_xtcompat faked sysv-msg syscalls,
the nft_* modules had 3 partial __linux__ islands each, fuse_legacy /
nf_tables had inner-only ifdef blocks) — all replaced with the uniform
outer-wrap shape from dirty_pipe / dirtydecrypt / fragnesia / pack2theroot.

Where a module includes core/kernel_range.h, core/finisher.h, or
core/offsets.h, those are now inside the ifdef block as well — silences
clangd's "unused-includes" LSP warning on macOS while keeping them
present for the real Linux build.

No exploit logic, constant, struct, shellcode byte, or rule string was
modified — only include placement and ifdef markers.

Build verification:
  macOS (local): make clean && make → Mach-O x86_64, 31 modules
                 registered, --scan reports each Linux-only module as
                 "Linux-only module — not applicable here".
  Linux (docker gcc:latest + libglib2.0-dev): make clean && make →
                 ELF 64-bit, 31 modules. Exploit code paths unchanged.
This commit is contained in:
2026-05-22 22:58:16 -04:00
parent 9a4cc91619
commit cdb8f5e8f9
14 changed files with 448 additions and 202 deletions
@@ -43,16 +43,20 @@
#include "skeletonkey_modules.h"
#include "../../core/registry.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#ifdef __linux__
#include "../../core/kernel_range.h"
#include "../../core/offsets.h"
#include "../../core/finisher.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <sched.h>
#include <fcntl.h>
#include <errno.h>
@@ -585,7 +589,6 @@ static int bring_lo_up(void)
return 0;
}
#ifdef __linux__
static size_t build_trigger_batch(uint8_t *batch, uint32_t *seq)
{
size_t off = 0;
@@ -596,7 +599,6 @@ static size_t build_trigger_batch(uint8_t *batch, uint32_t *seq)
put_batch_end(batch, &off, (*seq)++);
return off;
}
#endif
/* ------------------------------------------------------------------
* --full-chain arb-write context. The technique:
@@ -617,8 +619,6 @@ static size_t build_trigger_batch(uint8_t *batch, uint32_t *seq)
* mismatches as SKELETONKEY_EXPLOIT_FAIL rather than fake success.
* ------------------------------------------------------------------ */
#ifdef __linux__
#define SPRAY_QUEUES_ARB 32
struct fwd_arb_ctx {
@@ -721,8 +721,6 @@ static int nft_fwd_dup_arb_write(uintptr_t kaddr,
return 0;
}
#endif /* __linux__ */
/* ------------------------------------------------------------------
* Exploit driver.
* ------------------------------------------------------------------ */
@@ -748,11 +746,6 @@ static skeletonkey_result_t nft_fwd_dup_exploit(const struct skeletonkey_ctx *ct
return pre;
}
#ifndef __linux__
fprintf(stderr, "[-] nft_fwd_dup: linux-only exploit; non-linux build\n");
(void)ctx;
return SKELETONKEY_PRECOND_FAIL;
#else
if (!ctx->json) {
if (ctx->full_chain) {
fprintf(stderr, "[*] nft_fwd_dup: --full-chain — trigger + OOB-write "
@@ -946,7 +939,6 @@ static skeletonkey_result_t nft_fwd_dup_exploit(const struct skeletonkey_ctx *ct
fprintf(stderr, "[-] nft_fwd_dup: unexpected child rc=%d\n", rc);
}
return SKELETONKEY_EXPLOIT_FAIL;
#endif /* __linux__ */
}
/* ------------------------------------------------------------------
@@ -958,7 +950,6 @@ static skeletonkey_result_t nft_fwd_dup_cleanup(const struct skeletonkey_ctx *ct
if (!ctx->json) {
fprintf(stderr, "[*] nft_fwd_dup: cleaning up sysv queues + log\n");
}
#ifdef __linux__
/* Best-effort drain of any leftover msg queues with IPC_PRIVATE
* key owned by us. SysV doesn't enumerate by key, but msgctl
* IPC_STAT walks /proc/sysvipc/msg to find them. */
@@ -979,13 +970,38 @@ static skeletonkey_result_t nft_fwd_dup_cleanup(const struct skeletonkey_ctx *ct
}
fclose(f);
}
#endif
if (unlink("/tmp/skeletonkey-nft_fwd_dup.log") < 0 && errno != ENOENT) {
/* harmless */
}
return SKELETONKEY_OK;
}
#else /* !__linux__ */
/* Non-Linux dev builds: nf_tables / NETLINK_NETFILTER / SysV msg_msg
* groom — all Linux-only kernel surface. Stub out so the module still
* registers and the top-level `make` completes on macOS/BSD dev boxes. */
static skeletonkey_result_t nft_fwd_dup_detect(const struct skeletonkey_ctx *ctx)
{
if (!ctx->json)
fprintf(stderr, "[i] nft_fwd_dup: Linux-only module "
"(nf_tables HW-offload OOB) — not applicable here\n");
return SKELETONKEY_PRECOND_FAIL;
}
static skeletonkey_result_t nft_fwd_dup_exploit(const struct skeletonkey_ctx *ctx)
{
(void)ctx;
fprintf(stderr, "[-] nft_fwd_dup: Linux-only module — cannot run here\n");
return SKELETONKEY_PRECOND_FAIL;
}
static skeletonkey_result_t nft_fwd_dup_cleanup(const struct skeletonkey_ctx *ctx)
{
(void)ctx;
return SKELETONKEY_OK;
}
#endif /* __linux__ */
/* ------------------------------------------------------------------
* Embedded detection rules.
* ------------------------------------------------------------------ */