x86: Lock down IO port access when the kernel is locked down
authorMatthew Garrett <matthew.garrett@nebula.com>
Wed, 5 Apr 2017 16:40:30 +0000 (17:40 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Sat, 12 Aug 2017 22:09:26 +0000 (23:09 +0100)
IO port access would permit users to gain access to PCI configuration
registers, which in turn (on a lot of hardware) give access to MMIO
register space. This would potentially permit root to trigger arbitrary
DMA, so lock it down by default.

This also implicitly locks down the KDADDIO, KDDELIO, KDENABIO and
KDDISABIO console ioctls.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Gbp-Pq: Topic features/all/lockdown
Gbp-Pq: Name 0050-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch

arch/x86/kernel/ioport.c
drivers/char/mem.c

index 9c3cf0944bce35471cf0d1c34eac1e9a92d2eaa7..4a613fed94b6546da1f09ca3c5fb01079992125c 100644 (file)
@@ -30,7 +30,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 
        if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
                return -EINVAL;
-       if (turn_on && !capable(CAP_SYS_RAWIO))
+       if (turn_on && (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down()))
                return -EPERM;
 
        /*
@@ -120,7 +120,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
                return -EINVAL;
        /* Trying to gain more privileges? */
        if (level > old) {
-               if (!capable(CAP_SYS_RAWIO))
+               if (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down())
                        return -EPERM;
        }
        regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
index ba68add9677f43c2994e1e5c589e18d1d075da92..5e2a260fb89fb06edb148e0ea8c78e2a00f97100 100644 (file)
@@ -768,6 +768,8 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
 
 static int open_port(struct inode *inode, struct file *filp)
 {
+       if (kernel_is_locked_down())
+               return -EPERM;
        return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
 }