add_random_kstack_offset() uses get/put_cpu_var() which is pointless
overhead when it is invoked from low level entry code with interrupts
disabled.

Provide a irqsoff() variant, which avoids that.

Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Kees Cook <[email protected]>
---
 include/linux/randomize_kstack.h |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

--- a/include/linux/randomize_kstack.h
+++ b/include/linux/randomize_kstack.h
@@ -77,8 +77,27 @@ static __always_inline u32 get_kstack_of
        }                                                               \
 } while (0)
 
+/**
+ * add_random_kstack_offset_irqsoff - Increase stack utilization by a random 
offset.
+ *
+ * This should be used in the syscall entry path after user registers have been
+ * stored to the stack. Interrupts must be still disabled.
+ */
+#define add_random_kstack_offset_irqsoff()                                     
\
+do {                                                                           
\
+       lockdep_assert_irqs_disabled();                                         
\
+       if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT,         
\
+                               &randomize_kstack_offset)) {                    
\
+               u32 offset = prandom_u32_state(raw_cpu_ptr(&kstack_rnd_state)); 
\
+               u8 *ptr = __kstack_alloca(KSTACK_OFFSET_MAX(offset));           
\
+               /* Keep allocation even after "ptr" loses scope. */             
\
+               asm volatile("" :: "r"(ptr) : "memory");                        
\
+       }                                                                       
\
+} while (0)
+
 #else /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
 #define add_random_kstack_offset()             do { } while (0)
+#define add_random_kstack_offset_irqsoff()     do { } while (0)
 #endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
 
 #endif


Reply via email to