From patchwork Thu Dec 14 00:47:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: andrey.konovalov@linux.dev X-Patchwork-Id: 178390 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:3b04:b0:fb:cd0c:d3e with SMTP id c4csp8222809dys; Wed, 13 Dec 2023 16:48:21 -0800 (PST) X-Google-Smtp-Source: AGHT+IEVfUQxJLgLtpW8G5ZFbyj7x/9f1Se/eSL6f6KsfXPfFyXoiF0CfihbzjF3aDHMCryEj7bS X-Received: by 2002:a05:6870:315:b0:1fa:f68b:8b9c with SMTP id m21-20020a056870031500b001faf68b8b9cmr9734015oaf.34.1702514901184; Wed, 13 Dec 2023 16:48:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702514901; cv=none; d=google.com; s=arc-20160816; b=x9H4i6VQR8LNK490DNQcYo6QMSvDAxXWuSHQY9AnW7PVYeFLdnQZ/ivTc7COIoO/7i UpaOFJVj09wvaw1FJE//499Z2FKF24I6PyQ9yagY9v1wNL99XM76B+Sb08L7NYVAebHf zmyWWdEjAFXmGjCME5/Jp+SVdCLTuZ31AcIumQu961A6omEtuyjLQ5vxUwmO5neezIkw g1P5e2xAOlv7QnqIF/ujUz458CV0IXjPDwUCMe8Rwj8ClzQXUEr/vGsGplPp4oUil5N1 1TLoV2EMxn6NbUwh1riFGC9qC0gmiUmdXpgHGOUOMmikUHUrvbMG0CJiRTnhqo3RY/A0 0SPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=8YssiUYIuDBfUgViHa8UWZbb+o2fPyHhfOU9iGYPOo4=; fh=xumGgQ3/A3VHYu1DQDaIWA+Xl29EI5lD+bm6U+z1O60=; b=l01mrL3ftJDy9S249av5M28ybLjZi7Y41N94hVxR3nC8hxU5b1PrUCjY/UL4HucNm1 LCQILwOJtyQGumHq0YQ0jO791b3sX1hApz+K8XPUFx/zL9IUOIjA2FV7tqYmgjuzYl3c vxhg3gcOx3yNkkxa6rhx2Vf/gDz4DgdzADeyMJhC+7JP46L+jGroSDElS7E5+vr0psdS VMmoDh4H5r/bzcRM/CeMlf3GqBloPVMxcobYgFgdWsAV9X4cO0lgjV8PSttvktPE95l3 CmK5bQ9cUHbRXC7nehME916xrDtsl4RAM7JTN1xvNNGwd46MBl9gigDKLDdbP/n27veO 1g3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=ukeh5H64; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id m7-20020a635807000000b005bdf5961826si10118900pgb.136.2023.12.13.16.48.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Dec 2023 16:48:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=ukeh5H64; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 8E5758022C4A; Wed, 13 Dec 2023 16:48:13 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442905AbjLNAr7 (ORCPT + 99 others); Wed, 13 Dec 2023 19:47:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234109AbjLNArz (ORCPT ); Wed, 13 Dec 2023 19:47:55 -0500 Received: from out-176.mta1.migadu.com (out-176.mta1.migadu.com [95.215.58.176]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1510E9A for ; Wed, 13 Dec 2023 16:48:02 -0800 (PST) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1702514880; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8YssiUYIuDBfUgViHa8UWZbb+o2fPyHhfOU9iGYPOo4=; b=ukeh5H64ggk42fU3s6NTf9eHd2GIMqqgZ/CqDcfXQdJSfR4jhY5GxkoRPyps3uU323JLgZ TniRsk/5uPbcuJZvJRywDrgPNugzxiX76SI4CJMOmkh/ZLwplUIxY/5qcBKDt2czbq/Gkx jFr5MxIf7T+y9Q0QrUq8z27yYq8OoyQ= From: andrey.konovalov@linux.dev To: Andrew Morton Cc: Andrey Konovalov , Marco Elver , Alexander Potapenko , Dmitry Vyukov , Vlastimil Babka , kasan-dev@googlegroups.com, Evgenii Stepanov , Tetsuo Handa , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrey Konovalov , syzbot+186b55175d8360728234@syzkaller.appspotmail.com Subject: [PATCH -v2 mm 2/4] kasan: handle concurrent kasan_record_aux_stack calls Date: Thu, 14 Dec 2023 01:47:52 +0100 Message-Id: <88fc85e2a8cca03f2bfcae76100d1a3d54eac840.1702514411.git.andreyknvl@google.com> In-Reply-To: References: MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Wed, 13 Dec 2023 16:48:13 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785216265285001831 X-GMAIL-MSGID: 1785216265285001831 From: Andrey Konovalov kasan_record_aux_stack can be called concurrently on the same object. This might lead to a race condition when rotating the saved aux stack trace handles, which in turns leads to incorrect accounting of stack depot handles and refcount underflows in the stack depot code. Fix by introducing a spinlock to protect the aux stack trace handles in kasan_record_aux_stack. Reported-by: Tetsuo Handa Reported-by: syzbot+186b55175d8360728234@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/000000000000784b1c060b0074a2@google.com/ Fixes: 773688a6cb24 ("kasan: use stack_depot_put for Generic mode") Signed-off-by: Andrey Konovalov --- Changes v1->v2: - Use per-object spinlock instead of a global one. --- mm/kasan/generic.c | 32 +++++++++++++++++++++++++++++--- mm/kasan/kasan.h | 2 ++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index 54e20b2bc3e1..b9d41d6c70fd 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -471,8 +472,18 @@ void kasan_init_object_meta(struct kmem_cache *cache, const void *object) struct kasan_free_meta *free_meta; alloc_meta = kasan_get_alloc_meta(cache, object); - if (alloc_meta) + if (alloc_meta) { __memset(alloc_meta, 0, sizeof(*alloc_meta)); + + /* + * Temporarily disable KASAN bug reporting to allow instrumented + * spin_lock_init to access aux_lock, which resides inside of a + * redzone. + */ + kasan_disable_current(); + spin_lock_init(&alloc_meta->aux_lock); + kasan_enable_current(); + } free_meta = kasan_get_free_meta(cache, object); if (free_meta) __memset(free_meta, 0, sizeof(*free_meta)); @@ -502,6 +513,8 @@ static void __kasan_record_aux_stack(void *addr, depot_flags_t depot_flags) struct kmem_cache *cache; struct kasan_alloc_meta *alloc_meta; void *object; + depot_stack_handle_t new_handle, old_handle; + unsigned long flags; if (is_kfence_address(addr) || !slab) return; @@ -512,9 +525,22 @@ static void __kasan_record_aux_stack(void *addr, depot_flags_t depot_flags) if (!alloc_meta) return; - stack_depot_put(alloc_meta->aux_stack[1]); + new_handle = kasan_save_stack(0, depot_flags); + + /* + * Temporarily disable KASAN bug reporting to allow instrumented + * spinlock functions to access aux_lock, which resides inside of a + * redzone. + */ + kasan_disable_current(); + spin_lock_irqsave(&alloc_meta->aux_lock, flags); + old_handle = alloc_meta->aux_stack[1]; alloc_meta->aux_stack[1] = alloc_meta->aux_stack[0]; - alloc_meta->aux_stack[0] = kasan_save_stack(0, depot_flags); + alloc_meta->aux_stack[0] = new_handle; + spin_unlock_irqrestore(&alloc_meta->aux_lock, flags); + kasan_enable_current(); + + stack_depot_put(old_handle); } void kasan_record_aux_stack(void *addr) diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 5e298e3ac909..8b4125fecdc7 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) @@ -249,6 +250,7 @@ struct kasan_global { struct kasan_alloc_meta { struct kasan_track alloc_track; /* Free track is stored in kasan_free_meta. */ + spinlock_t aux_lock; depot_stack_handle_t aux_stack[2]; };