Merge tag 'perf-tools-for-v5.10-2020-10-15' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-microblaze.git] / mm / kasan / report.c
index 4f49fa6..00a53f1 100644 (file)
@@ -33,6 +33,8 @@
 
 #include <asm/sections.h>
 
+#include <kunit/test.h>
+
 #include "kasan.h"
 #include "../slab.h"
 
@@ -93,7 +95,7 @@ static void end_report(unsigned long *flags)
        pr_err("==================================================================\n");
        add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
        spin_unlock_irqrestore(&report_lock, *flags);
-       if (panic_on_warn) {
+       if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) {
                /*
                 * This thread may hit another WARN() in the panic path.
                 * Resetting this prevents additional WARN() from panicking the
@@ -464,12 +466,37 @@ static bool report_enabled(void)
        return !test_and_set_bit(KASAN_BIT_REPORTED, &kasan_flags);
 }
 
+#if IS_ENABLED(CONFIG_KUNIT)
+static void kasan_update_kunit_status(struct kunit *cur_test)
+{
+       struct kunit_resource *resource;
+       struct kunit_kasan_expectation *kasan_data;
+
+       resource = kunit_find_named_resource(cur_test, "kasan_data");
+
+       if (!resource) {
+               kunit_set_failure(cur_test);
+               return;
+       }
+
+       kasan_data = (struct kunit_kasan_expectation *)resource->data;
+       kasan_data->report_found = true;
+       kunit_put_resource(resource);
+}
+#endif /* IS_ENABLED(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_ENABLED(CONFIG_KUNIT)
+       if (current->kunit_test)
+               kasan_update_kunit_status(current->kunit_test);
+#endif /* IS_ENABLED(CONFIG_KUNIT) */
+
        start_report(&flags);
        pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", (void *)ip);
        print_tags(tag, object);
@@ -488,6 +515,11 @@ static void __kasan_report(unsigned long addr, size_t size, bool is_write,
        void *untagged_addr;
        unsigned long flags;
 
+#if IS_ENABLED(CONFIG_KUNIT)
+       if (current->kunit_test)
+               kasan_update_kunit_status(current->kunit_test);
+#endif /* IS_ENABLED(CONFIG_KUNIT) */
+
        disable_trace_on_warning();
 
        tagged_addr = (void *)addr;