Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: implement CONFIG_STRICT_DEVMEM by disabling access to RAM via /dev/mem

There are very few legitimate use cases, if any, for directly accessing
system RAM through /dev/mem. So let's mimic what they do on x86 and
forbid it when CONFIG_STRICT_DEVMEM is turned on.

Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>

authored by

Nicolas Pitre and committed by
Nicolas Pitre
087aaffc 7c63984b

+37
+14
arch/arm/Kconfig.debug
··· 2 2 3 3 source "lib/Kconfig.debug" 4 4 5 + config STRICT_DEVMEM 6 + bool "Filter access to /dev/mem" 7 + depends on MMU 8 + ---help--- 9 + If this option is disabled, you allow userspace (root) access to all 10 + of memory, including kernel and userspace memory. Accidental 11 + access to this is obviously disastrous, but specific access can 12 + be used by people debugging the kernel. 13 + 14 + If this option is switched on, the /dev/mem file only allows 15 + userspace access to memory mapped peripherals. 16 + 17 + If in doubt, say Y. 18 + 5 19 # RMK wants arm kernels compiled with frame pointers or stack unwinding. 6 20 # If you know what you are doing and are willing to live without stack 7 21 # traces, you can get a slightly smaller kernel by setting this option to
+1
arch/arm/include/asm/io.h
··· 294 294 #define ARCH_HAS_VALID_PHYS_ADDR_RANGE 295 295 extern int valid_phys_addr_range(unsigned long addr, size_t size); 296 296 extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); 297 + extern int devmem_is_allowed(unsigned long pfn); 297 298 #endif 298 299 299 300 /*
+22
arch/arm/mm/mmap.c
··· 144 144 { 145 145 return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); 146 146 } 147 + 148 + #ifdef CONFIG_STRICT_DEVMEM 149 + 150 + #include <linux/ioport.h> 151 + 152 + /* 153 + * devmem_is_allowed() checks to see if /dev/mem access to a certain 154 + * address is valid. The argument is a physical page number. 155 + * We mimic x86 here by disallowing access to system RAM as well as 156 + * device-exclusive MMIO regions. This effectively disable read()/write() 157 + * on /dev/mem. 158 + */ 159 + int devmem_is_allowed(unsigned long pfn) 160 + { 161 + if (iomem_is_exclusive(pfn << PAGE_SHIFT)) 162 + return 0; 163 + if (!page_is_ram(pfn)) 164 + return 1; 165 + return 0; 166 + } 167 + 168 + #endif