Skip to content

Commit 4340546

Browse files
committed
arch: make every module band cover its configurations
The band is a validation union: its floor must sit at or below the module region under every configuration the header models, or module addresses are discarded before they become observations — silently, since proc_modules then reports "no kernel address found", the same as an empty file. Auditing all seven candidate arches found two floors that did not. x86_64: MODULES_VADDR is __START_KERNEL_map + KERNEL_IMAGE_SIZE, and that size is 1 GiB only with CONFIG_RANDOMIZE_BASE; a kernel built without it puts modules at 0xffffffffa0000000, half a gigabyte below the old floor. Build-time, so booting nokaslr does not reproduce it and the nokaslr VM cells never caught it. sidt.c had to stop reading MODULES_START as its kernel-text ceiling, which it could while the two coincided. ppc64: 64-bit PowerPC has no MODULES_VADDR, so modules come from vmalloc, whose base spans 32 TiB across MMU configurations — 0xc008000000000000 for radix and 64k-page hash, but 0xc0003d0000000000 for 4k-page hash and 0xc000100000000000 for Book3E. The floor is now the lowest. loongarch64: vm_map_base is 0 - (1 << cpu_vabits), read from CPUCFG1, so a wider VA moves the region down. Shipping parts report 39 and 48, but the kernel's page tables reach 58 bits, so the floor is anchored there rather than on the widest part that happens to exist. riscv64, s390, mips32 and mips64 already held and are declared as-is. With the bands exact, module_base_execmem_window confines Q_MODULE_BASE to execmem_arch_setup()'s own window: start = MODULES_VADDR + rand(1,1024) * PAGE_SIZE, about 10 bits drawn independently of the text slide. It is gated on evidence the image moved, which proves RANDOMIZE_BASE=y and so fixes which MODULES_VADDR is live; without that the window could be in the wrong place entirely, so the rule stays silent. Offset 0 stays in range because RANDOMIZE_MEMORY depends on RANDOMIZE_BASE. x86_64 Module Region Base goes from unbounded to 1025 candidates. Doc samples re-captured from the same mainline 7.0 boot under KVM.
1 parent 060ac36 commit 4340546

14 files changed

Lines changed: 249 additions & 25 deletions

File tree

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,25 @@ KASLD 0.3.1-dev -- Kernel ASLR derandomization
7676
Target: x86_64 / 7.0.0
7777
7878
Running 101 of 104 components (3 experimental skipped; use -x to enable)...
79-
[####################] 100% 101/101 38.4s
79+
[####################] 100% 101/101 39.1s
8080
1 component timed out after 30s and was killed (prefetch_directmap)
8181
8282
Quantity Basis Range Search space Align
8383
------------------- ---------- --------------------------------------- ------------ -----
84-
Virtual Image Base guaranteed 0xffffffffa5e00000 slide +0x24e00000 1 of 505 2 MiB
84+
Virtual Image Base guaranteed 0xffffffffa2e00000 slide +0x21e00000 1 of 505 2 MiB
8585
Physical Image Base guaranteed 0x200000 - 0x3d400000 481 2 MiB
86-
Physical Image Base likely 0x1000000 - 0x3c346000 474 of 481 2 MiB
86+
Physical Image Base likely 0x1000000 - 0x3c345000 474 of 481 2 MiB
8787
Direct Map Base guaranteed 0xffff800000000000 - 0xffffa4aa80000000 37547 1 GiB
8888
Vmalloc Base guaranteed 0xffff898000000000 - 0xffffd6d580000000 79191 1 GiB
8989
Vmemmap Base guaranteed 0xffffa98040000000 - 0xfffffd0000000000 85504 1 GiB
90+
Module Region Base guaranteed 0xffffffffc0000000 - 0xffffffffc0400000 1025 4 KiB
9091
9192
Note: physical and virtual text randomize independently
9293
9394
Evidence (2 findings, 4 components)
94-
virt kernel text [interior] 0xffffffffa5f04109
95+
virt kernel text [interior] 0xffffffffa309cab5
9596
from perf_event_open, perf_text_poke_leak, proc_kallsyms
96-
virt kernel image [base] 0xffffffffa5e00000
97+
virt kernel image [base] 0xffffffffa2e00000
9798
from perf_event_open, prefetch, proc_kallsyms
9899
99100
[-v: detailed results, memory map, system info] [-H: hardening assessment]

docs/usage.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,24 +164,26 @@ KASLD 0.3.1-dev -- Kernel ASLR derandomization
164164
Target: x86_64 / 7.0.0
165165
166166
Running 101 of 104 components (3 experimental skipped; use -x to enable)...
167-
[####################] 100% 101/101 12.1s
167+
[####################] 100% 101/101 39.1s
168+
1 component timed out after 30s and was killed (prefetch_directmap)
168169
169170
Quantity Basis Range Search space Align
170171
------------------- ---------- --------------------------------------- ------------ -----
171-
Virtual Image Base guaranteed 0xffffffffb7000000 slide +0x36000000 1 of 505 2 MiB
172+
Virtual Image Base guaranteed 0xffffffffa2e00000 slide +0x21e00000 1 of 505 2 MiB
172173
Physical Image Base guaranteed 0x200000 - 0x3d400000 481 2 MiB
173-
Physical Image Base likely 0x1000000 - 0x3c346000 474 of 481 2 MiB
174+
Physical Image Base likely 0x1000000 - 0x3c345000 474 of 481 2 MiB
174175
Direct Map Base guaranteed 0xffff800000000000 - 0xffffa4aa80000000 37547 1 GiB
175176
Vmalloc Base guaranteed 0xffff898000000000 - 0xffffd6d580000000 79191 1 GiB
176177
Vmemmap Base guaranteed 0xffffa98040000000 - 0xfffffd0000000000 85504 1 GiB
178+
Module Region Base guaranteed 0xffffffffc0000000 - 0xffffffffc0400000 1025 4 KiB
177179
178180
Note: physical and virtual text randomize independently
179181
180-
Evidence (2 findings, 3 components)
181-
virt kernel text [interior] 0xffffffffb7298cb2
182+
Evidence (2 findings, 4 components)
183+
virt kernel text [interior] 0xffffffffa309cab5
182184
from perf_event_open, perf_text_poke_leak, proc_kallsyms
183-
virt kernel image [base] 0xffffffffb7000000
184-
from perf_event_open, proc_kallsyms
185+
virt kernel image [base] 0xffffffffa2e00000
186+
from perf_event_open, prefetch, proc_kallsyms
185187
186188
[-v: detailed results, memory map, system info] [-H: hardening assessment]
187189
```
@@ -412,7 +414,7 @@ or not applicable to the arch/run renders the sentinel `na` (never a
412414
fabricated, defaulted, or leaked value):
413415

414416
```
415-
arch=x86_64 kaslr=on text=0xffffffffb7000000 stext=na slide=+0x36000000(905969664) entropy=0bits ptext=na pstext=na pslide=na pentropy=9bits dmap=0xffff800000000000 dram=[0x0..0x3ffdefff](1023.9 MiB) results=25
417+
arch=x86_64 kaslr=on text=0xffffffffa2e00000 stext=na slide=+0x21e00000(568328192) entropy=0bits ptext=na pstext=na pslide=na pentropy=9bits dmap=0xffff800000000000 dram=[0x0..0x3ffdefff](1023.9 MiB) results=27
416418
```
417419

418420
| Key | Meaning |

src/components/sidt.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ static int is_fixmap_region(unsigned long addr) {
141141
}
142142

143143
static int is_kernel_text_region(unsigned long addr) {
144-
return addr >= KERNEL_VIRT_TEXT_MIN && addr < MODULES_START;
144+
/* Bounded by KERNEL_VIRT_TEXT_MAX, not MODULES_START. The two coincided while
145+
* the module band began where the text window ends, but the band's floor is
146+
* the non-randomized MODULES_VADDR (512 MiB lower), and text does extend
147+
* above it -- reading the band's floor as a text ceiling would reject
148+
* legitimate text on a KASLR kernel. */
149+
return addr >= KERNEL_VIRT_TEXT_MIN && addr < KERNEL_VIRT_TEXT_MAX;
145150
}
146151

147152
#else /* __i386__ */

src/engine_rules.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static const rule_fn k_rules[] = {
8181
rule_module_text_bound,
8282
rule_module_text_bracket,
8383
rule_module_base_bounds,
84+
rule_module_base_execmem_window,
8485

8586
/* Multi-entry EFI_LOADER_CODE → Q_PHYS_IMAGE_BASE pin */
8687
rule_efi_loader_kernel_pick,

src/include/kasld/arch/loongarch64.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,24 @@
6161
// Module region size: SZ_256M.
6262
// Use conservative floor (48-bit VA) and wide ceiling to cover all VA configs.
6363
// https://elixir.bootlin.com/linux/v6.12/source/arch/loongarch/include/asm/pgtable.h#L82
64-
#define MODULES_START 0xffff000000000000ul
64+
// The floor covers any VALEN the kernel can describe, not just today's parts.
65+
// vm_map_base = 0 - (1 << cpu_vabits), read from CPUCFG1 at boot, so a wider
66+
// VA moves the module region DOWN. Shipping parts report 39 (Loongson-2K) and
67+
// 48 (LA464/LA664) -- both land above 0xffff000000000000 -- but the kernel's
68+
// own page tables reach VA_BITS = PGDIR_SHIFT + (PAGE_SHIFT - PTRLOG) = 58 at
69+
// 4 levels with 16K pages, so a future VALEN in 49..58 would sit below it.
70+
// Anchor on that geometric bound (0 - (1 << 58)) rather than on the widest
71+
// part that happens to exist: the failure mode of guessing is a silently
72+
// dropped module address, and the cost of the wider band is only
73+
// classify-by-range, which the REGION_MODULE provenance split already made
74+
// non-load-bearing.
75+
#define MODULES_START 0xfc00000000000000ul // 0 - (1 << 58)
6576
#define MODULES_END 0xffffffffffff0000ul
77+
78+
// Usable as a BOUND, not only as an admission filter: the floor above is
79+
// derived from the widest VA the kernel's page tables can describe, so it sits
80+
// at or below vm_map_base for every VALEN a running kernel could report.
81+
#define MODULES_BAND_EXACT 1
6682
#define MODULES_RELATIVE_TO_TEXT 0
6783

6884
// EFI_KIMG_ALIGN is SZ_2M, but KASLR offset uses << 16 = 64 KiB granularity.

src/include/kasld/arch/mips32.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949

5050
#define MODULES_START 0xc0000000ul
5151
#define MODULES_END 0xfffffffful
52+
53+
// Usable as a BOUND: 32-bit MIPS has no MODULES_VADDR, so modules come from
54+
// vmalloc at MAP_BASE (kseg2, 0xc0000000) -- this floor exactly. The
55+
// machine-specific MAP_BASE override (Loongson) is 64-bit only.
56+
#define MODULES_BAND_EXACT 1
5257
#define MODULES_RELATIVE_TO_TEXT 0
5358

5459
// KASLR offset is shifted left 16 bits (64 KiB granularity).

src/include/kasld/arch/mips64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@
4444

4545
#define MODULES_START 0xffffffffc0000000ul
4646
#define MODULES_END 0xfffffffffffffffful
47+
48+
// Usable as a BOUND: MODULES_VADDR is CKSSEG (0xffffffffc0000000), a fixed
49+
// MIPS segment address, and MODULES_END is FIXADDR_START - 2 pages, below the
50+
// ceiling here. Neither varies with config.
51+
#define MODULES_BAND_EXACT 1
4752
#define MODULES_RELATIVE_TO_TEXT 0
4853

4954
// KASLR offset is shifted left 16 bits (64 KiB granularity).

src/include/kasld/arch/ppc64.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,27 @@
4343
#define KERNEL_VIRT_TEXT_MIN PAGE_OFFSET
4444
#define KERNEL_VIRT_TEXT_MAX 0xffffffffff000000ul
4545

46-
// Modules are loaded in the vmalloc region, which starts at
47-
// PAGE_OFFSET + KERN_VIRT_SIZE (0xc008000000000000 on Book3S).
48-
// https://elixir.bootlin.com/linux/v6.1.1/source/arch/powerpc/include/asm/book3s/64/pgtable.h#L324
49-
// https://elixir.bootlin.com/linux/v6.1.1/source/arch/powerpc/mm/book3s64/hash_utils.c
50-
#define MODULES_START 0xc008000000000000ul
46+
// 64-bit PowerPC defines no MODULES_VADDR, so modules come from the vmalloc
47+
// region -- whose base differs by MMU and page size, across a 32 TiB spread:
48+
//
49+
// radix RADIX_KERN_VIRT_START = 0xc008000000000000 (+ 1<<49)
50+
// hash-64k H_KERN_VIRT_START = 0xc008000000000000
51+
// hash-4k H_KERN_VIRT_START = 0xc0003d0000000000
52+
// Book3E KERN_VIRT_START = 0xc000100000000000 (+ 0x100000000000)
53+
//
54+
// The floor is the lowest of those (Book3E), not the Book3S one: a floor at
55+
// 0xc008000000000000 admits radix and 64k-page hash but rejects every module
56+
// address on a 4K-page hash kernel or a Book3E part (e5500/e6500), which is a
57+
// silent drop -- proc_modules reports "no kernel address found", the same as
58+
// an empty file. The ceiling is the radix vmalloc end, the highest of the four.
59+
// https://elixir.bootlin.com/linux/v7.2/source/arch/powerpc/include/asm/book3s/64/radix.h
60+
// https://elixir.bootlin.com/linux/v7.2/source/arch/powerpc/include/asm/nohash/64/pgtable.h
61+
#define MODULES_START 0xc000100000000000ul
5162
#define MODULES_END 0xc009fffffffffffful
63+
64+
// Usable as a BOUND: the floor is the lowest vmalloc base of any 64-bit
65+
// PowerPC MMU configuration, and the ceiling the highest vmalloc end.
66+
#define MODULES_BAND_EXACT 1
5267
#define MODULES_RELATIVE_TO_TEXT 0
5368

5469
// Plausible physical address range for kernel image

src/include/kasld/arch/riscv64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@
8989
#define MODULES_START 0xffffffde00000000ul
9090
#define MODULES_END 0xffffffffc0000000ul
9191

92+
// Usable as a BOUND: modules occupy [_end - 2 GiB, _start], so the lowest
93+
// possible base is (lowest text) - 2 GiB = 0xffffffdf80000000, ~6 GiB above
94+
// this floor, and the ceiling is exactly the highest _start the arch admits.
95+
#define MODULES_BAND_EXACT 1
96+
9297
// Module region is anchored to kernel _end (shifts with KASLR)
9398
#define MODULES_RELATIVE_TO_TEXT 1
9499
// MODULES_BELOW_TEXT_START selects the s390-style "Case B" placement

src/include/kasld/arch/s390.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@
114114
// Runtime-determined; use wide bounds for validation.
115115
#define MODULES_START 0ul
116116
#define MODULES_END 0x20000000000000ul
117+
118+
// Usable as a BOUND: the boot decompressor sets MODULES_END =
119+
// round_down(kernel_start, _SEGMENT_SIZE) and MODULES_VADDR = MODULES_END -
120+
// 2 GiB, so both stay within this window for any image placement, and a floor
121+
// of 0 cannot be too high whatever the layout.
122+
#define MODULES_BAND_EXACT 1
117123
#define MODULES_RELATIVE_TO_TEXT 1
118124
#define MODULES_BELOW_TEXT_START 1
119125
#define MODULES_END_TO_TEXT_OFFSET \

0 commit comments

Comments
 (0)