From patchwork Tue Oct 18 17:17:04 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: 4265 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp2076081wrs; Tue, 18 Oct 2022 10:29:52 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5nuHwZMNoUNptjIniIQLAf4LAnHn3rLKFAd/NNDO3g582lSKEFNEQdEM/+ifn5PdkCXQ4U X-Received: by 2002:a17:902:bd02:b0:178:1a1c:889 with SMTP id p2-20020a170902bd0200b001781a1c0889mr4229447pls.107.1666114192212; Tue, 18 Oct 2022 10:29:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666114192; cv=none; d=google.com; s=arc-20160816; b=Ov2kYqOzN2YMbTW0i1Gna6JbR5tNZdLJ7OF3FyKe5OnTNz8wCOIYgVlJga5yd2UbhP 5Vtr6UFDTLVdVhj1u7/0SCBwRhv83/WuCfNiNR0fILWlbwdBD2hcuWxzBbBx1cICkZR3 T+9oiRdB3YmAJB/yBRVQ/vIHd0WvqsGmhpIbu+v4G+xkm8ThqtaCVV4X4WmFX5meNepP XuYBE6xpQZ1bUtJiNmwC1aFFKWHWKIU8nIAKSUIDpxXOCBQHoR9wpadB65qa3In4OUUU pKAHai5gPEmVhffe/GUNBwcPS/A1C/0BgbHik3GHzYRq945gPNjDMcBludta7G3ZujfH susA== 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 :message-id:date:subject:cc:to:from:dkim-signature; bh=5qXG9FN8q1BZCzLXn/AJyCLf0ifsZsE4nXpgEgyO44I=; b=wCXJaM9ZOs+vlup1XWWnjUpe3eIf8aBz77rfaYgH2CNT7EvvfWNK2AYwwXoW1gnk+Z LVmldCP9Q0XFwU+GybbynpllRFxsiRIpDswtNsZjs8InnG77VVNqR4mQqacC0AZdkeNi UJU1g/G3tsP4523wtto4XDmxQ9kqsr8hDuCeNAGY/0+lq8Rk94H+7CLSaNJX1mZXIynD VSHYzZ65bSiGGen/kLJ4Vy5rdHCSjIMYiu4yonQstr1X4oMpZJ4gSgud7RCI+hVzVZ6s sKqE7k6SB8M6khEuiYdaoFz0dR4s5rY1z6nfbjjd5jq0ZCBeuQpZl+6yN44NSJL0FZ6t HstQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b="guGKFGP/"; 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 i6-20020a17090ad34600b001fd81d07d0esi14339933pjx.123.2022.10.18.10.29.39; Tue, 18 Oct 2022 10:29:52 -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="guGKFGP/"; 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 S230044AbiJRRRR (ORCPT + 99 others); Tue, 18 Oct 2022 13:17:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229678AbiJRRRM (ORCPT ); Tue, 18 Oct 2022 13:17:12 -0400 Received: from out2.migadu.com (out2.migadu.com [188.165.223.204]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16D2C72864 for ; Tue, 18 Oct 2022 10:17:10 -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=1666113429; 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; bh=5qXG9FN8q1BZCzLXn/AJyCLf0ifsZsE4nXpgEgyO44I=; b=guGKFGP/lx166oSzfSx1vR29JCW6JtRkWlZG/eAGpzqrkKaSFiGPPHTKJ2gDasaX8yg/Yj 7By7hwSct4gEuJq4b6iFnVJBvv0ZcW9hvSQA3yjP44OUK528jDAHTQWbXDJYHb6nUxURZ1 W1imCZcuTePj6DbTwmO+F0uiNzm2lz0= 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 1/3] kasan: switch kunit tests to console tracepoints Date: Tue, 18 Oct 2022 19:17:04 +0200 Message-Id: MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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?1747047355097966299?= X-GMAIL-MSGID: =?utf-8?q?1747047355097966299?= From: Andrey Konovalov Switch KUnit-compatible KASAN tests from using per-task KUnit resources to console tracepoints. This allows for two things: 1. Migrating tests that trigger a KASAN report in the context of a task other than current to KUnit framework. This is implemented in the patches that follow. 2. Parsing and matching the contents of KASAN reports. This is not yet implemented. Reviewed-by: Marco Elver Signed-off-by: Andrey Konovalov --- Changed v2->v3: - Rebased onto 6.1-rc1 Changes v1->v2: - Remove kunit_kasan_status struct definition. --- lib/Kconfig.kasan | 2 +- mm/kasan/kasan.h | 8 ---- mm/kasan/kasan_test.c | 85 +++++++++++++++++++++++++++++++------------ mm/kasan/report.c | 31 ---------------- 4 files changed, 63 insertions(+), 63 deletions(-) diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan index ca09b1cf8ee9..ba5b27962c34 100644 --- a/lib/Kconfig.kasan +++ b/lib/Kconfig.kasan @@ -181,7 +181,7 @@ config KASAN_VMALLOC config KASAN_KUNIT_TEST tristate "KUnit-compatible tests of KASAN bug detection capabilities" if !KUNIT_ALL_TESTS - depends on KASAN && KUNIT + depends on KASAN && KUNIT && TRACEPOINTS default KUNIT_ALL_TESTS help A KUnit-based KASAN test suite. Triggers different kinds of diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index abbcc1b0eec5..a84491bc4867 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -261,14 +261,6 @@ struct kasan_stack_ring { #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */ -#if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) -/* Used in KUnit-compatible KASAN tests. */ -struct kunit_kasan_status { - bool report_found; - bool sync_fault; -}; -#endif - #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) static inline const void *kasan_shadow_to_mem(const void *shadow_addr) diff --git a/mm/kasan/kasan_test.c b/mm/kasan/kasan_test.c index 0d59098f0876..0ff20bfa3376 100644 --- a/mm/kasan/kasan_test.c +++ b/mm/kasan/kasan_test.c @@ -5,8 +5,12 @@ * Author: Andrey Ryabinin */ +#define pr_fmt(fmt) "kasan_test: " fmt + +#include #include #include +#include #include #include #include @@ -14,21 +18,28 @@ #include #include #include +#include #include #include +#include #include -#include #include -#include +#include #include -#include - #include "kasan.h" #define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_GRANULE_SIZE) +static bool multishot; + +/* Fields set based on lines observed in the console. */ +static struct { + bool report_found; + bool async_fault; +} test_status; + /* * Some tests use these global variables to store return values from function * calls that could otherwise be eliminated by the compiler as dead code. @@ -36,35 +47,61 @@ void *kasan_ptr_result; int kasan_int_result; -static struct kunit_resource resource; -static struct kunit_kasan_status test_status; -static bool multishot; +/* Probe for console output: obtains test_status lines of interest. */ +static void probe_console(void *ignore, const char *buf, size_t len) +{ + if (strnstr(buf, "BUG: KASAN: ", len)) + WRITE_ONCE(test_status.report_found, true); + else if (strnstr(buf, "Asynchronous fault: ", len)) + WRITE_ONCE(test_status.async_fault, true); +} -/* - * Temporarily enable multi-shot mode. Otherwise, KASAN would only report the - * first detected bug and panic the kernel if panic_on_warn is enabled. For - * hardware tag-based KASAN also allow tag checking to be reenabled for each - * test, see the comment for KUNIT_EXPECT_KASAN_FAIL(). - */ -static int kasan_test_init(struct kunit *test) +static void register_tracepoints(struct tracepoint *tp, void *ignore) +{ + check_trace_callback_type_console(probe_console); + if (!strcmp(tp->name, "console")) + WARN_ON(tracepoint_probe_register(tp, probe_console, NULL)); +} + +static void unregister_tracepoints(struct tracepoint *tp, void *ignore) +{ + if (!strcmp(tp->name, "console")) + tracepoint_probe_unregister(tp, probe_console, NULL); +} + +static int kasan_suite_init(struct kunit_suite *suite) { if (!kasan_enabled()) { - kunit_err(test, "can't run KASAN tests with KASAN disabled"); + pr_err("Can't run KASAN tests with KASAN disabled"); return -1; } + /* + * Temporarily enable multi-shot mode. Otherwise, KASAN would only + * report the first detected bug and panic the kernel if panic_on_warn + * is enabled. + */ multishot = kasan_save_enable_multi_shot(); - test_status.report_found = false; - test_status.sync_fault = false; - kunit_add_named_resource(test, NULL, NULL, &resource, - "kasan_status", &test_status); + + /* + * Because we want to be able to build the test as a module, we need to + * iterate through all known tracepoints, since the static registration + * won't work here. + */ + for_each_kernel_tracepoint(register_tracepoints, NULL); return 0; } -static void kasan_test_exit(struct kunit *test) +static void kasan_suite_exit(struct kunit_suite *suite) { kasan_restore_multi_shot(multishot); - KUNIT_EXPECT_FALSE(test, test_status.report_found); + for_each_kernel_tracepoint(unregister_tracepoints, NULL); + tracepoint_synchronize_unregister(); +} + +static void kasan_test_exit(struct kunit *test) +{ + KUNIT_EXPECT_FALSE(test, READ_ONCE(test_status.report_found)); } /** @@ -106,11 +143,12 @@ static void kasan_test_exit(struct kunit *test) if (IS_ENABLED(CONFIG_KASAN_HW_TAGS) && \ kasan_sync_fault_possible()) { \ if (READ_ONCE(test_status.report_found) && \ - READ_ONCE(test_status.sync_fault)) \ + !READ_ONCE(test_status.async_fault)) \ kasan_enable_tagging(); \ migrate_enable(); \ } \ WRITE_ONCE(test_status.report_found, false); \ + WRITE_ONCE(test_status.async_fault, false); \ } while (0) #define KASAN_TEST_NEEDS_CONFIG_ON(test, config) do { \ @@ -1447,9 +1485,10 @@ static struct kunit_case kasan_kunit_test_cases[] = { static struct kunit_suite kasan_kunit_test_suite = { .name = "kasan", - .init = kasan_test_init, .test_cases = kasan_kunit_test_cases, .exit = kasan_test_exit, + .suite_init = kasan_suite_init, + .suite_exit = kasan_suite_exit, }; kunit_test_suite(kasan_kunit_test_suite); diff --git a/mm/kasan/report.c b/mm/kasan/report.c index df3602062bfd..31355851a5ec 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -30,8 +30,6 @@ #include -#include - #include "kasan.h" #include "../slab.h" @@ -114,41 +112,12 @@ EXPORT_SYMBOL_GPL(kasan_restore_multi_shot); #endif -#if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) -static void update_kunit_status(bool sync) -{ - struct kunit *test; - struct kunit_resource *resource; - struct kunit_kasan_status *status; - - test = current->kunit_test; - if (!test) - return; - - resource = kunit_find_named_resource(test, "kasan_status"); - if (!resource) { - kunit_set_failure(test); - return; - } - - status = (struct kunit_kasan_status *)resource->data; - WRITE_ONCE(status->report_found, true); - WRITE_ONCE(status->sync_fault, sync); - - kunit_put_resource(resource); -} -#else -static void update_kunit_status(bool sync) { } -#endif - static DEFINE_SPINLOCK(report_lock); static void start_report(unsigned long *flags, bool sync) { /* Respect the /proc/sys/kernel/traceoff_on_warning interface. */ disable_trace_on_warning(); - /* Update status of the currently running KASAN test. */ - update_kunit_status(sync); /* Do not allow LOCKDEP mangling KASAN reports. */ lockdep_off(); /* Make sure we don't end up in loop. */ 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); From patchwork Tue Oct 18 17:17:06 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: 4264 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp2076075wrs; Tue, 18 Oct 2022 10:29:51 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4RKRH91xQOUexePWIF3rIZkbsKhVorZC5oU0cmlk1eezwGkqqh/dctqrwswFPJispVdn8M X-Received: by 2002:a17:90a:e2c3:b0:209:9af2:4e1a with SMTP id fr3-20020a17090ae2c300b002099af24e1amr41688684pjb.44.1666114190382; Tue, 18 Oct 2022 10:29:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666114190; cv=none; d=google.com; s=arc-20160816; b=WOxprqTtrpJKCAaykwLIG7uTF5oJzPw+7IPBHJiqhLlNbzU9vh1dYlvXeUXcbQWHh7 0muCMlj9Qb4v7+Yj7tvYUm1gMwULH0Ko0ZdQIZ/8pVoHgcsHfICgVIHRLlOdLAe7DCFk 0K7B9v1JvIx1aisxtfNor0KRn5FBcA5J4B3nKcTvUKDidfV56ndCMDkkkBMbhDPJCaeP SGVEABkDLkY+ddefZlbiRjNHaLHnfWFxEOywnltGCNfk1bZxetxqHA477VNCcb/sQe6+ jnMMqs0saSd+DsdmR1mX6JhcabwuZpTdcADZuq0HlTxSn+wDf/Av4iStkz+q5x4JBJIK Po8g== 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=7sMEqDPOnA0B1xo/BBovBSGH55UI1F4ZzoT+c6nAvV4=; b=wWwZVlW66JNJ6+4etXqQ/FOu/V+XN8ecobA38KauNBtnNd8JDZQN8mYbuZwo1UIWCb aYqTi5/U6bzouDQjAIRz89wQmJ8M0RolZCDDSj44/CrY9PXri0oKHAvjXKiqMqLVgEsg 1oDRc3a+wPfUQbadZBE17pJhW6FCkT3pe/AvectDysKPt/S58ToqyhGwxpduV0ztscgT mpYq+84tynBoLZLjAuxYGKRbarM66drAwh8Jmpsg0ZZWPHadmCb7cEE1iV+6GCEU3nPC bk+sbw12GVkMnGnGj814Gq0B7c8EBlUxxalss1J/uJ+g4iulgHJNOoMtf7BdkAi93tb3 r2Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=iQpOwSCL; 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 mu7-20020a17090b388700b0020b1f42bf47si17515304pjb.112.2022.10.18.10.29.36; Tue, 18 Oct 2022 10:29:50 -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=iQpOwSCL; 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 S229994AbiJRRRP (ORCPT + 99 others); Tue, 18 Oct 2022 13:17:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229746AbiJRRRN (ORCPT ); Tue, 18 Oct 2022 13:17:13 -0400 Received: from out2.migadu.com (out2.migadu.com [188.165.223.204]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1D73A2A96 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=7sMEqDPOnA0B1xo/BBovBSGH55UI1F4ZzoT+c6nAvV4=; b=iQpOwSCLZjzJ52HhFXaIUvgFQ1sUWc4Sc9mt8RosAmIo8bQnSklMNwaQpWMQIBavCfsZ/X ELYid2RnVBuJjL7uKJah1g3sJuR8mpsKtJhJ7qrO5piVxy2cFIa7J1uhE+kEUOxuE6Gpdp 6D/jHBZckDcxA2Um5/ChnTrtAQsS3Zo= 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 3/3] kasan: migrate workqueue_uaf test to kunit Date: Tue, 18 Oct 2022 19:17:06 +0200 Message-Id: <3a28fa0c89771e47418fb2d5f0e009c83aec5eba.1666113393.git.andreyknvl@google.com> In-Reply-To: References: MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,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?1747047353555664308?= X-GMAIL-MSGID: =?utf-8?q?1747047353555664308?= From: Andrey Konovalov Migrate the workqueue_uaf test to the KUnit framework. Initially, this test was intended to check that Generic KASAN prints auxiliary stack traces for workqueues. Nevertheless, the test is enabled for all modes to make that KASAN reports bad accesses in the tested scenario. 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 | 40 +++++++++++++++++++++++++++++------- mm/kasan/kasan_test_module.c | 30 --------------------------- 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/mm/kasan/kasan_test.c b/mm/kasan/kasan_test.c index 38bf6ed61cb8..e27591ef2777 100644 --- a/mm/kasan/kasan_test.c +++ b/mm/kasan/kasan_test.c @@ -1141,6 +1141,14 @@ static void kmalloc_double_kzfree(struct kunit *test) KUNIT_EXPECT_KASAN_FAIL(test, kfree_sensitive(ptr)); } +/* + * The two tests below check that Generic KASAN prints auxiliary stack traces + * for RCU callbacks and workqueues. The reports need to be inspected manually. + * + * These tests are still enabled for other KASAN modes to make sure that all + * modes report bad accesses in tested scenarios. + */ + static struct kasan_rcu_info { int i; struct rcu_head rcu; @@ -1155,13 +1163,6 @@ static void rcu_uaf_reclaim(struct rcu_head *rp) ((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; @@ -1177,6 +1178,30 @@ static void rcu_uaf(struct kunit *test) rcu_barrier()); } +static void workqueue_uaf_work(struct work_struct *work) +{ + kfree(work); +} + +static void workqueue_uaf(struct kunit *test) +{ + struct workqueue_struct *workqueue; + struct work_struct *work; + + workqueue = create_workqueue("kasan_workqueue_test"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, workqueue); + + work = kmalloc(sizeof(struct work_struct), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, work); + + INIT_WORK(work, workqueue_uaf_work); + queue_work(workqueue, work); + destroy_workqueue(workqueue); + + KUNIT_EXPECT_KASAN_FAIL(test, + ((volatile struct work_struct *)work)->data); +} + static void vmalloc_helpers_tags(struct kunit *test) { void *ptr; @@ -1509,6 +1534,7 @@ static struct kunit_case kasan_kunit_test_cases[] = { KUNIT_CASE(kasan_bitops_tags), KUNIT_CASE(kmalloc_double_kzfree), KUNIT_CASE(rcu_uaf), + KUNIT_CASE(workqueue_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 4688cbcd722d..7be7bed456ef 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 noinline void __init kasan_workqueue_work(struct work_struct *work) -{ - kfree(work); -} - -static noinline void __init kasan_workqueue_uaf(void) -{ - struct workqueue_struct *workqueue; - struct work_struct *work; - - workqueue = create_workqueue("kasan_wq_test"); - if (!workqueue) { - pr_err("Allocation failed\n"); - return; - } - work = kmalloc(sizeof(struct work_struct), GFP_KERNEL); - if (!work) { - pr_err("Allocation failed\n"); - return; - } - - INIT_WORK(work, kasan_workqueue_work); - queue_work(workqueue, work); - destroy_workqueue(workqueue); - - pr_info("use-after-free on workqueue\n"); - ((volatile struct work_struct *)work)->data; -} - static int __init test_kasan_module_init(void) { /* @@ -101,7 +72,6 @@ static int __init test_kasan_module_init(void) bool multishot = kasan_save_enable_multi_shot(); copy_user_test(); - kasan_workqueue_uaf(); kasan_restore_multi_shot(multishot); return -EAGAIN;