Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp2630396rwb; Sat, 24 Sep 2022 11:50:47 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6MvZZc0SHOBOsv8ltoL54qil1oc+KmdlcC1CwVWmQ4sNV7QxA1rV1W9tZMDVtD8KCHDZn+ X-Received: by 2002:a63:fa4f:0:b0:438:e26d:5ec with SMTP id g15-20020a63fa4f000000b00438e26d05ecmr12974886pgk.361.1664045447008; Sat, 24 Sep 2022 11:50:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664045447; cv=none; d=google.com; s=arc-20160816; b=i2Y7apWxvhTxDaSuT90WpiSNDotJXVerhHv69Y+wxwgIcd2d7Hl1GgGSD5jvBosw/E o2MiMDXh0Aw+C1RZeOtOQzHCHF7ni8Hqvz1DA7+Pd8GoNgdTOGw+UiG6HfA9+35/Ii9i 90h6c8bNkAyC6l6/RT+oIofdAk6J3g4cFfn3kEoHw2fyQ26MDJsT2WvrjnFD0kpc5qCR kaoWmuzjgtTqE7hrHnrpL2OgHc5ZrT3zwmVGe/0f8vVIHP9tf0f58xYKoN1pngp4AGYM 1OOM5jZ5e59x0kci9EJHpuAD8ZFGde32Ip1iWtOOsk0fZ+07MuUXPWor5rJAwYjYu6vV gdZg== 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=hSHn8pdWEz/EAWLe2z3ri8yOC1WGCkjx3I21+gYS0z4=; b=JRL8KqsWmgG10JdSfYUucNy3EDeXWX7C9eHzWM+eiN5I2HCLX15Co1OzHUw2bpZKlf 9QEryptsWb5Tkj3roFAZrO3nt1sJagXl5JeQsjtkTLqjwqbCmDefNuXcLLkYYzs2wyUx R53e06MSecbxQJay5vIRCDPw2FJxqGWepHg9urksOrij6B7RhILerfHA8NALxqpIMRve wE/vLtyFqffAK1ggvgFRKxY/soom5kr4blQeYhoj1e1DGZjfc3FAKQGUGzvDCnykGEOd GmI0csE/lKk3yIg7H/ouIK9uu5LQeMYpjZ/xt/Yq1pWcicDfrz4CCb1EqM5G3yTiUeKf OpnQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b="wm4LrK/u"; 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id p17-20020a631e51000000b0043bf053c72asi12720120pgm.483.2022.09.24.11.50.35; Sat, 24 Sep 2022 11:50:46 -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="wm4LrK/u"; 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 S233744AbiIXScd (ORCPT + 99 others); Sat, 24 Sep 2022 14:32:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47226 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230017AbiIXScc (ORCPT ); Sat, 24 Sep 2022 14:32:32 -0400 Received: from out2.migadu.com (out2.migadu.com [IPv6:2001:41d0:2:aacc::]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D6BC3A4B1 for ; Sat, 24 Sep 2022 11:32:31 -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=1664044349; 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=hSHn8pdWEz/EAWLe2z3ri8yOC1WGCkjx3I21+gYS0z4=; b=wm4LrK/u//STiB7sxFAPXzhzOrb5u7tdGsFqjfuykHjFsd5KNCqvBIWByfC8kazmxtZWk/ CKxzoj98SET0txBWzTn/8VyxcHmpJe0uFZpdGZzQUYpQ7Agskv7Uq5YKIIdVTTWckblDr+ 5RXF0rS5KNcne9jsHaBZ4ZXHeiGmrx8= From: andrey.konovalov@linux.dev To: Marco Elver , Alexander Potapenko Cc: Andrey Konovalov , Dmitry Vyukov , Andrey Ryabinin , kasan-dev@googlegroups.com, Andrew Morton , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrey Konovalov Subject: [PATCH mm 2/3] kasan: migrate kasan_rcu_uaf test to kunit Date: Sat, 24 Sep 2022 20:31:52 +0200 Message-Id: In-Reply-To: <653d43e9a6d9aad2ae148a941dab048cb8e765a8.1664044241.git.andreyknvl@google.com> References: <653d43e9a6d9aad2ae148a941dab048cb8e765a8.1664044241.git.andreyknvl@google.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Migadu-Auth-User: linux.dev 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 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. Signed-off-by: Andrey Konovalov --- 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 3a2886f85e69..005776325e20 100644 --- a/mm/kasan/kasan_test.c +++ b/mm/kasan/kasan_test.c @@ -1134,6 +1134,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; @@ -1465,6 +1501,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); -- 2.25.1