Add TIF_FD_SLOTS and test it once the untraced system call has stored
its result. A task that reserved descriptors calls syscall_trace_leave()
and joins ret_from_sys_call with the flag gone.

We mirror the traced error path where the switch stack is set up and the
return address and the syscall restart state are placed in callee-saved
registers.

Btw, let's remove alpha... It's a pain.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 arch/alpha/include/asm/thread_info.h |  2 ++
 arch/alpha/kernel/entry.S            | 24 +++++++++++++++++++++++-
 arch/alpha/kernel/ptrace.c           |  3 +++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/alpha/include/asm/thread_info.h 
b/arch/alpha/include/asm/thread_info.h
index 1552ecca8520..db8465f5fabb 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -67,6 +67,7 @@ register unsigned long *current_stack_pointer __asm__ ("$30");
 #define TIF_NOTIFY_SIGNAL      5       /* signal notifications exist */
 #define TIF_SECCOMP            6       /* seccomp syscall filtering active */
 #define        TIF_SYSCALL_TRACEPOINT  7       /* syscall tracepoint 
instrumentation */
+#define TIF_FD_SLOTS           8       /* syscall prepared descriptors */
 #define TIF_DIE_IF_KERNEL      9       /* dik recursion lock */
 #define TIF_MEMDIE             13      /* is terminating due to OOM killer */
 #define TIF_POLLING_NRFLAG     14      /* idle is polling for TIF_NEED_RESCHED 
*/
@@ -80,6 +81,7 @@ register unsigned long *current_stack_pointer __asm__ ("$30");
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
+#define _TIF_FD_SLOTS          (1<<TIF_FD_SLOTS)
 
 /*
  * Work to do on syscall entry (in entry.S).
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 9f2608de2544..20372e926359 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -569,6 +569,13 @@ entSys:
 $ret_success:
        stq     $0, 0($sp)
        stq     $31, 72($sp)            /* a3=0 => no error */
+$syscall_exit:
+       /* Descriptors reserved by the syscall are committed in
+          syscall_trace_leave, off the return path interrupts share.  */
+       ldl     $17, TI_FLAGS($8)
+       lda     $2, _TIF_FD_SLOTS
+       and     $17, $2, $2
+       bne     $2, $fd_slots_exit
 
        .align  4
        .globl  ret_from_sys_call
@@ -612,7 +619,7 @@ $syscall_error:
        stq     $0, 0($sp)
        mov     $31, $26        /* tell "ret_from_sys_call" we can restart */
        stq     $1, 72($sp)     /* a3 for return */
-       br      ret_from_sys_call
+       br      $syscall_exit
 
 /*
  * Do all cleanup when returning from all interrupts and system calls.
@@ -648,6 +655,21 @@ $work_notifysig:
        UNDO_SWITCH_STACK
        br      restore_all
 
+       .align  4
+$fd_slots_exit:
+       /* Keep the return address and the syscall restart state in
+          $26/$18/$19 across the call.  */
+       DO_SWITCH_STACK
+       mov     $26, $9
+       mov     $18, $10
+       mov     $19, $11
+       jsr     $26, syscall_trace_leave
+       mov     $9, $26
+       mov     $10, $18
+       mov     $11, $19
+       UNDO_SWITCH_STACK
+       br      ret_from_sys_call
+
 /*
  * PTRACE syscall handler
  */
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index fc8f6cedbb28..736218b34601 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -6,6 +6,7 @@
 /* more mutilation by David Mosberger ([email protected]) */
 
 #include <linux/kernel.h>
+#include <linux/file.h>
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
 #include <linux/mm.h>
@@ -507,6 +508,8 @@ asmlinkage unsigned long syscall_trace_enter(void)
 asmlinkage void
 syscall_trace_leave(void)
 {
+       if (test_thread_flag(TIF_FD_SLOTS))
+               fd_slots_commit(current_pt_regs());
        audit_syscall_exit(current_pt_regs());
        if (test_thread_flag(TIF_SYSCALL_TRACE))
                ptrace_report_syscall_exit(current_pt_regs(), 0);

-- 
2.53.0


Reply via email to