aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-10-13 17:50:31 -0400
committerJames Morris <jmorris@namei.org>2010-10-20 19:12:59 -0400
commit845ca30fe9691f1bab7cfbf30b6d11c944eb4abd (patch)
treeeabf2b17957c2214375f870387eaab6c43d9e931 /security/selinux
parentcee74f47a6baba0ac457e87687fdcf0abd599f0a (diff)
selinux: implement mmap on /selinux/policy
/selinux/policy allows a user to copy the policy back out of the kernel. This patch allows userspace to actually mmap that file and use it directly. Signed-off-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/selinuxfs.c44
-rw-r--r--security/selinux/ss/services.c2
2 files changed, 45 insertions, 1 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 8eb102c72606..87e0556bae70 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -439,9 +439,53 @@ out:
439 return ret; 439 return ret;
440} 440}
441 441
442static int sel_mmap_policy_fault(struct vm_area_struct *vma,
443 struct vm_fault *vmf)
444{
445 struct policy_load_memory *plm = vma->vm_file->private_data;
446 unsigned long offset;
447 struct page *page;
448
449 if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
450 return VM_FAULT_SIGBUS;
451
452 offset = vmf->pgoff << PAGE_SHIFT;
453 if (offset >= roundup(plm->len, PAGE_SIZE))
454 return VM_FAULT_SIGBUS;
455
456 page = vmalloc_to_page(plm->data + offset);
457 get_page(page);
458
459 vmf->page = page;
460
461 return 0;
462}
463
464static struct vm_operations_struct sel_mmap_policy_ops = {
465 .fault = sel_mmap_policy_fault,
466 .page_mkwrite = sel_mmap_policy_fault,
467};
468
469int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
470{
471 if (vma->vm_flags & VM_SHARED) {
472 /* do not allow mprotect to make mapping writable */
473 vma->vm_flags &= ~VM_MAYWRITE;
474
475 if (vma->vm_flags & VM_WRITE)
476 return -EACCES;
477 }
478
479 vma->vm_flags |= VM_RESERVED;
480 vma->vm_ops = &sel_mmap_policy_ops;
481
482 return 0;
483}
484
442static const struct file_operations sel_policy_ops = { 485static const struct file_operations sel_policy_ops = {
443 .open = sel_open_policy, 486 .open = sel_open_policy,
444 .read = sel_read_policy, 487 .read = sel_read_policy,
488 .mmap = sel_mmap_policy,
445 .release = sel_release_policy, 489 .release = sel_release_policy,
446}; 490};
447 491
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 7565d16aac31..3a1739b33b78 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -3169,7 +3169,7 @@ int security_read_policy(void **data, ssize_t *len)
3169 3169
3170 *len = security_policydb_len(); 3170 *len = security_policydb_len();
3171 3171
3172 *data = vmalloc(*len); 3172 *data = vmalloc_user(*len);
3173 if (!*data) 3173 if (!*data)
3174 return -ENOMEM; 3174 return -ENOMEM;
3175 3175