|
| 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