]> Git Repo - linux.git/commitdiff
MIPS: Export syscall stack arguments properly for remote use
authorMaciej W. Rozycki <[email protected]>
Tue, 11 Feb 2025 18:22:30 +0000 (18:22 +0000)
committerThomas Bogendoerfer <[email protected]>
Thu, 13 Feb 2025 11:41:18 +0000 (12:41 +0100)
We have several places across the kernel where we want to access another
task's syscall arguments, such as ptrace(2), seccomp(2), etc., by making
a call to syscall_get_arguments().

This works for register arguments right away by accessing the task's
`regs' member of `struct pt_regs', however for stack arguments seen with
32-bit/o32 kernels things are more complicated.  Technically they ought
to be obtained from the user stack with calls to an access_remote_vm(),
but we have an easier way available already.

So as to be able to access syscall stack arguments as regular function
arguments following the MIPS calling convention we copy them over from
the user stack to the kernel stack in arch/mips/kernel/scall32-o32.S, in
handle_sys(), to the current stack frame's outgoing argument space at
the top of the stack, which is where the handler called expects to see
its incoming arguments.  This area is also pointed at by the `pt_regs'
pointer obtained by task_pt_regs().

Make the o32 stack argument space a proper member of `struct pt_regs'
then, by renaming the existing member from `pad0' to `args' and using
generated offsets to access the space.  No functional change though.

With the change in place the o32 kernel stack frame layout at the entry
to a syscall handler invoked by handle_sys() is therefore as follows:

$sp + 68 -> |         ...         | <- pt_regs.regs[9]
            +---------------------+
$sp + 64 -> |         $t0         | <- pt_regs.regs[8]
            +---------------------+
$sp + 60 -> |   $a3/argument #4   | <- pt_regs.regs[7]
            +---------------------+
$sp + 56 -> |   $a2/argument #3   | <- pt_regs.regs[6]
            +---------------------+
$sp + 52 -> |   $a1/argument #2   | <- pt_regs.regs[5]
            +---------------------+
$sp + 48 -> |   $a0/argument #1   | <- pt_regs.regs[4]
            +---------------------+
$sp + 44 -> |         $v1         | <- pt_regs.regs[3]
            +---------------------+
$sp + 40 -> |         $v0         | <- pt_regs.regs[2]
            +---------------------+
$sp + 36 -> |         $at         | <- pt_regs.regs[1]
            +---------------------+
$sp + 32 -> |        $zero        | <- pt_regs.regs[0]
            +---------------------+
$sp + 28 -> |  stack argument #8  | <- pt_regs.args[7]
            +---------------------+
$sp + 24 -> |  stack argument #7  | <- pt_regs.args[6]
            +---------------------+
$sp + 20 -> |  stack argument #6  | <- pt_regs.args[5]
            +---------------------+
$sp + 16 -> |  stack argument #5  | <- pt_regs.args[4]
            +---------------------+
$sp + 12 -> | psABI space for $a3 | <- pt_regs.args[3]
            +---------------------+
$sp +  8 -> | psABI space for $a2 | <- pt_regs.args[2]
            +---------------------+
$sp +  4 -> | psABI space for $a1 | <- pt_regs.args[1]
            +---------------------+
$sp +  0 -> | psABI space for $a0 | <- pt_regs.args[0]
            +---------------------+

holding user data received and with the first 4 frame slots reserved by
the psABI for the compiler to spill the incoming arguments from $a0-$a3
registers (which it sometimes does according to its needs) and the next
4 frame slots designated by the psABI for any stack function arguments
that follow.  This data is also available for other tasks to peek/poke
at as reqired and where permitted.

Signed-off-by: Maciej W. Rozycki <[email protected]>
Signed-off-by: Thomas Bogendoerfer <[email protected]>
arch/mips/include/asm/ptrace.h
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/scall32-o32.S

index 4a2b40ce39e0911d74806b2db54d69a9735d33ef..85fa9962266a2b5c15d190eb7a101ee7266f5576 100644 (file)
@@ -27,8 +27,8 @@
  */
 struct pt_regs {
 #ifdef CONFIG_32BIT
-       /* Pad bytes for argument save space on the stack. */
-       unsigned long pad0[8];
+       /* Saved syscall stack arguments; entries 0-3 unused. */
+       unsigned long args[8];
 #endif
 
        /* Saved main processor registers. */
index cb1045ebab0621ad2c8c59eaebe96b13d47e4514..b910ec54a3a1781476bfc3c6a0d237a2efefc821 100644 (file)
@@ -27,6 +27,12 @@ void output_ptreg_defines(void);
 void output_ptreg_defines(void)
 {
        COMMENT("MIPS pt_regs offsets.");
+#ifdef CONFIG_32BIT
+       OFFSET(PT_ARG4, pt_regs, args[4]);
+       OFFSET(PT_ARG5, pt_regs, args[5]);
+       OFFSET(PT_ARG6, pt_regs, args[6]);
+       OFFSET(PT_ARG7, pt_regs, args[7]);
+#endif
        OFFSET(PT_R0, pt_regs, regs[0]);
        OFFSET(PT_R1, pt_regs, regs[1]);
        OFFSET(PT_R2, pt_regs, regs[2]);
index 2c604717e63080b1c1949a080bfadf1cab94acd6..4947a4f39e3713522e4538d36bb6f50d273066ca 100644 (file)
@@ -64,10 +64,10 @@ load_a6: user_lw(t7, 24(t0))                # argument #7 from usp
 load_a7: user_lw(t8, 28(t0))           # argument #8 from usp
 loads_done:
 
-       sw      t5, 16(sp)              # argument #5 to ksp
-       sw      t6, 20(sp)              # argument #6 to ksp
-       sw      t7, 24(sp)              # argument #7 to ksp
-       sw      t8, 28(sp)              # argument #8 to ksp
+       sw      t5, PT_ARG4(sp)         # argument #5 to ksp
+       sw      t6, PT_ARG5(sp)         # argument #6 to ksp
+       sw      t7, PT_ARG6(sp)         # argument #7 to ksp
+       sw      t8, PT_ARG7(sp)         # argument #8 to ksp
        .set    pop
 
        .section __ex_table,"a"
This page took 0.06369 seconds and 4 git commands to generate.