Skip to content

Commit d177fee

Browse files
committed
regions: rename REGION_MODULE_REGION to REGION_MODULE_BAND
The pair read backwards: "module_region" says region twice and looks like the more specific of the two, when it is the weaker one — the band itself, or an address merely assumed to be a module because it fell inside it. The codebase already calls that concept a band everywhere in prose, and the MODULES_BAND_EXACT arch axis uses the same word, so the enum was the odd one out. The wire name follows: module_region -> module_band. kasld_addr_is_module_region() becomes kasld_addr_is_module_band(), and its comment gains the distinction it was missing: a source that already knows it read a module's address uses the predicate as a sanity filter and still emits REGION_MODULE, while a source holding a bare pointer uses it to classify and must emit REGION_MODULE_BAND. Two comments were stale rather than merely misnamed. The region note said module_text_bound "reads both" and that its arches have a narrow text-relative band; neither is true — it reads REGION_MODULE only, and the band contains the whole kernel-text range on both riscv64 and s390. And the wire-token parse was documented against "longest module_region = 13" when virt_page_offset and efi_loader_image are 16.
1 parent d313dab commit d177fee

21 files changed

Lines changed: 87 additions & 77 deletions

src/components/dmesg_backtrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static int in_directmap_range(unsigned long val) {
105105
if (val >= KERNEL_VIRT_TEXT_MIN)
106106
return 0;
107107
#if MODULES_START >= PAGE_OFFSET
108-
if (kasld_addr_is_module_region(val))
108+
if (kasld_addr_is_module_band(val))
109109
return 0;
110110
#endif
111111
return 1;

src/components/dmesg_mem_init_kernel_layout.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ static const struct layout_entry entries[] = {
184184
{"lowmem : 0x", KASLD_TYPE_VIRT, "kernel lowmem start", REGION_DIRECTMAP,
185185
KERNEL_VIRT_VAS_START, KERNEL_VIRT_VAS_END, LK_BASE},
186186
{"modules : 0x", KASLD_TYPE_VIRT, "kernel modules start",
187-
REGION_MODULE_REGION, MODULES_START, MODULES_END, LK_BASE},
187+
REGION_MODULE_BAND, MODULES_START, MODULES_END, LK_BASE},
188188
{"memory : 0x", KASLD_TYPE_VIRT, "kernel memory start", REGION_DIRECTMAP,
189189
KERNEL_VIRT_VAS_START, KERNEL_VIRT_VAS_END, LK_BASE},
190190
/* Range extractions (lo,hi). One needle per print-format dialect:
@@ -264,7 +264,7 @@ static void emit_base(int idx, unsigned long addr) {
264264
kasld_info("%s: %lx", entries[idx].display, addr);
265265

266266
#if KERNEL_VIRT_VAS_START /* vacuous where VAS_START is 0 (s390) */
267-
if ((region == REGION_DIRECTMAP || region == REGION_MODULE_REGION) &&
267+
if ((region == REGION_DIRECTMAP || region == REGION_MODULE_BAND) &&
268268
addr < (unsigned long)KERNEL_VIRT_VAS_START)
269269
kasld_err("warning: %s %lx below configured KERNEL_VIRT_VAS_START %lx",
270270
entries[idx].display, addr, (unsigned long)KERNEL_VIRT_VAS_START);

src/components/perf_ksymbol_leak.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
// perf_event_paranoid<=0 for unprivileged users (or CAP_PERFMON).
2424
//
2525
// The component subscribes, polls for a short window, and emits one
26-
// REGION_MODULE_REGION observation per ksymbol register record. The kernel
26+
// REGION_MODULE_BAND observation per ksymbol register record. The kernel
2727
// virtual addresses BPF JIT pages, kprobe OOL pages, and ftrace trampolines
2828
// occupy all live in the module region on every supported arch.
2929
// Notification-driven: yields nothing if no BPF / kprobe / ftrace registration
@@ -223,16 +223,16 @@ static int drain_ring(struct perf_event_mmap_page *meta, const char *ring,
223223
/* Only emit an address inside the module window. A KSYMBOL record is a
224224
* BPF-JIT / kprobe-OOL / ftrace-trampoline allocation, normally in the
225225
* module region; one outside it (a separate bpf/vmalloc region on some
226-
* configs) must be DROPPED, not tagged REGION_MODULE_REGION — that would
226+
* configs) must be DROPPED, not tagged REGION_MODULE_BAND — that would
227227
* feed module_text_bound a bogus text-base bound on
228228
* MODULES_RELATIVE_TO_TEXT arches (riscv64/s390). Mirrors the window
229229
* check perf_text_poke_leak already applies. */
230230
if (!(k->flags & KSYM_FLAG_UNREGISTER) && k->addr != 0 &&
231-
kasld_addr_is_module_region((unsigned long)k->addr)) {
231+
kasld_addr_is_module_band((unsigned long)k->addr)) {
232232
kasld_found("ksymbol: addr=0x%lx len=%u type=%u name=%s",
233233
(unsigned long)k->addr, k->len, k->ksym_type,
234234
name_copy[0] ? name_copy : "(anon)");
235-
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_REGION,
235+
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_BAND,
236236
(unsigned long)k->addr,
237237
name_copy[0] ? name_copy : NULL, CONF_PARSED);
238238
emitted++;

src/components/perf_text_poke_leak.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
// each leaked address is emitted only under the region it actually falls in: a
4444
// core-.text address as a KERNEL_TEXT interior sample (bounds the image base
4545
// from above), a module-region address (ftrace trampoline / kprobe page) as
46-
// REGION_MODULE_REGION; anything outside both windows is skipped.
46+
// REGION_MODULE_BAND; anything outside both windows is skipped.
4747
//
4848
// Requires:
4949
// - kernel.perf_event_paranoid <= 0 (or CAP_PERFMON / CAP_SYS_ADMIN)
@@ -255,7 +255,7 @@ static void drain_ring(struct perf_event_mmap_page *meta, const char *ring,
255255
if (acc->text_n == 0 || addr > acc->text_hi)
256256
acc->text_hi = addr;
257257
acc->text_n++;
258-
} else if (addr != 0 && kasld_addr_is_module_region(addr)) {
258+
} else if (addr != 0 && kasld_addr_is_module_band(addr)) {
259259
if (acc->mod_n == 0 || addr < acc->mod_lo)
260260
acc->mod_lo = addr;
261261
if (acc->mod_n == 0 || addr > acc->mod_hi)
@@ -408,11 +408,11 @@ int main(int argc, char *argv[]) {
408408
if (acc.mod_n) {
409409
kasld_found("%d module-region poke(s); lowest 0x%lx highest 0x%lx",
410410
acc.mod_n, acc.mod_lo, acc.mod_hi);
411-
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_REGION, acc.mod_lo, NULL,
411+
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_BAND, acc.mod_lo, NULL,
412412
CONF_PARSED);
413413
if (acc.mod_hi != acc.mod_lo)
414-
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_REGION, acc.mod_hi,
415-
NULL, CONF_PARSED);
414+
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_BAND, acc.mod_hi, NULL,
415+
CONF_PARSED);
416416
}
417417
return 0;
418418
}

src/components/proc_modules.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static struct module_range get_addr_proc_modules(void) {
7979
if (!module_addr)
8080
continue;
8181

82-
if (kasld_addr_is_module_region(module_addr)) {
82+
if (kasld_addr_is_module_band(module_addr)) {
8383
if (!range.lo || module_addr < range.lo)
8484
range.lo = module_addr;
8585
if (module_addr > range.hi)
@@ -109,7 +109,7 @@ int main(void) {
109109
* The component aggregates them into a min/max range — both endpoints
110110
* are within the module region. (A future version could enumerate
111111
* each module by name with kasld_result().) */
112-
/* REGION_MODULE, not REGION_MODULE_REGION: each address is a loaded
112+
/* REGION_MODULE, not REGION_MODULE_BAND: each address is a loaded
113113
* module's own base, read from a per-module record — the region is known
114114
* structurally, not inferred from the address falling in a band. That is
115115
* what lets module_text_bracket consume it on arches whose band is a wide

src/components/sysfs_iscsi_transport_handle.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static enum handle_read read_transport_handle(const char *transport,
204204

205205
/* The struct iscsi_transport lives in MODULE memory when the driver is built as
206206
* a module (the usual case), or in the kernel image .data section when built
207-
* in. Classify by range so a module pointer is tagged REGION_MODULE_REGION, not
207+
* in. Classify by range so a module pointer is tagged REGION_MODULE_BAND, not
208208
* an image region: a KERNEL_DATA tag on a module pointer feeds
209209
* image_size_text_data_gap a bogus (>1 GiB) text..data gap, which pushes the
210210
* Q_VIRT_IMAGE_BASE ceiling below the true base and excludes it.
@@ -216,12 +216,12 @@ static enum handle_read read_transport_handle(const char *transport,
216216
* range, so a text-first order would tag real module pointers KERNEL_DATA and
217217
* reproduce exactly the ceiling bug described above. Range classification
218218
* cannot separate the two where the ranges overlap; what makes the ambiguity
219-
* harmless is that REGION_MODULE_REGION no longer reaches any rule that moves
219+
* harmless is that REGION_MODULE_BAND no longer reaches any rule that moves
220220
* a text base (module_text_bound and module_text_bracket both require
221221
* REGION_MODULE), so a mis-tag here is presentational. */
222222
static void emit_iscsi_transport(unsigned long addr, const char *name) {
223-
if (kasld_addr_is_module_region(addr))
224-
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_REGION, addr, name,
223+
if (kasld_addr_is_module_band(addr))
224+
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_BAND, addr, name,
225225
CONF_PARSED);
226226
else if (kasld_addr_is_kernel_text(addr))
227227
kasld_result_sample(KASLD_TYPE_VIRT, REGION_KERNEL_DATA, addr, name,

src/components/sysfs_module_sections.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static unsigned long read_module_text(char *path) {
8181

8282
addr = strtoul(buff, &endptr, 16);
8383

84-
if (addr && kasld_addr_is_module_region(addr))
84+
if (addr && kasld_addr_is_module_band(addr))
8585
return addr;
8686

8787
return 0;
@@ -138,7 +138,7 @@ int main(void) {
138138
return 0;
139139
}
140140

141-
/* REGION_MODULE, not REGION_MODULE_REGION: these are section addresses read
141+
/* REGION_MODULE, not REGION_MODULE_BAND: these are section addresses read
142142
* from a named module's own sysfs directory, so the region is known
143143
* structurally rather than inferred from the address falling in a band —
144144
* the provenance module_text_bracket requires (see api.h). */

src/components/tracefs_printk_formats.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ int main(int argc, char **argv) {
9999
if (!have_text || a > text_hi)
100100
text_hi = a;
101101
have_text = 1;
102-
} else if (kasld_addr_is_module_region(a)) {
102+
} else if (kasld_addr_is_module_band(a)) {
103103
if (!have_mod || a < mod_lo)
104104
mod_lo = a;
105105
if (!have_mod || a > mod_hi)
@@ -129,10 +129,10 @@ int main(int argc, char **argv) {
129129
}
130130
if (have_mod) {
131131
kasld_info("module format addresses: 0x%lx-0x%lx", mod_lo, mod_hi);
132-
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_REGION, mod_lo,
132+
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_BAND, mod_lo,
133133
"printk_fmt", CONF_PARSED);
134134
if (mod_hi != mod_lo)
135-
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_REGION, mod_hi,
135+
kasld_result_sample(KASLD_TYPE_VIRT, REGION_MODULE_BAND, mod_hi,
136136
"printk_fmt", CONF_PARSED);
137137
}
138138
return 0;

src/components/zfs_dbgmsg.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ static int emit_addr(unsigned long addr) {
9999
enum kasld_region region;
100100
if (kasld_addr_is_kernel_text(addr))
101101
region = REGION_KERNEL_TEXT;
102-
else if (kasld_addr_is_module_region(addr))
103-
region = REGION_MODULE_REGION;
102+
else if (kasld_addr_is_module_band(addr))
103+
region = REGION_MODULE_BAND;
104104
else if (kasld_addr_is_directmap(addr))
105105
region = REGION_DIRECTMAP;
106106
else if (kasld_addr_is_kernel_vas(addr))

src/include/kasld/api.h

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static inline int kasld_mul_ovf(unsigned long a, unsigned long b,
9393
* the relocatable range; a static band describes the region only when KASLR
9494
* is off. Widening far enough to do that can leave range-classification
9595
* vacuous on an arch -- that is the correct trade, and it is contained by
96-
* the REGION_MODULE / REGION_MODULE_REGION provenance split (see the region
96+
* the REGION_MODULE / REGION_MODULE_BAND provenance split (see the region
9797
* table), never by narrowing the union back.
9898
*
9999
* - MODULES_RELATIVE_TO_TEXT: 1 if the module region shifts with KASLR text.
@@ -652,15 +652,20 @@ static inline int kasld_addr_in_range(unsigned long long addr,
652652
return addr >= lo && addr <= hi;
653653
}
654654

655-
/* Predicate: is `va` plausibly inside the kernel module region on this arch?
655+
/* Predicate: is `va` plausibly inside the kernel module BAND on this arch?
656656
*
657657
* Wraps the MODULES_START/END validation union (see the CONTRACT in the
658-
* arch-header contract banner above).
659-
* Used by components that classify leaked addresses as module-region
660-
* (proc_modules, sysfs_module_sections, dmesg-parsers). Centralising the
661-
* check here means the per-arch widening / future per-version handling
662-
* lives in one place rather than four. */
663-
static inline int kasld_addr_is_module_region(unsigned long va) {
658+
* arch-header contract banner above). Centralising the check here means the
659+
* per-arch widening / future per-version handling lives in one place.
660+
*
661+
* Two different uses, and the difference decides the region tag. A source that
662+
* already KNOWS it read a module's address (proc_modules,
663+
* sysfs_module_sections) uses this only as a sanity filter and still emits
664+
* REGION_MODULE. A source holding a bare pointer uses it to CLASSIFY, and must
665+
* emit REGION_MODULE_BAND — membership in the band is not evidence that an
666+
* address is a module, since the band overlaps other regions on several arches
667+
* (see the region note by the region table). */
668+
static inline int kasld_addr_is_module_band(unsigned long va) {
664669
return kasld_addr_in_range(va, (unsigned long)MODULES_START,
665670
(unsigned long)MODULES_END);
666671
}
@@ -921,24 +926,29 @@ enum kasld_confidence {
921926
X(REGION_KERNEL_DATA, "kernel_data", "data", K_OPEN) \
922927
X(REGION_KERNEL_BSS, "kernel_bss", "bss", K_OPEN) \
923928
X(REGION_KERNEL_IMAGE, "kernel_image", "text", K_OPEN) \
924-
/* The two module regions differ by PROVENANCE, not by address range — */ \
925-
/* both are validated against the same [MODULES_START, MODULES_END] band.*/ \
926-
/* MODULE: the source structurally KNOWS the address belongs to a loaded */ \
927-
/* module (it read a module's own address — /proc/modules, a sysfs */ \
928-
/* per-module sections entry, a named symbol in a known module). */ \
929-
/* MODULE_REGION: the band itself, OR an address merely CLASSIFIED as */ \
930-
/* module because it fell inside the band (dmesg parsers, opportunistic */ \
931-
/* pointer leaks, perf JIT/trampoline records). */ \
932-
/* The distinction is load-bearing on MODULES_BRACKET_TEXT arches, where */ \
933-
/* the band is a wide multi-layout union that overlaps other regions: */ \
934-
/* on arm64 a VA_BITS=48 direct map starts at MODULES_START, so a */ \
935-
/* range-classified kmalloc pointer would otherwise bound the text base */ \
936-
/* ~128 TiB below the truth. module_text_bracket therefore reads MODULE */ \
937-
/* only; module_text_bound (whose arches have a narrow text-relative */ \
938-
/* band) reads both. Emit MODULE_REGION when in any doubt — it is the */ \
939-
/* weaker, always-safe tag. */ \
929+
/* The two module regions differ by PROVENANCE, not by address range — */ \
930+
/* both are validated against the same [MODULES_START, MODULES_END] band. */ \
931+
/* MODULE: the source structurally KNOWS the address belongs to a loaded */ \
932+
/* module (it read a module's own address — /proc/modules, a sysfs */ \
933+
/* per-module sections entry, a named symbol in a known module). */ \
934+
/* MODULE_BAND: the band itself, OR an address merely CLASSIFIED as a */ \
935+
/* module because it fell inside the band (dmesg parsers, opportunistic */ \
936+
/* pointer leaks, perf JIT/trampoline records). */ \
937+
/* */ \
938+
/* The distinction is load-bearing wherever a module address moves a TEXT */ \
939+
/* base, because the band overlaps other regions on every such arch: on */ \
940+
/* arm64 a VA_BITS=48 direct map starts at MODULES_START, and on riscv64 */ \
941+
/* and s390 the band contains the whole kernel-text range. A */ \
942+
/* range-classified address is then indistinguishable from a module one. */ \
943+
/* So module_text_bracket AND module_text_bound both read MODULE only. */ \
944+
/* */ \
945+
/* MODULE_BAND is read where the claim is about the REGION rather than a */ \
946+
/* module: the rendered band, and (with POS_BASE) the kernel's own */ \
947+
/* "modules : 0x..." layout line, which pins Q_MODULE_BASE. */ \
948+
/* */ \
949+
/* Emit MODULE_BAND when in any doubt — it is the weaker, always-safe tag.*/ \
940950
X(REGION_MODULE, "module", "module", K_MODULE) \
941-
X(REGION_MODULE_REGION, "module_region", "module", K_MODULE) \
951+
X(REGION_MODULE_BAND, "module_band", "module", K_MODULE) \
942952
/* ---- Direct-map / virtual landmarks --------------------------------- */ \
943953
X(REGION_DIRECTMAP, "directmap", "directmap", K_VIRT) \
944954
X(REGION_PAGE_OFFSET, "virt_page_offset", "pageoffset", K_PAGEOFFSET) \

0 commit comments

Comments
 (0)