aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/slub.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 6833b73ef6b3..37555ad8894d 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -20,6 +20,7 @@
20#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
21#include <linux/notifier.h> 21#include <linux/notifier.h>
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/kasan.h>
23#include <linux/kmemcheck.h> 24#include <linux/kmemcheck.h>
24#include <linux/cpu.h> 25#include <linux/cpu.h>
25#include <linux/cpuset.h> 26#include <linux/cpuset.h>
@@ -468,12 +469,30 @@ static char *slub_debug_slabs;
468static int disable_higher_order_debug; 469static int disable_higher_order_debug;
469 470
470/* 471/*
472 * slub is about to manipulate internal object metadata. This memory lies
473 * outside the range of the allocated object, so accessing it would normally
474 * be reported by kasan as a bounds error. metadata_access_enable() is used
475 * to tell kasan that these accesses are OK.
476 */
477static inline void metadata_access_enable(void)
478{
479 kasan_disable_current();
480}
481
482static inline void metadata_access_disable(void)
483{
484 kasan_enable_current();
485}
486
487/*
471 * Object debugging 488 * Object debugging
472 */ 489 */
473static void print_section(char *text, u8 *addr, unsigned int length) 490static void print_section(char *text, u8 *addr, unsigned int length)
474{ 491{
492 metadata_access_enable();
475 print_hex_dump(KERN_ERR, text, DUMP_PREFIX_ADDRESS, 16, 1, addr, 493 print_hex_dump(KERN_ERR, text, DUMP_PREFIX_ADDRESS, 16, 1, addr,
476 length, 1); 494 length, 1);
495 metadata_access_disable();
477} 496}
478 497
479static struct track *get_track(struct kmem_cache *s, void *object, 498static struct track *get_track(struct kmem_cache *s, void *object,
@@ -503,7 +522,9 @@ static void set_track(struct kmem_cache *s, void *object,
503 trace.max_entries = TRACK_ADDRS_COUNT; 522 trace.max_entries = TRACK_ADDRS_COUNT;
504 trace.entries = p->addrs; 523 trace.entries = p->addrs;
505 trace.skip = 3; 524 trace.skip = 3;
525 metadata_access_enable();
506 save_stack_trace(&trace); 526 save_stack_trace(&trace);
527 metadata_access_disable();
507 528
508 /* See rant in lockdep.c */ 529 /* See rant in lockdep.c */
509 if (trace.nr_entries != 0 && 530 if (trace.nr_entries != 0 &&
@@ -677,7 +698,9 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
677 u8 *fault; 698 u8 *fault;
678 u8 *end; 699 u8 *end;
679 700
701 metadata_access_enable();
680 fault = memchr_inv(start, value, bytes); 702 fault = memchr_inv(start, value, bytes);
703 metadata_access_disable();
681 if (!fault) 704 if (!fault)
682 return 1; 705 return 1;
683 706
@@ -770,7 +793,9 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
770 if (!remainder) 793 if (!remainder)
771 return 1; 794 return 1;
772 795
796 metadata_access_enable();
773 fault = memchr_inv(end - remainder, POISON_INUSE, remainder); 797 fault = memchr_inv(end - remainder, POISON_INUSE, remainder);
798 metadata_access_disable();
774 if (!fault) 799 if (!fault)
775 return 1; 800 return 1;
776 while (end > fault && end[-1] == POISON_INUSE) 801 while (end > fault && end[-1] == POISON_INUSE)