patch-2.2.0-pre7 linux/arch/i386/kernel/ioport.c

Next file: linux/arch/i386/kernel/process.c
Previous file: linux/arch/alpha/kernel/time.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.0-pre6/linux/arch/i386/kernel/ioport.c linux/arch/i386/kernel/ioport.c
@@ -58,7 +58,7 @@
 
 	if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
 		return -EINVAL;
-	if (!capable(CAP_SYS_RAWIO))
+	if (turn_on && !capable(CAP_SYS_RAWIO))
 		return -EPERM;
 	/*
 	 * If it's the first ioperm() call in this thread's lifetime, set the
@@ -91,11 +91,15 @@
 {
 	struct pt_regs * regs = (struct pt_regs *) &unused;
 	unsigned int level = regs->ebx;
+	unsigned int old = (regs->eflags >> 12) & 3;
 
 	if (level > 3)
 		return -EINVAL;
-	if (!capable(CAP_SYS_RAWIO))
-		return -EPERM;
+	/* Trying to gain more privileges? */
+	if (level > old) {
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+	}
 	regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
 	return 0;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov