s390/kasan: fix insecure W+X mapping warning
authorAlexander Gordeev <agordeev@linux.ibm.com>
Fri, 26 May 2023 12:30:29 +0000 (14:30 +0200)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Tue, 20 Jun 2023 17:52:12 +0000 (19:52 +0200)
Since commit 3b5c3f000c2e ("s390/kasan: move shadow mapping
to decompressor") the decompressor establishes mappings for
the shadow memory and sets initial protection attributes to
RWX. The decompressed kernel resets protection to RW+NX
later on.

In case a shadow memory range is not aligned on page boundary
(e.g. as result of mem= kernel command line parameter use),
the "Checked W+X mappings: FAILED, 1 W+X pages found" warning
hits.

Reported-by: Vasily Gorbik <gor@linux.ibm.com>
Fixes: 557b19709da9 ("s390/kasan: move shadow mapping to decompressor")
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/mm/vmem.c

index 5b22c6e24528aa2d7a359d9a29182088738975c1..b9dcb4ae6c59aea5a9fdf5e52e4d49a09f4d0721 100644 (file)
@@ -667,7 +667,15 @@ static void __init memblock_region_swap(void *a, void *b, int size)
 
 #ifdef CONFIG_KASAN
 #define __sha(x)       ((unsigned long)kasan_mem_to_shadow((void *)x))
+
+static inline int set_memory_kasan(unsigned long start, unsigned long end)
+{
+       start = PAGE_ALIGN_DOWN(__sha(start));
+       end = PAGE_ALIGN(__sha(end));
+       return set_memory_rwnx(start, (end - start) >> PAGE_SHIFT);
+}
 #endif
+
 /*
  * map whole physical memory to virtual memory (identity mapping)
  * we reserve enough space in the vmalloc area for vmemmap to hotplug
@@ -737,10 +745,8 @@ void __init vmem_map_init(void)
        }
 
 #ifdef CONFIG_KASAN
-       for_each_mem_range(i, &base, &end) {
-               set_memory_rwnx(__sha(base),
-                               (__sha(end) - __sha(base)) >> PAGE_SHIFT);
-       }
+       for_each_mem_range(i, &base, &end)
+               set_memory_kasan(base, end);
 #endif
        set_memory_rox((unsigned long)_stext,
                       (unsigned long)(_etext - _stext) >> PAGE_SHIFT);