]> granicus.if.org Git - strace/commitdiff
ppc64: truncate syscall args for 32-bit personality tracees
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 20 Sep 2017 00:15:02 +0000 (00:15 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 20 Sep 2017 00:15:02 +0000 (00:15 +0000)
* linux/powerpc/get_syscall_args.c (get_syscall_args): Clear upper
32 bits of syscall args for 32-bit personality tracees.
* NEWS: Mention this fix.

NEWS
linux/powerpc/get_syscall_args.c

diff --git a/NEWS b/NEWS
index 7d08bb73349b64345012f8541b9ef757d1321d6c..6c7f1876123bae862ef93be2492da74c876fa75d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ Noteworthy changes in release ?.?? (????-??-??)
     MEMBARRIER_CMD_*, MFD_*, SO_*, SOL_*, TCP_*, and UFFD_FEATURE_* constants.
   * Updated lists of ioctl commands from Linux 4.14.
 
+* Bug fixes
+  * Fixed powerpc personality support on powerpc64.
+
 Noteworthy changes in release 4.19 (2017-09-05)
 ===============================================
 
index 66bcae31f57d08448840c96c3fea661fbd13cc73..b54377efcf12508ad3b470482d29447005b6bc71 100644 (file)
@@ -2,11 +2,26 @@
 static int
 get_syscall_args(struct tcb *tcp)
 {
-       tcp->u_arg[0] = ppc_regs.orig_gpr3;
-       tcp->u_arg[1] = ppc_regs.gpr[4];
-       tcp->u_arg[2] = ppc_regs.gpr[5];
-       tcp->u_arg[3] = ppc_regs.gpr[6];
-       tcp->u_arg[4] = ppc_regs.gpr[7];
-       tcp->u_arg[5] = ppc_regs.gpr[8];
+       if (current_personality != 0) {
+               /*
+                * Zero-extend from 32 bits.
+                * Use truncate_klong_to_current_wordsize(tcp->u_arg[N])
+                * in syscall handlers
+                * if you need to use *sign-extended* parameter.
+                */
+               tcp->u_arg[0] = (uint32_t) ppc_regs.orig_gpr3;
+               tcp->u_arg[1] = (uint32_t) ppc_regs.gpr[4];
+               tcp->u_arg[2] = (uint32_t) ppc_regs.gpr[5];
+               tcp->u_arg[3] = (uint32_t) ppc_regs.gpr[6];
+               tcp->u_arg[4] = (uint32_t) ppc_regs.gpr[7];
+               tcp->u_arg[5] = (uint32_t) ppc_regs.gpr[8];
+       } else {
+               tcp->u_arg[0] = ppc_regs.orig_gpr3;
+               tcp->u_arg[1] = ppc_regs.gpr[4];
+               tcp->u_arg[2] = ppc_regs.gpr[5];
+               tcp->u_arg[3] = ppc_regs.gpr[6];
+               tcp->u_arg[4] = ppc_regs.gpr[7];
+               tcp->u_arg[5] = ppc_regs.gpr[8];
+       }
        return 1;
 }