From: Yeoreum Yun <yeoreum.yun@arm.com>
To: Andrey Konovalov <andreyknvl@gmail.com>
Cc: ryabinin.a.a@gmail.com, glider@google.com, dvyukov@google.com,
vincenzo.frascino@arm.com, corbet@lwn.net,
catalin.marinas@arm.com, will@kernel.org,
akpm@linux-foundation.org, scott@os.amperecomputing.com,
jhubbard@nvidia.com, pankaj.gupta@amd.com, leitao@debian.org,
kaleshsingh@google.com, maz@kernel.org, broonie@kernel.org,
oliver.upton@linux.dev, james.morse@arm.com, ardb@kernel.org,
hardevsinh.palaniya@siliconsignals.io, david@redhat.com,
yang@os.amperecomputing.com, kasan-dev@googlegroups.com,
workflows@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org
Subject: Re: [PATCH v2 2/2] kasan: apply store-only mode in kasan kunit testcases
Date: Thu, 14 Aug 2025 12:13:50 +0100 [thread overview]
Message-ID: <aJ3E7u5ENWTjC4ZM@e129823.arm.com> (raw)
In-Reply-To: <CA+fCnZeT2J7W62Ydv0AuDLC13wO-VrH1Q_uqhkZbGLqc4Ktf5g@mail.gmail.com>
Hi Andrey,
> >
> > When KASAN is configured in store-only mode,
> > fetch/load operations do not trigger tag check faults.
> >
> > As a result, the outcome of some test cases may differ
> > compared to when KASAN is configured without store-only mode.
> >
> > Therefore, by modifying pre-exist testcases
> > check the store only makes tag check fault (TCF) where
> > writing is perform in "allocated memory" but tag is invalid
> > (i.e) redzone write in atomic_set() testcases.
> > Otherwise check the invalid fetch/read doesn't generate TCF.
> >
> > Also, skip some testcases affected by initial value
> > (i.e) atomic_cmpxchg() testcase maybe successd if
> > it passes valid atomic_t address and invalid oldaval address.
> > In this case, if invalid atomic_t doesn't have the same oldval,
> > it won't trigger store operation so the test will pass.
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > ---
> > mm/kasan/kasan_test_c.c | 366 +++++++++++++++++++++++++++++++---------
> > 1 file changed, 286 insertions(+), 80 deletions(-)
> >
> > diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c
> > index 2aa12dfa427a..e5d08a6ee3a2 100644
> > --- a/mm/kasan/kasan_test_c.c
> > +++ b/mm/kasan/kasan_test_c.c
> > @@ -94,11 +94,13 @@ static void kasan_test_exit(struct kunit *test)
> > }
> >
> > /**
> > - * KUNIT_EXPECT_KASAN_FAIL - check that the executed expression produces a
> > - * KASAN report; causes a KUnit test failure otherwise.
> > + * _KUNIT_EXPECT_KASAN_TEMPLATE - check that the executed expression produces
> > + * a KASAN report or not; a KUnit test failure when it's different from @produce.
> > *
> > * @test: Currently executing KUnit test.
> > - * @expression: Expression that must produce a KASAN report.
> > + * @expr: Expression produce a KASAN report or not.
> > + * @expr_str: Expression string
> > + * @produce: expression should produce a KASAN report.
> > *
> > * For hardware tag-based KASAN, when a synchronous tag fault happens, tag
> > * checking is auto-disabled. When this happens, this test handler reenables
> > @@ -110,25 +112,29 @@ static void kasan_test_exit(struct kunit *test)
> > * Use READ/WRITE_ONCE() for the accesses and compiler barriers around the
> > * expression to prevent that.
> > *
> > - * In between KUNIT_EXPECT_KASAN_FAIL checks, test_status.report_found is kept
> > + * In between _KUNIT_EXPECT_KASAN_TEMPLATE checks, test_status.report_found is kept
> > * as false. This allows detecting KASAN reports that happen outside of the
> > * checks by asserting !test_status.report_found at the start of
> > - * KUNIT_EXPECT_KASAN_FAIL and in kasan_test_exit.
> > + * _KUNIT_EXPECT_KASAN_TEMPLATE and in kasan_test_exit.
> > */
> > -#define KUNIT_EXPECT_KASAN_FAIL(test, expression) do { \
> > +#define _KUNIT_EXPECT_KASAN_TEMPLATE(test, expr, expr_str, produce) \
> > +do { \
> > if (IS_ENABLED(CONFIG_KASAN_HW_TAGS) && \
> > kasan_sync_fault_possible()) \
> > migrate_disable(); \
> > KUNIT_EXPECT_FALSE(test, READ_ONCE(test_status.report_found)); \
> > barrier(); \
> > - expression; \
> > + expr; \
> > barrier(); \
> > if (kasan_async_fault_possible()) \
> > kasan_force_async_fault(); \
> > - if (!READ_ONCE(test_status.report_found)) { \
> > - KUNIT_FAIL(test, KUNIT_SUBTEST_INDENT "KASAN failure " \
> > - "expected in \"" #expression \
> > - "\", but none occurred"); \
> > + if (READ_ONCE(test_status.report_found) != produce) { \
> > + KUNIT_FAIL(test, KUNIT_SUBTEST_INDENT "KASAN %s " \
> > + "expected in \"" expr_str \
> > + "\", but %soccurred", \
> > + (produce ? "failure" : "success"), \
> > + (test_status.report_found ? \
> > + "" : "none ")); \
> > } \
> > if (IS_ENABLED(CONFIG_KASAN_HW_TAGS) && \
> > kasan_sync_fault_possible()) { \
> > @@ -141,6 +147,26 @@ static void kasan_test_exit(struct kunit *test)
> > WRITE_ONCE(test_status.async_fault, false); \
> > } while (0)
> >
> > +/*
> > + * KUNIT_EXPECT_KASAN_FAIL - check that the executed expression produces a
> > + * KASAN report; causes a KUnit test failure otherwise.
> > + *
> > + * @test: Currently executing KUnit test.
> > + * @expr: Expression produce a KASAN report.
> > + */
> > +#define KUNIT_EXPECT_KASAN_FAIL(test, expr) \
> > + _KUNIT_EXPECT_KASAN_TEMPLATE(test, expr, #expr, true)
> > +
> > +/*
> > + * KUNIT_EXPECT_KASAN_SUCCESS - check that the executed expression doesn't
> > + * produces a KASAN report; causes a KUnit test failure otherwise.
>
> Should be no need for this, the existing functionality already checks
> that there are no reports outside of KUNIT_EXPECT_KASAN_FAIL().
This is function's purpose is to print failure situtations:
- KASAN should reports but no report is found.
- KASAN shouldn't report but there report is found.
To print the second error, the "TEMPLATE" macro is added.
not just checking the no report but to check whether report was
generated as expected.
>
> > + *
> > + * @test: Currently executing KUnit test.
> > + * @expr: Expression doesn't produce a KASAN report.
> > + */
> > +#define KUNIT_EXPECT_KASAN_SUCCESS(test, expr) \
> > + _KUNIT_EXPECT_KASAN_TEMPLATE(test, expr, #expr, false)
> > +
> > #define KASAN_TEST_NEEDS_CONFIG_ON(test, config) do { \
> > if (!IS_ENABLED(config)) \
> > kunit_skip((test), "Test requires " #config "=y"); \
> > @@ -183,8 +209,12 @@ static void kmalloc_oob_right(struct kunit *test)
> > KUNIT_EXPECT_KASAN_FAIL(test, ptr[size + 5] = 'y');
> >
> > /* Out-of-bounds access past the aligned kmalloc object. */
> > - KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] =
> > - ptr[size + KASAN_GRANULE_SIZE + 5]);
> > + if (kasan_store_only_enabled())
> > + KUNIT_EXPECT_KASAN_SUCCESS(test, ptr[0] =
> > + ptr[size + KASAN_GRANULE_SIZE + 5]);
> > + else
> > + KUNIT_EXPECT_KASAN_FAIL(test, ptr[0] =
> > + ptr[size + KASAN_GRANULE_SIZE + 5]);
>
> Let's instead add KUNIT_EXPECT_KASAN_FAIL_READ() that only expects a
> KASAN report when the store-only mode is not enabled. And use that for
> the bad read accesses done in tests.
Okay. I rename the KUNIT_EXPECT_KASAN_SUCCESS and integrate it
in the macro. Thanks!
--
Sincerely,
Yeoreum Yun
next prev parent reply other threads:[~2025-08-14 11:14 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-13 17:53 [PATCH v2 0/2] introduce kasan.store_only option in hw-tags Yeoreum Yun
2025-08-13 17:53 ` [PATCH v2 1/2] kasan/hw-tags: introduce kasan.store_only option Yeoreum Yun
2025-08-14 5:03 ` Andrey Konovalov
2025-08-14 8:51 ` Yeoreum Yun
2025-08-15 11:19 ` Catalin Marinas
2025-08-15 11:13 ` Catalin Marinas
2025-08-15 13:51 ` Yeoreum Yun
2025-08-15 15:10 ` Yeoreum Yun
2025-08-15 17:44 ` Catalin Marinas
2025-08-15 14:47 ` Yeoreum Yun
2025-08-15 17:46 ` Catalin Marinas
2025-08-13 17:53 ` [PATCH v2 2/2] kasan: apply store-only mode in kasan kunit testcases Yeoreum Yun
2025-08-14 5:04 ` Andrey Konovalov
2025-08-14 11:13 ` Yeoreum Yun [this message]
2025-08-15 6:14 ` Andrey Konovalov
2025-08-15 8:06 ` Yeoreum Yun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aJ3E7u5ENWTjC4ZM@e129823.arm.com \
--to=yeoreum.yun@arm.com \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=ardb@kernel.org \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=corbet@lwn.net \
--cc=david@redhat.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=hardevsinh.palaniya@siliconsignals.io \
--cc=james.morse@arm.com \
--cc=jhubbard@nvidia.com \
--cc=kaleshsingh@google.com \
--cc=kasan-dev@googlegroups.com \
--cc=leitao@debian.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=pankaj.gupta@amd.com \
--cc=ryabinin.a.a@gmail.com \
--cc=scott@os.amperecomputing.com \
--cc=vincenzo.frascino@arm.com \
--cc=will@kernel.org \
--cc=workflows@vger.kernel.org \
--cc=yang@os.amperecomputing.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox