Revert "FROMGIT: kasan, arm64: allow using KUnit tests with HW_TAGS mode"

This reverts commit a599a4e3b9.

The upstream version of this patch has been updated. Revert the FROMGIT
version before applying the UPSTREAM one.

Bug: 172318110
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Change-Id: I423a68e2a3e55b97b04180fedd7160c704ae0972
This commit is contained in:
Andrey Konovalov
2021-03-05 16:29:21 +01:00
committed by Will Deacon
parent c0a166c983
commit 9f925b293d
7 changed files with 9 additions and 67 deletions

View File

@@ -233,7 +233,6 @@ static inline const void *__tag_set(const void *addr, u8 tag)
#ifdef CONFIG_KASAN_HW_TAGS #ifdef CONFIG_KASAN_HW_TAGS
#define arch_enable_tagging() mte_enable_kernel() #define arch_enable_tagging() mte_enable_kernel()
#define arch_set_tagging_report_once(state) mte_set_report_once(state)
#define arch_init_tags(max_tag) mte_init_tags(max_tag) #define arch_init_tags(max_tag) mte_init_tags(max_tag)
#define arch_get_random_tag() mte_get_random_tag() #define arch_get_random_tag() mte_get_random_tag()
#define arch_get_mem_tag(addr) mte_get_mem_tag(addr) #define arch_get_mem_tag(addr) mte_get_mem_tag(addr)

View File

@@ -80,9 +80,6 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag)
void mte_enable_kernel(void); void mte_enable_kernel(void);
void mte_init_tags(u64 max_tag); void mte_init_tags(u64 max_tag);
void mte_set_report_once(bool state);
bool mte_report_once(void);
#else /* CONFIG_ARM64_MTE */ #else /* CONFIG_ARM64_MTE */
static inline u8 mte_get_ptr_tag(void *ptr) static inline u8 mte_get_ptr_tag(void *ptr)
@@ -112,15 +109,6 @@ static inline void mte_init_tags(u64 max_tag)
{ {
} }
static inline void mte_set_report_once(bool state)
{
}
static inline bool mte_report_once(void)
{
return false;
}
#endif /* CONFIG_ARM64_MTE */ #endif /* CONFIG_ARM64_MTE */
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */

View File

@@ -24,8 +24,6 @@
u64 gcr_kernel_excl __ro_after_init; u64 gcr_kernel_excl __ro_after_init;
static bool report_fault_once = true;
static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap)
{ {
pte_t old_pte = READ_ONCE(*ptep); pte_t old_pte = READ_ONCE(*ptep);
@@ -114,16 +112,6 @@ void mte_enable_kernel(void)
isb(); isb();
} }
void mte_set_report_once(bool state)
{
WRITE_ONCE(report_fault_once, state);
}
bool mte_report_once(void)
{
return READ_ONCE(report_fault_once);
}
static void update_sctlr_el1_tcf0(u64 tcf0) static void update_sctlr_el1_tcf0(u64 tcf0)
{ {
/* ISB required for the kernel uaccess routines */ /* ISB required for the kernel uaccess routines */

View File

@@ -306,24 +306,12 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
static void report_tag_fault(unsigned long addr, unsigned int esr, static void report_tag_fault(unsigned long addr, unsigned int esr,
struct pt_regs *regs) struct pt_regs *regs)
{ {
static bool reported; bool is_write = ((esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT) != 0;
bool is_write;
if (READ_ONCE(reported))
return;
/*
* This is used for KASAN tests and assumes that no MTE faults
* happened before running the tests.
*/
if (mte_report_once())
WRITE_ONCE(reported, true);
/* /*
* SAS bits aren't set for all faults reported in EL1, so we can't * SAS bits aren't set for all faults reported in EL1, so we can't
* find out access size. * find out access size.
*/ */
is_write = !!(esr & ESR_ELx_WNR);
kasan_report(addr, 0, is_write, regs->pc); kasan_report(addr, 0, is_write, regs->pc);
} }
#else #else
@@ -335,8 +323,12 @@ static inline void report_tag_fault(unsigned long addr, unsigned int esr,
static void do_tag_recovery(unsigned long addr, unsigned int esr, static void do_tag_recovery(unsigned long addr, unsigned int esr,
struct pt_regs *regs) struct pt_regs *regs)
{ {
static bool reported;
if (!READ_ONCE(reported)) {
report_tag_fault(addr, esr, regs); report_tag_fault(addr, esr, regs);
WRITE_ONCE(reported, true);
}
/* /*
* Disable MTE Tag Checking on the local CPU for the current EL. * Disable MTE Tag Checking on the local CPU for the current EL.

View File

@@ -199,11 +199,11 @@ config KASAN_KUNIT_TEST
kernel debugging features like KASAN. kernel debugging features like KASAN.
For more information on KUnit and unit tests in general, please refer For more information on KUnit and unit tests in general, please refer
to the KUnit documentation in Documentation/dev-tools/kunit. to the KUnit documentation in Documentation/dev-tools/kunit
config KASAN_MODULE_TEST config KASAN_MODULE_TEST
tristate "KUnit-incompatible tests of KASAN bug detection capabilities" tristate "KUnit-incompatible tests of KASAN bug detection capabilities"
depends on m && KASAN && !KASAN_HW_TAGS depends on m && KASAN
help help
This is a part of the KASAN test suite that is incompatible with This is a part of the KASAN test suite that is incompatible with
KUnit. Currently includes tests that do bad copy_from/to_user KUnit. Currently includes tests that do bad copy_from/to_user

View File

@@ -41,9 +41,7 @@ static bool multishot;
/* /*
* Temporarily enable multi-shot mode. Otherwise, KASAN would only report the * 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 * first detected bug and panic the kernel if panic_on_warn is enabled.
* 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 int kasan_test_init(struct kunit *test)
{ {
@@ -53,13 +51,11 @@ static int kasan_test_init(struct kunit *test)
} }
multishot = kasan_save_enable_multi_shot(); multishot = kasan_save_enable_multi_shot();
hw_set_tagging_report_once(false);
return 0; return 0;
} }
static void kasan_test_exit(struct kunit *test) static void kasan_test_exit(struct kunit *test)
{ {
hw_set_tagging_report_once(true);
kasan_restore_multi_shot(multishot); kasan_restore_multi_shot(multishot);
} }
@@ -69,19 +65,12 @@ static void kasan_test_exit(struct kunit *test)
* resource named "kasan_data". Do not use this name for KUnit resources * resource named "kasan_data". Do not use this name for KUnit resources
* outside of KASAN tests. * outside of KASAN tests.
* *
* For hardware tag-based KASAN, when a tag fault happens, tag checking is
* normally auto-disabled. When this happens, this test handler reenables
* tag checking. As tag checking can be only disabled or enabled per CPU, this
* handler disables migration (preemption).
*
* Since the compiler doesn't see that the expression can change the fail_data * Since the compiler doesn't see that the expression can change the fail_data
* fields, it can reorder or optimize away the accesses to those fields. * fields, it can reorder or optimize away the accesses to those fields.
* Use READ/WRITE_ONCE() for the accesses and compiler barriers around the * Use READ/WRITE_ONCE() for the accesses and compiler barriers around the
* expression to prevent that. * expression to prevent that.
*/ */
#define KUNIT_EXPECT_KASAN_FAIL(test, expression) do { \ #define KUNIT_EXPECT_KASAN_FAIL(test, expression) do { \
if (IS_ENABLED(CONFIG_KASAN_HW_TAGS)) \
migrate_disable(); \
WRITE_ONCE(fail_data.report_expected, true); \ WRITE_ONCE(fail_data.report_expected, true); \
WRITE_ONCE(fail_data.report_found, false); \ WRITE_ONCE(fail_data.report_found, false); \
kunit_add_named_resource(test, \ kunit_add_named_resource(test, \
@@ -95,11 +84,6 @@ static void kasan_test_exit(struct kunit *test)
KUNIT_EXPECT_EQ(test, \ KUNIT_EXPECT_EQ(test, \
READ_ONCE(fail_data.report_expected), \ READ_ONCE(fail_data.report_expected), \
READ_ONCE(fail_data.report_found)); \ READ_ONCE(fail_data.report_found)); \
if (IS_ENABLED(CONFIG_KASAN_HW_TAGS)) { \
if (READ_ONCE(fail_data.report_found)) \
hw_enable_tagging(); \
migrate_enable(); \
} \
} while (0) } while (0)
#define KASAN_TEST_NEEDS_CONFIG_ON(test, config) do { \ #define KASAN_TEST_NEEDS_CONFIG_ON(test, config) do { \

View File

@@ -281,9 +281,6 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
#ifndef arch_init_tags #ifndef arch_init_tags
#define arch_init_tags(max_tag) #define arch_init_tags(max_tag)
#endif #endif
#ifndef arch_set_tagging_report_once
#define arch_set_tagging_report_once(state)
#endif
#ifndef arch_get_random_tag #ifndef arch_get_random_tag
#define arch_get_random_tag() (0xFF) #define arch_get_random_tag() (0xFF)
#endif #endif
@@ -296,16 +293,10 @@ static inline const void *arch_kasan_set_tag(const void *addr, u8 tag)
#define hw_enable_tagging() arch_enable_tagging() #define hw_enable_tagging() arch_enable_tagging()
#define hw_init_tags(max_tag) arch_init_tags(max_tag) #define hw_init_tags(max_tag) arch_init_tags(max_tag)
#define hw_set_tagging_report_once(state) arch_set_tagging_report_once(state)
#define hw_get_random_tag() arch_get_random_tag() #define hw_get_random_tag() arch_get_random_tag()
#define hw_get_mem_tag(addr) arch_get_mem_tag(addr) #define hw_get_mem_tag(addr) arch_get_mem_tag(addr)
#define hw_set_mem_tag_range(addr, size, tag) arch_set_mem_tag_range((addr), (size), (tag)) #define hw_set_mem_tag_range(addr, size, tag) arch_set_mem_tag_range((addr), (size), (tag))
#else /* CONFIG_KASAN_HW_TAGS */
#define hw_enable_tagging()
#define hw_set_tagging_report_once(state)
#endif /* CONFIG_KASAN_HW_TAGS */ #endif /* CONFIG_KASAN_HW_TAGS */
#ifdef CONFIG_KASAN_SW_TAGS #ifdef CONFIG_KASAN_SW_TAGS