All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alan Maguire <alan.maguire@oracle.com>
To: Patricia Alfonso <trishalfonso@google.com>
Cc: davidgow@google.com, brendanhiggins@google.com,
	aryabinin@virtuozzo.com, dvyukov@google.com, mingo@redhat.com,
	peterz@infradead.org, juri.lelli@redhat.com,
	vincent.guittot@linaro.org, linux-kernel@vger.kernel.org,
	kasan-dev@googlegroups.com, kunit-dev@googlegroups.com,
	linux-kselftest@vger.kernel.org
Subject: Re: [RFC PATCH v2 2/3] KUnit: KASAN Integration
Date: Tue, 24 Mar 2020 16:45:06 +0000 (GMT)	[thread overview]
Message-ID: <alpine.LRH.2.21.2003241640150.30637@localhost> (raw)
In-Reply-To: <20200319164227.87419-3-trishalfonso@google.com>


On Thu, 19 Mar 2020, Patricia Alfonso wrote:

> Integrate KASAN into KUnit testing framework.
> 	- Fail tests when KASAN reports an error that is not expected
>      	- Use KUNIT_EXPECT_KASAN_FAIL to expect a KASAN error in KASAN tests
>      	- Expected KASAN reports pass tests and are still printed when run
>      	without kunit_tool (kunit_tool still bypasses the report due to the
> 	test passing)
>      	- KUnit struct in current task used to keep track of the current test
>      	from KASAN code
> 
> Make use of "[RFC PATCH kunit-next 1/2] kunit: generalize
> kunit_resource API beyond allocated resources" and "[RFC PATCH
> kunit-next 2/2] kunit: add support for named resources" from Alan
> Maguire [1]
> 	- A named resource is added to a test when a KASAN report is
> 	 expected
>         - This resource contains a struct for kasan_data containing
>         booleans representing if a KASAN report is expected and if a
>         KASAN report is found
> 
> [1] (https://lore.kernel.org/linux-kselftest/1583251361-12748-1-git-send-email-alan.maguire@oracle.com/T/#t)
> 
> Signed-off-by: Patricia Alfonso <trishalfonso@google.com>
> ---
>  include/kunit/test.h | 10 ++++++++++
>  lib/kunit/test.c     | 10 +++++++++-
>  lib/test_kasan.c     | 37 +++++++++++++++++++++++++++++++++++++
>  mm/kasan/report.c    | 33 +++++++++++++++++++++++++++++++++
>  4 files changed, 89 insertions(+), 1 deletion(-)
> 
> diff --git a/include/kunit/test.h b/include/kunit/test.h
> index 70ee581b19cd..2ab265f4f76c 100644
> --- a/include/kunit/test.h
> +++ b/include/kunit/test.h
> @@ -19,9 +19,19 @@
>  
>  struct kunit_resource;
>  
> +#ifdef CONFIG_KASAN
> +/* kasan_data struct is used in KUnit tests for KASAN expected failures */
> +struct kunit_kasan_expectation {
> +	bool report_expected;
> +	bool report_found;
> +};
> +#endif /* CONFIG_KASAN */
> +

Above should be moved to mm/kasan/kasan.h I think.

>  typedef int (*kunit_resource_init_t)(struct kunit_resource *, void *);
>  typedef void (*kunit_resource_free_t)(struct kunit_resource *);
>  
> +void kunit_set_failure(struct kunit *test);
> +

Can you explain a bit more about why we need this exported?
I see where it's used but I'd just like to make sure I
understand what you're trying to do. Thanks!

>  /**
>   * struct kunit_resource - represents a *test managed resource*
>   * @data: for the user to store arbitrary data.
> diff --git a/lib/kunit/test.c b/lib/kunit/test.c
> index 86a4d9ca0a45..3f927ef45827 100644
> --- a/lib/kunit/test.c
> +++ b/lib/kunit/test.c
> @@ -10,11 +10,12 @@
>  #include <linux/kernel.h>
>  #include <linux/kref.h>
>  #include <linux/sched/debug.h>
> +#include <linux/sched.h>
>  
>  #include "string-stream.h"
>  #include "try-catch-impl.h"
>  
> -static void kunit_set_failure(struct kunit *test)
> +void kunit_set_failure(struct kunit *test)
>  {
>  	WRITE_ONCE(test->success, false);
>  }
> @@ -237,6 +238,10 @@ static void kunit_try_run_case(void *data)
>  	struct kunit_suite *suite = ctx->suite;
>  	struct kunit_case *test_case = ctx->test_case;
>  
> +#if (IS_ENABLED(CONFIG_KASAN) && IS_BUILTIN(CONFIG_KUNIT))
> +	current->kunit_test = test;
> +#endif /* IS_ENABLED(CONFIG_KASAN) && IS_BUILTIN(CONFIG_KUNIT) */
> +
>  	/*
>  	 * kunit_run_case_internal may encounter a fatal error; if it does,
>  	 * abort will be called, this thread will exit, and finally the parent
> @@ -590,6 +595,9 @@ void kunit_cleanup(struct kunit *test)
>  		spin_unlock(&test->lock);
>  		kunit_remove_resource(test, res);
>  	}
> +#if (IS_ENABLED(CONFIG_KASAN) && IS_BUILTIN(CONFIG_KUNIT))
> +	current->kunit_test = NULL;

As per patch 1, I'd suggest changing here and elsewhere to 
"IS_ENABLED(CONFIG_KUNIT)".

> +#endif /* IS_ENABLED(CONFIG_KASAN) && IS_BUILTIN(CONFIG_KUNIT)*/
>  }
>  EXPORT_SYMBOL_GPL(kunit_cleanup);
>  
> diff --git a/lib/test_kasan.c b/lib/test_kasan.c
> index 3872d250ed2c..cf73c6bee81b 100644
> --- a/lib/test_kasan.c
> +++ b/lib/test_kasan.c
> @@ -23,6 +23,43 @@
>  
>  #include <asm/page.h>
>  
> +#include <kunit/test.h>
> +
> +struct kunit_resource resource;
> +struct kunit_kasan_expectation fail_data;
> +
> +#define KUNIT_SET_KASAN_DATA(test) do { \
> +	fail_data.report_expected = true; \
> +	fail_data.report_found = false; \
> +	kunit_add_named_resource(test, \
> +				NULL, \
> +				NULL, \
> +				&resource, \
> +				"kasan_data", &fail_data); \
> +} while (0)
> +
> +#define KUNIT_DO_EXPECT_KASAN_FAIL(test, condition) do { \
> +	struct kunit_resource *resource; \
> +	struct kunit_kasan_expectation *kasan_data; \
> +	condition; \
> +	resource = kunit_find_named_resource(test, "kasan_data"); \
> +	kasan_data = resource->data; \
> +	KUNIT_EXPECT_EQ(test, \
> +			kasan_data->report_expected, \
> +			kasan_data->report_found); \
> +	kunit_put_resource(resource); \
> +} while (0)
> +
> +/**
> + * KUNIT_EXPECT_KASAN_FAIL() - Causes a test failure when the expression does
> + * not cause a KASAN error.
> + *
> + */
> +#define KUNIT_EXPECT_KASAN_FAIL(test, condition) do { \
> +	KUNIT_SET_KASAN_DATA(test); \
> +	KUNIT_DO_EXPECT_KASAN_FAIL(test, condition); \
> +} while (0)
> +
>  /*
>   * Note: test functions are marked noinline so that their names appear in
>   * reports.
> diff --git a/mm/kasan/report.c b/mm/kasan/report.c
> index 5ef9f24f566b..ef3d0f54097e 100644
> --- a/mm/kasan/report.c
> +++ b/mm/kasan/report.c
> @@ -32,6 +32,8 @@
>  
>  #include <asm/sections.h>
>  
> +#include <kunit/test.h>
> +
>  #include "kasan.h"
>  #include "../slab.h"
>  
> @@ -455,12 +457,38 @@ static bool report_enabled(void)
>  	return !test_and_set_bit(KASAN_BIT_REPORTED, &kasan_flags);
>  }
>  
> +#if IS_BUILTIN(CONFIG_KUNIT)

again we could tweak this to IS_ENABLED(CONFIG_KUNIT); BTW
the reason we can compile kunit as a module for these tests
is the KASAN tests are tristate themselves. If they were
builtin only it wouldn't be possible to build kunit as
a module.

> +void kasan_update_kunit_status(struct kunit *cur_test)
> +{
> +	struct kunit_resource *resource;
> +	struct kunit_kasan_expectation *kasan_data;
> +
> +	if (kunit_find_named_resource(cur_test, "kasan_data")) {
> +		resource = kunit_find_named_resource(cur_test, "kasan_data");
> +		kasan_data = resource->data;
> +		kasan_data->report_found = true;
> +
> +		if (!kasan_data->report_expected)
> +			kunit_set_failure(current->kunit_test);
> +		else
> +			return;
> +	} else
> +		kunit_set_failure(current->kunit_test);
> +}
> +#endif /* IS_BUILTIN(CONFIG_KUNIT) */
> +
>  void kasan_report_invalid_free(void *object, unsigned long ip)
>  {
>  	unsigned long flags;
>  	u8 tag = get_tag(object);
>  
>  	object = reset_tag(object);
> +
> +#if IS_BUILTIN(CONFIG_KUNIT)

same comment as above.
 
> +	if (current->kunit_test)
> +		kasan_update_kunit_status(current->kunit_test);
> +#endif /* IS_BUILTIN(CONFIG_KUNIT) */
> +
>  	start_report(&flags);
>  	pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", (void *)ip);
>  	print_tags(tag, object);
> @@ -481,6 +509,11 @@ void __kasan_report(unsigned long addr, size_t size, bool is_write, unsigned lon
>  	if (likely(!report_enabled()))
>  		return;
>  
> +#if IS_BUILTIN(CONFIG_KUNIT)

here too.

> +	if (current->kunit_test)
> +		kasan_update_kunit_status(current->kunit_test);
> +#endif /* IS_BUILTIN(CONFIG_KUNIT) */
> +
>  	disable_trace_on_warning();
>  
>  	tagged_addr = (void *)addr;
> -- 
> 2.25.1.696.g5e7596f4ac-goog
> 
> 

  reply	other threads:[~2020-03-24 16:45 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-19 16:42 [RFC PATCH v2 0/3] KASAN/KUnit Integration Patricia Alfonso
2020-03-19 16:42 ` [RFC PATCH v2 1/3] Add KUnit Struct to Current Task Patricia Alfonso
2020-03-24 11:32   ` Dmitry Vyukov
2020-03-24 16:39   ` Alan Maguire
2020-03-24 17:42     ` Patricia Alfonso
2020-03-25 12:42       ` Alan Maguire
2020-03-25 19:00         ` Patricia Alfonso
2020-03-30 19:30           ` Patricia Alfonso
2020-03-31  7:48             ` Dmitry Vyukov
2020-03-24 18:12   ` Brendan Higgins
2020-03-19 16:42 ` [RFC PATCH v2 2/3] KUnit: KASAN Integration Patricia Alfonso
2020-03-24 16:45   ` Alan Maguire [this message]
2020-03-24 17:48     ` Patricia Alfonso
2020-03-19 16:42 ` [RFC PATCH v2 3/3] KASAN: Port KASAN Tests to KUnit Patricia Alfonso
2020-03-24 11:24   ` Dmitry Vyukov
2020-03-24 15:05     ` Patricia Alfonso
2020-03-26  9:12       ` Dmitry Vyukov
2020-03-26 15:15         ` Patricia Alfonso
2020-03-27  5:31           ` Dmitry Vyukov
2020-03-30 18:57             ` Patricia Alfonso
2020-03-31 10:12               ` Dmitry Vyukov
2020-03-24 16:48   ` Alan Maguire
2020-03-24 17:52     ` Patricia Alfonso
2020-03-24 18:20   ` Brendan Higgins
2020-03-26  9:10   ` Dmitry Vyukov

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=alpine.LRH.2.21.2003241640150.30637@localhost \
    --to=alan.maguire@oracle.com \
    --cc=aryabinin@virtuozzo.com \
    --cc=brendanhiggins@google.com \
    --cc=davidgow@google.com \
    --cc=dvyukov@google.com \
    --cc=juri.lelli@redhat.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=trishalfonso@google.com \
    --cc=vincent.guittot@linaro.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.