Skip to content

Commit

Permalink
x86: Lock down IO port access when securelevel is enabled
Browse files Browse the repository at this point in the history
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 when securelevel is set.

Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
  • Loading branch information
mjg59 authored and Matthew Garrett committed Apr 3, 2016
1 parent 2533a38 commit 2ad64f6
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
5 changes: 3 additions & 2 deletions arch/x86/kernel/ioport.c
Expand Up @@ -15,6 +15,7 @@
#include <linux/thread_info.h>
#include <linux/syscalls.h>
#include <linux/bitmap.h>
#include <linux/security.h>
#include <asm/syscalls.h>

/*
Expand All @@ -28,7 +29,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) || (get_securelevel() > 0)))
return -EPERM;

/*
Expand Down Expand Up @@ -108,7 +109,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) || (get_securelevel() > 0))
return -EPERM;
}
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
Expand Down
7 changes: 7 additions & 0 deletions drivers/char/mem.c
Expand Up @@ -27,6 +27,7 @@
#include <linux/export.h>
#include <linux/io.h>
#include <linux/uio.h>
#include <linux/security.h>

#include <linux/uaccess.h>

Expand Down Expand Up @@ -559,6 +560,9 @@ static ssize_t read_port(struct file *file, char __user *buf,
unsigned long i = *ppos;
char __user *tmp = buf;

if (get_securelevel() > 0)
return -EPERM;

if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
Expand All @@ -577,6 +581,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
unsigned long i = *ppos;
const char __user *tmp = buf;

if (get_securelevel() > 0)
return -EPERM;

if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
Expand Down

0 comments on commit 2ad64f6

Please sign in to comment.