diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2010-04-28 15:57:57 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-04-28 18:58:45 -0400 |
commit | fcaaade1db63bb2d6f7611d7824eb50d2f07a546 (patch) | |
tree | 9091dbdd0c9bd1e3af9ece6f5cce5c0d6c258253 | |
parent | cb84aa9b42b506299e5aea1ba4da26c03ab12877 (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.c | 14 |
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 | ||
3002 | static int default_noexec; | ||
3003 | |||
3002 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) | 3004 | static 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); |