Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

syscall_get_arch: add "struct task_struct *" argument

This argument is required to extend the generic ptrace API with
PTRACE_GET_SYSCALL_INFO request: syscall_get_arch() is going
to be called from ptrace_request() along with syscall_get_nr(),
syscall_get_arguments(), syscall_get_error(), and
syscall_get_return_value() functions with a tracee as their argument.

The primary intent is that the triple (audit_arch, syscall_nr, arg1..arg6)
should describe what system call is being called and what its arguments
are.

Reverts: 5e937a9ae913 ("syscall_get_arch: remove useless function arguments")
Reverts: 1002d94d3076 ("syscall.h: fix doc text for syscall_get_arch()")
Reviewed-by: Andy Lutomirski <luto@kernel.org> # for x86
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Acked-by: Paul Burton <paul.burton@mips.com> # MIPS parts
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
Acked-by: Kees Cook <keescook@chromium.org> # seccomp parts
Acked-by: Mark Salter <msalter@redhat.com> # for the c6x bit
Cc: Elvira Khabirova <lineprinter@altlinux.org>
Cc: Eugene Syromyatnikov <esyr@redhat.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: x86@kernel.org
Cc: linux-alpha@vger.kernel.org
Cc: linux-snps-arc@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-c6x-dev@linux-c6x.org
Cc: uclinux-h8-devel@lists.sourceforge.jp
Cc: linux-hexagon@vger.kernel.org
Cc: linux-ia64@vger.kernel.org
Cc: linux-m68k@lists.linux-m68k.org
Cc: linux-mips@vger.kernel.org
Cc: nios2-dev@lists.rocketboards.org
Cc: openrisc@lists.librecores.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-riscv@lists.infradead.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linux-um@lists.infradead.org
Cc: linux-xtensa@linux-xtensa.org
Cc: linux-arch@vger.kernel.org
Cc: linux-audit@redhat.com
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Dmitry V. Levin and committed by
Paul Moore
16add411 b15fe94a

+52 -42
+1 -1
arch/alpha/include/asm/syscall.h
··· 4 4 5 5 #include <uapi/linux/audit.h> 6 6 7 - static inline int syscall_get_arch(void) 7 + static inline int syscall_get_arch(struct task_struct *task) 8 8 { 9 9 return AUDIT_ARCH_ALPHA; 10 10 }
+1 -1
arch/arc/include/asm/syscall.h
··· 70 70 } 71 71 72 72 static inline int 73 - syscall_get_arch(void) 73 + syscall_get_arch(struct task_struct *task) 74 74 { 75 75 return IS_ENABLED(CONFIG_ISA_ARCOMPACT) 76 76 ? (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)
+1 -1
arch/arm/include/asm/syscall.h
··· 104 104 memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0])); 105 105 } 106 106 107 - static inline int syscall_get_arch(void) 107 + static inline int syscall_get_arch(struct task_struct *task) 108 108 { 109 109 /* ARM tasks don't change audit architectures on the fly. */ 110 110 return AUDIT_ARCH_ARM;
+2 -2
arch/arm64/include/asm/syscall.h
··· 117 117 * We don't care about endianness (__AUDIT_ARCH_LE bit) here because 118 118 * AArch64 has the same system calls both on little- and big- endian. 119 119 */ 120 - static inline int syscall_get_arch(void) 120 + static inline int syscall_get_arch(struct task_struct *task) 121 121 { 122 - if (is_compat_task()) 122 + if (is_compat_thread(task_thread_info(task))) 123 123 return AUDIT_ARCH_ARM; 124 124 125 125 return AUDIT_ARCH_AARCH64;
+1 -1
arch/c6x/include/asm/syscall.h
··· 121 121 } 122 122 } 123 123 124 - static inline int syscall_get_arch(void) 124 + static inline int syscall_get_arch(struct task_struct *task) 125 125 { 126 126 return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) 127 127 ? AUDIT_ARCH_C6XBE : AUDIT_ARCH_C6X;
+1 -1
arch/csky/include/asm/syscall.h
··· 70 70 } 71 71 72 72 static inline int 73 - syscall_get_arch(void) 73 + syscall_get_arch(struct task_struct *task) 74 74 { 75 75 return AUDIT_ARCH_CSKY; 76 76 }
+1 -1
arch/h8300/include/asm/syscall.h
··· 49 49 } 50 50 51 51 static inline int 52 - syscall_get_arch(void) 52 + syscall_get_arch(struct task_struct *task) 53 53 { 54 54 return AUDIT_ARCH_H8300; 55 55 }
+1 -1
arch/hexagon/include/asm/syscall.h
··· 46 46 memcpy(args, &(&regs->r00)[i], n * sizeof(args[0])); 47 47 } 48 48 49 - static inline int syscall_get_arch(void) 49 + static inline int syscall_get_arch(struct task_struct *task) 50 50 { 51 51 return AUDIT_ARCH_HEXAGON; 52 52 }
+1 -1
arch/ia64/include/asm/syscall.h
··· 81 81 ia64_syscall_get_set_arguments(task, regs, i, n, args, 1); 82 82 } 83 83 84 - static inline int syscall_get_arch(void) 84 + static inline int syscall_get_arch(struct task_struct *task) 85 85 { 86 86 return AUDIT_ARCH_IA64; 87 87 }
+1 -1
arch/m68k/include/asm/syscall.h
··· 4 4 5 5 #include <uapi/linux/audit.h> 6 6 7 - static inline int syscall_get_arch(void) 7 + static inline int syscall_get_arch(struct task_struct *task) 8 8 { 9 9 return AUDIT_ARCH_M68K; 10 10 }
+1 -1
arch/microblaze/include/asm/syscall.h
··· 101 101 asmlinkage unsigned long do_syscall_trace_enter(struct pt_regs *regs); 102 102 asmlinkage void do_syscall_trace_leave(struct pt_regs *regs); 103 103 104 - static inline int syscall_get_arch(void) 104 + static inline int syscall_get_arch(struct task_struct *task) 105 105 { 106 106 return AUDIT_ARCH_MICROBLAZE; 107 107 }
+3 -3
arch/mips/include/asm/syscall.h
··· 140 140 extern const unsigned long sys32_call_table[]; 141 141 extern const unsigned long sysn32_call_table[]; 142 142 143 - static inline int syscall_get_arch(void) 143 + static inline int syscall_get_arch(struct task_struct *task) 144 144 { 145 145 int arch = AUDIT_ARCH_MIPS; 146 146 #ifdef CONFIG_64BIT 147 - if (!test_thread_flag(TIF_32BIT_REGS)) { 147 + if (!test_tsk_thread_flag(task, TIF_32BIT_REGS)) { 148 148 arch |= __AUDIT_ARCH_64BIT; 149 149 /* N32 sets only TIF_32BIT_ADDR */ 150 - if (test_thread_flag(TIF_32BIT_ADDR)) 150 + if (test_tsk_thread_flag(task, TIF_32BIT_ADDR)) 151 151 arch |= __AUDIT_ARCH_CONVENTION_MIPS64_N32; 152 152 } 153 153 #endif
+1 -1
arch/mips/kernel/ptrace.c
··· 1418 1418 unsigned long args[6]; 1419 1419 1420 1420 sd.nr = syscall; 1421 - sd.arch = syscall_get_arch(); 1421 + sd.arch = syscall_get_arch(current); 1422 1422 syscall_get_arguments(current, regs, 0, 6, args); 1423 1423 for (i = 0; i < 6; i++) 1424 1424 sd.args[i] = args[i];
+1 -1
arch/nds32/include/asm/syscall.h
··· 188 188 } 189 189 190 190 static inline int 191 - syscall_get_arch(void) 191 + syscall_get_arch(struct task_struct *task) 192 192 { 193 193 return IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) 194 194 ? AUDIT_ARCH_NDS32BE : AUDIT_ARCH_NDS32;
+1 -1
arch/nios2/include/asm/syscall.h
··· 136 136 } 137 137 } 138 138 139 - static inline int syscall_get_arch(void) 139 + static inline int syscall_get_arch(struct task_struct *task) 140 140 { 141 141 return AUDIT_ARCH_NIOS2; 142 142 }
+1 -1
arch/openrisc/include/asm/syscall.h
··· 72 72 memcpy(&regs->gpr[3 + i], args, n * sizeof(args[0])); 73 73 } 74 74 75 - static inline int syscall_get_arch(void) 75 + static inline int syscall_get_arch(struct task_struct *task) 76 76 { 77 77 return AUDIT_ARCH_OPENRISC; 78 78 }
+2 -2
arch/parisc/include/asm/syscall.h
··· 62 62 /* do nothing */ 63 63 } 64 64 65 - static inline int syscall_get_arch(void) 65 + static inline int syscall_get_arch(struct task_struct *task) 66 66 { 67 67 int arch = AUDIT_ARCH_PARISC; 68 68 #ifdef CONFIG_64BIT 69 - if (!is_compat_task()) 69 + if (!__is_compat_task(task)) 70 70 arch = AUDIT_ARCH_PARISC64; 71 71 #endif 72 72 return arch;
+8 -2
arch/powerpc/include/asm/syscall.h
··· 99 99 regs->orig_gpr3 = args[0]; 100 100 } 101 101 102 - static inline int syscall_get_arch(void) 102 + static inline int syscall_get_arch(struct task_struct *task) 103 103 { 104 - int arch = is_32bit_task() ? AUDIT_ARCH_PPC : AUDIT_ARCH_PPC64; 104 + int arch; 105 + 106 + if (IS_ENABLED(CONFIG_PPC64) && !test_tsk_thread_flag(task, TIF_32BIT)) 107 + arch = AUDIT_ARCH_PPC64; 108 + else 109 + arch = AUDIT_ARCH_PPC; 110 + 105 111 #ifdef __LITTLE_ENDIAN__ 106 112 arch |= __AUDIT_ARCH_LE; 107 113 #endif
+1 -1
arch/riscv/include/asm/syscall.h
··· 100 100 memcpy(&regs->a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0)); 101 101 } 102 102 103 - static inline int syscall_get_arch(void) 103 + static inline int syscall_get_arch(struct task_struct *task) 104 104 { 105 105 #ifdef CONFIG_64BIT 106 106 return AUDIT_ARCH_RISCV64;
+2 -2
arch/s390/include/asm/syscall.h
··· 92 92 regs->orig_gpr2 = args[0]; 93 93 } 94 94 95 - static inline int syscall_get_arch(void) 95 + static inline int syscall_get_arch(struct task_struct *task) 96 96 { 97 97 #ifdef CONFIG_COMPAT 98 - if (test_tsk_thread_flag(current, TIF_31BIT)) 98 + if (test_tsk_thread_flag(task, TIF_31BIT)) 99 99 return AUDIT_ARCH_S390; 100 100 #endif 101 101 return AUDIT_ARCH_S390X;
+1 -1
arch/sh/include/asm/syscall_32.h
··· 95 95 } 96 96 } 97 97 98 - static inline int syscall_get_arch(void) 98 + static inline int syscall_get_arch(struct task_struct *task) 99 99 { 100 100 int arch = AUDIT_ARCH_SH; 101 101
+1 -1
arch/sh/include/asm/syscall_64.h
··· 63 63 memcpy(&regs->regs[2 + i], args, n * sizeof(args[0])); 64 64 } 65 65 66 - static inline int syscall_get_arch(void) 66 + static inline int syscall_get_arch(struct task_struct *task) 67 67 { 68 68 int arch = AUDIT_ARCH_SH; 69 69
+3 -2
arch/sparc/include/asm/syscall.h
··· 128 128 regs->u_regs[UREG_I0 + i + j] = args[j]; 129 129 } 130 130 131 - static inline int syscall_get_arch(void) 131 + static inline int syscall_get_arch(struct task_struct *task) 132 132 { 133 133 #if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT) 134 - return in_compat_syscall() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64; 134 + return test_tsk_thread_flag(task, TIF_32BIT) 135 + ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64; 135 136 #elif defined(CONFIG_SPARC64) 136 137 return AUDIT_ARCH_SPARC64; 137 138 #else
+1 -1
arch/unicore32/include/asm/syscall.h
··· 4 4 5 5 #include <uapi/linux/audit.h> 6 6 7 - static inline int syscall_get_arch(void) 7 + static inline int syscall_get_arch(struct task_struct *task) 8 8 { 9 9 return AUDIT_ARCH_UNICORE; 10 10 }
+5 -3
arch/x86/include/asm/syscall.h
··· 107 107 memcpy(&regs->bx + i, args, n * sizeof(args[0])); 108 108 } 109 109 110 - static inline int syscall_get_arch(void) 110 + static inline int syscall_get_arch(struct task_struct *task) 111 111 { 112 112 return AUDIT_ARCH_I386; 113 113 } ··· 236 236 } 237 237 } 238 238 239 - static inline int syscall_get_arch(void) 239 + static inline int syscall_get_arch(struct task_struct *task) 240 240 { 241 241 /* x32 tasks should be considered AUDIT_ARCH_X86_64. */ 242 - return in_ia32_syscall() ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; 242 + return (IS_ENABLED(CONFIG_IA32_EMULATION) && 243 + task->thread_info.status & TS_COMPAT) 244 + ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64; 243 245 } 244 246 #endif /* CONFIG_X86_32 */ 245 247
+1 -1
arch/x86/um/asm/syscall.h
··· 9 9 unsigned long, unsigned long, 10 10 unsigned long, unsigned long); 11 11 12 - static inline int syscall_get_arch(void) 12 + static inline int syscall_get_arch(struct task_struct *task) 13 13 { 14 14 #ifdef CONFIG_X86_32 15 15 return AUDIT_ARCH_I386;
+1 -1
arch/xtensa/include/asm/syscall.h
··· 14 14 #include <asm/ptrace.h> 15 15 #include <uapi/linux/audit.h> 16 16 17 - static inline int syscall_get_arch(void) 17 + static inline int syscall_get_arch(struct task_struct *task) 18 18 { 19 19 return AUDIT_ARCH_XTENSA; 20 20 }
+3 -2
include/asm-generic/syscall.h
··· 144 144 145 145 /** 146 146 * syscall_get_arch - return the AUDIT_ARCH for the current system call 147 + * @task: task of interest, must be blocked 147 148 * 148 149 * Returns the AUDIT_ARCH_* based on the system call convention in use. 149 150 * 150 - * It's only valid to call this when current is stopped on entry to a system 151 + * It's only valid to call this when @task is stopped on entry to a system 151 152 * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %TIF_SECCOMP. 152 153 * 153 154 * Architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must 154 155 * provide an implementation of this. 155 156 */ 156 - int syscall_get_arch(void); 157 + int syscall_get_arch(struct task_struct *task); 157 158 #endif /* _ASM_SYSCALL_H */
+2 -2
kernel/auditsc.c
··· 1636 1636 return; 1637 1637 } 1638 1638 1639 - context->arch = syscall_get_arch(); 1639 + context->arch = syscall_get_arch(current); 1640 1640 context->major = major; 1641 1641 context->argv[0] = a1; 1642 1642 context->argv[1] = a2; ··· 2590 2590 return; 2591 2591 audit_log_task(ab); 2592 2592 audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x", 2593 - signr, syscall_get_arch(), syscall, 2593 + signr, syscall_get_arch(current), syscall, 2594 2594 in_compat_syscall(), KSTK_EIP(current), code); 2595 2595 audit_log_end(ab); 2596 2596 }
+2 -2
kernel/seccomp.c
··· 148 148 unsigned long args[6]; 149 149 150 150 sd->nr = syscall_get_nr(task, regs); 151 - sd->arch = syscall_get_arch(); 151 + sd->arch = syscall_get_arch(task); 152 152 syscall_get_arguments(task, regs, 0, 6, args); 153 153 sd->args[0] = args[0]; 154 154 sd->args[1] = args[1]; ··· 591 591 info->si_code = SYS_SECCOMP; 592 592 info->si_call_addr = (void __user *)KSTK_EIP(current); 593 593 info->si_errno = reason; 594 - info->si_arch = syscall_get_arch(); 594 + info->si_arch = syscall_get_arch(current); 595 595 info->si_syscall = syscall; 596 596 } 597 597