test harness: kernel_range unit tests + coverage report + register_all helper
Three coupled improvements to the test harness:
1. New tests/test_kernel_range.c — 32 pure unit tests covering
kernel_range_is_patched(), skeletonkey_host_kernel_at_least(),
and skeletonkey_host_kernel_in_range(). These are the central
comparison primitives every module routes through; a regression
in any of them silently mis-classifies entire CVE families. Tests
cover exact boundary, one-below, mainline-only, multi-LTS,
between-branch, and NULL-safety cases. Builds and runs
cross-platform (no Linux syscalls).
2. tests/test_detect.c additions:
- mk_host(base, major, minor, patch, release) builder so new
fingerprint-based tests don't duplicate 14-line struct literals
to override one (major, minor, patch) triple.
- Post-run coverage report that iterates the runtime registry and
warns about modules without at least one direct test row. Output
is informational (no CI fail) so coverage grows incrementally.
- 7 new boundary tests for the kernel_patched_from entries added
by tools/refresh-kernel-ranges.py (commit 8de46e2):
- af_unix_gc 6.4.12 → VULNERABLE / 6.4.13 → OK
- vmwgfx 5.10.127 → OK
- nft_set_uaf 5.10.179 → OK / 6.1.27 → OK
- nft_payload 5.10.162 → OK
- nf_tables 5.10.209 → OK
3. core/registry_all.c — extracts the 27-line 'call every
skeletonkey_register_<family>()' enumeration from skeletonkey.c
into a shared helper. skeletonkey.c main() now calls
skeletonkey_register_all_modules() once; the detect-test main()
does the same. Kept in its own translation unit so registry.c
stays standalone for the lean kernel_range unit-test binary
(which links core/ only, no modules).
Makefile: builds two test binaries now —
skeletonkey-test — detect() integration tests (full corpus)
skeletonkey-test-kr — kernel_range unit tests (core/ only)
'make test' runs both.
Verification:
- macOS: 32/32 kernel_range tests pass; detect tests skipped
(non-Linux platform, stubbed bodies).
- Linux (docker gcc:latest): 32/32 kernel_range + 51/51 detect.
Coverage report identifies 2 modules without direct tests
(copy_fail, entrybleed) out of 31 registered.
Test counts: 44 -> 83 (+39).
This commit is contained in:
@@ -23,6 +23,11 @@ BIN := skeletonkey
|
||||
CORE_SRCS := core/registry.c core/kernel_range.c core/offsets.c core/finisher.c core/host.c
|
||||
CORE_OBJS := $(patsubst %.c,$(BUILD)/%.o,$(CORE_SRCS))
|
||||
|
||||
# Register-every-module helper. Lives in its own translation unit so
|
||||
# the kernel_range unit-test binary can link just CORE_OBJS without
|
||||
# pulling in every module symbol via registry_all.o.
|
||||
REGISTRY_ALL_OBJ := $(BUILD)/core/registry_all.o
|
||||
|
||||
# Family: copy_fail_family
|
||||
# All DIRTYFAIL .c files contribute; skeletonkey_modules.c is the bridge.
|
||||
CFF_DIR := modules/copy_fail_family
|
||||
@@ -186,16 +191,26 @@ MODULE_OBJS := $(CFF_OBJS) $(DP_OBJS) $(EB_OBJS) $(PK_OBJS) $(NFT_OBJS) \
|
||||
$(SAM_OBJS) $(SEQ_OBJS) $(SUE_OBJS) $(VMW_OBJS) \
|
||||
$(DDC_OBJS) $(FGN_OBJS) $(P2TR_OBJS)
|
||||
|
||||
ALL_OBJS := $(TOP_OBJ) $(CORE_OBJS) $(MODULE_OBJS)
|
||||
ALL_OBJS := $(TOP_OBJ) $(CORE_OBJS) $(REGISTRY_ALL_OBJ) $(MODULE_OBJS)
|
||||
|
||||
# Tests — `make test` builds and runs the detect() unit-test harness.
|
||||
# Links against the same module objects as the main binary minus the
|
||||
# top-level dispatcher (which provides main(); the test has its own).
|
||||
# Tests — `make test` builds and runs both unit-test binaries.
|
||||
#
|
||||
# skeletonkey-test — detect() integration tests against
|
||||
# synthetic host fingerprints. Links
|
||||
# the full module corpus.
|
||||
# skeletonkey-test-kr — pure unit tests for kernel_range +
|
||||
# host comparison helpers. Tiny binary
|
||||
# (core/ only); runs cross-platform.
|
||||
TEST_DIR := tests
|
||||
TEST_SRCS := $(TEST_DIR)/test_detect.c
|
||||
TEST_OBJS := $(patsubst %.c,$(BUILD)/%.o,$(TEST_SRCS))
|
||||
TEST_BIN := skeletonkey-test
|
||||
TEST_ALL_OBJS := $(TEST_OBJS) $(CORE_OBJS) $(MODULE_OBJS)
|
||||
TEST_ALL_OBJS := $(TEST_OBJS) $(CORE_OBJS) $(REGISTRY_ALL_OBJ) $(MODULE_OBJS)
|
||||
|
||||
TEST_KR_SRCS := $(TEST_DIR)/test_kernel_range.c
|
||||
TEST_KR_OBJS := $(patsubst %.c,$(BUILD)/%.o,$(TEST_KR_SRCS))
|
||||
TEST_KR_BIN := skeletonkey-test-kr
|
||||
TEST_KR_ALL_OBJS := $(TEST_KR_OBJS) $(CORE_OBJS)
|
||||
|
||||
.PHONY: all clean debug static help test
|
||||
|
||||
@@ -207,8 +222,14 @@ $(BIN): $(ALL_OBJS)
|
||||
$(TEST_BIN): $(TEST_ALL_OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -lpthread $(P2TR_LIBS)
|
||||
|
||||
test: $(TEST_BIN)
|
||||
@echo "[*] running test suite ($(TEST_BIN))"
|
||||
$(TEST_KR_BIN): $(TEST_KR_ALL_OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
test: $(TEST_BIN) $(TEST_KR_BIN)
|
||||
@echo "[*] running kernel_range unit tests ($(TEST_KR_BIN))"
|
||||
./$(TEST_KR_BIN)
|
||||
@echo
|
||||
@echo "[*] running detect() integration tests ($(TEST_BIN))"
|
||||
./$(TEST_BIN)
|
||||
|
||||
# Generic compile: any .c → corresponding .o under build/
|
||||
@@ -223,7 +244,7 @@ static: LDFLAGS += -static
|
||||
static: clean $(BIN)
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD) $(BIN) $(TEST_BIN)
|
||||
rm -rf $(BUILD) $(BIN) $(TEST_BIN) $(TEST_KR_BIN)
|
||||
|
||||
help:
|
||||
@echo "Targets:"
|
||||
|
||||
Reference in New Issue
Block a user