MIPS: scall64-o32: Fix indirect syscall number load [Linux 3.16.72]

This Linux kernel change "MIPS: scall64-o32: Fix indirect syscall number load" is included in the Linux 3.16.72 release. This change is authored by Aurelien Jarno <aurelien [at] aurel32.net> on Tue Apr 9 16:53:55 2019 +0200. The commit for this change in Linux stable tree is e7fd68a (patch) which is from upstream commit 79b4a9c. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 79b4a9c.

MIPS: scall64-o32: Fix indirect syscall number load

commit 79b4a9cf0e2ea8203ce777c8d5cfa86c71eae86e upstream.

Commit 4c21b8fd8f14 (MIPS: seccomp: Handle indirect system calls (o32))
added indirect syscall detection for O32 processes running on MIPS64,
but it did not work correctly for big endian kernel/processes. The
reason is that the syscall number is loaded from ARG1 using the lw
instruction while this is a 64-bit value, so zero is loaded instead of
the syscall number.

Fix the code by using the ld instruction instead. When running a 32-bit
processes on a 64 bit CPU, the values are properly sign-extended, so it
ensures the value passed to syscall_trace_enter is correct.

Recent systemd versions with seccomp enabled whitelist the getpid
syscall for their internal  processes (e.g. systemd-journald), but call
it through syscall(SYS_getpid). This fix therefore allows O32 big endian
systems with a 64-bit kernel to run recent systemd versions.

Signed-off-by: Aurelien Jarno <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Paul Burton <[email protected]>
Cc: Ralf Baechle <[email protected]>
Cc: James Hogan <[email protected]>
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Ben Hutchings <[email protected]>

There are 2 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 arch/mips/kernel/scall64-o32.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 3736150..ff9987f 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -124,7 +124,7 @@ trace_a_syscall:
    subu    t1, v0,  __NR_O32_Linux
    move    a1, v0
    bnez    t1, 1f /* __NR_syscall at offset 0 */
-   lw  a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
+   ld  a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
    .set    pop

 1: jal syscall_trace_enter

Leave a Reply

Your email address will not be published. Required fields are marked *