diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index ed8bd0f..1de9072 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -43,7 +43,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; #ifdef CONFIG_GRKERNSEC_IO - if (turn_on) { + if (turn_on && grsec_priv_io_disable) { gr_handle_ioperm(); return -EPERM; } @@ -119,12 +119,13 @@ static int do_iopl(unsigned int level, struct pt_regs *regs) /* Trying to gain more privileges? */ if (level > old) { #ifdef CONFIG_GRKERNSEC_IO - gr_handle_iopl(); - return -EPERM; -#else - if (!capable(CAP_SYS_RAWIO)) + if (grsec_priv_io_disable) { + gr_handle_iopl(); return -EPERM; + } #endif + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; } regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig index 9045a44..1c8de4f 100644 --- a/grsecurity/Kconfig +++ b/grsecurity/Kconfig @@ -255,7 +255,9 @@ config GRKERNSEC_IO that hwclock operates correctly. XFree86 still will not operate correctly with this option enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86 and you still want to - protect your kernel against modification, use the RBAC system. + protect your kernel against modification, use the RBAC system. If the + sysctl option is enabled, a sysctl option with name "priv_io_disable" + will be created. config GRKERNSEC_DISABLE_SWAP bool "Disable mounting of swap devices" diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c index 5a4609d..1a49848 100644 --- a/grsecurity/grsec_init.c +++ b/grsecurity/grsec_init.c @@ -7,6 +7,7 @@ #include #include +int grsec_priv_io_disable; int grsec_enable_link; int grsec_enable_dmesg; int grsec_enable_harden_ptrace; @@ -124,6 +125,9 @@ grsecurity_init(void) #ifndef CONFIG_GRKERNSEC_SYSCTL grsec_lock = 1; #endif +#ifdef CONFIG_GRKERNSEC_IO + grsec_priv_io_disable; +#endif #ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL grsec_enable_audit_textrel = 1; #endif diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c index d20fce0..38fe46e 100644 --- a/grsecurity/grsec_sysctl.c +++ b/grsecurity/grsec_sysctl.c @@ -23,6 +23,16 @@ static int __maybe_unused one = 1; #if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_ROFS) ctl_table grsecurity_table[] = { #ifdef CONFIG_GRKERNSEC_SYSCTL +#ifdef CONFIG_GRKERNSEC_IO + { + .ctl_name = CTL_UNNUMBERED, + .procname = "priv_io_disable", + .data = &grsec_priv_io_disable, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = &proc_dointvec, + }, +#endif #ifdef CONFIG_GRKERNSEC_LINK { .ctl_name = CTL_UNNUMBERED, diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h index f2d09a4..59b3064 100644 --- a/include/linux/grsecurity.h +++ b/include/linux/grsecurity.h @@ -22,6 +22,7 @@ #error "CONFIG_PAX enabled, but no PaX options are enabled." #endif +extern int grsec_priv_io_disable; extern int grsec_netdev_blackhole; void gr_handle_brute_attach(struct task_struct *p);