]> granicus.if.org Git - strace/commitdiff
Fix syscall tampering when PTRACE_GET_SYSCALL_INFO is in use on some architectures
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 15 Aug 2019 20:23:19 +0000 (20:23 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 15 Aug 2019 20:23:19 +0000 (20:23 +0000)
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"
14 files changed:
NEWS
linux/arc/set_scno.c
linux/avr32/set_scno.c
linux/csky/set_scno.c
linux/ia64/set_scno.c
linux/m68k/set_scno.c
linux/metag/set_scno.c
linux/mips/set_scno.c
linux/nios2/set_scno.c
linux/or1k/set_scno.c
linux/riscv/set_scno.c
linux/s390/set_scno.c
linux/sparc/set_scno.c
linux/tile/set_scno.c

diff --git a/NEWS b/NEWS
index 17125b8d9fa704257daf0e5b2e1766ecad9c2afa..a23b361b2c2296da1536598d57a4a2d6d8b6d126 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@ Noteworthy changes in release ?.? (????-??-??)
     XDP_*, and *_MAGIC constants.
 
 * Bug fixes
+  * Fixed syscall tampering on arc, avr32, csky, ia64, m68k, metag, mips,
+    nios2, or1k, riscv, s390, s390x, sparc, sparc64, and tile architectures
+    when PTRACE_GET_SYSCALL_INFO is in use.
   * Fixed tests on alpha with Linux kernel headers 5.1+.
 
 * Portability
index adbf218ec660f87ea4a3590907eb9c9914730438..5314e87fa9439e1f927756948b16e57acdd94573 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        arc_regs.scratch.r8 = scno;
        return set_regs(tcp->pid);
 }
index da218f4a7e6641f708ae06f6c1efb60d8de5da63..56c84abf9f3f7cee82d62a18b75a42ab02911356 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        avr32_regs.r8 = scno;
        return set_regs(tcp->pid);
 }
index 1f043caf750a80f35ed3a0ea6e7de75565567b49..655d108f7dc77aa97d01c911a1d5a00e45a1d7b8 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
 #if defined(__CSKYABIV2__)
        csky_regs.regs[3] = scno;
 #else
index c1c89df9ac943f6f652381b4851bd82cc80562ff..ff6c359d2ba377250f040296ca484afdf5a9ff4e 100644 (file)
@@ -8,7 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        ia64_regs.gr[15] = scno;
-
        return set_regs(tcp->pid);
 }
index 84e8835c7c7f250308efb2158e17641ba9ff4228..8e748a0ba90a6252abec12d35facf1e087997f38 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        m68k_regs.orig_d0 = scno;
        return set_regs(tcp->pid);
 }
index 08dc3cd99c332c8c01a2cb74b049a2c8a861bcb4..59206e1d9e5b0856afdbf00465bcf474fb2a6efd 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        metag_regs.dx[0][1] = scno;
        return set_regs(tcp->pid);
 }
index ad3125836d477966792581cf096d6002f5880413..db572c4e41c00843de324f97a509d505cc5ba58d 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        mips_REG_V0 = scno;
        return set_regs(tcp->pid);
 }
index 64f226b16c4c95edb625dba09fc2412ec4e07dae..e79b1cd24bfc1b5f4fe45f8666e4ddf2d0a4c0f7 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        nios2_regs.regs[2] = scno;
        return set_regs(tcp->pid);
 }
index df2c5ad8e0c8d9c18a549f6a7d6ebced6302848c..ca72f92e944f7a06da926fdcd3fdf706d42ce2e7 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        or1k_regs.gpr[11] = scno;
        return set_regs(tcp->pid);
 }
index 2c586ee95d687fb2aea5cf91222771327e4f00e8..6e3272c5ccdc84c798b8f9a7e8116308c1b79b45 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        riscv_regs.a7 = scno;
        return set_regs(tcp->pid);
 }
index 650deecb841c5402e4e8dca2c1dbac1861167584..bb533591ff69f0fcb4dc5ebc962fe5a90cb158c0 100644 (file)
@@ -12,6 +12,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        ARCH_REGSET.gprs[2] = scno;
        return set_regs(tcp->pid);
 }
index 813fc3a0fdd93e3bef3632a321615cc9b206709a..5aa282c81ab0e04667466028a1cf2b2f93a516d6 100644 (file)
@@ -13,6 +13,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        sparc_regs.u_regs[U_REG_G1] = scno;
        return set_regs(tcp->pid);
 }
index c1ab0d55c0eec3cd764f5a99af098f62f9dd811b..6def5f4c96374d42e1b1e5a956aafb57d0ad2b41 100644 (file)
@@ -8,6 +8,8 @@
 static int
 arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
 {
+       if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+               return -1;
        tile_regs.regs[10] = scno;
        return set_regs(tcp->pid);
 }