kasan, vmalloc: only tag normal vmalloc allocations
[linux-2.6-microblaze.git] / mm / vmalloc.c
index 185ab3e..e163372 100644 (file)
@@ -2242,7 +2242,7 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node)
         * With hardware tag-based KASAN, marking is skipped for
         * non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc().
         */
-       mem = kasan_unpoison_vmalloc(mem, size, KASAN_VMALLOC_NONE);
+       mem = kasan_unpoison_vmalloc(mem, size, KASAN_VMALLOC_PROT_NORMAL);
 
        return mem;
 }
@@ -2481,7 +2481,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
         */
        if (!(flags & VM_ALLOC))
                area->addr = kasan_unpoison_vmalloc(area->addr, requested_size,
-                                                       KASAN_VMALLOC_NONE);
+                                                   KASAN_VMALLOC_PROT_NORMAL);
 
        return area;
 }
@@ -3091,7 +3091,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 {
        struct vm_struct *area;
        void *ret;
-       kasan_vmalloc_flags_t kasan_flags;
+       kasan_vmalloc_flags_t kasan_flags = KASAN_VMALLOC_NONE;
        unsigned long real_size = size;
        unsigned long real_align = align;
        unsigned int shift = PAGE_SHIFT;
@@ -3144,21 +3144,28 @@ again:
                goto fail;
        }
 
-       /* Prepare arguments for __vmalloc_area_node(). */
-       if (kasan_hw_tags_enabled() &&
-           pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) {
-               /*
-                * Modify protection bits to allow tagging.
-                * This must be done before mapping in __vmalloc_area_node().
-                */
-               prot = arch_vmap_pgprot_tagged(prot);
+       /*
+        * Prepare arguments for __vmalloc_area_node() and
+        * kasan_unpoison_vmalloc().
+        */
+       if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) {
+               if (kasan_hw_tags_enabled()) {
+                       /*
+                        * Modify protection bits to allow tagging.
+                        * This must be done before mapping.
+                        */
+                       prot = arch_vmap_pgprot_tagged(prot);
 
-               /*
-                * Skip page_alloc poisoning and zeroing for physical pages
-                * backing VM_ALLOC mapping. Memory is instead poisoned and
-                * zeroed by kasan_unpoison_vmalloc().
-                */
-               gfp_mask |= __GFP_SKIP_KASAN_UNPOISON | __GFP_SKIP_ZERO;
+                       /*
+                        * Skip page_alloc poisoning and zeroing for physical
+                        * pages backing VM_ALLOC mapping. Memory is instead
+                        * poisoned and zeroed by kasan_unpoison_vmalloc().
+                        */
+                       gfp_mask |= __GFP_SKIP_KASAN_UNPOISON | __GFP_SKIP_ZERO;
+               }
+
+               /* Take note that the mapping is PAGE_KERNEL. */
+               kasan_flags |= KASAN_VMALLOC_PROT_NORMAL;
        }
 
        /* Allocate physical pages and map them into vmalloc space. */
@@ -3172,10 +3179,13 @@ again:
         * (except for the should_skip_init() check) to make sure that memory
         * is initialized under the same conditions regardless of the enabled
         * KASAN mode.
+        * Tag-based KASAN modes only assign tags to normal non-executable
+        * allocations, see __kasan_unpoison_vmalloc().
         */
-       kasan_flags = KASAN_VMALLOC_VM_ALLOC;
+       kasan_flags |= KASAN_VMALLOC_VM_ALLOC;
        if (!want_init_on_free() && want_init_on_alloc(gfp_mask))
                kasan_flags |= KASAN_VMALLOC_INIT;
+       /* KASAN_VMALLOC_PROT_NORMAL already set if required. */
        area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);
 
        /*
@@ -3881,8 +3891,7 @@ retry:
         */
        for (area = 0; area < nr_vms; area++)
                vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr,
-                                                        vms[area]->size,
-                                                        KASAN_VMALLOC_NONE);
+                               vms[area]->size, KASAN_VMALLOC_PROT_NORMAL);
 
        kfree(vas);
        return vms;