From patchwork Tue Oct 18 17:17:05 2022 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: 4266 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp2076256wrs; Tue, 18 Oct 2022 10:30:15 -0700 (PDT) X-Google-Smtp-Source: AMsMyM41E5SUAhLuRKJ99/LJpTzYEm6FC/voN0WA0WQJpMMUMmBbiqm3OmRKw3yEUlzJJmn9hCC6 X-Received: by 2002:a17:90a:d48a:b0:20a:f65b:143c with SMTP id s10-20020a17090ad48a00b0020af65b143cmr4716581pju.199.1666114214912; Tue, 18 Oct 2022 10:30:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666114214; cv=none; d=google.com; s=arc-20160816; b=EHAN8ke0XT70BovIhcPhj6aLL1b0G18p0/03yL51QmV4uuf6vVYIPkb6dlAT+2Fd2z EYxDj9WOVrcm5KSFVPX2ZhkvrTmyTN6BOLD4G1VIlsxTM1M5Kg8e4Vty8vFChCkOnLW/ YRXbVNGiyCyf9abY1Ygd+9lHGEvz7UHuW19RDUtqWlzdaaNc/wmvbhlC0hk8h9c4dyMI zHqY+LPNwufWijD2H+22sXJLr/+0Jif5yCbrHYLnFWhM7Ym1UryjO7Ohb6cIo0NEjmmU 2oY7XP2X4oK2p2cc066aTaTpFy7ILp7O5jKuqgti7IrSlu5mszqloAFUm9z2uMhyKolQ Lw9Q== 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=trOBmB/29htB1a2FV9dsqNXlc3ZPebKRyrhVw3YMtXQ=; b=anYM7PbB4adR9qrj+c9VMDzMYoMDOEY7W1r3jswtymObAoFs2cl/1xrdmRhf8BYecX Kgg9rj8ZE0R+dQAkXF4GljHajFZqmUk5hNzY+W2dxpfckT/hV4HKvxX1XWBmKz4bcPQm WH20u6MeqwtjYbT5Gv5WFuzmc04gpXf+yfoYT5+QDYMmjNVbaO3mIbxYII2ut0So+eTe jxuRhT/gFD5OI8pNW79bg7jBMBy83bL7KDWSjYaAjCV/qmj+jcryRv+PZDh1n/LLs4kF bSbAngVGApQjOvVxU3TBqy0KU/NCzVTtyjmWLFMkvYDTo7/tGNx6PTU3tM1Sa8aELyal i6NA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=nyrPW2sf; 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=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v12-20020a63464c000000b00434f41f6981si15315221pgk.360.2022.10.18.10.30.01; Tue, 18 Oct 2022 10:30:14 -0700 (PDT) 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=@linux.dev header.s=key1 header.b=nyrPW2sf; 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=NONE sp=NONE dis=NONE) header.from=linux.dev Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230087AbiJRRRU (ORCPT + 99 others); Tue, 18 Oct 2022 13:17:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229769AbiJRRRN (ORCPT ); Tue, 18 Oct 2022 13:17:13 -0400 Received: from out2.migadu.com (out2.migadu.com [IPv6:2001:41d0:2:aacc::]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE1BAA2A91 for ; Tue, 18 Oct 2022 10:17:11 -0700 (PDT) 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=1666113430; 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=trOBmB/29htB1a2FV9dsqNXlc3ZPebKRyrhVw3YMtXQ=; b=nyrPW2sfLQ/6svuB36vjGbHjp2XYyDWxhRQ/hiLgKHUBRXU3X4HBsA/NXq4Gww6w2mEnHe Gatq2uYPHNo4uVqzZvlqwRykdvI5k2L/GZdgKPK4IhZp1fF/gyEITSHUNR5QvxMQXVBoNH XTvlwbgOICotjNz6qLLgrCU1XzJ5gHs= From: andrey.konovalov@linux.dev To: Andrew Morton Cc: Andrey Konovalov , Marco Elver , Alexander Potapenko , Dmitry Vyukov , Andrey Ryabinin , kasan-dev@googlegroups.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrey Konovalov Subject: [PATCH v3 2/3] kasan: migrate kasan_rcu_uaf test to kunit Date: Tue, 18 Oct 2022 19:17:05 +0200 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_PASS 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: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747047378588525685?= X-GMAIL-MSGID: =?utf-8?q?1747047378588525685?= From: Andrey Konovalov Migrate the kasan_rcu_uaf test to the KUnit framework. Changes to the implementation of the test: - Call rcu_barrier() after call_rcu() to make that the RCU callbacks get triggered before the test is over. - Cast pointer passed to rcu_dereference_protected as __rcu to get rid of the Sparse warning. - Check that KASAN prints a report via KUNIT_EXPECT_KASAN_FAIL. Initially, this test was intended to check that Generic KASAN prints auxiliary stack traces for RCU objects. Nevertheless, the test is enabled for all modes to make that KASAN reports bad accesses in RCU callbacks. The presence of auxiliary stack traces for the Generic mode needs to be inspected manually. Reviewed-by: Marco Elver Signed-off-by: Andrey Konovalov --- Changed v2->v3: - Rebased onto 6.1-rc1 --- mm/kasan/kasan_test.c | 37 ++++++++++++++++++++++++++++++++++++ mm/kasan/kasan_test_module.c | 30 ----------------------------- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/mm/kasan/kasan_test.c b/mm/kasan/kasan_test.c index 0ff20bfa3376..38bf6ed61cb8 100644 --- a/mm/kasan/kasan_test.c +++ b/mm/kasan/kasan_test.c @@ -1141,6 +1141,42 @@ static void kmalloc_double_kzfree(struct kunit *test) KUNIT_EXPECT_KASAN_FAIL(test, kfree_sensitive(ptr)); } +static struct kasan_rcu_info { + int i; + struct rcu_head rcu; +} *global_rcu_ptr; + +static void rcu_uaf_reclaim(struct rcu_head *rp) +{ + struct kasan_rcu_info *fp = + container_of(rp, struct kasan_rcu_info, rcu); + + kfree(fp); + ((volatile struct kasan_rcu_info *)fp)->i; +} + +/* + * Check that Generic KASAN prints auxiliary stack traces for RCU callbacks. + * The report needs to be inspected manually. + * + * This test is still enabled for other KASAN modes to make sure that all modes + * report bad accesses in tested scenarios. + */ +static void rcu_uaf(struct kunit *test) +{ + struct kasan_rcu_info *ptr; + + ptr = kmalloc(sizeof(struct kasan_rcu_info), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); + + global_rcu_ptr = rcu_dereference_protected( + (struct kasan_rcu_info __rcu *)ptr, NULL); + + KUNIT_EXPECT_KASAN_FAIL(test, + call_rcu(&global_rcu_ptr->rcu, rcu_uaf_reclaim); + rcu_barrier()); +} + static void vmalloc_helpers_tags(struct kunit *test) { void *ptr; @@ -1472,6 +1508,7 @@ static struct kunit_case kasan_kunit_test_cases[] = { KUNIT_CASE(kasan_bitops_generic), KUNIT_CASE(kasan_bitops_tags), KUNIT_CASE(kmalloc_double_kzfree), + KUNIT_CASE(rcu_uaf), KUNIT_CASE(vmalloc_helpers_tags), KUNIT_CASE(vmalloc_oob), KUNIT_CASE(vmap_tags), diff --git a/mm/kasan/kasan_test_module.c b/mm/kasan/kasan_test_module.c index e4ca82dc2c16..4688cbcd722d 100644 --- a/mm/kasan/kasan_test_module.c +++ b/mm/kasan/kasan_test_module.c @@ -62,35 +62,6 @@ static noinline void __init copy_user_test(void) kfree(kmem); } -static struct kasan_rcu_info { - int i; - struct rcu_head rcu; -} *global_rcu_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); - ((volatile struct kasan_rcu_info *)fp)->i; -} - -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_rcu_ptr = rcu_dereference_protected(ptr, NULL); - call_rcu(&global_rcu_ptr->rcu, kasan_rcu_reclaim); -} - static noinline void __init kasan_workqueue_work(struct work_struct *work) { kfree(work); @@ -130,7 +101,6 @@ static int __init test_kasan_module_init(void) bool multishot = kasan_save_enable_multi_shot(); copy_user_test(); - kasan_rcu_uaf(); kasan_workqueue_uaf(); kasan_restore_multi_shot(multishot);