diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2013-02-09 02:03:04 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2013-02-09 02:03:04 +0000 |
commit | 338c069e69d24424a11ef8ec15b5ac6a8d08c03d (patch) | |
tree | 0a721a6d4086250fed849bd63ef01d15ba6c91cc /signal.c | |
parent | 0cf04b6595a951df7671eafef5f9e7a114a6c691 (diff) | |
download | strace-338c069e69d24424a11ef8ec15b5ac6a8d08c03d.tar.gz strace-338c069e69d24424a11ef8ec15b5ac6a8d08c03d.tar.bz2 strace-338c069e69d24424a11ef8ec15b5ac6a8d08c03d.tar.xz |
Fix sigaltstack decoder
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
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 28 |
1 files changed, 13 insertions, 15 deletions
@@ -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; } |