| From: Andrey Konovalov <andreyknvl@google.com> |
| Subject: kasan: better invalid/double-free report header |
| Date: Sun, 11 Sep 2022 01:25:30 +0200 |
| |
| Update the report header for invalid- and double-free bugs to contain the |
| address being freed: |
| |
| BUG: KASAN: invalid-free in kfree+0x280/0x2a8 |
| Free of addr ffff00000beac001 by task kunit_try_catch/99 |
| |
| Link: https://lkml.kernel.org/r/fce40f8dbd160972fe01a1ff39d0c426c310e4b7.1662852281.git.andreyknvl@google.com |
| Signed-off-by: Andrey Konovalov <andreyknvl@google.com> |
| Reviewed-by: Marco Elver <elver@google.com> |
| Cc: Alexander Potapenko <glider@google.com> |
| Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> |
| Cc: Dmitry Vyukov <dvyukov@google.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/kasan/report.c | 23 ++++++++++++++++------- |
| mm/kasan/report_generic.c | 3 ++- |
| mm/kasan/report_tags.c | 2 +- |
| 3 files changed, 19 insertions(+), 9 deletions(-) |
| |
| --- a/mm/kasan/report.c~kasan-better-invalid-double-free-report-header |
| +++ a/mm/kasan/report.c |
| @@ -175,17 +175,14 @@ static void end_report(unsigned long *fl |
| |
| static void print_error_description(struct kasan_report_info *info) |
| { |
| - if (info->type == KASAN_REPORT_INVALID_FREE) { |
| - pr_err("BUG: KASAN: invalid-free in %pS\n", (void *)info->ip); |
| - return; |
| - } |
| + pr_err("BUG: KASAN: %s in %pS\n", info->bug_type, (void *)info->ip); |
| |
| - if (info->type == KASAN_REPORT_DOUBLE_FREE) { |
| - pr_err("BUG: KASAN: double-free in %pS\n", (void *)info->ip); |
| + if (info->type != KASAN_REPORT_ACCESS) { |
| + pr_err("Free of addr %px by task %s/%d\n", |
| + info->access_addr, current->comm, task_pid_nr(current)); |
| return; |
| } |
| |
| - pr_err("BUG: KASAN: %s in %pS\n", info->bug_type, (void *)info->ip); |
| if (info->access_size) |
| pr_err("%s of size %zu at addr %px by task %s/%d\n", |
| info->is_write ? "Write" : "Read", info->access_size, |
| @@ -420,6 +417,18 @@ static void complete_report_info(struct |
| } else |
| info->cache = info->object = NULL; |
| |
| + switch (info->type) { |
| + case KASAN_REPORT_INVALID_FREE: |
| + info->bug_type = "invalid-free"; |
| + break; |
| + case KASAN_REPORT_DOUBLE_FREE: |
| + info->bug_type = "double-free"; |
| + break; |
| + default: |
| + /* bug_type filled in by kasan_complete_mode_report_info. */ |
| + break; |
| + } |
| + |
| /* Fill in mode-specific report info fields. */ |
| kasan_complete_mode_report_info(info); |
| } |
| --- a/mm/kasan/report_generic.c~kasan-better-invalid-double-free-report-header |
| +++ a/mm/kasan/report_generic.c |
| @@ -132,7 +132,8 @@ void kasan_complete_mode_report_info(str |
| struct kasan_alloc_meta *alloc_meta; |
| struct kasan_free_meta *free_meta; |
| |
| - info->bug_type = get_bug_type(info); |
| + if (!info->bug_type) |
| + info->bug_type = get_bug_type(info); |
| |
| if (!info->cache || !info->object) |
| return; |
| --- a/mm/kasan/report_tags.c~kasan-better-invalid-double-free-report-header |
| +++ a/mm/kasan/report_tags.c |
| @@ -37,7 +37,7 @@ void kasan_complete_mode_report_info(str |
| bool is_free; |
| bool alloc_found = false, free_found = false; |
| |
| - if (!info->cache || !info->object) { |
| + if ((!info->cache || !info->object) && !info->bug_type) { |
| info->bug_type = get_common_bug_type(info); |
| return; |
| } |
| _ |