From patchwork Fri May 22 02:00:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Walter Wu X-Patchwork-Id: 11564331 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9EE921391 for ; Fri, 22 May 2020 02:01:10 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 5EEA92083E for ; Fri, 22 May 2020 02:01:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="LoLmQVuP" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EEA92083E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 702E080008; Thu, 21 May 2020 22:01:09 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 68C8D80007; Thu, 21 May 2020 22:01:09 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 554C280008; Thu, 21 May 2020 22:01:09 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0218.hostedemail.com [216.40.44.218]) by kanga.kvack.org (Postfix) with ESMTP id 3A24480007 for ; Thu, 21 May 2020 22:01:09 -0400 (EDT) Received: from smtpin03.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id E7DA3180AD820 for ; Fri, 22 May 2020 02:01:08 +0000 (UTC) X-FDA: 76842702216.03.owl34_7e4700d52092d X-Spam-Summary: 2,0,0,462a87acd545a3df,d41d8cd98f00b204,walter-zh.wu@mediatek.com,,RULES_HIT:1:2:41:355:379:421:541:800:960:966:967:973:988:989:1185:1260:1277:1311:1313:1314:1345:1431:1437:1514:1515:1516:1518:1585:1605:1719:1730:1747:1777:1792:1981:2194:2196:2197:2198:2199:2200:2201:2202:2393:2525:2559:2564:2682:2685:2693:2859:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3653:3865:3867:3868:3870:3871:3874:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4049:4250:4321:4385:4605:5007:6119:6261:6653:6737:7514:7903:8660:8784:8957:9010:9025:9592:10004:11026:11218:11473:11658:11914:12043:12048:12049:12291:12296:12297:12438:12521:12555:12698:12737:12895:12986:13148:13230:14394:21080:21212:21221:21347:21451:21627:21772:21939:21990:30054:30070:30075,0,RBL:210.61.82.184:@mediatek.com:.lbl8.mailshell.net-62.2.12.100 64.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:ft,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25 ,LUA_SUM X-HE-Tag: owl34_7e4700d52092d X-Filterd-Recvd-Size: 11627 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by imf03.hostedemail.com (Postfix) with ESMTP for ; Fri, 22 May 2020 02:01:07 +0000 (UTC) X-UUID: 9f0f0c40d8e54e41b1d7ff79c117022a-20200522 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=kry6DzLo7jc9925L70T8XcjXeiprwsgXtu1B1gyF3lw=; b=LoLmQVuP6IERnuIk0LvDmZmXKcgPWDRbk22QO6VPGhwtGOdUQ+NoFB92HEVanjnXShVNTzX+EP1e/elGzZMtMDyQytUvxuT1LXMrhzdqJ+fMIh6SWaFZDc89Wd0lkkb0ZBeqHlv+7+al4By9yZEro0RW6JmQc5D/EUqqkiUArvw=; X-UUID: 9f0f0c40d8e54e41b1d7ff79c117022a-20200522 Received: from mtkcas08.mediatek.inc [(172.21.101.126)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 121922522; Fri, 22 May 2020 10:01:02 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs01n2.mediatek.inc (172.21.101.79) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 22 May 2020 10:01:00 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 22 May 2020 10:00:59 +0800 From: Walter Wu To: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Matthias Brugger , "Paul E . McKenney" , Josh Triplett , Mathieu Desnoyers , Lai Jiangshan , Joel Fernandes , Andrew Morton , Andrey Konovalov CC: , , , , wsd_upstream , , Walter Wu Subject: [PATCH v6 1/4] rcu/kasan: record and print call_rcu() call stack Date: Fri, 22 May 2020 10:00:59 +0800 Message-ID: <20200522020059.22332-1-walter-zh.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-TM-SNTS-SMTP: 2AC2276E087F6D73DD4AF33E2264B3F334C3BE3B77DDB36EB8CAFEB4B585EE532000:8 X-MTK: N X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This feature will record the last two call_rcu() call stacks and prints up to 2 call_rcu() call stacks in KASAN report. When call_rcu() is called, we store the call_rcu() call stack into slub alloc meta-data, so that the KASAN report can print rcu stack. [1]https://bugzilla.kernel.org/show_bug.cgi?id=198437 [2]https://groups.google.com/forum/#!searchin/kasan-dev/better$20stack$20traces$20for$20rcu%7Csort:date/kasan-dev/KQsjT_88hDE/7rNUZprRBgAJ Signed-off-by: Walter Wu Suggested-by: Dmitry Vyukov Acked-by: Paul E. McKenney Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Andrew Morton Cc: Josh Triplett Cc: Mathieu Desnoyers Cc: Lai Jiangshan Cc: Joel Fernandes Cc: Andrey Konovalov --- include/linux/kasan.h | 2 ++ kernel/rcu/tree.c | 2 ++ mm/kasan/common.c | 4 ++-- mm/kasan/generic.c | 21 +++++++++++++++++++++ mm/kasan/kasan.h | 10 ++++++++++ mm/kasan/report.c | 28 +++++++++++++++++++++++----- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 31314ca7c635..23b7ee00572d 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -174,11 +174,13 @@ static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } void kasan_cache_shrink(struct kmem_cache *cache); void kasan_cache_shutdown(struct kmem_cache *cache); +void kasan_record_aux_stack(void *ptr); #else /* CONFIG_KASAN_GENERIC */ static inline void kasan_cache_shrink(struct kmem_cache *cache) {} static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} +static inline void kasan_record_aux_stack(void *ptr) {} #endif /* CONFIG_KASAN_GENERIC */ diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 06548e2ebb72..36a4ff7f320b 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "../time/tick-internal.h" #include "tree.h" @@ -2668,6 +2669,7 @@ __call_rcu(struct rcu_head *head, rcu_callback_t func) head->func = func; head->next = NULL; local_irq_save(flags); + kasan_record_aux_stack(head); rdp = this_cpu_ptr(&rcu_data); /* Add the callback to our list. */ diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 2906358e42f0..8bc618289bb1 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -41,7 +41,7 @@ #include "kasan.h" #include "../slab.h" -static inline depot_stack_handle_t save_stack(gfp_t flags) +depot_stack_handle_t kasan_save_stack(gfp_t flags) { unsigned long entries[KASAN_STACK_DEPTH]; unsigned int nr_entries; @@ -54,7 +54,7 @@ static inline depot_stack_handle_t save_stack(gfp_t flags) static inline void set_track(struct kasan_track *track, gfp_t flags) { track->pid = current->pid; - track->stack = save_stack(flags); + track->stack = kasan_save_stack(flags); } void kasan_enable_current(void) diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index 56ff8885fe2e..8acf48882ba2 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -325,3 +325,24 @@ DEFINE_ASAN_SET_SHADOW(f2); DEFINE_ASAN_SET_SHADOW(f3); DEFINE_ASAN_SET_SHADOW(f5); DEFINE_ASAN_SET_SHADOW(f8); + +void kasan_record_aux_stack(void *addr) +{ + struct page *page = kasan_addr_to_page(addr); + struct kmem_cache *cache; + struct kasan_alloc_meta *alloc_info; + void *object; + + if (!(page && PageSlab(page))) + return; + + cache = page->slab_cache; + object = nearest_obj(cache, page, addr); + alloc_info = get_alloc_info(cache, object); + + /* + * record the last two call_rcu() call stacks. + */ + alloc_info->aux_stack[1] = alloc_info->aux_stack[0]; + alloc_info->aux_stack[0] = kasan_save_stack(GFP_NOWAIT); +} diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index e8f37199d885..a7391bc83070 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -104,7 +104,15 @@ struct kasan_track { struct kasan_alloc_meta { struct kasan_track alloc_track; +#ifdef CONFIG_KASAN_GENERIC + /* + * call_rcu() call stack is stored into struct kasan_alloc_meta. + * The free stack is stored into struct kasan_free_meta. + */ + depot_stack_handle_t aux_stack[2]; +#else struct kasan_track free_track[KASAN_NR_FREE_STACKS]; +#endif #ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY u8 free_pointer_tag[KASAN_NR_FREE_STACKS]; u8 free_track_idx; @@ -159,6 +167,8 @@ void kasan_report_invalid_free(void *object, unsigned long ip); struct page *kasan_addr_to_page(const void *addr); +depot_stack_handle_t kasan_save_stack(gfp_t flags); + #if defined(CONFIG_KASAN_GENERIC) && \ (defined(CONFIG_SLAB) || defined(CONFIG_SLUB)) void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache); diff --git a/mm/kasan/report.c b/mm/kasan/report.c index 80f23c9da6b0..2421a4bd9227 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -105,15 +105,20 @@ static void end_report(unsigned long *flags) kasan_enable_current(); } +static void print_stack(depot_stack_handle_t stack) +{ + unsigned long *entries; + unsigned int nr_entries; + + nr_entries = stack_depot_fetch(stack, &entries); + stack_trace_print(entries, nr_entries, 0); +} + static void print_track(struct kasan_track *track, const char *prefix) { pr_err("%s by task %u:\n", prefix, track->pid); if (track->stack) { - unsigned long *entries; - unsigned int nr_entries; - - nr_entries = stack_depot_fetch(track->stack, &entries); - stack_trace_print(entries, nr_entries, 0); + print_stack(track->stack); } else { pr_err("(stack is not available)\n"); } @@ -192,6 +197,19 @@ static void describe_object(struct kmem_cache *cache, void *object, free_track = kasan_get_free_track(cache, object, tag); print_track(free_track, "Freed"); pr_err("\n"); + +#ifdef CONFIG_KASAN_GENERIC + if (alloc_info->aux_stack[0]) { + pr_err("Last call_rcu():\n"); + print_stack(alloc_info->aux_stack[0]); + pr_err("\n"); + } + if (alloc_info->aux_stack[1]) { + pr_err("Second to last call_rcu():\n"); + print_stack(alloc_info->aux_stack[1]); + pr_err("\n"); + } +#endif } describe_object_addr(cache, object, addr); From patchwork Fri May 22 02:01:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Walter Wu X-Patchwork-Id: 11564339 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 462E690 for ; Fri, 22 May 2020 02:01:39 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 0641E207F7 for ; Fri, 22 May 2020 02:01:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="c0/Vqv2U" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0641E207F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 2710B80009; Thu, 21 May 2020 22:01:38 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 21FBD80007; Thu, 21 May 2020 22:01:38 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 10EC980009; Thu, 21 May 2020 22:01:38 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0040.hostedemail.com [216.40.44.40]) by kanga.kvack.org (Postfix) with ESMTP id EC3E480007 for ; Thu, 21 May 2020 22:01:37 -0400 (EDT) Received: from smtpin06.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id B11823D0F for ; Fri, 22 May 2020 02:01:37 +0000 (UTC) X-FDA: 76842703434.06.care79_8273cb4f9a102 X-Spam-Summary: 2,0,0,6bc2e486caafb0cf,d41d8cd98f00b204,walter-zh.wu@mediatek.com,,RULES_HIT:1:2:41:69:355:379:541:800:960:965:966:967:968:973:988:989:1185:1260:1277:1311:1313:1314:1345:1431:1437:1514:1515:1516:1518:1585:1605:1730:1747:1777:1792:1981:2194:2196:2198:2199:2200:2201:2393:2525:2559:2563:2682:2685:2731:2859:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3872:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4052:4250:4321:4385:4390:4395:4605:5007:6261:6653:8603:8784:9025:9592:10004:11026:11473:11658:11914:12043:12291:12295:12296:12297:12438:12521:12555:12683:12698:12737:12895:12986:14394:21080:21451:21524:21627:21990:30034:30054:30070:30075,0,RBL:210.61.82.184:@mediatek.com:.lbl8.mailshell.net-64.100.201.201 62.2.12.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:ft,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:27,LUA_SUMMARY:none X-HE-Tag: care79_8273cb4f9a102 X-Filterd-Recvd-Size: 14735 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by imf06.hostedemail.com (Postfix) with ESMTP for ; Fri, 22 May 2020 02:01:36 +0000 (UTC) X-UUID: de79162e14814ce886e5b28c7a44c117-20200522 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=ygxU9L+teLE9h+8ckCc3XIvMVVxtE0J3NAV4/iqXpQ0=; b=c0/Vqv2UgSLNKfwITPIb/ysp7DgguXQuLk58OVyxxcpKMAVquidsDKTfAkt5ffCWm8cX2LpaDrZ7/Gl1uMO9F5J4vgBU6OAo9wekLlMWVH+bVQnUfhOvOg+/GjtF0uJozne4jSKfEJKgQ7FQZQkEli491WatH/bk8o2Ku57JAN8=; X-UUID: de79162e14814ce886e5b28c7a44c117-20200522 Received: from mtkcas11.mediatek.inc [(172.21.101.40)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1094467034; Fri, 22 May 2020 10:01:30 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs06n2.mediatek.inc (172.21.101.130) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 22 May 2020 10:01:27 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 22 May 2020 10:01:27 +0800 From: Walter Wu To: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov CC: , , , , wsd_upstream , , Walter Wu Subject: [PATCH v6 2/4] kasan: record and print the free track Date: Fri, 22 May 2020 10:01:27 +0800 Message-ID: <20200522020127.23335-1-walter-zh.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-TM-SNTS-SMTP: C05555AF27A2F975019ED4F7F8AC95149C28085B11B06F35329B9402831811992000:8 X-MTK: N X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Move free track from kasan_alloc_meta to kasan_free_meta in order to make struct kasan_alloc_meta and kasan_free_meta size are both 16 bytes. It is a good size because it is the minimal redzone size and a good number of alignment. For free track, we make some modifications as shown below: 1) Remove the free_track from struct kasan_alloc_meta. 2) Add the free_track into struct kasan_free_meta. 3) Add a macro KASAN_KMALLOC_FREETRACK in order to check whether it can print free stack in KASAN report. [1]https://bugzilla.kernel.org/show_bug.cgi?id=198437 Signed-off-by: Walter Wu Suggested-by: Dmitry Vyukov Co-developed-by: Dmitry Vyukov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Alexander Potapenko --- mm/kasan/common.c | 22 ++-------------------- mm/kasan/generic.c | 22 ++++++++++++++++++++++ mm/kasan/generic_report.c | 1 + mm/kasan/kasan.h | 13 +++++++++++-- mm/kasan/quarantine.c | 1 + mm/kasan/report.c | 26 ++++---------------------- mm/kasan/tags.c | 37 +++++++++++++++++++++++++++++++++++++ 7 files changed, 78 insertions(+), 44 deletions(-) diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 8bc618289bb1..47b53912f322 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -51,7 +51,7 @@ depot_stack_handle_t kasan_save_stack(gfp_t flags) return stack_depot_save(entries, nr_entries, flags); } -static inline void set_track(struct kasan_track *track, gfp_t flags) +void kasan_set_track(struct kasan_track *track, gfp_t flags) { track->pid = current->pid; track->stack = kasan_save_stack(flags); @@ -299,24 +299,6 @@ struct kasan_free_meta *get_free_info(struct kmem_cache *cache, return (void *)object + cache->kasan_info.free_meta_offset; } - -static void kasan_set_free_info(struct kmem_cache *cache, - void *object, u8 tag) -{ - struct kasan_alloc_meta *alloc_meta; - u8 idx = 0; - - alloc_meta = get_alloc_info(cache, object); - -#ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY - idx = alloc_meta->free_track_idx; - alloc_meta->free_pointer_tag[idx] = tag; - alloc_meta->free_track_idx = (idx + 1) % KASAN_NR_FREE_STACKS; -#endif - - set_track(&alloc_meta->free_track[idx], GFP_NOWAIT); -} - void kasan_poison_slab(struct page *page) { unsigned long i; @@ -492,7 +474,7 @@ static void *__kasan_kmalloc(struct kmem_cache *cache, const void *object, KASAN_KMALLOC_REDZONE); if (cache->flags & SLAB_KASAN) - set_track(&get_alloc_info(cache, object)->alloc_track, flags); + kasan_set_track(&get_alloc_info(cache, object)->alloc_track, flags); return set_tag(object, tag); } diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index 8acf48882ba2..4b3cbad7431b 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -346,3 +346,25 @@ void kasan_record_aux_stack(void *addr) alloc_info->aux_stack[1] = alloc_info->aux_stack[0]; alloc_info->aux_stack[0] = kasan_save_stack(GFP_NOWAIT); } + +void kasan_set_free_info(struct kmem_cache *cache, + void *object, u8 tag) +{ + struct kasan_free_meta *free_meta; + + free_meta = get_free_info(cache, object); + kasan_set_track(&free_meta->free_track, GFP_NOWAIT); + + /* + * the object was freed and has free track set + */ + *(u8 *)kasan_mem_to_shadow(object) = KASAN_KMALLOC_FREETRACK; +} + +struct kasan_track *kasan_get_free_track(struct kmem_cache *cache, + void *object, u8 tag) +{ + if (*(u8 *)kasan_mem_to_shadow(object) != KASAN_KMALLOC_FREETRACK) + return NULL; + return &get_free_info(cache, object)->free_track; +} diff --git a/mm/kasan/generic_report.c b/mm/kasan/generic_report.c index e200acb2d292..a38c7a9e192a 100644 --- a/mm/kasan/generic_report.c +++ b/mm/kasan/generic_report.c @@ -80,6 +80,7 @@ static const char *get_shadow_bug_type(struct kasan_access_info *info) break; case KASAN_FREE_PAGE: case KASAN_KMALLOC_FREE: + case KASAN_KMALLOC_FREETRACK: bug_type = "use-after-free"; break; case KASAN_ALLOCA_LEFT: diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index a7391bc83070..ef655a1c6e15 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -17,15 +17,17 @@ #define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */ #define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */ #define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */ +#define KASAN_KMALLOC_FREETRACK 0xFA /* object was freed and has free track set */ #else #define KASAN_FREE_PAGE KASAN_TAG_INVALID #define KASAN_PAGE_REDZONE KASAN_TAG_INVALID #define KASAN_KMALLOC_REDZONE KASAN_TAG_INVALID #define KASAN_KMALLOC_FREE KASAN_TAG_INVALID +#define KASAN_KMALLOC_FREETRACK KASAN_TAG_INVALID #endif -#define KASAN_GLOBAL_REDZONE 0xFA /* redzone for global variable */ -#define KASAN_VMALLOC_INVALID 0xF9 /* unallocated space in vmapped page */ +#define KASAN_GLOBAL_REDZONE 0xF9 /* redzone for global variable */ +#define KASAN_VMALLOC_INVALID 0xF8 /* unallocated space in vmapped page */ /* * Stack redzone shadow values @@ -127,6 +129,9 @@ struct kasan_free_meta { * Otherwise it might be used for the allocator freelist. */ struct qlist_node quarantine_link; +#ifdef CONFIG_KASAN_GENERIC + struct kasan_track free_track; +#endif }; struct kasan_alloc_meta *get_alloc_info(struct kmem_cache *cache, @@ -168,6 +173,10 @@ void kasan_report_invalid_free(void *object, unsigned long ip); struct page *kasan_addr_to_page(const void *addr); depot_stack_handle_t kasan_save_stack(gfp_t flags); +void kasan_set_track(struct kasan_track *track, gfp_t flags); +void kasan_set_free_info(struct kmem_cache *cache, void *object, u8 tag); +struct kasan_track *kasan_get_free_track(struct kmem_cache *cache, + void *object, u8 tag); #if defined(CONFIG_KASAN_GENERIC) && \ (defined(CONFIG_SLAB) || defined(CONFIG_SLUB)) diff --git a/mm/kasan/quarantine.c b/mm/kasan/quarantine.c index 978bc4a3eb51..4c5375810449 100644 --- a/mm/kasan/quarantine.c +++ b/mm/kasan/quarantine.c @@ -145,6 +145,7 @@ static void qlink_free(struct qlist_node *qlink, struct kmem_cache *cache) if (IS_ENABLED(CONFIG_SLAB)) local_irq_save(flags); + *(u8 *)kasan_mem_to_shadow(object) = KASAN_KMALLOC_FREE; ___cache_free(cache, object, _THIS_IP_); if (IS_ENABLED(CONFIG_SLAB)) diff --git a/mm/kasan/report.c b/mm/kasan/report.c index 2421a4bd9227..fed3c8fdfd25 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -164,26 +164,6 @@ static void describe_object_addr(struct kmem_cache *cache, void *object, (void *)(object_addr + cache->object_size)); } -static struct kasan_track *kasan_get_free_track(struct kmem_cache *cache, - void *object, u8 tag) -{ - struct kasan_alloc_meta *alloc_meta; - int i = 0; - - alloc_meta = get_alloc_info(cache, object); - -#ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY - for (i = 0; i < KASAN_NR_FREE_STACKS; i++) { - if (alloc_meta->free_pointer_tag[i] == tag) - break; - } - if (i == KASAN_NR_FREE_STACKS) - i = alloc_meta->free_track_idx; -#endif - - return &alloc_meta->free_track[i]; -} - static void describe_object(struct kmem_cache *cache, void *object, const void *addr, u8 tag) { @@ -195,8 +175,10 @@ static void describe_object(struct kmem_cache *cache, void *object, print_track(&alloc_info->alloc_track, "Allocated"); pr_err("\n"); free_track = kasan_get_free_track(cache, object, tag); - print_track(free_track, "Freed"); - pr_err("\n"); + if (free_track) { + print_track(free_track, "Freed"); + pr_err("\n"); + } #ifdef CONFIG_KASAN_GENERIC if (alloc_info->aux_stack[0]) { diff --git a/mm/kasan/tags.c b/mm/kasan/tags.c index 25b7734e7013..201dee5d6ae0 100644 --- a/mm/kasan/tags.c +++ b/mm/kasan/tags.c @@ -162,3 +162,40 @@ void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size) kasan_poison_shadow((void *)addr, size, tag); } EXPORT_SYMBOL(__hwasan_tag_memory); + +void kasan_set_free_info(struct kmem_cache *cache, + void *object, u8 tag) +{ + struct kasan_alloc_meta *alloc_meta; + u8 idx = 0; + + alloc_meta = get_alloc_info(cache, object); + +#ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY + idx = alloc_meta->free_track_idx; + alloc_meta->free_pointer_tag[idx] = tag; + alloc_meta->free_track_idx = (idx + 1) % KASAN_NR_FREE_STACKS; +#endif + + kasan_set_track(&alloc_meta->free_track[idx], GFP_NOWAIT); +} + +struct kasan_track *kasan_get_free_track(struct kmem_cache *cache, + void *object, u8 tag) +{ + struct kasan_alloc_meta *alloc_meta; + int i = 0; + + alloc_meta = get_alloc_info(cache, object); + +#ifdef CONFIG_KASAN_SW_TAGS_IDENTIFY + for (i = 0; i < KASAN_NR_FREE_STACKS; i++) { + if (alloc_meta->free_pointer_tag[i] == tag) + break; + } + if (i == KASAN_NR_FREE_STACKS) + i = alloc_meta->free_track_idx; +#endif + + return &alloc_meta->free_track[i]; +} From patchwork Fri May 22 02:01:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Walter Wu X-Patchwork-Id: 11564345 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 09E3790 for ; Fri, 22 May 2020 02:02:02 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id CBCFF207F7 for ; Fri, 22 May 2020 02:02:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="H2iF5wuN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CBCFF207F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id E2F328000A; Thu, 21 May 2020 22:02:00 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id DDF6280007; Thu, 21 May 2020 22:02:00 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id CF5518000A; Thu, 21 May 2020 22:02:00 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0027.hostedemail.com [216.40.44.27]) by kanga.kvack.org (Postfix) with ESMTP id B8A4780007 for ; Thu, 21 May 2020 22:02:00 -0400 (EDT) Received: from smtpin04.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 77E13181AEF1A for ; Fri, 22 May 2020 02:02:00 +0000 (UTC) X-FDA: 76842704400.04.loss09_85d8b6915f517 X-Spam-Summary: 2,0,0,d619b8f0a0f97119,d41d8cd98f00b204,walter-zh.wu@mediatek.com,,RULES_HIT:41:355:379:541:800:960:966:973:988:989:1185:1260:1277:1311:1313:1314:1345:1431:1437:1514:1515:1516:1518:1534:1541:1585:1711:1730:1747:1777:1792:2196:2199:2393:2559:2562:2915:3138:3139:3140:3141:3142:3352:3868:3870:3871:3872:4250:4321:4385:5007:6119:6261:6653:7514:8660:10004:10400:10450:10455:11026:11658:11914:12043:12048:12291:12296:12297:12438:12521:12555:12683:12895:13069:13148:13230:13311:13357:14110:14181:14394:14721:19904:19999:21080:21212:21451:21627:21939:21990:30054:30069,0,RBL:210.61.82.184:@mediatek.com:.lbl8.mailshell.net-62.2.12.100 64.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:78,LUA_SUMMARY:none X-HE-Tag: loss09_85d8b6915f517 X-Filterd-Recvd-Size: 4437 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by imf44.hostedemail.com (Postfix) with ESMTP for ; Fri, 22 May 2020 02:01:59 +0000 (UTC) X-UUID: 12f6c77d0e474357b2a3248c96270604-20200522 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=DbdlJu8vuZUyyQAeAhd6YD50kjTkWp9bEKvDh4VAu5A=; b=H2iF5wuNTraJnSdG7Ffis1XK7pyl3iR2z+l9XEAeYzo/8VWbcCPQ68hrW4TGFXoIKLDO22wJOB9a7zmIp0IAS2313vnVCuMbemcW/gwTHv2biWrbg+7MR9KtEuaxOBFxuI8c+jx6DAaiJtfQtb5VuGGVbkNwrl+q6+rPo3mMAUA=; X-UUID: 12f6c77d0e474357b2a3248c96270604-20200522 Received: from mtkcas08.mediatek.inc [(172.21.101.126)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1189950889; Fri, 22 May 2020 10:01:54 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs01n2.mediatek.inc (172.21.101.79) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 22 May 2020 10:01:52 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 22 May 2020 10:01:51 +0800 From: Walter Wu To: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Matthias Brugger CC: , , , , wsd_upstream , , Walter Wu Subject: [PATCH v6 3/4] kasan: add tests for call_rcu stack recording Date: Fri, 22 May 2020 10:01:51 +0800 Message-ID: <20200522020151.23405-1-walter-zh.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-TM-SNTS-SMTP: 1DF83D308094557B8096DD8171A9C524EA3231510A950D2F5EB96F4701E47C662000:8 X-MTK: N X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Test call_rcu() call stack recording and verify whether it correctly is printed in KASAN report. Signed-off-by: Walter Wu Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Matthias Brugger --- lib/test_kasan.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/test_kasan.c b/lib/test_kasan.c index e3087d90e00d..6e5fb05d42d8 100644 --- a/lib/test_kasan.c +++ b/lib/test_kasan.c @@ -792,6 +792,35 @@ static noinline void __init vmalloc_oob(void) static void __init vmalloc_oob(void) {} #endif +static struct kasan_rcu_info { + int i; + struct rcu_head rcu; +} *global_ptr; + +static noinline void __init kasan_rcu_reclaim(struct rcu_head *rp) +{ + struct kasan_rcu_info *fp = container_of(rp, + struct kasan_rcu_info, rcu); + + kfree(fp); + fp->i = 1; +} + +static noinline void __init kasan_rcu_uaf(void) +{ + struct kasan_rcu_info *ptr; + + pr_info("use-after-free in kasan_rcu_reclaim\n"); + ptr = kmalloc(sizeof(struct kasan_rcu_info), GFP_KERNEL); + if (!ptr) { + pr_err("Allocation failed\n"); + return; + } + + global_ptr = rcu_dereference_protected(ptr, NULL); + call_rcu(&global_ptr->rcu, kasan_rcu_reclaim); +} + static int __init kmalloc_tests_init(void) { /* @@ -839,6 +868,7 @@ static int __init kmalloc_tests_init(void) kasan_bitops(); kmalloc_double_kzfree(); vmalloc_oob(); + kasan_rcu_uaf(); kasan_restore_multi_shot(multishot); From patchwork Fri May 22 02:02:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Walter Wu X-Patchwork-Id: 11564351 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 142861391 for ; Fri, 22 May 2020 02:02:20 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id D3848207F7 for ; Fri, 22 May 2020 02:02:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="W4d4mS/l" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D3848207F7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 1F9C28000B; Thu, 21 May 2020 22:02:19 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 182DF80007; Thu, 21 May 2020 22:02:19 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 098F38000B; Thu, 21 May 2020 22:02:19 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0077.hostedemail.com [216.40.44.77]) by kanga.kvack.org (Postfix) with ESMTP id E37B580007 for ; Thu, 21 May 2020 22:02:18 -0400 (EDT) Received: from smtpin20.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id A4B295DDB for ; Fri, 22 May 2020 02:02:18 +0000 (UTC) X-FDA: 76842705156.20.waves96_8878c2bd6143b X-Spam-Summary: 2,0,0,66320411798d406a,d41d8cd98f00b204,walter-zh.wu@mediatek.com,,RULES_HIT:41:355:379:421:541:800:960:973:988:989:1042:1185:1260:1277:1311:1313:1314:1345:1431:1437:1514:1515:1516:1518:1534:1541:1585:1711:1730:1747:1777:1792:1978:1981:2194:2198:2199:2200:2393:2559:2562:2693:2895:3138:3139:3140:3141:3142:3352:3865:3867:3868:3870:3872:3874:4250:5007:6119:6261:6653:8660:10004:10400:11232:11658:11914:12043:12048:12198:12297:12521:12555:12895:13069:13148:13230:13311:13357:14181:14394:14721:21080:21451:21627:21772:21939:30012:30054:30070,0,RBL:210.61.82.184:@mediatek.com:.lbl8.mailshell.net-62.2.12.100 64.100.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: waves96_8878c2bd6143b X-Filterd-Recvd-Size: 3656 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by imf23.hostedemail.com (Postfix) with ESMTP for ; Fri, 22 May 2020 02:02:17 +0000 (UTC) X-UUID: 7421c5cce6cf45d086d0431ffc9b90f3-20200522 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=qIWtxoGuZ5P6mO49eH/CrXHztmv7j3tYchUpE2BMWOE=; b=W4d4mS/lmhxkiGXUku7OiRPcT+PtShkiyBU8ll5t8mWZfJBWYwtCJVK436oJiJF766jBshnlD/DLQB4VKr1W82iwuR4u08y5qbrsc2596txEJ8u7PEhDvh+LwavCy5hx1Jl4ZIEIb2WSENR0+YSMdI+/xZlyqney+VETXWo6QKo=; X-UUID: 7421c5cce6cf45d086d0431ffc9b90f3-20200522 Received: from mtkcas08.mediatek.inc [(172.21.101.126)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 944133403; Fri, 22 May 2020 10:02:14 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs06n2.mediatek.inc (172.21.101.130) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 22 May 2020 10:02:11 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 22 May 2020 10:02:12 +0800 From: Walter Wu To: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Jonathan Corbet CC: , , , , wsd_upstream , , Walter Wu Subject: [PATCH v6 4/4] kasan: update documentation for generic kasan Date: Fri, 22 May 2020 10:02:12 +0800 Message-ID: <20200522020212.23460-1-walter-zh.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-TM-SNTS-SMTP: 96CB23A265DA29919D6ADF75D54BB85AE65E7498DE570CC72449AA74EB4B50CD2000:8 X-MTK: N X-Bogosity: Ham, tests=bogofilter, spamicity=0.023764, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Generic KASAN will support to record the last two call_rcu() call stacks and print them in KASAN report. So that need to update documentation. Signed-off-by: Walter Wu Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Jonathan Corbet --- Documentation/dev-tools/kasan.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst index c652d740735d..fede42e6536b 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -193,6 +193,9 @@ function calls GCC directly inserts the code to check the shadow memory. This option significantly enlarges kernel but it gives x1.1-x2 performance boost over outline instrumented kernel. +Generic KASAN prints up to 2 call_rcu() call stacks in reports, the last one +and the second to last. + Software tag-based KASAN ~~~~~~~~~~~~~~~~~~~~~~~~