aboutsummaryrefslogtreecommitdiffstats
path: root/mm/kasan/report.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/kasan/report.c')
-rw-r--r--mm/kasan/report.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index f479365530b6..ab42a0803f16 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -13,7 +13,9 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/bitops.h>
16#include <linux/ftrace.h> 17#include <linux/ftrace.h>
18#include <linux/init.h>
17#include <linux/kernel.h> 19#include <linux/kernel.h>
18#include <linux/mm.h> 20#include <linux/mm.h>
19#include <linux/printk.h> 21#include <linux/printk.h>
@@ -293,6 +295,40 @@ static void kasan_report_error(struct kasan_access_info *info)
293 kasan_end_report(&flags); 295 kasan_end_report(&flags);
294} 296}
295 297
298static unsigned long kasan_flags;
299
300#define KASAN_BIT_REPORTED 0
301#define KASAN_BIT_MULTI_SHOT 1
302
303bool kasan_save_enable_multi_shot(void)
304{
305 return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
306}
307EXPORT_SYMBOL_GPL(kasan_save_enable_multi_shot);
308
309void kasan_restore_multi_shot(bool enabled)
310{
311 if (!enabled)
312 clear_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
313}
314EXPORT_SYMBOL_GPL(kasan_restore_multi_shot);
315
316static int __init kasan_set_multi_shot(char *str)
317{
318 set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
319 return 1;
320}
321__setup("kasan_multi_shot", kasan_set_multi_shot);
322
323static inline bool kasan_report_enabled(void)
324{
325 if (current->kasan_depth)
326 return false;
327 if (test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
328 return true;
329 return !test_and_set_bit(KASAN_BIT_REPORTED, &kasan_flags);
330}
331
296void kasan_report(unsigned long addr, size_t size, 332void kasan_report(unsigned long addr, size_t size,
297 bool is_write, unsigned long ip) 333 bool is_write, unsigned long ip)
298{ 334{