On Tue, 21 May 2019 at 17:53, Alexander Potapenko <glider@xxxxxxxxxx> wrote: > > On Tue, May 21, 2019 at 5:43 PM Andrey Ryabinin <aryabinin@xxxxxxxxxxxxx> wrote: > > > > On 5/20/19 6:47 PM, Marco Elver wrote: > > > > > +static void print_decoded_frame_descr(const char *frame_descr) > > > +{ > > > + /* > > > + * We need to parse the following string: > > > + * "n alloc_1 alloc_2 ... alloc_n" > > > + * where alloc_i looks like > > > + * "offset size len name" > > > + * or "offset size len name:line". > > > + */ > > > + > > > + char token[64]; > > > + unsigned long num_objects; > > > + > > > + if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), > > > + &num_objects)) > > > + return; > > > + > > > + pr_err("\n"); > > > + pr_err("this frame has %lu %s:\n", num_objects, > > > + num_objects == 1 ? "object" : "objects"); > > > + > > > + while (num_objects--) { > > > + unsigned long offset; > > > + unsigned long size; > > > + > > > + /* access offset */ > > > + if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), > > > + &offset)) > > > + return; > > > + /* access size */ > > > + if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), > > > + &size)) > > > + return; > > > + /* name length (unused) */ > > > + if (!tokenize_frame_descr(&frame_descr, NULL, 0, NULL)) > > > + return; > > > + /* object name */ > > > + if (!tokenize_frame_descr(&frame_descr, token, sizeof(token), > > > + NULL)) > > > + return; > > > + > > > + /* Strip line number, if it exists. */ > > > > Why? The filename is not included, and I don't think it adds much in terms of ability to debug; nor is the line number included with all descriptions. I think, the added complexity of separating the line number and parsing is not worthwhile here. Alternatively, I could not pay attention to the line number at all, and leave it as is -- in that case, some variable names will display as "foo:123". > > > > > + strreplace(token, ':', '\0'); > > > + > > > > ... > > > > > + > > > + aligned_addr = round_down((unsigned long)addr, sizeof(long)); > > > + mem_ptr = round_down(aligned_addr, KASAN_SHADOW_SCALE_SIZE); > > > + shadow_ptr = kasan_mem_to_shadow((void *)aligned_addr); > > > + shadow_bottom = kasan_mem_to_shadow(end_of_stack(current)); > > > + > > > + while (shadow_ptr >= shadow_bottom && *shadow_ptr != KASAN_STACK_LEFT) { > > > + shadow_ptr--; > > > + mem_ptr -= KASAN_SHADOW_SCALE_SIZE; > > > + } > > > + > > > + while (shadow_ptr >= shadow_bottom && *shadow_ptr == KASAN_STACK_LEFT) { > > > + shadow_ptr--; > > > + mem_ptr -= KASAN_SHADOW_SCALE_SIZE; > > > + } > > > + > > > > I suppose this won't work if stack grows up, which is fine because it grows up only on parisc arch. > > But "BUILD_BUG_ON(IS_ENABLED(CONFIG_STACK_GROUWSUP))" somewhere wouldn't hurt. > Note that KASAN was broken on parisc from day 1 because of other > assumptions on the stack growth direction hardcoded into KASAN > (e.g. __kasan_unpoison_stack() and __asan_allocas_unpoison()). > So maybe this BUILD_BUG_ON can be added in a separate patch as it's > not specific to what Marco is doing here? Happy to send a follow-up patch, or add here. Let me know what you prefer. Thanks, -- Marco