powerpc: Implement CONFIG_STRICT_DEVMEM
authorsukadev@linux.vnet.ibm.com <sukadev@linux.vnet.ibm.com>
Tue, 30 Aug 2011 09:19:17 +0000 (09:19 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 28 Nov 2011 00:42:08 +0000 (11:42 +1100)
As described in the help text in the patch, this token restricts general
access to /dev/mem as a way of increasing the security. Specifically, access
to exclusive IOMEM and kernel RAM is denied unless CONFIG_STRICT_DEVMEM is
set to 'n'.

Implement the 'devmem_is_allowed()' interface for Powerpc. It will be
called from range_is_allowed() when userpsace attempts to access /dev/mem.

This patch is based on an earlier patch from Steve Best and with input from
Paul Mackerras and Scott Wood.

[BenH] Fixed a typo or two and removed the generic change which should
       be submitted as a separate patch

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/Kconfig.debug
arch/powerpc/include/asm/page.h
arch/powerpc/mm/mem.c

index 1b8a9c905cf7f429e13be1ab97f809cd5a92aa80..4ccb2a009f745f3477502964be609eeb14147cfa 100644 (file)
@@ -336,4 +336,16 @@ config PPC_EARLY_DEBUG_CPM_ADDR
          platform probing is done, all platforms selected must
          share the same address.
 
+config STRICT_DEVMEM
+       def_bool y
+       prompt "Filter access to /dev/mem"
+       help
+         This option restricts access to /dev/mem.  If this option is
+         disabled, you allow userspace access to all memory, including
+         kernel and userspace memory. Accidental memory access is likely
+         to be disastrous.
+         Memory access is required for experts who want to debug the kernel.
+
+         If you are unsure, say Y.
+
 endmenu
index dd9c4fd038e00b336d14c68e4d00a63cf20073b8..9d7485c7e6f8c5864fc447ec8b5aa361a541ee57 100644 (file)
@@ -290,6 +290,7 @@ extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
 extern void copy_user_page(void *to, void *from, unsigned long vaddr,
                struct page *p);
 extern int page_is_ram(unsigned long pfn);
+extern int devmem_is_allowed(unsigned long pfn);
 
 #ifdef CONFIG_PPC_SMLPAR
 void arch_free_page(struct page *page, int order);
index 2dd6bdd31fe14f77a0bc097f746ca59e790f0b0e..22563b9664c3524cf1939238355d6b7d50f37f99 100644 (file)
@@ -585,3 +585,21 @@ static int add_system_ram_resources(void)
        return 0;
 }
 subsys_initcall(add_system_ram_resources);
+
+#ifdef CONFIG_STRICT_DEVMEM
+/*
+ * devmem_is_allowed(): check to see if /dev/mem access to a certain address
+ * is valid. The argument is a physical page number.
+ *
+ * Access has to be given to non-kernel-ram areas as well, these contain the
+ * PCI mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pfn)
+{
+       if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+               return 0;
+       if (!page_is_ram(pfn))
+               return 1;
+       return 0;
+}
+#endif /* CONFIG_STRICT_DEVMEM */