[PATCH] Fix bugs in SELinux mprotect hook

From: James Morris
Date: Tue Sep 28 2004 - 21:28:23 EST


The patch below by Roland McGrath fixes two bugs in the implementation of
the selinux_file_mprotect hook:

It calls selinux_file_mmap, which has two problems. First, the stacked
security module will get both mmap and mprotect callbacks for an
mprotect call, which is wrong. Secondly, the vm_flags value contains
VM_* bits, and these do not match the MAP_* bits of the same name or
function, so it passes bogus flags and causes every mprotect to be
treated as if MAP_SHARED were in use.

The patch shares the common code while not having one function call the
other, and fixes these two bugs.

Please apply.

Signed-off-by: James Morris <jmorris@xxxxxxxxxx>
Signed-off-by: Roland McGrath <roland@xxxxxxxxxx>


diff -purN -X dontdiff linux-2.6.9-rc2-bk14.o/security/selinux/hooks.c linux-2.6.9-rc2-bk14.w/security/selinux/hooks.c
--- linux-2.6.9-rc2-bk14.o/security/selinux/hooks.c 2004-09-13 01:33:37.000000000 -0400
+++ linux-2.6.9-rc2-bk14.w/security/selinux/hooks.c 2004-09-28 22:04:53.306900408 -0400
@@ -2466,21 +2466,14 @@ static int selinux_file_ioctl(struct fil
return error;
}

-static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned long flags)
+static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
{
- u32 av;
- int rc;
-
- rc = secondary_ops->file_mmap(file, prot, flags);
- if (rc)
- return rc;
-
if (file) {
/* read access is always possible with a mapping */
- av = FILE__READ;
+ u32 av = FILE__READ;

/* write access only matters if the mapping is shared */
- if ((flags & MAP_TYPE) == MAP_SHARED && (prot & PROT_WRITE))
+ if (shared && (prot & PROT_WRITE))
av |= FILE__WRITE;

if (prot & PROT_EXEC)
@@ -2491,6 +2484,18 @@ static int selinux_file_mmap(struct file
return 0;
}

+static int selinux_file_mmap(struct file *file, unsigned long prot, unsigned long flags)
+{
+ int rc;
+
+ rc = secondary_ops->file_mmap(file, prot, flags);
+ if (rc)
+ return rc;
+
+ return file_map_prot_check(file, prot,
+ (flags & MAP_TYPE) == MAP_SHARED);
+}
+
static int selinux_file_mprotect(struct vm_area_struct *vma,
unsigned long prot)
{
@@ -2500,7 +2505,7 @@ static int selinux_file_mprotect(struct
if (rc)
return rc;

- return selinux_file_mmap(vma->vm_file, prot, vma->vm_flags);
+ return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
}

static int selinux_file_lock(struct file *file, unsigned int cmd)

-
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/