Message ID | 20221118152216.3914899-1-elver@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp263005wrr; Fri, 18 Nov 2022 07:37:41 -0800 (PST) X-Google-Smtp-Source: AA0mqf7raDKHgvvGizqoJNMNqcUxYM4Vo0NnOakcqS0jxNoEJ0B/VvovdqX6xKTQ7FJRyLIRSIa6 X-Received: by 2002:a62:5b05:0:b0:562:c9d0:2c8c with SMTP id p5-20020a625b05000000b00562c9d02c8cmr8443410pfb.44.1668785860826; Fri, 18 Nov 2022 07:37:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668785860; cv=none; d=google.com; s=arc-20160816; b=rgaV2K/10SFF9hmqgvK4yG4U8SW8B+IEVZjLtzeBnMN9m6Nt66hWKIUiFBTF6FmCN8 hYmMexosqLAEtQZOQcgUectHH2oU6bN6mE55Z9rUPWWImXy9PWO+gaTFUvOQtTyYskSi wwSTxYAT8gQik4nIdROdWRbDViDpPToCVRB3nfKaR0fY0mOSW0rh7KDJLJZItzIr5Tug ytdsHSVnaRc0flbII21TWSfpJkZIpT6OFbVrMKFGr6B/OeRqSXkB/ME3t9lFX9oaMhxH o26UcIb1nQHj25S5TzMfY/l7pAeI76Z7qzKdaFjRt1vdTiDuZrYTzAIesJmsZh3B487W WkqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:mime-version:date :dkim-signature; bh=PXs9oQxTshLyON7VsLwg1Sxn4Bm1fEFFQRofp2aAizY=; b=YJc3U8CEmzBxWwL/MWJKN7e9Hk6JlmFChF1KiGxoRwK+mwB2fh0/UmOqs+HYU6r5q4 8nxoQ5ZYmCsbn8Zdp7qs75cIPz4JkTqD2WX1fHltHz2d5UHk8trSZzB3FwUSf054knii Fuh3BUmJcTRFmfCuQuSMblt7e5q245WHserfUf3i1n0k0NjAMFwDH0UNFjuaAPyL3LT2 NWseKmrgpRm2jiHnj2tdvYjSGRzx0eFAM0PbgneX88MIukHUouyb86YG5g2UHKzzS4EV O7T0XXCMCso742She9XBm2TOtEeNiyOZk9D/+qj7usi0w68AwNOXeqU13qlXGP1BAgfa TPtg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=s8dI+I16; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ng18-20020a17090b1a9200b0020d3fa4d1edsi5927317pjb.64.2022.11.18.07.37.27; Fri, 18 Nov 2022 07:37:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=s8dI+I16; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S235327AbiKRPW1 (ORCPT <rfc822;kkmonlee@gmail.com> + 99 others); Fri, 18 Nov 2022 10:22:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235170AbiKRPWX (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 18 Nov 2022 10:22:23 -0500 Received: from mail-ed1-x549.google.com (mail-ed1-x549.google.com [IPv6:2a00:1450:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD6411CB08 for <linux-kernel@vger.kernel.org>; Fri, 18 Nov 2022 07:22:22 -0800 (PST) Received: by mail-ed1-x549.google.com with SMTP id f20-20020a0564021e9400b00461ea0ce17cso3166171edf.16 for <linux-kernel@vger.kernel.org>; Fri, 18 Nov 2022 07:22:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=PXs9oQxTshLyON7VsLwg1Sxn4Bm1fEFFQRofp2aAizY=; b=s8dI+I16xOEuDRsdf4jECwVTSX53sIE6vf0opOeUrkxo9ZQ7kt8qURebrLB39xuPpy oIvI36NbtUXmE9TmXxhhkyxfWZoRqkPYmkL7eedoNbia2Uk6z9P95RDl1QrWFdtbNiRz P5C22iiBvcecS8Akf5SMvRKUNYeSTXKQUXJN7s3nlIqlZmGfaTb1MWZ6xo4kLoBQvtZP tE73/bJFXmnqcH2qI/7zOzicZ5YMN6pZKcLnCmColPwRxGPFT79KtP4waHTCVdAj50FO XlAyrMxA3dW5B3XUIU2gSZ8QxB0JNno13lFk89nlQlotG9nGc3mztDMZrjO7Nc+NHfAs ZSTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=PXs9oQxTshLyON7VsLwg1Sxn4Bm1fEFFQRofp2aAizY=; b=toXQeQEtbR3O6En25WBjdGBWr+5ieYjb1eUj6ruAmtCuI2aFMoPmiA6WL9yGKvk5SX qR5gYGnilz8Vl7rF1yn4Fy4Lw3wO2r+o08tvar7ZURTn0wUdWvYI49su0mwoEVYcs8lS SQHOB2/HiwVXoc91klRCdz/cW5tjh+Wdi8L+Mpwe/tOoQCFHEnTn2mgvu1vIQ5hxxpbK xcTW5C28hnOw924LaTr8LW+FJAne0Dm9T9DnQe/RmdTRYyVWn6WbrDozJpCWxWyFoIMj EYbb5uo1ppRZxe/gMT7LNBPAUsL/nfCmy28geWVCCIMl0VYazwEGn/6BLwvMg4dhpWwS z78g== X-Gm-Message-State: ANoB5pniJRkeri41mfHFoVdkBbympMx7tJnNxbaQUYBlPbfGVQWKofRi sgAFbW/p+9AQYTFsdJgvJBg9ZKmKrg== X-Received: from elver.muc.corp.google.com ([2a00:79e0:9c:201:4799:a943:410e:976]) (user=elver job=sendgmr) by 2002:a05:6402:f11:b0:467:8813:cab5 with SMTP id i17-20020a0564020f1100b004678813cab5mr6512139eda.369.1668784941290; Fri, 18 Nov 2022 07:22:21 -0800 (PST) Date: Fri, 18 Nov 2022 16:22:16 +0100 Mime-Version: 1.0 X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Message-ID: <20221118152216.3914899-1-elver@google.com> Subject: [PATCH] kfence: fix stack trace pruning From: Marco Elver <elver@google.com> To: elver@google.com, Andrew Morton <akpm@linux-foundation.org> Cc: Alexander Potapenko <glider@google.com>, Dmitry Vyukov <dvyukov@google.com>, kasan-dev@googlegroups.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Hyeonggon Yoo <42.hyeyoo@gmail.com>, Feng Tang <feng.tang@intel.com> Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749848802701925930?= X-GMAIL-MSGID: =?utf-8?q?1749848802701925930?= |
Series |
kfence: fix stack trace pruning
|
|
Commit Message
Marco Elver
Nov. 18, 2022, 3:22 p.m. UTC
Commit b14051352465 ("mm/sl[au]b: generalize kmalloc subsystem")
refactored large parts of the kmalloc subsystem, resulting in the stack
trace pruning logic done by KFENCE to no longer work.
While b14051352465 attempted to fix the situation by including
'__kmem_cache_free' in the list of functions KFENCE should skip through,
this only works when the compiler actually optimized the tail call from
kfree() to __kmem_cache_free() into a jump (and thus kfree() _not_
appearing in the full stack trace to begin with).
In some configurations, the compiler no longer optimizes the tail call
into a jump, and __kmem_cache_free() appears in the stack trace. This
means that the pruned stack trace shown by KFENCE would include kfree()
which is not intended - for example:
| BUG: KFENCE: invalid free in kfree+0x7c/0x120
|
| Invalid free of 0xffff8883ed8fefe0 (in kfence-#126):
| kfree+0x7c/0x120
| test_double_free+0x116/0x1a9
| kunit_try_run_case+0x90/0xd0
| [...]
Fix it by moving __kmem_cache_free() to the list of functions that may
be tail called by an allocator entry function, making the pruning logic
work in both the optimized and unoptimized tail call cases.
Fixes: b14051352465 ("mm/sl[au]b: generalize kmalloc subsystem")
Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Cc: Feng Tang <feng.tang@intel.com>
Signed-off-by: Marco Elver <elver@google.com>
---
mm/kfence/report.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
Comments
On Fri, Nov 18, 2022 at 4:22 PM Marco Elver <elver@google.com> wrote: > > Commit b14051352465 ("mm/sl[au]b: generalize kmalloc subsystem") > refactored large parts of the kmalloc subsystem, resulting in the stack > trace pruning logic done by KFENCE to no longer work. > > While b14051352465 attempted to fix the situation by including > '__kmem_cache_free' in the list of functions KFENCE should skip through, > this only works when the compiler actually optimized the tail call from > kfree() to __kmem_cache_free() into a jump (and thus kfree() _not_ > appearing in the full stack trace to begin with). > > In some configurations, the compiler no longer optimizes the tail call > into a jump, and __kmem_cache_free() appears in the stack trace. This > means that the pruned stack trace shown by KFENCE would include kfree() > which is not intended - for example: > > | BUG: KFENCE: invalid free in kfree+0x7c/0x120 > | > | Invalid free of 0xffff8883ed8fefe0 (in kfence-#126): > | kfree+0x7c/0x120 > | test_double_free+0x116/0x1a9 > | kunit_try_run_case+0x90/0xd0 > | [...] > > Fix it by moving __kmem_cache_free() to the list of functions that may > be tail called by an allocator entry function, making the pruning logic > work in both the optimized and unoptimized tail call cases. > > Fixes: b14051352465 ("mm/sl[au]b: generalize kmalloc subsystem") > Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com> > Cc: Feng Tang <feng.tang@intel.com> > Signed-off-by: Marco Elver <elver@google.com> Reviewed-by: Alexander Potapenko <glider@google.com> > --- > mm/kfence/report.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/mm/kfence/report.c b/mm/kfence/report.c > index 7e496856c2eb..46ecea18c4ca 100644 > --- a/mm/kfence/report.c > +++ b/mm/kfence/report.c > @@ -75,18 +75,23 @@ static int get_stack_skipnr(const unsigned long stack_entries[], int num_entries > > if (str_has_prefix(buf, ARCH_FUNC_PREFIX "kfence_") || > str_has_prefix(buf, ARCH_FUNC_PREFIX "__kfence_") || > + str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmem_cache_free") || > !strncmp(buf, ARCH_FUNC_PREFIX "__slab_free", len)) { > /* > - * In case of tail calls from any of the below > - * to any of the above. > + * In case of tail calls from any of the below to any of > + * the above, optimized by the compiler such that the > + * stack trace would omit the initial entry point below. > */ > fallback = skipnr + 1; > } > > - /* Also the *_bulk() variants by only checking prefixes. */ > + /* > + * The below list should only include the initial entry points > + * into the slab allocators. Includes the *_bulk() variants by > + * checking prefixes. > + */ > if (str_has_prefix(buf, ARCH_FUNC_PREFIX "kfree") || > str_has_prefix(buf, ARCH_FUNC_PREFIX "kmem_cache_free") || > - str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmem_cache_free") || > str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmalloc") || > str_has_prefix(buf, ARCH_FUNC_PREFIX "kmem_cache_alloc")) > goto found; > -- > 2.38.1.584.g0f3c55d4c2-goog >
diff --git a/mm/kfence/report.c b/mm/kfence/report.c index 7e496856c2eb..46ecea18c4ca 100644 --- a/mm/kfence/report.c +++ b/mm/kfence/report.c @@ -75,18 +75,23 @@ static int get_stack_skipnr(const unsigned long stack_entries[], int num_entries if (str_has_prefix(buf, ARCH_FUNC_PREFIX "kfence_") || str_has_prefix(buf, ARCH_FUNC_PREFIX "__kfence_") || + str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmem_cache_free") || !strncmp(buf, ARCH_FUNC_PREFIX "__slab_free", len)) { /* - * In case of tail calls from any of the below - * to any of the above. + * In case of tail calls from any of the below to any of + * the above, optimized by the compiler such that the + * stack trace would omit the initial entry point below. */ fallback = skipnr + 1; } - /* Also the *_bulk() variants by only checking prefixes. */ + /* + * The below list should only include the initial entry points + * into the slab allocators. Includes the *_bulk() variants by + * checking prefixes. + */ if (str_has_prefix(buf, ARCH_FUNC_PREFIX "kfree") || str_has_prefix(buf, ARCH_FUNC_PREFIX "kmem_cache_free") || - str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmem_cache_free") || str_has_prefix(buf, ARCH_FUNC_PREFIX "__kmalloc") || str_has_prefix(buf, ARCH_FUNC_PREFIX "kmem_cache_alloc")) goto found;