lkml.org 
[lkml]   [2019]   [Jun]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH V34 12/29] x86: Lock down IO port access when the kernel is locked down
    From
    From: Matthew Garrett <mjg59@srcf.ucam.org>

    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 <mjg59@google.com>
    Signed-off-by: David Howells <dhowells@redhat.com>
    cc: x86@kernel.org
    ---
    arch/x86/kernel/ioport.c | 7 +++++--
    include/linux/security.h | 1 +
    security/lockdown/lockdown.c | 1 +
    3 files changed, 7 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
    index 0fe1c8782208..61a89d3c0382 100644
    --- a/arch/x86/kernel/ioport.c
    +++ b/arch/x86/kernel/ioport.c
    @@ -11,6 +11,7 @@
    #include <linux/errno.h>
    #include <linux/types.h>
    #include <linux/ioport.h>
    +#include <linux/security.h>
    #include <linux/smp.h>
    #include <linux/stddef.h>
    #include <linux/slab.h>
    @@ -31,7 +32,8 @@ long ksys_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) ||
    + security_locked_down(LOCKDOWN_IOPORT)))
    return -EPERM;

    /*
    @@ -126,7 +128,8 @@ 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) ||
    + security_locked_down(LOCKDOWN_IOPORT))
    return -EPERM;
    }
    regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
    diff --git a/include/linux/security.h b/include/linux/security.h
    index 1b849f10dec6..60569b7e9465 100644
    --- a/include/linux/security.h
    +++ b/include/linux/security.h
    @@ -87,6 +87,7 @@ enum lockdown_reason {
    LOCKDOWN_KEXEC,
    LOCKDOWN_HIBERNATION,
    LOCKDOWN_PCI_ACCESS,
    + LOCKDOWN_IOPORT,
    LOCKDOWN_INTEGRITY_MAX,
    LOCKDOWN_CONFIDENTIALITY_MAX,
    };
    diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
    index e2ee8a16b94c..895ef3ba1b4c 100644
    --- a/security/lockdown/lockdown.c
    +++ b/security/lockdown/lockdown.c
    @@ -23,6 +23,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
    [LOCKDOWN_KEXEC] = "kexec of unsigned images",
    [LOCKDOWN_HIBERNATION] = "hibernation",
    [LOCKDOWN_PCI_ACCESS] = "direct PCI access",
    + [LOCKDOWN_IOPORT] = "raw io port access",
    [LOCKDOWN_INTEGRITY_MAX] = "integrity",
    [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
    };
    --
    2.22.0.410.gd8fdbe21b5-goog
    \
     
     \ /
      Last update: 2019-06-22 02:04    [W:3.203 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site