File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 5555/*
5656 * Initialize the stackprotector canary value.
5757 *
58- * NOTE: this must only be called from functions that never return,
58+ * NOTE: this must only be called from functions that never return
5959 * and it must always be inlined.
60+ *
61+ * In addition, it should be called from a compilation unit for which
62+ * stack protector is disabled. Alternatively, the caller should not end
63+ * with a function call which gets tail-call optimized as that would
64+ * lead to checking a modified canary value.
6065 */
6166static __always_inline void boot_init_stack_canary (void )
6267{
Original file line number Diff line number Diff line change @@ -266,6 +266,14 @@ static void notrace start_secondary(void *unused)
266266
267267 wmb ();
268268 cpu_startup_entry (CPUHP_AP_ONLINE_IDLE );
269+
270+ /*
271+ * Prevent tail call to cpu_startup_entry() because the stack protector
272+ * guard has been changed a couple of function calls up, in
273+ * boot_init_stack_canary() and must not be checked before tail calling
274+ * another function.
275+ */
276+ prevent_tail_call_optimization ();
269277}
270278
271279/**
Original file line number Diff line number Diff line change @@ -93,6 +93,7 @@ asmlinkage __visible void cpu_bringup_and_idle(void)
9393 cpu_bringup ();
9494 boot_init_stack_canary ();
9595 cpu_startup_entry (CPUHP_AP_ONLINE_IDLE );
96+ prevent_tail_call_optimization ();
9697}
9798
9899void xen_smp_intr_free_pv (unsigned int cpu )
Original file line number Diff line number Diff line change @@ -356,4 +356,10 @@ static inline void *offset_to_ptr(const int *off)
356356/* &a[0] degrades to a pointer: a different type from an array */
357357#define __must_be_array (a ) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
358358
359+ /*
360+ * This is needed in functions which generate the stack canary, see
361+ * arch/x86/kernel/smpboot.c::start_secondary() for an example.
362+ */
363+ #define prevent_tail_call_optimization () mb()
364+
359365#endif /* __LINUX_COMPILER_H */
Original file line number Diff line number Diff line change @@ -1038,6 +1038,8 @@ asmlinkage __visible void __init start_kernel(void)
10381038
10391039 /* Do the rest non-__init'ed, we're now alive */
10401040 arch_call_rest_init ();
1041+
1042+ prevent_tail_call_optimization ();
10411043}
10421044
10431045/* Call all constructor functions linked into the kernel. */
You can’t perform that action at this time.
0 commit comments