kasan: unify large kfree checks
[linux-2.6-microblaze.git] / mm / kasan / common.c
index 48d51da..8a3d663 100644 (file)
@@ -364,6 +364,31 @@ bool __kasan_slab_free(struct kmem_cache *cache, void *object, unsigned long ip)
        return ____kasan_slab_free(cache, object, ip, true);
 }
 
+static bool ____kasan_kfree_large(void *ptr, unsigned long ip)
+{
+       if (ptr != page_address(virt_to_head_page(ptr))) {
+               kasan_report_invalid_free(ptr, ip);
+               return true;
+       }
+
+       if (!kasan_byte_accessible(ptr)) {
+               kasan_report_invalid_free(ptr, ip);
+               return true;
+       }
+
+       /*
+        * The object will be poisoned by kasan_free_pages() or
+        * kasan_slab_free_mempool().
+        */
+
+       return false;
+}
+
+void __kasan_kfree_large(void *ptr, unsigned long ip)
+{
+       ____kasan_kfree_large(ptr, ip);
+}
+
 void __kasan_slab_free_mempool(void *ptr, unsigned long ip)
 {
        struct page *page;
@@ -377,10 +402,8 @@ void __kasan_slab_free_mempool(void *ptr, unsigned long ip)
         * KMALLOC_MAX_SIZE, and kmalloc falls back onto page_alloc.
         */
        if (unlikely(!PageSlab(page))) {
-               if (ptr != page_address(page)) {
-                       kasan_report_invalid_free(ptr, ip);
+               if (____kasan_kfree_large(ptr, ip))
                        return;
-               }
                kasan_poison(ptr, page_size(page), KASAN_FREE_PAGE);
        } else {
                ____kasan_slab_free(page->slab_cache, ptr, ip, false);
@@ -539,13 +562,6 @@ void * __must_check __kasan_krealloc(const void *object, size_t size, gfp_t flag
                return ____kasan_kmalloc(page->slab_cache, object, size, flags);
 }
 
-void __kasan_kfree_large(void *ptr, unsigned long ip)
-{
-       if (ptr != page_address(virt_to_head_page(ptr)))
-               kasan_report_invalid_free(ptr, ip);
-       /* The object will be poisoned by kasan_free_pages(). */
-}
-
 bool __kasan_check_byte(const void *address, unsigned long ip)
 {
        if (!kasan_byte_accessible(address)) {