[PATCH][RFC] introduce a mmap MAP_DONTEXPAND flag

From: Bart Oldeman
Date: Thu Mar 11 2004 - 09:03:56 EST


Sometimes it is advantageous to mmap a special portion of /dev/mem
(framebuffer, ...) before dropping root priviliges. However right now a
program can simply mremap that area even after dropping root and if the
/dev/mem file descriptor is closed, thus being able to access arbitrary
portions of /dev/mem beyond the initial VMA start.

An idea to get around this is to expose the VM_DONTEXPAND flag to user
space via a MAP_DONTEXPAND flag, to be able to get failure in the
following example program (when it's suid-root):

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>

#define MAP_DONTEXPAND 0x20000

int main(void)
{
int fd = open("/dev/mem", O_RDWR);
mmap((char *)0xb8000, 0x8000, PROT_READ | PROT_WRITE,
MAP_SHARED|MAP_FIXED|MAP_DONTEXPAND, fd, 0xb8000);
close(fd);
setuid(getuid());
printf("%x\n", mremap((char *)0xb8000, 0x8000, 0x1000000, 0));
}


The patch below (for 2.6.3) is for i386 only but is easy to adjust
for other architectures, just because each of them has their own asm/mman.h.

Unless I'm completely overlooking something here ....

Bart

--- mm/mmap.c~ Wed Feb 25 19:21:10 2004
+++ mm/mmap.c Thu Mar 11 13:39:52 2004
@@ -511,6 +511,10 @@
vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;

+ if (flags & MAP_DONTEXPAND) {
+ vm_flags |= VM_DONTEXPAND;
+ }
+
if (flags & MAP_LOCKED) {
if (!capable(CAP_IPC_LOCK))
return -EPERM;
--- include/asm-i386/mman.h~ Sat Oct 25 19:42:58 2003
+++ include/asm-i386/mman.h Thu Mar 11 13:37:33 2004
@@ -22,6 +22,7 @@
#define MAP_NORESERVE 0x4000 /* don't check for reservations */
#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+#define MAP_DONTEXPAND 0x20000 /* do not allow mremap to expand */

#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/