mm: slub: add kernel address sanitizer support for slub allocator
[linux-2.6-block.git] / mm / kasan / report.c
index fab8e7882ff104bcc13d3ae7b40af4d4284efbdd..2760edb4d0a8a5921cfdd7f5681a51745befcf5a 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kasan.h>
 
 #include "kasan.h"
+#include "../slab.h"
 
 /* Shadow layout customization. */
 #define SHADOW_BYTES_PER_BLOCK 1
@@ -55,8 +56,11 @@ static void print_error_description(struct kasan_access_info *info)
 
        switch (shadow_val) {
        case KASAN_FREE_PAGE:
+       case KASAN_KMALLOC_FREE:
                bug_type = "use after free";
                break;
+       case KASAN_PAGE_REDZONE:
+       case KASAN_KMALLOC_REDZONE:
        case 0 ... KASAN_SHADOW_SCALE_SIZE - 1:
                bug_type = "out of bounds access";
                break;
@@ -77,6 +81,23 @@ static void print_address_description(struct kasan_access_info *info)
        if ((addr >= (void *)PAGE_OFFSET) &&
                (addr < high_memory)) {
                struct page *page = virt_to_head_page(addr);
+
+               if (PageSlab(page)) {
+                       void *object;
+                       struct kmem_cache *cache = page->slab_cache;
+                       void *last_object;
+
+                       object = virt_to_obj(cache, page_address(page), addr);
+                       last_object = page_address(page) +
+                               page->objects * cache->size;
+
+                       if (unlikely(object > last_object))
+                               object = last_object; /* we hit into padding */
+
+                       object_err(cache, page, object,
+                               "kasan: bad access detected");
+                       return;
+               }
                dump_page(page, "kasan: bad access detected");
        }