powerpc/64/signal: Fix regression in __kernel_sigtramp_rt64() semantics
authorRaoni Fassina Firmino <raoni@linux.ibm.com>
Mon, 1 Feb 2021 20:05:05 +0000 (17:05 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Feb 2021 12:55:02 +0000 (13:55 +0100)
commit 24321ac668e452a4942598533d267805f291fdc9 upstream.

Commit 0138ba5783ae ("powerpc/64/signal: Balance return predictor
stack in signal trampoline") changed __kernel_sigtramp_rt64() VDSO and
trampoline code, and introduced a regression in the way glibc's
backtrace()[1] detects the signal-handler stack frame. Apart from the
practical implications, __kernel_sigtramp_rt64() was a VDSO function
with the semantics that it is a function you can call from userspace
to end a signal handling. Now this semantics are no longer valid.

I believe the aforementioned change affects all releases since 5.9.

This patch tries to fix both the semantics and practical aspect of
__kernel_sigtramp_rt64() returning it to the previous code, whilst
keeping the intended behaviour of 0138ba5783ae by adding a new symbol
to serve as the jump target from the kernel to the trampoline. Now the
trampoline has two parts, a new entry point and the old return point.

[1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2021-January/223194.html

Fixes: 0138ba5783ae ("powerpc/64/signal: Balance return predictor stack in signal trampoline")
Cc: stable@vger.kernel.org # v5.9+
Signed-off-by: Raoni Fassina Firmino <raoni@linux.ibm.com>
Acked-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Minor tweaks to change log formatting, add stable tag]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210201200505.iz46ubcizipnkcxe@work-tp
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vdso64/sigtramp.S
arch/powerpc/kernel/vdso64/vdso64.lds.S

index 8dad442..495ffc9 100644 (file)
@@ -475,7 +475,7 @@ static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
         */
 
 #ifdef CONFIG_PPC64
-       vdso64_rt_sigtramp = find_function64(v64, "__kernel_sigtramp_rt64");
+       vdso64_rt_sigtramp = find_function64(v64, "__kernel_start_sigtramp_rt64");
 #endif
        vdso32_sigtramp    = find_function32(v32, "__kernel_sigtramp32");
        vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");
index bbf68cd..2d40675 100644 (file)
 
        .text
 
+/*
+ * __kernel_start_sigtramp_rt64 and __kernel_sigtramp_rt64 together
+ * are one function split in two parts. The kernel jumps to the former
+ * and the signal handler indirectly (by blr) returns to the latter.
+ * __kernel_sigtramp_rt64 needs to point to the return address so
+ * glibc can correctly identify the trampoline stack frame.
+ */
        .balign 8
        .balign IFETCH_ALIGN_BYTES
-V_FUNCTION_BEGIN(__kernel_sigtramp_rt64)
+V_FUNCTION_BEGIN(__kernel_start_sigtramp_rt64)
 .Lsigrt_start:
        bctrl   /* call the handler */
+V_FUNCTION_END(__kernel_start_sigtramp_rt64)
+V_FUNCTION_BEGIN(__kernel_sigtramp_rt64)
        addi    r1, r1, __SIGNAL_FRAMESIZE
        li      r0,__NR_rt_sigreturn
        sc
index 256fb97..bd120f5 100644 (file)
@@ -150,6 +150,7 @@ VERSION
                __kernel_get_tbfreq;
                __kernel_sync_dicache;
                __kernel_sync_dicache_p5;
+               __kernel_start_sigtramp_rt64;
                __kernel_sigtramp_rt64;
                __kernel_getcpu;
                __kernel_time;