]> granicus.if.org Git - strace/commitdiff
Fix sigaltstack decoder
authorDmitry V. Levin <ldv@altlinux.org>
Sat, 9 Feb 2013 02:03:04 +0000 (02:03 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sat, 9 Feb 2013 02:03:04 +0000 (02:03 +0000)
strace used to hang when decoding sigaltstack called with invalid
stack_t pointers because of mishandling umove() return code.

* signal.c (print_stack_t): Handle unfetchable stack_t properly.
Change return type to void.
(sys_sigaltstack): Update print_stack_t() usage.

Reported-by: kawillia@ucalgary.ca
signal.c

index 265e929234e42d18ffa7b5fcaf4a2310de53c350..5a4a8d5e894499a5f037e1e4e508d630ed96fa1c 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -1015,33 +1015,31 @@ static const struct xlat sigaltstack_flags[] = {
        { 0,            NULL            },
 };
 
-static int
+static void
 print_stack_t(struct tcb *tcp, unsigned long addr)
 {
        stack_t ss;
-       if (umove(tcp, addr, &ss) < 0)
-               return -1;
-       tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
-       printflags(sigaltstack_flags, ss.ss_flags, "SS_???");
-       tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
-       return 0;
+
+       if (!addr) {
+               tprints("NULL");
+       } else if (umove(tcp, addr, &ss) < 0) {
+               tprintf("%#lx", addr);
+       } else {
+               tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
+               printflags(sigaltstack_flags, ss.ss_flags, "SS_???");
+               tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
+       }
 }
 
 int
 sys_sigaltstack(struct tcb *tcp)
 {
        if (entering(tcp)) {
-               if (tcp->u_arg[0] == 0)
-                       tprints("NULL");
-               else if (print_stack_t(tcp, tcp->u_arg[0]) < 0)
-                       return -1;
+               print_stack_t(tcp, tcp->u_arg[0]);
        }
        else {
                tprints(", ");
-               if (tcp->u_arg[1] == 0)
-                       tprints("NULL");
-               else if (print_stack_t(tcp, tcp->u_arg[1]) < 0)
-                       return -1;
+               print_stack_t(tcp, tcp->u_arg[1]);
        }
        return 0;
 }