Browse Source

Fix syscall tampering when PTRACE_GET_SYSCALL_INFO is in use on some architectures

When PTRACE_GET_SYSCALL_INFO is in use on those architectures
that invoke set_regs in arch_set_scno, get_regs is not called,
so it has to be invoked explicitly before tampering.

* linux/arc/set_scno.c (arch_set_scno): Explicitly call get_regs
when PTRACE_GET_SYSCALL_INFO is in use.
* linux/avr32/set_scno.c: Likewise.
* linux/csky/set_scno.c: Likewise.
* linux/ia64/set_scno.c: Likewise.
* linux/m68k/set_scno.c: Likewise.
* linux/metag/set_scno.c: Likewise.
* linux/mips/set_scno.c: Likewise.
* linux/nios2/set_scno.c: Likewise.
* linux/or1k/set_scno.c: Likewise.
* linux/riscv/set_scno.c: Likewise.
* linux/s390/set_scno.c: Likewise.
* linux/sparc/set_scno.c: Likewise.
* linux/tile/set_scno.c: Likewise.
* NEWS: Mention this fix.

Thanks-to: Anatoly Pugachev <matorola@gmail.com>
Fixes: v5.2~27 "sparc, sparc64: fix syscall tampering when PTRACE_GET_SYSCALL_INFO is in use"
Dmitry V. Levin 1 month ago
parent
commit
2b3d59c14b

+ 3
- 0
NEWS View File

@@ -9,6 +9,9 @@ Noteworthy changes in release ?.? (????-??-??)
9 9
     XDP_*, and *_MAGIC constants.
10 10
 
11 11
 * Bug fixes
12
+  * Fixed syscall tampering on arc, avr32, csky, ia64, m68k, metag, mips,
13
+    nios2, or1k, riscv, s390, s390x, sparc, sparc64, and tile architectures
14
+    when PTRACE_GET_SYSCALL_INFO is in use.
12 15
   * Fixed tests on alpha with Linux kernel headers 5.1+.
13 16
 
14 17
 * Portability

+ 2
- 0
linux/arc/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	arc_regs.scratch.r8 = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/avr32/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	avr32_regs.r8 = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/csky/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 #if defined(__CSKYABIV2__)
12 14
 	csky_regs.regs[3] = scno;
13 15
 #else

+ 2
- 1
linux/ia64/set_scno.c View File

@@ -8,7 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	ia64_regs.gr[15] = scno;
12
-
13 14
 	return set_regs(tcp->pid);
14 15
 }

+ 2
- 0
linux/m68k/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	m68k_regs.orig_d0 = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/metag/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	metag_regs.dx[0][1] = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/mips/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	mips_REG_V0 = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/nios2/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	nios2_regs.regs[2] = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/or1k/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	or1k_regs.gpr[11] = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/riscv/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	riscv_regs.a7 = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

+ 2
- 0
linux/s390/set_scno.c View File

@@ -12,6 +12,8 @@
12 12
 static int
13 13
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
14 14
 {
15
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
16
+		return -1;
15 17
 	ARCH_REGSET.gprs[2] = scno;
16 18
 	return set_regs(tcp->pid);
17 19
 }

+ 2
- 0
linux/sparc/set_scno.c View File

@@ -13,6 +13,8 @@
13 13
 static int
14 14
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
15 15
 {
16
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
17
+		return -1;
16 18
 	sparc_regs.u_regs[U_REG_G1] = scno;
17 19
 	return set_regs(tcp->pid);
18 20
 }

+ 2
- 0
linux/tile/set_scno.c View File

@@ -8,6 +8,8 @@
8 8
 static int
9 9
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
10 10
 {
11
+	if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
12
+		return -1;
11 13
 	tile_regs.regs[10] = scno;
12 14
 	return set_regs(tcp->pid);
13 15
 }

Loading…
Cancel
Save