33// Inference plugin: forbidden lower slots from kernel image size
44// (POST_COLLECTION)
55//
6- // Both MIPS and LoongArch enforce a minimum KASLR offset:
6+ // Both MIPS and LoongArch enforce a minimum KASLR offset using identical
7+ // arithmetic in their respective `relocate_kernel.c`:
78//
89// offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1);
910// if (offset < kernel_length)
10- // offset += ALIGN(kernel_length, KERNEL_ALIGN); // MIPS
11- // // or, on LoongArch: offset = ALIGN(kernel_length, KERNEL_ALIGN)
11+ // offset += ALIGN(kernel_length, KERNEL_ALIGN);
12+ //
13+ // (Verified against arch/mips/kernel/relocate.c and
14+ // arch/loongarch/kernel/relocate.c on Linux 6.17.)
1215//
1316// Any randomly-drawn offset in [0, kernel_length) is bumped upward. The
1417// range [0, kernel_length) is a forbidden zone: no valid text base falls
2326// sound: the kernel cannot load within the forbidden zone, and the zone
2427// extends at least gap bytes from KASLR_BASE_MIN.
2528//
26- // LoongArch extension :
29+ // LoongArch diagnostic :
2730// When kernel_length ≥ CONFIG_RANDOMIZE_BASE_MAX_OFFSET, every offset
28- // drawn from [0, max_offset) satisfies offset < kernel_length, so the
29- // bump always fires. On LoongArch the bump is an assignment (not an
30- // addition), making the result a single fixed value:
31- //
32- // text_base = KASLR_BASE_MIN + ALIGN(kernel_length, KERNEL_ALIGN)
33- //
34- // When kernel_length_estimate ≥ max_offset this plugin emits a verbose
35- // diagnostic. A bilateral pin is not applied: the gap is a lower bound
36- // (gap ≤ true kernel_length), so ALIGN(gap) ≤ ALIGN(true_kernel_length),
37- // and setting text_base_max = KASLR_BASE_MIN + ALIGN(gap) could exclude
38- // the true text base if gap underestimates by more than one KERNEL_ALIGN
39- // step. Implementing the bilateral pin soundly requires exact kernel_length
40- // (e.g. from /boot/Image header — see riscv64_fdt_kaslr_seed inference for
41- // the Image-header approach; a LoongArch variant is a future enhancement).
31+ // drawn from [0, max_offset) satisfies `offset < kernel_length`, so the
32+ // bump always fires. The post-bump offset lands in
33+ // [ALIGN(kernel_length, KERNEL_ALIGN),
34+ // max_offset + ALIGN(kernel_length, KERNEL_ALIGN)) — *not* a single
35+ // deterministic value. We emit a verbose diagnostic noting that the
36+ // randomization range has been shifted into a higher window. No further
37+ // bound tightening is applied because the gap is only a lower bound on
38+ // kernel_length; soundly pinning text_base_max requires the exact
39+ // kernel_length (e.g. from /boot/Image header — see
40+ // riscv64_fdt_kaslr_seed for the Image-header approach; a LoongArch
41+ // variant is a future enhancement).
4242//
4343// Note: config_max_offset_bound (PRE_COLLECTION) sets
4444// text_base_max = KASLR_BASE_MIN + max_offset.
@@ -162,10 +162,12 @@ static void min_offset_from_image_size_run(struct kasld_analysis_ctx *ctx) {
162162 }
163163
164164#if defined(__loongarch__ )
165- /* LoongArch extension: when kernel_length >= max_offset the bump always
166- * fires (assignment semantics), making KASLR deterministic. Log this
167- * condition for awareness; a bilateral pin is not applied because gap is
168- * a lower bound on the true kernel_length (see file header). */
165+ /* LoongArch diagnostic: when kernel_length >= max_offset, every random
166+ * draw triggers the bump branch, shifting the slot window from
167+ * [0, max_offset) to [ALIGN(kernel_length), max_offset +
168+ * ALIGN(kernel_length)). The kernel is still randomized within this shifted
169+ * window — not a single deterministic point. Log for awareness; no bound pin
170+ * (see file header for why). */
169171 struct utsname uts ;
170172 if (uname (& uts ) == 0 ) {
171173 FILE * fp = open_boot_config (uts .release );
@@ -179,13 +181,11 @@ static void min_offset_from_image_size_run(struct kasld_analysis_ctx *ctx) {
179181 : gap ;
180182
181183 if (verbose && !quiet )
182- fprintf (
183- stdout ,
184- "[infer] min_offset_from_image_size: LoongArch KASLR"
185- " deterministic (kernel_length_estimate=%#lx >= max_offset=%#lx);"
186- " deterministic virt_text_base >= %#lx;"
187- " bilateral pin requires exact kernel_length\n" ,
188- gap , max_offset , kaslr_min + aligned_gap );
184+ fprintf (stdout ,
185+ "[infer] min_offset_from_image_size: LoongArch KASLR window"
186+ " shifted (kernel_length_estimate=%#lx >= max_offset=%#lx);"
187+ " virt_text_base >= %#lx; range shifted, not pinned\n" ,
188+ gap , max_offset , kaslr_min + aligned_gap );
189189 }
190190 }
191191 }
0 commit comments