Re: [PATCH v2] sched: move stack_canary to the start of the randomizable region
Charles Mirabile <[email protected]>
| Newsgroups | org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi Ruidong, Valentin, (+ copying in RISC-V list/maintainers)— On Tue, May 12, 2026 at 06:16:43PM +0200, Valentin Schneider wrote: > On 09/05/26 11:50, Ruidong Tian wrote: > > task_struct keeps growing over time. On architectures that compute the > > per-task stack canary offset from asm-offsets.h and pass it to the > > compiler via -mstack-protector-guard-offset=, this growth eventually > > pushes stack_canary beyond what the target ISA can encode. > > > > On RISC-V, canary loads are emitted as > > > > ld t0, TSK_STACK_CANARY(tp) > > > > where TSK_STACK_CANARY must fit into a 12-bit signed immediate, i.e. > > [-2048, 2047]. Once stack_canary sits past byte 2047 of task_struct, > > the build fails with > > > > cc1: error: '<N>' is not a valid offset in > > '-mstack-protector-guard-offset=' Thanks for this patch. We just ran into this exact issue during a CKI build https://datawarehouse.cki-project.org/kcidb/builds/1639782 and this seems like exactly the fix we need. > > > > * On RISC-V, CONFIG_STACKPROTECTOR_PER_TASK depends on !RANDSTRUCT, > > so randomized_struct_fields_start/end always expand to nothing and > > stack_canary lands at a small, stable offset well within the > > 12-bit signed immediate range. The build error goes away. > > > > * On architectures that enable RANDSTRUCT for hardening, stack_canary > > stays inside the randomized region and is still shuffled together > > with the other fields by the layout randomization, so its hardening > > coverage is preserved. asm-offsets-based architectures read the > > shuffled offset at build time, so the generated canary accesses > > remain correct. > > > > pahole on a typical 64-bit config shows that the area around the > > wakee_* fields already contains a usable hole: > > > > struct __call_single_node wake_entry; /* 56 16 */ > > /* --- cacheline 1 boundary (64 bytes) --- */ > > unsigned int wakee_flips; /* 72 4 */ > > /* XXX 4 bytes hole, try to pack */ > > unsigned long int wakee_flip_decay_ts; /* 80 8 */ > > struct task_struct * last_wakee; /* 88 8 */ > > > > Move wakee_flips to sit after last_wakee. That opens up a clean > > 8-byte slot at offset 72 into which stack_canary fits exactly: > > > > struct __call_single_node wake_entry; /* 56 16 */ > > /* --- cacheline 1 boundary (64 bytes) --- */ > > unsigned long stack_canary; /* 72 8 */ > > unsigned long int wakee_flip_decay_ts; /* 80 8 */ > > struct task_struct * last_wakee; /* 88 8 */ > > unsigned int wakee_flips; /* 96 4 */ > > > > Suggested-by: K Prateek Nayak <[email protected]> > > Signed-off-by: Ruidong Tian <[email protected]> > > Reviewed-by: Valentin Schneider <[email protected]> > Thanks for the review, is there any hope of this patch going in during the 7.3 merge window? I have also copied the RISC-V list as well, maybe if it is ok with the sched folks, the RISC-V maintainers could take it through their tree as a RISC-V specific urgent fix? Best—Charlie _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv