SELinux: Convert avc_audit to use lsm_audit.h
[safe/jmp/linux-2.6] / security / selinux / hooks.c
index 7c52ba2..254b798 100644 (file)
@@ -93,7 +93,6 @@
 
 extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
-extern int selinux_compat_net;
 extern struct security_operations *security_ops;
 
 /* SECMARK reference count */
@@ -311,7 +310,7 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
        ssec->sid = SECINITSID_UNLABELED;
        sk->sk_security = ssec;
 
-       selinux_netlbl_sk_security_reset(ssec, family);
+       selinux_netlbl_sk_security_reset(ssec);
 
        return 0;
 }
@@ -1479,14 +1478,14 @@ static int task_has_capability(struct task_struct *tsk,
                               const struct cred *cred,
                               int cap, int audit)
 {
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        struct av_decision avd;
        u16 sclass;
        u32 sid = cred_sid(cred);
        u32 av = CAP_TO_MASK(cap);
        int rc;
 
-       AVC_AUDIT_DATA_INIT(&ad, CAP);
+       COMMON_AUDIT_DATA_INIT(&ad, CAP);
        ad.tsk = tsk;
        ad.u.cap = cap;
 
@@ -1525,10 +1524,10 @@ static int task_has_system(struct task_struct *tsk,
 static int inode_has_perm(const struct cred *cred,
                          struct inode *inode,
                          u32 perms,
-                         struct avc_audit_data *adp)
+                         struct common_audit_data *adp)
 {
        struct inode_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid;
 
        if (unlikely(IS_PRIVATE(inode)))
@@ -1539,7 +1538,7 @@ static int inode_has_perm(const struct cred *cred,
 
        if (!adp) {
                adp = &ad;
-               AVC_AUDIT_DATA_INIT(&ad, FS);
+               COMMON_AUDIT_DATA_INIT(&ad, FS);
                ad.u.fs.inode = inode;
        }
 
@@ -1555,9 +1554,9 @@ static inline int dentry_has_perm(const struct cred *cred,
                                  u32 av)
 {
        struct inode *inode = dentry->d_inode;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path.mnt = mnt;
        ad.u.fs.path.dentry = dentry;
        return inode_has_perm(cred, inode, av, &ad);
@@ -1577,11 +1576,11 @@ static int file_has_perm(const struct cred *cred,
 {
        struct file_security_struct *fsec = file->f_security;
        struct inode *inode = file->f_path.dentry->d_inode;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = cred_sid(cred);
        int rc;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path = file->f_path;
 
        if (sid != fsec->sid) {
@@ -1612,7 +1611,7 @@ static int may_create(struct inode *dir,
        struct inode_security_struct *dsec;
        struct superblock_security_struct *sbsec;
        u32 sid, newsid;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        int rc;
 
        dsec = dir->i_security;
@@ -1621,7 +1620,7 @@ static int may_create(struct inode *dir,
        sid = tsec->sid;
        newsid = tsec->create_sid;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path.dentry = dentry;
 
        rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
@@ -1665,7 +1664,7 @@ static int may_link(struct inode *dir,
 
 {
        struct inode_security_struct *dsec, *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
        u32 av;
        int rc;
@@ -1673,7 +1672,7 @@ static int may_link(struct inode *dir,
        dsec = dir->i_security;
        isec = dentry->d_inode->i_security;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path.dentry = dentry;
 
        av = DIR__SEARCH;
@@ -1708,7 +1707,7 @@ static inline int may_rename(struct inode *old_dir,
                             struct dentry *new_dentry)
 {
        struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
        u32 av;
        int old_is_dir, new_is_dir;
@@ -1719,7 +1718,7 @@ static inline int may_rename(struct inode *old_dir,
        old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
        new_dsec = new_dir->i_security;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
 
        ad.u.fs.path.dentry = old_dentry;
        rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
@@ -1761,7 +1760,7 @@ static inline int may_rename(struct inode *old_dir,
 static int superblock_has_perm(const struct cred *cred,
                               struct super_block *sb,
                               u32 perms,
-                              struct avc_audit_data *ad)
+                              struct common_audit_data *ad)
 {
        struct superblock_security_struct *sbsec;
        u32 sid = cred_sid(cred);
@@ -1855,12 +1854,12 @@ static inline u32 open_file_to_av(struct file *file)
 
 /* Hook functions begin here. */
 
-static int selinux_ptrace_may_access(struct task_struct *child,
+static int selinux_ptrace_access_check(struct task_struct *child,
                                     unsigned int mode)
 {
        int rc;
 
-       rc = cap_ptrace_may_access(child, mode);
+       rc = cap_ptrace_access_check(child, mode);
        if (rc)
                return rc;
 
@@ -1981,10 +1980,6 @@ static int selinux_sysctl(ctl_table *table, int op)
        u32 tsid, sid;
        int rc;
 
-       rc = secondary_ops->sysctl(table, op);
-       if (rc)
-               return rc;
-
        sid = current_sid();
 
        rc = selinux_sysctl_get_sid(table, (op == 0001) ?
@@ -2105,7 +2100,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
        const struct task_security_struct *old_tsec;
        struct task_security_struct *new_tsec;
        struct inode_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        struct inode *inode = bprm->file->f_path.dentry->d_inode;
        int rc;
 
@@ -2143,7 +2138,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
                        return rc;
        }
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path = bprm->file->f_path;
 
        if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
@@ -2236,7 +2231,7 @@ extern struct dentry *selinux_null;
 static inline void flush_unauthorized_files(const struct cred *cred,
                                            struct files_struct *files)
 {
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        struct file *file, *devnull = NULL;
        struct tty_struct *tty;
        struct fdtable *fdt;
@@ -2270,7 +2265,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
 
        /* Revalidate access to inherited open files. */
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
 
        spin_lock(&files->file_lock);
        for (;;) {
@@ -2376,10 +2371,8 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
 {
        const struct task_security_struct *tsec = current_security();
        struct itimerval itimer;
-       struct sighand_struct *psig;
        u32 osid, sid;
        int rc, i;
-       unsigned long flags;
 
        osid = tsec->osid;
        sid = tsec->sid;
@@ -2399,22 +2392,20 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
                memset(&itimer, 0, sizeof itimer);
                for (i = 0; i < 3; i++)
                        do_setitimer(i, &itimer, NULL);
-               flush_signals(current);
                spin_lock_irq(&current->sighand->siglock);
-               flush_signal_handlers(current, 1);
-               sigemptyset(&current->blocked);
-               recalc_sigpending();
+               if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
+                       __flush_signals(current);
+                       flush_signal_handlers(current, 1);
+                       sigemptyset(&current->blocked);
+               }
                spin_unlock_irq(&current->sighand->siglock);
        }
 
        /* Wake up the parent if it is waiting so that it can recheck
         * wait permission to the new task SID. */
-       read_lock_irq(&tasklist_lock);
-       psig = current->parent->sighand;
-       spin_lock_irqsave(&psig->siglock, flags);
-       wake_up_interruptible(&current->parent->signal->wait_chldexit);
-       spin_unlock_irqrestore(&psig->siglock, flags);
-       read_unlock_irq(&tasklist_lock);
+       read_lock(&tasklist_lock);
+       wake_up_interruptible(&current->real_parent->signal->wait_chldexit);
+       read_unlock(&tasklist_lock);
 }
 
 /* superblock security operations */
@@ -2523,7 +2514,7 @@ out:
 static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
 {
        const struct cred *cred = current_cred();
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        int rc;
 
        rc = superblock_doinit(sb, data);
@@ -2534,7 +2525,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
        if (flags & MS_KERNMOUNT)
                return 0;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path.dentry = sb->s_root;
        return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
 }
@@ -2542,9 +2533,9 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
 static int selinux_sb_statfs(struct dentry *dentry)
 {
        const struct cred *cred = current_cred();
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path.dentry = dentry->d_sb->s_root;
        return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
 }
@@ -2764,7 +2755,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
        struct inode *inode = dentry->d_inode;
        struct inode_security_struct *isec = inode->i_security;
        struct superblock_security_struct *sbsec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 newsid, sid = current_sid();
        int rc = 0;
 
@@ -2778,7 +2769,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
        if (!is_owner_or_cap(inode))
                return -EPERM;
 
-       AVC_AUDIT_DATA_INIT(&ad, FS);
+       COMMON_AUDIT_DATA_INIT(&ad, FS);
        ad.u.fs.path.dentry = dentry;
 
        rc = avc_has_perm(sid, isec->sid, isec->sclass,
@@ -2945,24 +2936,14 @@ static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
 static int selinux_revalidate_file_permission(struct file *file, int mask)
 {
        const struct cred *cred = current_cred();
-       int rc;
        struct inode *inode = file->f_path.dentry->d_inode;
 
-       if (!mask) {
-               /* No permission to check.  Existence test. */
-               return 0;
-       }
-
        /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */
        if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
                mask |= MAY_APPEND;
 
-       rc = file_has_perm(cred, file,
-                          file_mask_to_av(inode->i_mode, mask));
-       if (rc)
-               return rc;
-
-       return selinux_netlbl_inode_permission(inode, mask);
+       return file_has_perm(cred, file,
+                            file_mask_to_av(inode->i_mode, mask));
 }
 
 static int selinux_file_permission(struct file *file, int mask)
@@ -2972,14 +2953,14 @@ static int selinux_file_permission(struct file *file, int mask)
        struct inode_security_struct *isec = inode->i_security;
        u32 sid = current_sid();
 
-       if (!mask) {
+       if (!mask)
                /* No permission to check.  Existence test. */
                return 0;
-       }
 
-       if (sid == fsec->sid && fsec->isid == isec->sid
-           && fsec->pseqno == avc_policy_seqno())
-               return selinux_netlbl_inode_permission(inode, mask);
+       if (sid == fsec->sid && fsec->isid == isec->sid &&
+           fsec->pseqno == avc_policy_seqno())
+               /* No change since dentry_open check. */
+               return 0;
 
        return selinux_revalidate_file_permission(file, mask);
 }
@@ -3053,9 +3034,21 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot,
        int rc = 0;
        u32 sid = current_sid();
 
-       if (addr < mmap_min_addr)
+       /*
+        * notice that we are intentionally putting the SELinux check before
+        * the secondary cap_file_mmap check.  This is such a likely attempt
+        * at bad behaviour/exploit that we always want to get the AVC, even
+        * if DAC would have also denied the operation.
+        */
+       if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
                rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
                                  MEMPROTECT__MMAP_ZERO, NULL);
+               if (rc)
+                       return rc;
+       }
+
+       /* do DAC check on address space usage */
+       rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
        if (rc || addr_only)
                return rc;
 
@@ -3169,7 +3162,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
                                       struct fown_struct *fown, int signum)
 {
        struct file *file;
-       u32 sid = current_sid();
+       u32 sid = task_sid(tsk);
        u32 perm;
        struct file_security_struct *fsec;
 
@@ -3303,6 +3296,11 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
        return 0;
 }
 
+static int selinux_kernel_module_request(void)
+{
+       return task_has_system(current, SYSTEM__MODULE_REQUEST);
+}
+
 static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return current_has_perm(p, PROCESS__SETPGID);
@@ -3420,7 +3418,7 @@ static void selinux_task_to_inode(struct task_struct *p,
 
 /* Returns error only if unable to parse addresses */
 static int selinux_parse_skb_ipv4(struct sk_buff *skb,
-                       struct avc_audit_data *ad, u8 *proto)
+                       struct common_audit_data *ad, u8 *proto)
 {
        int offset, ihlen, ret = -EINVAL;
        struct iphdr _iph, *ih;
@@ -3501,7 +3499,7 @@ out:
 
 /* Returns error only if unable to parse addresses */
 static int selinux_parse_skb_ipv6(struct sk_buff *skb,
-                       struct avc_audit_data *ad, u8 *proto)
+                       struct common_audit_data *ad, u8 *proto)
 {
        u8 nexthdr;
        int ret = -EINVAL, offset;
@@ -3572,7 +3570,7 @@ out:
 
 #endif /* IPV6 */
 
-static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
+static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
                             char **_addrp, int src, u8 *proto)
 {
        char *addrp;
@@ -3654,7 +3652,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
                           u32 perms)
 {
        struct inode_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid;
        int err = 0;
 
@@ -3664,7 +3662,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock,
                goto out;
        sid = task_sid(task);
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.sk = sock->sk;
        err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
 
@@ -3723,7 +3721,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
                sksec = sock->sk->sk_security;
                sksec->sid = isec->sid;
                sksec->sclass = isec->sclass;
-               err = selinux_netlbl_socket_post_create(sock);
+               err = selinux_netlbl_socket_post_create(sock->sk, family);
        }
 
        return err;
@@ -3751,7 +3749,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
        if (family == PF_INET || family == PF_INET6) {
                char *addrp;
                struct inode_security_struct *isec;
-               struct avc_audit_data ad;
+               struct common_audit_data ad;
                struct sockaddr_in *addr4 = NULL;
                struct sockaddr_in6 *addr6 = NULL;
                unsigned short snum;
@@ -3780,7 +3778,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                                                      snum, &sid);
                                if (err)
                                        goto out;
-                               AVC_AUDIT_DATA_INIT(&ad, NET);
+                               COMMON_AUDIT_DATA_INIT(&ad, NET);
                                ad.u.net.sport = htons(snum);
                                ad.u.net.family = family;
                                err = avc_has_perm(isec->sid, sid,
@@ -3813,7 +3811,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                if (err)
                        goto out;
 
-               AVC_AUDIT_DATA_INIT(&ad, NET);
+               COMMON_AUDIT_DATA_INIT(&ad, NET);
                ad.u.net.sport = htons(snum);
                ad.u.net.family = family;
 
@@ -3847,7 +3845,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
        isec = SOCK_INODE(sock)->i_security;
        if (isec->sclass == SECCLASS_TCP_SOCKET ||
            isec->sclass == SECCLASS_DCCP_SOCKET) {
-               struct avc_audit_data ad;
+               struct common_audit_data ad;
                struct sockaddr_in *addr4 = NULL;
                struct sockaddr_in6 *addr6 = NULL;
                unsigned short snum;
@@ -3872,7 +3870,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
                perm = (isec->sclass == SECCLASS_TCP_SOCKET) ?
                       TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
 
-               AVC_AUDIT_DATA_INIT(&ad, NET);
+               COMMON_AUDIT_DATA_INIT(&ad, NET);
                ad.u.net.dport = htons(snum);
                ad.u.net.family = sk->sk_family;
                err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad);
@@ -3914,13 +3912,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
 static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
                                  int size)
 {
-       int rc;
-
-       rc = socket_has_perm(current, sock, SOCKET__WRITE);
-       if (rc)
-               return rc;
-
-       return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE);
+       return socket_has_perm(current, sock, SOCKET__WRITE);
 }
 
 static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
@@ -3968,13 +3960,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
        struct sk_security_struct *ssec;
        struct inode_security_struct *isec;
        struct inode_security_struct *other_isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        int err;
 
        isec = SOCK_INODE(sock)->i_security;
        other_isec = SOCK_INODE(other)->i_security;
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.sk = other->sk;
 
        err = avc_has_perm(isec->sid, other_isec->sid,
@@ -4000,13 +3992,13 @@ static int selinux_socket_unix_may_send(struct socket *sock,
 {
        struct inode_security_struct *isec;
        struct inode_security_struct *other_isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        int err;
 
        isec = SOCK_INODE(sock)->i_security;
        other_isec = SOCK_INODE(other)->i_security;
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.sk = other->sk;
 
        err = avc_has_perm(isec->sid, other_isec->sid,
@@ -4019,7 +4011,7 @@ static int selinux_socket_unix_may_send(struct socket *sock,
 
 static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
                                    u32 peer_sid,
-                                   struct avc_audit_data *ad)
+                                   struct common_audit_data *ad)
 {
        int err;
        u32 if_sid;
@@ -4040,72 +4032,6 @@ static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
                            SECCLASS_NODE, NODE__RECVFROM, ad);
 }
 
-static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
-                                               struct sk_buff *skb,
-                                               struct avc_audit_data *ad,
-                                               u16 family,
-                                               char *addrp)
-{
-       int err;
-       struct sk_security_struct *sksec = sk->sk_security;
-       u16 sk_class;
-       u32 netif_perm, node_perm, recv_perm;
-       u32 port_sid, node_sid, if_sid, sk_sid;
-
-       sk_sid = sksec->sid;
-       sk_class = sksec->sclass;
-
-       switch (sk_class) {
-       case SECCLASS_UDP_SOCKET:
-               netif_perm = NETIF__UDP_RECV;
-               node_perm = NODE__UDP_RECV;
-               recv_perm = UDP_SOCKET__RECV_MSG;
-               break;
-       case SECCLASS_TCP_SOCKET:
-               netif_perm = NETIF__TCP_RECV;
-               node_perm = NODE__TCP_RECV;
-               recv_perm = TCP_SOCKET__RECV_MSG;
-               break;
-       case SECCLASS_DCCP_SOCKET:
-               netif_perm = NETIF__DCCP_RECV;
-               node_perm = NODE__DCCP_RECV;
-               recv_perm = DCCP_SOCKET__RECV_MSG;
-               break;
-       default:
-               netif_perm = NETIF__RAWIP_RECV;
-               node_perm = NODE__RAWIP_RECV;
-               recv_perm = 0;
-               break;
-       }
-
-       err = sel_netif_sid(skb->iif, &if_sid);
-       if (err)
-               return err;
-       err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
-       if (err)
-               return err;
-
-       err = sel_netnode_sid(addrp, family, &node_sid);
-       if (err)
-               return err;
-       err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad);
-       if (err)
-               return err;
-
-       if (!recv_perm)
-               return 0;
-       err = sel_netport_sid(sk->sk_protocol,
-                             ntohs(ad->u.net.sport), &port_sid);
-       if (unlikely(err)) {
-               printk(KERN_WARNING
-                      "SELinux: failure in"
-                      " selinux_sock_rcv_skb_iptables_compat(),"
-                      " network port label not found\n");
-               return err;
-       }
-       return avc_has_perm(sk_sid, port_sid, sk_class, recv_perm, ad);
-}
-
 static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
                                       u16 family)
 {
@@ -4113,24 +4039,22 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
        struct sk_security_struct *sksec = sk->sk_security;
        u32 peer_sid;
        u32 sk_sid = sksec->sid;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        char *addrp;
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.netif = skb->iif;
        ad.u.net.family = family;
        err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
        if (err)
                return err;
 
-       if (selinux_compat_net)
-               err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad,
-                                                          family, addrp);
-       else if (selinux_secmark_enabled())
+       if (selinux_secmark_enabled()) {
                err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET,
                                   PACKET__RECV, &ad);
-       if (err)
-               return err;
+               if (err)
+                       return err;
+       }
 
        if (selinux_policycap_netpeer) {
                err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
@@ -4156,7 +4080,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        struct sk_security_struct *sksec = sk->sk_security;
        u16 family = sk->sk_family;
        u32 sk_sid = sksec->sid;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        char *addrp;
        u8 secmark_active;
        u8 peerlbl_active;
@@ -4172,7 +4096,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
         * to the selinux_sock_rcv_skb_compat() function to deal with the
         * special handling.  We do this in an attempt to keep this function
         * as fast and as clean as possible. */
-       if (selinux_compat_net || !selinux_policycap_netpeer)
+       if (!selinux_policycap_netpeer)
                return selinux_sock_rcv_skb_compat(sk, skb, family);
 
        secmark_active = selinux_secmark_enabled();
@@ -4180,7 +4104,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        if (!secmark_active && !peerlbl_active)
                return 0;
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.netif = skb->iif;
        ad.u.net.family = family;
        err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
@@ -4304,7 +4228,7 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
        newssec->peer_sid = ssec->peer_sid;
        newssec->sclass = ssec->sclass;
 
-       selinux_netlbl_sk_security_reset(newssec, newsk->sk_family);
+       selinux_netlbl_sk_security_reset(newssec);
 }
 
 static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -4348,16 +4272,15 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
        if (peersid == SECSID_NULL) {
                req->secid = sksec->sid;
                req->peer_secid = SECSID_NULL;
-               return 0;
+       } else {
+               err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
+               if (err)
+                       return err;
+               req->secid = newsid;
+               req->peer_secid = peersid;
        }
 
-       err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
-       if (err)
-               return err;
-
-       req->secid = newsid;
-       req->peer_secid = peersid;
-       return 0;
+       return selinux_netlbl_inet_conn_request(req, family);
 }
 
 static void selinux_inet_csk_clone(struct sock *newsk,
@@ -4374,7 +4297,7 @@ static void selinux_inet_csk_clone(struct sock *newsk,
 
        /* We don't need to take any sort of lock here as we are the only
         * thread with access to newsksec */
-       selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family);
+       selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family);
 }
 
 static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
@@ -4387,8 +4310,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
                family = PF_INET;
 
        selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
-
-       selinux_netlbl_inet_conn_established(sk, family);
 }
 
 static void selinux_req_classify_flow(const struct request_sock *req,
@@ -4441,7 +4362,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
        int err;
        char *addrp;
        u32 peer_sid;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u8 secmark_active;
        u8 netlbl_active;
        u8 peerlbl_active;
@@ -4458,7 +4379,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
        if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
                return NF_DROP;
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.netif = ifindex;
        ad.u.net.family = family;
        if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
@@ -4540,78 +4461,13 @@ static unsigned int selinux_ipv4_output(unsigned int hooknum,
        return selinux_ip_output(skb, PF_INET);
 }
 
-static int selinux_ip_postroute_iptables_compat(struct sock *sk,
-                                               int ifindex,
-                                               struct avc_audit_data *ad,
-                                               u16 family, char *addrp)
-{
-       int err;
-       struct sk_security_struct *sksec = sk->sk_security;
-       u16 sk_class;
-       u32 netif_perm, node_perm, send_perm;
-       u32 port_sid, node_sid, if_sid, sk_sid;
-
-       sk_sid = sksec->sid;
-       sk_class = sksec->sclass;
-
-       switch (sk_class) {
-       case SECCLASS_UDP_SOCKET:
-               netif_perm = NETIF__UDP_SEND;
-               node_perm = NODE__UDP_SEND;
-               send_perm = UDP_SOCKET__SEND_MSG;
-               break;
-       case SECCLASS_TCP_SOCKET:
-               netif_perm = NETIF__TCP_SEND;
-               node_perm = NODE__TCP_SEND;
-               send_perm = TCP_SOCKET__SEND_MSG;
-               break;
-       case SECCLASS_DCCP_SOCKET:
-               netif_perm = NETIF__DCCP_SEND;
-               node_perm = NODE__DCCP_SEND;
-               send_perm = DCCP_SOCKET__SEND_MSG;
-               break;
-       default:
-               netif_perm = NETIF__RAWIP_SEND;
-               node_perm = NODE__RAWIP_SEND;
-               send_perm = 0;
-               break;
-       }
-
-       err = sel_netif_sid(ifindex, &if_sid);
-       if (err)
-               return err;
-       err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
-               return err;
-
-       err = sel_netnode_sid(addrp, family, &node_sid);
-       if (err)
-               return err;
-       err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad);
-       if (err)
-               return err;
-
-       if (send_perm != 0)
-               return 0;
-
-       err = sel_netport_sid(sk->sk_protocol,
-                             ntohs(ad->u.net.dport), &port_sid);
-       if (unlikely(err)) {
-               printk(KERN_WARNING
-                      "SELinux: failure in"
-                      " selinux_ip_postroute_iptables_compat(),"
-                      " network port label not found\n");
-               return err;
-       }
-       return avc_has_perm(sk_sid, port_sid, sk_class, send_perm, ad);
-}
-
 static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                                                int ifindex,
                                                u16 family)
 {
        struct sock *sk = skb->sk;
        struct sk_security_struct *sksec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        char *addrp;
        u8 proto;
 
@@ -4619,21 +4475,16 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                return NF_ACCEPT;
        sksec = sk->sk_security;
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.netif = ifindex;
        ad.u.net.family = family;
        if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
                return NF_DROP;
 
-       if (selinux_compat_net) {
-               if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex,
-                                                        &ad, family, addrp))
-                       return NF_DROP;
-       } else if (selinux_secmark_enabled()) {
+       if (selinux_secmark_enabled())
                if (avc_has_perm(sksec->sid, skb->secmark,
                                 SECCLASS_PACKET, PACKET__SEND, &ad))
                        return NF_DROP;
-       }
 
        if (selinux_policycap_netpeer)
                if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
@@ -4648,7 +4499,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
        u32 secmark_perm;
        u32 peer_sid;
        struct sock *sk;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        char *addrp;
        u8 secmark_active;
        u8 peerlbl_active;
@@ -4657,7 +4508,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         * to the selinux_ip_postroute_compat() function to deal with the
         * special handling.  We do this in an attempt to keep this function
         * as fast and as clean as possible. */
-       if (selinux_compat_net || !selinux_policycap_netpeer)
+       if (!selinux_policycap_netpeer)
                return selinux_ip_postroute_compat(skb, ifindex, family);
 #ifdef CONFIG_XFRM
        /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
@@ -4666,7 +4517,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         * when the packet is on it's final way out.
         * NOTE: there appear to be some IPv6 multicast cases where skb->dst
         *       is NULL, in this case go ahead and apply access control. */
-       if (skb->dst != NULL && skb->dst->xfrm != NULL)
+       if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
                return NF_ACCEPT;
 #endif
        secmark_active = selinux_secmark_enabled();
@@ -4707,7 +4558,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
                secmark_perm = PACKET__SEND;
        }
 
-       AVC_AUDIT_DATA_INIT(&ad, NET);
+       COMMON_AUDIT_DATA_INIT(&ad, NET);
        ad.u.net.netif = ifindex;
        ad.u.net.family = family;
        if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
@@ -4777,13 +4628,13 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 static int selinux_netlink_recv(struct sk_buff *skb, int capability)
 {
        int err;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
 
        err = cap_netlink_recv(skb, capability);
        if (err)
                return err;
 
-       AVC_AUDIT_DATA_INIT(&ad, CAP);
+       COMMON_AUDIT_DATA_INIT(&ad, CAP);
        ad.u.cap = capability;
 
        return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
@@ -4842,12 +4693,12 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
                        u32 perms)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
 
        isec = ipc_perms->security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = ipc_perms->key;
 
        return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
@@ -4867,7 +4718,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg)
 static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
 
@@ -4877,7 +4728,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
 
        isec = msq->q_perm.security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4897,12 +4748,12 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq)
 static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
 
        isec = msq->q_perm.security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = msq->q_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4941,7 +4792,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
 {
        struct ipc_security_struct *isec;
        struct msg_security_struct *msec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
 
@@ -4962,7 +4813,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
                        return rc;
        }
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = msq->q_perm.key;
 
        /* Can this process write to the queue? */
@@ -4986,14 +4837,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 {
        struct ipc_security_struct *isec;
        struct msg_security_struct *msec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = task_sid(target);
        int rc;
 
        isec = msq->q_perm.security;
        msec = msg->security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid,
@@ -5008,7 +4859,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
 static int selinux_shm_alloc_security(struct shmid_kernel *shp)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
 
@@ -5018,7 +4869,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
 
        isec = shp->shm_perm.security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = shp->shm_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -5038,12 +4889,12 @@ static void selinux_shm_free_security(struct shmid_kernel *shp)
 static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
 
        isec = shp->shm_perm.security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = shp->shm_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -5100,7 +4951,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
 static int selinux_sem_alloc_security(struct sem_array *sma)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
        int rc;
 
@@ -5110,7 +4961,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
 
        isec = sma->sem_perm.security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = sma->sem_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -5130,12 +4981,12 @@ static void selinux_sem_free_security(struct sem_array *sma)
 static int selinux_sem_associate(struct sem_array *sma, int semflg)
 {
        struct ipc_security_struct *isec;
-       struct avc_audit_data ad;
+       struct common_audit_data ad;
        u32 sid = current_sid();
 
        isec = sma->sem_perm.security;
 
-       AVC_AUDIT_DATA_INIT(&ad, IPC);
+       COMMON_AUDIT_DATA_INIT(&ad, IPC);
        ad.u.ipc_id = sma->sem_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -5353,7 +5204,7 @@ static int selinux_setprocattr(struct task_struct *p,
 
                /* Only allow single threaded processes to change context */
                error = -EPERM;
-               if (!is_single_threaded(p)) {
+               if (!current_is_single_threaded()) {
                        error = security_bounded_transition(tsec->sid, sid);
                        if (error)
                                goto abort_change;
@@ -5481,7 +5332,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
 static struct security_operations selinux_ops = {
        .name =                         "selinux",
 
-       .ptrace_may_access =            selinux_ptrace_may_access,
+       .ptrace_access_check =          selinux_ptrace_access_check,
        .ptrace_traceme =               selinux_ptrace_traceme,
        .capget =                       selinux_capget,
        .capset =                       selinux_capset,
@@ -5558,6 +5409,7 @@ static struct security_operations selinux_ops = {
        .cred_prepare =                 selinux_cred_prepare,
        .kernel_act_as =                selinux_kernel_act_as,
        .kernel_create_files_as =       selinux_kernel_create_files_as,
+       .kernel_module_request =        selinux_kernel_module_request,
        .task_setpgid =                 selinux_task_setpgid,
        .task_getpgid =                 selinux_task_getpgid,
        .task_getsid =                  selinux_task_getsid,
@@ -5849,6 +5701,9 @@ int selinux_disable(void)
        selinux_disabled = 1;
        selinux_enabled = 0;
 
+       /* Try to destroy the avc node cache */
+       avc_disable();
+
        /* Reset security_ops to the secondary module, dummy or capability. */
        security_ops = secondary_ops;