Commit 90a545e9 authored by Dan Williams's avatar Dan Williams

restrict /dev/mem to idle io memory ranges

This effectively promotes IORESOURCE_BUSY to IORESOURCE_EXCLUSIVE
semantics by default.  If userspace really believes it is safe to access
the memory region it can also perform the extra step of disabling an
active driver.  This protects device address ranges with read side
effects and otherwise directs userspace to use the driver.

Persistent memory presents a large "mistake surface" to /dev/mem as now
accidental writes can corrupt a filesystem.

In general if a device driver is busily using a memory region it already
informs other parts of the kernel to not touch it via
request_mem_region().  /dev/mem should honor the same safety restriction
by default.  Debugging a device driver from userspace becomes more
difficult with this enabled.  Any application using /dev/mem or mmap of
sysfs pci resources will now need to perform the extra step of either:

1/ Disabling the driver, for example:

   echo <device id> > /dev/bus/<parent bus>/drivers/<driver name>/unbind

2/ Rebooting with "iomem=relaxed" on the command line

3/ Recompiling with CONFIG_IO_STRICT_DEVMEM=n

Traditional users of /dev/mem like dosemu are unaffected because the
first 1MB of memory is not subject to the IO_STRICT_DEVMEM restriction.
Legacy X configurations use /dev/mem to talk to graphics hardware, but
that functionality has since moved to kernel graphics drivers.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarIngo Molnar <mingo@redhat.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 21266be9
...@@ -1498,8 +1498,15 @@ int iomem_is_exclusive(u64 addr) ...@@ -1498,8 +1498,15 @@ int iomem_is_exclusive(u64 addr)
break; break;
if (p->end < addr) if (p->end < addr)
continue; continue;
if (p->flags & IORESOURCE_BUSY && /*
p->flags & IORESOURCE_EXCLUSIVE) { * A resource is exclusive if IORESOURCE_EXCLUSIVE is set
* or CONFIG_IO_STRICT_DEVMEM is enabled and the
* resource is busy.
*/
if ((p->flags & IORESOURCE_BUSY) == 0)
continue;
if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)
|| p->flags & IORESOURCE_EXCLUSIVE) {
err = 1; err = 1;
break; break;
} }
......
...@@ -1869,9 +1869,26 @@ config STRICT_DEVMEM ...@@ -1869,9 +1869,26 @@ config STRICT_DEVMEM
enabled, even in this case there are restrictions on /dev/mem enabled, even in this case there are restrictions on /dev/mem
use due to the cache aliasing requirements. use due to the cache aliasing requirements.
If this option is switched on, and IO_STRICT_DEVMEM=n, the /dev/mem
file only allows userspace access to PCI space and the BIOS code and
data regions. This is sufficient for dosemu and X and all common
users of /dev/mem.
If in doubt, say Y.
config IO_STRICT_DEVMEM
bool "Filter I/O access to /dev/mem"
depends on STRICT_DEVMEM
default STRICT_DEVMEM
---help---
If this option is disabled, you allow userspace (root) access to all
io-memory regardless of whether a driver is actively using that
range. Accidental access to this is obviously disastrous, but
specific access can be used by people debugging kernel drivers.
If this option is switched on, the /dev/mem file only allows If this option is switched on, the /dev/mem file only allows
userspace access to PCI space and the BIOS code and data regions. userspace access to *idle* io-memory ranges (see /proc/iomem) This
This is sufficient for dosemu and X and all common users of may break traditional users of /dev/mem (dosemu, legacy X, etc...)
/dev/mem. if the driver using a given range cannot be disabled.
If in doubt, say Y. If in doubt, say Y.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment