Messages in this thread | | | From | Alex Henrie <> | Date | Mon, 11 May 2015 14:49:17 -0600 | Subject | Fwd: ioperm is preserved across fork and execve, but iopl is not |
| |
Dear kernel developers,
The ioperm and iopl calls are both used to grant a process permission to access I/O devices directly. iopl(3) is equivalent to ioperm(0, 0xFFFF, 1). However, permissions granted through ioperm are preserved across fork and execve, and permissions granted through iopl are not. This makes no sense: The two calls do the same thing, so there is no security benefit to dropping one on fork or execve but not the other.
As recently as October 2012, 32-bit Linux kernels preserved both iopl and ioperm across fork and execve, but the behavior of iopl changed with this commit: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/arch/x86/kernel/process_32.c?id=6783eaa2e1253fbcbe2c2f6bb4c843abf1343caf
And the man page for iopl continues to state "permissions are inherited by fork and execve": http://linux.die.net/man/2/iopl
A test program demonstrating the problem is attached, and I will send a proposed patch shortly. CAP_SYS_RAWIO is still required to use ioperm or iopl.
Please CC me on any reply, as I am not subscribed to the LKML.
-Alex #include <stdio.h> #include <unistd.h>
int main(int argc, char* argv[]) { if (iopl(3) == -1) { perror("iopl"); return 1; }
if (execvp(argv[1], &argv[1]) == -1) { perror("execvp"); return 1; }
return 0; } //Plays a tone on the system speaker for 1 second
#include <stdio.h>
int main() { __asm__("movb $0xB6, %al\n" "outb %al, $0x43\n" "inb $0x61, %al\n" "orb $0x03, %al\n" "outb %al, $0x61\n" "movb $0x64, %al\n" "outb %al, $0x42\n" "movb $0x01, %al\n" "outb %al, $0x42\n"); sleep(1); __asm__("inb $0x61, %al\n" "andb $0xFC, %al\n" "outb %al, $0x61\n"); return 0; } [unhandled content-type:application/x-sh] | |