Skip to content

Commit

Permalink
kasan: make report_lock a raw spinlock
Browse files Browse the repository at this point in the history
commit e30a036 upstream.

If PREEMPT_RT is enabled, report_lock is a sleeping spinlock and must not
be locked when IRQs are disabled.  However, KASAN reports may be triggered
in such contexts.  For example:

        char *s = kzalloc(1, GFP_KERNEL);
        kfree(s);
        local_irq_disable();
        char c = *s;  /* KASAN report here leads to spin_lock() */
        local_irq_enable();

Make report_spinlock a raw spinlock to prevent rescheduling when
PREEMPT_RT is enabled.

Link: https://lkml.kernel.org/r/[email protected]
Fixes: 342a932 ("locking/spinlock: Provide RT variant header: <linux/spinlock_rt.h>")
Signed-off-by: Jared Kangas <[email protected]>
Cc: Alexander Potapenko <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: Vincenzo Frascino <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
rh-jkangas authored and gregkh committed Dec 14, 2024
1 parent a71ddd5 commit 835ca04
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions mm/kasan/report.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ static inline void fail_non_kasan_kunit_test(void) { }

#endif /* CONFIG_KUNIT */

static DEFINE_SPINLOCK(report_lock);
static DEFINE_RAW_SPINLOCK(report_lock);

static void start_report(unsigned long *flags, bool sync)
{
Expand All @@ -211,7 +211,7 @@ static void start_report(unsigned long *flags, bool sync)
lockdep_off();
/* Make sure we don't end up in loop. */
report_suppress_start();
spin_lock_irqsave(&report_lock, *flags);
raw_spin_lock_irqsave(&report_lock, *flags);
pr_err("==================================================================\n");
}

Expand All @@ -221,7 +221,7 @@ static void end_report(unsigned long *flags, const void *addr, bool is_write)
trace_error_report_end(ERROR_DETECTOR_KASAN,
(unsigned long)addr);
pr_err("==================================================================\n");
spin_unlock_irqrestore(&report_lock, *flags);
raw_spin_unlock_irqrestore(&report_lock, *flags);
if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
check_panic_on_warn("KASAN");
switch (kasan_arg_fault) {
Expand Down

0 comments on commit 835ca04

Please sign in to comment.