Skip to content

Commit 6b9771b

Browse files
committed
tests: guard the KERNEL_TEXT-vs-KERNEL_IMAGE base contract
A POS_BASE in REGION_KERNEL_TEXT means _stext; the engine subtracts STEXT_OFFSET from it to recover the image base. Reporting the image base (_text) as KERNEL_TEXT lands it a head gap below _text on arm64/loongarch64 — the mistake that hit perf_event_open / prefetch and the riscv "kernel :" line. Add tests/check-text-region (run by make lint): it fails if a component emits a KERNEL_TEXT base outside a reviewed allowlist of genuine-_stext emitters, so a new mistag must be confirmed as _stext or switched to KERNEL_IMAGE. Document the contract on the region table in api.h.
1 parent 9d804dc commit 6b9771b

3 files changed

Lines changed: 78 additions & 0 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ lint :
394394
@$(TEST_DIR)/check-component-output
395395
@$(TEST_DIR)/check-component-meta
396396
@$(TEST_DIR)/check-text-floor
397+
@$(TEST_DIR)/check-text-region
397398
@$(TEST_DIR)/check-fdt-unflatten
398399
@$(TEST_DIR)/check-shellcheck
399400

src/include/kasld/api.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,12 @@ enum kasld_confidence {
721721
/* ---- Kernel image (legitimately exists in both phys and virt) ------- */ \
722722
/* K_OPEN keeps PHYS leaks visible alongside VIRT — per-type narrowing */ \
723723
/* lives in the parser / inference layer, not the region table. */ \
724+
/* BASE semantics (POS_BASE): KERNEL_TEXT base == _stext (.text start); */ \
725+
/* text_pin_from_observation subtracts STEXT_OFFSET (the head gap) to */ \
726+
/* recover the image base. KERNEL_IMAGE base == _text (the image base) */ \
727+
/* itself, used directly. Report the IMAGE BASE as KERNEL_IMAGE, never */ \
728+
/* KERNEL_TEXT — mis-tagging it KERNEL_TEXT lands the base a head gap */ \
729+
/* below _text on arm64/loongarch64 (checked by tests/check-text-region).*/ \
724730
X(REGION_KERNEL_TEXT, "kernel_text", "text", K_OPEN) \
725731
X(REGION_KERNEL_DATA, "kernel_data", "data", K_OPEN) \
726732
X(REGION_KERNEL_BSS, "kernel_bss", "bss", K_OPEN) \

tests/check-text-region

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/bin/sh
2+
# This file is part of KASLD - https://github.com/bcoles/kasld
3+
#
4+
# check-text-region — guard the KERNEL_TEXT-vs-KERNEL_IMAGE base contract.
5+
#
6+
# A POS_BASE observation in REGION_KERNEL_TEXT means _stext (the .text start):
7+
# text_pin_from_observation subtracts STEXT_OFFSET (the head gap) from it to
8+
# recover the image base. A component that reports the IMAGE base (_text) must
9+
# therefore use REGION_KERNEL_IMAGE — tagging it KERNEL_TEXT makes the engine
10+
# subtract the head gap and land below _text on arches where _stext != _text
11+
# (arm64 +0x10000, loongarch64 +0x20000), excluding the truth. This exact
12+
# mistake hit perf_event_open / prefetch and a riscv dmesg "kernel :" entry.
13+
#
14+
# Fails if a component emits a KERNEL_TEXT *base* (kasld_result_base /
15+
# kasld_result_sized, or an LK_BASE table entry) outside the reviewed allowlist
16+
# of components whose KERNEL_TEXT base genuinely is _stext. A new such emitter
17+
# forces the author to confirm the value is _stext (allowlist it) or switch to
18+
# REGION_KERNEL_IMAGE. Interior samples (kasld_result_sample) are unaffected —
19+
# they are not bases, so text_pin ignores them.
20+
#
21+
# Usage: tests/check-text-region (also run by `make test`)
22+
# ---
23+
# <bcoles@gmail.com>
24+
25+
set -u
26+
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
27+
COMP=$ROOT/src/components
28+
29+
if [ -t 2 ]; then
30+
RED=$(printf '\033[31m'); GREEN=$(printf '\033[32m'); RESET=$(printf '\033[0m')
31+
else
32+
RED=; GREEN=; RESET=
33+
fi
34+
35+
# Components whose REGION_KERNEL_TEXT base is genuinely _stext (reviewed):
36+
# proc_kallsyms — emits _stext (and _text as KERNEL_IMAGE)
37+
# dmesg_mem_init_kernel_layout — the ".text : 0x" line is _stext
38+
ALLOW="proc_kallsyms dmesg_mem_init_kernel_layout"
39+
40+
# Literal base emission tagged KERNEL_TEXT (drop // and block-comment lines so a
41+
# comment naming the region does not trip the guard).
42+
lit=$(grep -rnE 'kasld_result_(base|sized)\(.*REGION_KERNEL_TEXT' "$COMP" 2>/dev/null \
43+
| grep -vE ':[0-9]+:[[:space:]]*(//|\*)' \
44+
| sed 's/:.*//')
45+
46+
# Table-driven base: a file with an LK_BASE entry table that also references
47+
# REGION_KERNEL_TEXT (the dmesg_mem_init_kernel_layout style).
48+
tab=$(grep -rl 'LK_BASE' "$COMP" 2>/dev/null | while read -r f; do
49+
grep -q 'REGION_KERNEL_TEXT' "$f" && printf '%s\n' "$f"
50+
done)
51+
52+
bad=$(printf '%s\n%s\n' "$lit" "$tab" | sed '/^$/d' | sort -u | while read -r f; do
53+
name=$(basename "$f" .c)
54+
case " $ALLOW " in
55+
*" $name "*) ;; # reviewed _stext emitter
56+
*) printf '%s\n' "$f" ;; # unreviewed KERNEL_TEXT base
57+
esac
58+
done)
59+
60+
if [ -n "$bad" ]; then
61+
printf '%scheck-text-region: FAIL%s — component(s) emit a REGION_KERNEL_TEXT\n' "$RED" "$RESET" >&2
62+
echo "base. A KERNEL_TEXT base is read as _stext and shifted down by STEXT_OFFSET" >&2
63+
echo "(the head gap) to recover the image base. If the value is the IMAGE base" >&2
64+
echo "(_text), use REGION_KERNEL_IMAGE instead; if it genuinely is _stext, add the" >&2
65+
echo "component to ALLOW in tests/check-text-region with a note:" >&2
66+
printf '%s\n' "$bad" | sed 's/^/ /' >&2
67+
exit 1
68+
fi
69+
70+
printf '%scheck-text-region: OK%s (KERNEL_TEXT bases are reviewed _stext emitters)\n' \
71+
"$GREEN" "$RESET"

0 commit comments

Comments
 (0)