[PATCH 1/3] security: define vm_revoke_write

From: Serge E . Hallyn
Date: Tue Aug 08 2006 - 11:23:19 EST


Define vm_revoke_write() function which may be used to revoke write
permission from a vma_area_struct. This can be used, for example,
by security modules wishing to revoke write permissions to a process
whose clearance has changed.

The first intended user for this function is the SLIM LSM, which
implements dynamic process integrity labels. As integrity labels
on a process lower, write permission may need to be revoked to
high integrity files.

Signed-off-by: Serge E. Hallyn <serue@xxxxxxxxxx>
---
include/linux/mm.h | 2 ++
mm/mprotect.c | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 990957e..cad1936 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1072,5 +1072,7 @@ #endif

const char *arch_vma_name(struct vm_area_struct *vma);

+extern void vm_revoke_write(struct vm_area_struct *vma);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 638edab..21c322e 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -21,6 +21,7 @@ #include <linux/personality.h>
#include <linux/syscalls.h>
#include <linux/swap.h>
#include <linux/swapops.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
@@ -115,6 +116,23 @@ static void change_protection(struct vm_
flush_tlb_range(vma, start, end);
}

+void vm_revoke_write(struct vm_area_struct *vma)
+{
+ pgprot_t newprot;
+
+ down_write(&current->mm->mmap_sem);
+ if (!(vma->vm_flags & VM_SHARED))
+ goto out;
+ if (!(vma->vm_flags & (VM_WRITE|VM_MAYWRITE)))
+ goto out;
+ vma->vm_flags &= ~(VM_MAYWRITE|VM_WRITE);
+ newprot = protection_map[vma->vm_flags];
+ change_protection(vma, vma->vm_start, vma->vm_end, newprot);
+out:
+ up_write(&current->mm->mmap_sem);
+}
+EXPORT_SYMBOL_GPL(vm_revoke_write);
+
static int
mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
unsigned long start, unsigned long end, unsigned long newflags)
--
1.4.1.1