Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp496106pxa; Wed, 12 Aug 2020 07:15:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwAaJPrKNCgjUuJD+Vefgw7gEwou60AB4akFCGWijASu6xk+F3K3J3sPkQpkvcjWMho9ATT X-Received: by 2002:a17:907:42cd:: with SMTP id nz21mr2322462ejb.395.1597241715206; Wed, 12 Aug 2020 07:15:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597241715; cv=none; d=google.com; s=arc-20160816; b=Y0fNj2mMX46Gv/qd7wbkUSJwW43ImPj8oXN3r5tmN9ddSjrl9ddAICWrhO6FwNKayp uLVMmcbTw20cl8NAv+B5lAxDZSI5tDT4YRC5RjPeaVET9pt0Gvw20wnYAzkbp9GW7V9p fHUUE6Tlj9Cp52oxYYGuhCLyWQ8OqHoyWMP/uVodywt8Mz2S54Z9DpXGUQaMKRioe1tK u2zBwSpabJPRVzUbvVLBET9zW82M4DdIWg4Sl5WCtsiIHmb/1nNoxATYYjamB7aPG2qX ErNhb9/nqqIoAsQrZFeHdiN9MkQnhEbrMHSk9t/8dat4JEpMKK0zKtPJta84D6c4V+PX 7iBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=Eny7GtW3fheHTjAaLnI+U+IUiSf5L2wZMby5TEt/uUU=; b=g/9tXB9iDBVI+LJ113h6Y1fWGyjTZqG2Ge6XIRKvXYcW4zc9C6nl/7hBFuE5x4SVkI 5Klr4fKZE/2W3smlHaA9NUDNgQHjlZzP5nRX5bu5MMFqSgOmMoHgE1LoE35e4aGKMg27 aoQxfYeMYSRUQ4SXIfICeT2ONTA23Z9JUTPd4Mh4/0BdFr/eqDUeiFr04xCVB3MpgmLT 4IL0Ch0Ixtl4j1mSkpBWN+/Sid0Cuw+AFyvTgSacbrmWeo5qgT13e5lwydth7RRDwcCQ W1hg7uuZJ3ULzYDklSifv8PiLheXIgxzFX1TD5346GpdOvfQQX4K4IdGwTI5ZFSf4sua a4mg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="ZyrDNv/E"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dn20si1921167ejc.104.2020.08.12.07.14.51; Wed, 12 Aug 2020 07:15:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="ZyrDNv/E"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726768AbgHLON0 (ORCPT + 99 others); Wed, 12 Aug 2020 10:13:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44050 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726749AbgHLONX (ORCPT ); Wed, 12 Aug 2020 10:13:23 -0400 Received: from mail-oi1-x241.google.com (mail-oi1-x241.google.com [IPv6:2607:f8b0:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A4F7C061383 for ; Wed, 12 Aug 2020 07:13:23 -0700 (PDT) Received: by mail-oi1-x241.google.com with SMTP id 25so1948872oir.0 for ; Wed, 12 Aug 2020 07:13:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=Eny7GtW3fheHTjAaLnI+U+IUiSf5L2wZMby5TEt/uUU=; b=ZyrDNv/EFXrsfT2cLSeHIYizOdkcvsp1j7OBQ1aowLsdKMYwu3Erh3AfIT0w3ioDCQ KfZPUlQPzSoP+nUFYYYO75TVc/gwd5Pb29VR2AvJEi/zoQ05+n/MwJ7Ce5uYS3rN6mC5 cXGuavRO/u9qGk+OlTcMvNTTf0BH+S3ny3O8O6wGekHkSvY7XaEXxoreGvasTdQuVLLN 9k5KaqttiFGfMl0dKXpl/MS6KmuVwDc0i/TlFUM9bFFdvPTgN2wKkSauEFJWPUhuv+Sh JgKs2SJ/+byaCu7G78QKTwAlQ2T+UHsNjxsoHrSWI9ihc6q1Ecwt9WthXZ8Q5RUtMJ98 Ybrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Eny7GtW3fheHTjAaLnI+U+IUiSf5L2wZMby5TEt/uUU=; b=f2PGY7AxR0JIoFdYzXvDScctQTIvDOTsEIY8eAujSsNFRIyLCi0SLeZVpH+s4nHStw pyokEDKFfOEBRckMX3c3J1WM4CZ6fZlrJ7QrIW/ndwkzV+V2mE7b3b0Yz3cxi3UyrANJ Bk4++tuFQuV248Lzxgxv2lH0Dhjckm8krwV4jdxa+1IQ2uqWEVFk+eXHozuXbIB8VBks ZMtxa5R+YwyU+vK3YuMwtn+pKj3JLO8txUL/bujEjHSLEVFm41iConyLv7j+ngWuwmzQ gvCdlIdLlCye33m6I8TBsy3+RSxPnVT7wJrPbPiji1r8quVhaJdJxmaqeNX0eO+Xrd99 z6ZA== X-Gm-Message-State: AOAM532HDpb2npIo1NivZa1Yuno7KUv2dhX5GND/JLF6krYeiRv9g/k8 7Y2Jj5esiLU9VwR5yVgrVvJXfRpmABUT6ZS+VAQCsQ== X-Received: by 2002:aca:d4d5:: with SMTP id l204mr7728838oig.70.1597241602391; Wed, 12 Aug 2020 07:13:22 -0700 (PDT) MIME-Version: 1.0 References: <20200810072313.529-1-walter-zh.wu@mediatek.com> In-Reply-To: <20200810072313.529-1-walter-zh.wu@mediatek.com> From: Marco Elver Date: Wed, 12 Aug 2020 16:13:09 +0200 Message-ID: Subject: Re: [PATCH 1/5] timer: kasan: record and print timer stack To: Walter Wu Cc: Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Matthias Brugger , John Stultz , Stephen Boyd , Andrew Morton , kasan-dev , Linux Memory Management List , LKML , Linux ARM , wsd_upstream , linux-mediatek@lists.infradead.org, Thomas Gleixner Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 10 Aug 2020 at 09:23, Walter Wu wrote: > This patch records the last two timer queueing stacks and prints > up to 2 timer stacks in KASAN report. It is useful for programmers > to solve use-after-free or double-free memory timer issues. > > When timer_setup() or timer_setup_on_stack() is called, then it > prepares to use this timer and sets timer callback, we store > this call stack in order to print it in KASAN report. > > Signed-off-by: Walter Wu > Cc: Andrey Ryabinin > Cc: Dmitry Vyukov > Cc: Alexander Potapenko > Cc: Thomas Gleixner > Cc: John Stultz > Cc: Stephen Boyd > Cc: Andrew Morton > --- > include/linux/kasan.h | 2 ++ > kernel/time/timer.c | 2 ++ > mm/kasan/generic.c | 21 +++++++++++++++++++++ > mm/kasan/kasan.h | 4 +++- > mm/kasan/report.c | 11 +++++++++++ > 5 files changed, 39 insertions(+), 1 deletion(-) I'm commenting on the code here, but it also applies to patch 2/5, as it's almost a copy-paste. In general, I'd say the solution to get this feature is poorly designed, resulting in excessive LOC added. The logic added already exists for the aux stacks. > diff --git a/include/linux/kasan.h b/include/linux/kasan.h > index 23b7ee00572d..763664b36dc6 100644 > --- a/include/linux/kasan.h > +++ b/include/linux/kasan.h > @@ -175,12 +175,14 @@ 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); > +void kasan_record_tmr_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) {} > +static inline void kasan_record_tmr_stack(void *ptr) {} It appears that the 'aux' stack is currently only used for call_rcu stacks, but this interface does not inherently tie it to call_rcu. The only thing tying it to call_rcu is the fact that the report calls out call_rcu. > /** > diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c > index 4b3cbad7431b..f35dcec990ab 100644 > --- a/mm/kasan/generic.c > +++ b/mm/kasan/generic.c > @@ -347,6 +347,27 @@ void kasan_record_aux_stack(void *addr) > alloc_info->aux_stack[0] = kasan_save_stack(GFP_NOWAIT); > } > > +void kasan_record_tmr_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 timer stacks. > + */ > + alloc_info->tmr_stack[1] = alloc_info->tmr_stack[0]; > + alloc_info->tmr_stack[0] = kasan_save_stack(GFP_NOWAIT); > +} The solution here is, unfortunately, poorly designed. This is a copy-paste of the kasan_record_aux_stack() function. > void kasan_set_free_info(struct kmem_cache *cache, > void *object, u8 tag) > { > diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h > index ef655a1c6e15..c50827f388a3 100644 > --- a/mm/kasan/kasan.h > +++ b/mm/kasan/kasan.h > @@ -108,10 +108,12 @@ struct kasan_alloc_meta { > struct kasan_track alloc_track; > #ifdef CONFIG_KASAN_GENERIC > /* > - * call_rcu() call stack is stored into struct kasan_alloc_meta. > + * call_rcu() call stack and timer queueing stack are stored > + * into struct kasan_alloc_meta. > * The free stack is stored into struct kasan_free_meta. > */ > depot_stack_handle_t aux_stack[2]; > + depot_stack_handle_t tmr_stack[2]; > #else > struct kasan_track free_track[KASAN_NR_FREE_STACKS]; > #endif > diff --git a/mm/kasan/report.c b/mm/kasan/report.c > index fed3c8fdfd25..6fa3bfee381f 100644 > --- a/mm/kasan/report.c > +++ b/mm/kasan/report.c > @@ -191,6 +191,17 @@ static void describe_object(struct kmem_cache *cache, void *object, > print_stack(alloc_info->aux_stack[1]); > pr_err("\n"); > } > + > + if (alloc_info->tmr_stack[0]) { > + pr_err("Last timer stack:\n"); > + print_stack(alloc_info->tmr_stack[0]); > + pr_err("\n"); > + } > + if (alloc_info->tmr_stack[1]) { > + pr_err("Second to last timer stack:\n"); > + print_stack(alloc_info->tmr_stack[1]); > + pr_err("\n"); > + } Why can't we just use the aux stack for everything, and simply change the message printed in the report. After all, the stack trace will include all the information to tell if it's call_rcu, timer, or workqueue. The reporting code would simply have to be changed to say something like "Last potentially related work creation:" -- because what the "aux" thing is trying to abstract are stack traces to work creations that took an address that is closely related. Whether or not you want to call it "work" is up to you, but that's the most generic term I could think of right now (any better terms?). Another argument for this consolidation is that it's highly unlikely that aux_stack[a] && tmr_stack[b] && wq_stack[c], and you need to print all the stacks. If you are worried we need more aux stacks, just make the array size 3+ (but I think it's not necessary). Thanks, -- Marco