summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2013-02-09 02:03:04 +0000
committerDmitry V. Levin <ldv@altlinux.org>2013-02-09 02:03:04 +0000
commit338c069e69d24424a11ef8ec15b5ac6a8d08c03d (patch)
tree0a721a6d4086250fed849bd63ef01d15ba6c91cc /signal.c
parent0cf04b6595a951df7671eafef5f9e7a114a6c691 (diff)
downloadstrace-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.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/signal.c b/signal.c
index 265e929..5a4a8d5 100644
--- 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;
}