From 5e56c0d35f21aa4939b98349842e5354825c635c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 15 Sep 2010 22:49:00 +0200 Subject: stack limits dynamic check - fixies based on Akos' comments: - dynamic rlimit stack check - recognize [stack] map arrea and handle it properly --- ChangeLog | 4 ++++ src/stack.c | 50 +++++++++++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8a6c12..2470748 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-09-15 Jiri Olsa + * dynamic rlimit stack check + * recognize [stack] map arrea and handle it properly + 2010-09-07 Jiri Olsa * adding stack limits dynamic check - based on proposal from Akos Pasztory diff --git a/src/stack.c b/src/stack.c index ade5ef9..f38b32c 100644 --- a/src/stack.c +++ b/src/stack.c @@ -11,18 +11,15 @@ static __thread void *stack_end = NULL; static unsigned long get_stack_size(struct lt_config_audit *cfg) { - static unsigned long stack_size = 0; - static struct rlimit rlim; - - if (stack_size) - return stack_size; + struct rlimit rlim; if (getrlimit(RLIMIT_STACK, &rlim)) return 0; - PRINT_VERBOSE(cfg, 1, "stack size: %lx\n", rlim.rlim_cur); + PRINT_VERBOSE(cfg, 1, "stack cur size: %lx, max: %lx\n", + rlim.rlim_cur, rlim.rlim_max); - return stack_size = rlim.rlim_cur; + return rlim.rlim_cur; } /* find and update current stack boundaries */ @@ -32,6 +29,7 @@ static int load_stack(struct lt_config_audit *cfg, void *sp) char line[128]; int found = 0; void *start, *end; + unsigned long stack_size; maps = fopen("/proc/self/maps", "r"); if (!maps) { @@ -40,25 +38,39 @@ static int load_stack(struct lt_config_audit *cfg, void *sp) return -1; } + stack_size = get_stack_size(cfg); + /* XXX any sane idea what to do now ?*/ + if (!stack_size) + return -1; while (!found && fgets(line, sizeof(line), maps)) { - if (1 != sscanf(line, "%*p-%p", &end)) + if (2 != sscanf(line, "%p-%p", &start, &end)) continue; - /* FIXME - * what if the new stack is not GROWSDOWN? - * let's get the limit via RLIMIT_STACK, - * which should be ok for most cases now.. - * - * it does not feel safe/complete, but probably better - * than nothing - */ - start = end - get_stack_size(cfg); + PRINT_VERBOSE(cfg, 1, "line start %p, end %p\n", start, end); + + /* FIXME someone smart please figure out faster way, + * (somehow within the sscanf call?) + * + * Also what if the new stack is not GROWSDOWN, + * bounded by RLIMIT_STACK? + */ + if (strstr(line, "[stack]")) { + void *new_start = end - get_stack_size(cfg); + + /* FIXME weird, need to investigate, looks like the stack + * area could grow more than the stack limit (eg for xpdf) + * + * taking the lower value for now + */ + if (new_start < start) + start = new_start; + } found = ((start < sp) && (sp < end)); - PRINT_VERBOSE(cfg, 1, "start %p, end %p, sp %p, in %d\n", + PRINT_VERBOSE(cfg, 1, "final start %p, end %p, sp %p, in %d\n", start, end, sp, found); } @@ -91,7 +103,7 @@ int lt_stack_framesize(struct lt_config_audit *cfg, La_regs *regs) return framesize; } - /* FIXME what about stacks growing up.. arm might */ + /* FIXME what about stacks growing up.. */ sp_top = sp + framesize; if (sp_top > stack_end) { -- cgit