[PATCH] selinux_sb_copy_data() should not require a whole page
[linux-2.6.git] / security / selinux / hooks.c
index 8a2cc75..6be2738 100644 (file)
@@ -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"
@@ -672,6 +673,8 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
                        return SECCLASS_NETLINK_IP6FW_SOCKET;
                case NETLINK_DNRTMSG:
                        return SECCLASS_NETLINK_DNRT_SOCKET;
+               case NETLINK_KOBJECT_UEVENT:
+                       return SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET;
                default:
                        return SECCLASS_NETLINK_SOCKET;
                }
@@ -1656,9 +1659,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;
@@ -1942,7 +1944,8 @@ 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;
 }
@@ -2474,6 +2477,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
@@ -2485,6 +2499,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);
@@ -2853,8 +2877,7 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad
 
        nexthdr = ip6->nexthdr;
        offset += sizeof(_ipv6h);
-       offset = ipv6_skip_exthdr(skb, offset, &nexthdr,
-                                 skb->tail - skb->head - offset);
+       offset = ipv6_skip_exthdr(skb, offset, &nexthdr);
        if (offset < 0)
                goto out;
 
@@ -3418,7 +3441,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
        err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
        if (err) {
                if (err == -EINVAL) {
-                       audit_log(current->audit_context,
+                       audit_log(current->audit_context, AUDIT_SELINUX_ERR,
                                  "SELinux:  unrecognized netlink message"
                                  " type=%hu for sclass=%hu\n",
                                  nlh->nlmsg_type, isec->sclass);
@@ -3666,7 +3689,7 @@ static void msg_msg_free_security(struct msg_msg *msg)
 }
 
 static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
-                       u16 sclass, u32 perms)
+                       u32 perms)
 {
        struct task_security_struct *tsec;
        struct ipc_security_struct *isec;
@@ -3678,7 +3701,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
        AVC_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = ipc_perms->key;
 
-       return avc_has_perm(tsec->sid, isec->sid, sclass, perms, &ad);
+       return avc_has_perm(tsec->sid, isec->sid, isec->sclass, perms, &ad);
 }
 
 static int selinux_msg_msg_alloc_security(struct msg_msg *msg)
@@ -3763,7 +3786,7 @@ static int selinux_msg_queue_msgctl(struct msg_queue *msq, int cmd)
                return 0;
        }
 
-       err = ipc_has_perm(&msq->q_perm, SECCLASS_MSGQ, perms);
+       err = ipc_has_perm(&msq->q_perm, perms);
        return err;
 }
 
@@ -3915,7 +3938,7 @@ static int selinux_shm_shmctl(struct shmid_kernel *shp, int cmd)
                return 0;
        }
 
-       err = ipc_has_perm(&shp->shm_perm, SECCLASS_SHM, perms);
+       err = ipc_has_perm(&shp->shm_perm, perms);
        return err;
 }
 
@@ -3934,7 +3957,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
        else
                perms = SHM__READ | SHM__WRITE;
 
-       return ipc_has_perm(&shp->shm_perm, SECCLASS_SHM, perms);
+       return ipc_has_perm(&shp->shm_perm, perms);
 }
 
 /* Semaphore security operations */
@@ -4023,7 +4046,7 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd)
                return 0;
        }
 
-       err = ipc_has_perm(&sma->sem_perm, SECCLASS_SEM, perms);
+       err = ipc_has_perm(&sma->sem_perm, perms);
        return err;
 }
 
@@ -4037,18 +4060,13 @@ static int selinux_sem_semop(struct sem_array *sma,
        else
                perms = SEM__READ;
 
-       return ipc_has_perm(&sma->sem_perm, SECCLASS_SEM, perms);
+       return ipc_has_perm(&sma->sem_perm, perms);
 }
 
 static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
 {
-       struct ipc_security_struct *isec = ipcp->security;
-       u16 sclass = SECCLASS_IPC;
        u32 av = 0;
 
-       if (isec && isec->magic == SELINUX_MAGIC)
-               sclass = isec->sclass;
-
        av = 0;
        if (flag & S_IRUGO)
                av |= IPC__UNIX_READ;
@@ -4058,7 +4076,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
        if (av == 0)
                return 0;
 
-       return ipc_has_perm(ipcp, sclass, av);
+       return ipc_has_perm(ipcp, av);
 }
 
 /* module stacking operations */