aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2010-04-28 15:57:57 -0400
committerJames Morris <jmorris@namei.org>2010-04-28 18:58:45 -0400
commitfcaaade1db63bb2d6f7611d7824eb50d2f07a546 (patch)
tree9091dbdd0c9bd1e3af9ece6f5cce5c0d6c258253
parentcb84aa9b42b506299e5aea1ba4da26c03ab12877 (diff)
selinux: generalize disabling of execmem for plt-in-heap archs
On Tue, 2010-04-27 at 11:47 -0700, David Miller wrote: > From: "Tom \"spot\" Callaway" <tcallawa@redhat.com> > Date: Tue, 27 Apr 2010 14:20:21 -0400 > > > [root@apollo ~]$ cat /proc/2174/maps > > 00010000-00014000 r-xp 00000000 fd:00 15466577 > > /sbin/mingetty > > 00022000-00024000 rwxp 00002000 fd:00 15466577 > > /sbin/mingetty > > 00024000-00046000 rwxp 00000000 00:00 0 > > [heap] > > SELINUX probably barfs on the executable heap, the PLT is in the HEAP > just like powerpc32 and that's why VM_DATA_DEFAULT_FLAGS has to set > both executable and writable. > > You also can't remove the CONFIG_PPC32 ifdefs in selinux, since > because of the VM_DATA_DEFAULT_FLAGS setting used still in that arch, > the heap will always have executable permission, just like sparc does. > You have to support those binaries forever, whether you like it or not. > > Let's just replace the CONFIG_PPC32 ifdef in SELINUX with CONFIG_PPC32 > || CONFIG_SPARC as in Tom's original patch and let's be done with > this. > > In fact I would go through all the arch/ header files and check the > VM_DATA_DEFAULT_FLAGS settings and add the necessary new ifdefs to the > SELINUX code so that other platforms don't have the pain of having to > go through this process too. To avoid maintaining per-arch ifdefs, it seems that we could just directly use (VM_DATA_DEFAULT_FLAGS & VM_EXEC) as the basis for deciding whether to enable or disable these checks. VM_DATA_DEFAULT_FLAGS isn't constant on some architectures but instead depends on current->personality, but we want this applied uniformly. So we'll just use the initial task state to determine whether or not to enable these checks. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--security/selinux/hooks.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ebee467e2913..a03fd74602b4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2999,13 +2999,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
2999 return file_has_perm(cred, file, av); 2999 return file_has_perm(cred, file, av);
3000} 3000}
3001 3001
3002static int default_noexec;
3003
3002static int file_map_prot_check(struct file *file, unsigned long prot, int shared) 3004static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3003{ 3005{
3004 const struct cred *cred = current_cred(); 3006 const struct cred *cred = current_cred();
3005 int rc = 0; 3007 int rc = 0;
3006 3008
3007#ifndef CONFIG_PPC32 3009 if (default_noexec &&
3008 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { 3010 (prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
3009 /* 3011 /*
3010 * We are making executable an anonymous mapping or a 3012 * We are making executable an anonymous mapping or a
3011 * private file mapping that will also be writable. 3013 * private file mapping that will also be writable.
@@ -3015,7 +3017,6 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
3015 if (rc) 3017 if (rc)
3016 goto error; 3018 goto error;
3017 } 3019 }
3018#endif
3019 3020
3020 if (file) { 3021 if (file) {
3021 /* read access is always possible with a mapping */ 3022 /* read access is always possible with a mapping */
@@ -3076,8 +3077,8 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3076 if (selinux_checkreqprot) 3077 if (selinux_checkreqprot)
3077 prot = reqprot; 3078 prot = reqprot;
3078 3079
3079#ifndef CONFIG_PPC32 3080 if (default_noexec &&
3080 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { 3081 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
3081 int rc = 0; 3082 int rc = 0;
3082 if (vma->vm_start >= vma->vm_mm->start_brk && 3083 if (vma->vm_start >= vma->vm_mm->start_brk &&
3083 vma->vm_end <= vma->vm_mm->brk) { 3084 vma->vm_end <= vma->vm_mm->brk) {
@@ -3099,7 +3100,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3099 if (rc) 3100 if (rc)
3100 return rc; 3101 return rc;
3101 } 3102 }
3102#endif
3103 3103
3104 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); 3104 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3105} 3105}
@@ -5662,6 +5662,8 @@ static __init int selinux_init(void)
5662 /* Set the security state for the initial task. */ 5662 /* Set the security state for the initial task. */
5663 cred_init_security(); 5663 cred_init_security();
5664 5664
5665 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
5666
5665 sel_inode_cache = kmem_cache_create("selinux_inode_security", 5667 sel_inode_cache = kmem_cache_create("selinux_inode_security",
5666 sizeof(struct inode_security_struct), 5668 sizeof(struct inode_security_struct),
5667 0, SLAB_PANIC, NULL); 5669 0, SLAB_PANIC, NULL);