powerpc: fix syscall tampering when PTRACE_GET_SYSCALL_INFO is in use
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 4 Jul 2019 18:25:49 +0000 (18:25 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 4 Jul 2019 18:25:49 +0000 (18:25 +0000)
When PTRACE_GET_SYSCALL_INFO is in use, CCR is not loaded, so it has
to be loaded explicitly before tampering.

* linux/powerpc/set_error.c (arch_set_error, arch_set_success):
Explicitly load CCR before changing it when PTRACE_GET_SYSCALL_INFO
is in use.
* NEWS: Mention this fix.

NEWS
linux/powerpc/set_error.c

diff --git a/NEWS b/NEWS
index 10612448f2aad9a5e728fff5a8ffd39dcc15920a..84ad39a32b81e16ef1e69123d4aed04dcb9d602a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
 Noteworthy changes in release ?.? (????-??-??)
 ==============================================
 
+* Bug fixes
+  * Fixed syscall tampering on powerpc and powerpc64 when
+    PTRACE_GET_SYSCALL_INFO is in use.
+
 * Improvements
   * Implemented decoding of open_tree, move_mount, fsopen, fsconfig, fsmount,
     and fspick syscalls.
index 9b8a6f2fd39e19e5335defc2ab406761724a2113..068d6b749b028fb5c499cfbcb187da1a75fff41e 100644 (file)
@@ -8,6 +8,9 @@
 static int
 arch_set_error(struct tcb *tcp)
 {
+       if (ptrace_syscall_info_is_valid() &&
+           upeek(tcp, sizeof(long) * PT_CCR, &ppc_regs.ccr))
+                return -1;
        ppc_regs.gpr[3] = tcp->u_error;
        ppc_regs.ccr |= 0x10000000;
        return upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr) ||
@@ -17,6 +20,9 @@ arch_set_error(struct tcb *tcp)
 static int
 arch_set_success(struct tcb *tcp)
 {
+       if (ptrace_syscall_info_is_valid() &&
+           upeek(tcp, sizeof(long) * PT_CCR, &ppc_regs.ccr))
+                return -1;
        ppc_regs.gpr[3] = tcp->u_rval;
        ppc_regs.ccr &= ~0x10000000;
        return upoke(tcp, sizeof(long) * PT_CCR, ppc_regs.ccr) ||