diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 87302a49067..2253f388234 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -68,6 +68,7 @@ #include <linux/personality.h> #include <linux/sysctl.h> #include <linux/audit.h> +#include <linux/string.h> #include "avc.h" #include "objsec.h" @@ -825,7 +826,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent sid = sbsec->def_sid; rc = 0; } else { - rc = security_context_to_sid(context, rc, &sid); + rc = security_context_to_sid_default(context, rc, &sid, + sbsec->def_sid); if (rc) { printk(KERN_WARNING "%s: context_to_sid(%s) " "returned %d for dev=%s ino=%ld\n", @@ -1658,9 +1660,8 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm) static void selinux_bprm_free_security(struct linux_binprm *bprm) { - struct bprm_security_struct *bsec = bprm->security; + kfree(bprm->security); bprm->security = NULL; - kfree(bsec); } extern struct vfsmount *selinuxfs_mount; @@ -1944,7 +1945,7 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void } } while (*in_end++); - copy_page(in_save, nosec_save); + strcpy(in_save, nosec_save); free_page((unsigned long)nosec_save); out: return rc; @@ -2477,6 +2478,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, prot = reqprot; #ifndef CONFIG_PPC32 + if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) && + (vma->vm_start >= vma->vm_mm->start_brk && + vma->vm_end <= vma->vm_mm->brk)) { + /* + * We are making an executable mapping in the brk region. + * This has an additional execheap check. + */ + rc = task_has_perm(current, current, PROCESS__EXECHEAP); + if (rc) + return rc; + } if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { /* * We are making executable a file mapping that has @@ -2488,6 +2500,16 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, if (rc) return rc; } + if (!vma->vm_file && (prot & PROT_EXEC) && + vma->vm_start <= vma->vm_mm->start_stack && + vma->vm_end >= vma->vm_mm->start_stack) { + /* Attempt to make the process stack executable. + * This has an additional execstack check. + */ + rc = task_has_perm(current, current, PROCESS__EXECSTACK); + if (rc) + return rc; + } #endif return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); @@ -3104,12 +3126,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, if (sk->sk_family == PF_INET) { addr4 = (struct sockaddr_in *)address; - if (addrlen != sizeof(struct sockaddr_in)) + if (addrlen < sizeof(struct sockaddr_in)) return -EINVAL; snum = ntohs(addr4->sin_port); } else { addr6 = (struct sockaddr_in6 *)address; - if (addrlen != sizeof(struct sockaddr_in6)) + if (addrlen < SIN6_LEN_RFC2133) return -EINVAL; snum = ntohs(addr6->sin6_port); } |