um: properly align signal stack on x86_64
authorBenjamin Berg <benjamin.berg@intel.com>
Tue, 7 Jan 2025 13:35:09 +0000 (14:35 +0100)
committerRichard Weinberger <richard@nod.at>
Wed, 12 Feb 2025 22:40:42 +0000 (23:40 +0100)
The stack needs to be properly aligned so 16 byte memory accesses on the
stack are correct. This was broken when introducing the dynamic math
register sizing as the rounding was not moved appropriately.

Fixes: 3f17fed21491 ("um: switch to regset API and depend on XSTATE")
Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20250107133509.265576-1-benjamin@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
arch/x86/um/signal.c

index ea5b3bcc4245698cd725e044c7a2c8b1e0c6f219..2934e170b0fe0b2c6a2ef16374003a0a38dc867e 100644 (file)
@@ -372,11 +372,13 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
        int err = 0, sig = ksig->sig;
        unsigned long fp_to;
 
-       frame = (struct rt_sigframe __user *)
-               round_down(stack_top - sizeof(struct rt_sigframe), 16);
+       frame = (void __user *)stack_top - sizeof(struct rt_sigframe);
 
        /* Add required space for math frame */
-       frame = (struct rt_sigframe __user *)((unsigned long)frame - math_size);
+       frame = (void __user *)((unsigned long)frame - math_size);
+
+       /* ABI requires 16 byte boundary alignment */
+       frame = (void __user *)round_down((unsigned long)frame, 16);
 
        /* Subtract 128 for a red zone and 8 for proper alignment */
        frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);