]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - security/selinux/hooks.c
smsc75xx: fix phy interrupt acknowledge
[linux-2.6.git] / security / selinux / hooks.c
index 8878370c13bf43c3df5bba6e96c6c449604ea49c..d85b793c9321c5866a2f6bd2ce60cb5aaff42e17 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/tracehook.h>
 #include <linux/errno.h>
-#include <linux/ext2_fs.h>
 #include <linux/sched.h>
 #include <linux/security.h>
 #include <linux/xattr.h>
@@ -81,6 +80,8 @@
 #include <linux/syslog.h>
 #include <linux/user_namespace.h>
 #include <linux/export.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -1090,7 +1091,7 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
                        return SECCLASS_NETLINK_ROUTE_SOCKET;
                case NETLINK_FIREWALL:
                        return SECCLASS_NETLINK_FIREWALL_SOCKET;
-               case NETLINK_INET_DIAG:
+               case NETLINK_SOCK_DIAG:
                        return SECCLASS_NETLINK_TCPDIAG_SOCKET;
                case NETLINK_NFLOG:
                        return SECCLASS_NETLINK_NFLOG_SOCKET;
@@ -1415,11 +1416,11 @@ static int current_has_perm(const struct task_struct *tsk,
 #endif
 
 /* Check whether a task is allowed to use a capability. */
-static int task_has_capability(struct task_struct *tsk,
-                              const struct cred *cred,
+static int cred_has_capability(const struct cred *cred,
                               int cap, int audit)
 {
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        struct av_decision avd;
        u16 sclass;
        u32 sid = cred_sid(cred);
@@ -1427,7 +1428,8 @@ static int task_has_capability(struct task_struct *tsk,
        int rc;
 
        COMMON_AUDIT_DATA_INIT(&ad, CAP);
-       ad.tsk = tsk;
+       ad.selinux_audit_data = &sad;
+       ad.tsk = current;
        ad.u.cap = cap;
 
        switch (CAP_TO_INDEX(cap)) {
@@ -1492,9 +1494,11 @@ static int inode_has_perm_noadp(const struct cred *cred,
                                unsigned flags)
 {
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
 
        COMMON_AUDIT_DATA_INIT(&ad, INODE);
        ad.u.inode = inode;
+       ad.selinux_audit_data = &sad;
        return inode_has_perm(cred, inode, perms, &ad, flags);
 }
 
@@ -1507,9 +1511,11 @@ static inline int dentry_has_perm(const struct cred *cred,
 {
        struct inode *inode = dentry->d_inode;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
        ad.u.dentry = dentry;
+       ad.selinux_audit_data = &sad;
        return inode_has_perm(cred, inode, av, &ad, 0);
 }
 
@@ -1522,9 +1528,11 @@ static inline int path_has_perm(const struct cred *cred,
 {
        struct inode *inode = path->dentry->d_inode;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
 
        COMMON_AUDIT_DATA_INIT(&ad, PATH);
        ad.u.path = *path;
+       ad.selinux_audit_data = &sad;
        return inode_has_perm(cred, inode, av, &ad, 0);
 }
 
@@ -1543,11 +1551,13 @@ 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 common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = cred_sid(cred);
        int rc;
 
        COMMON_AUDIT_DATA_INIT(&ad, PATH);
        ad.u.path = file->f_path;
+       ad.selinux_audit_data = &sad;
 
        if (sid != fsec->sid) {
                rc = avc_has_perm(sid, fsec->sid,
@@ -1577,6 +1587,7 @@ static int may_create(struct inode *dir,
        struct superblock_security_struct *sbsec;
        u32 sid, newsid;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        int rc;
 
        dsec = dir->i_security;
@@ -1587,6 +1598,7 @@ static int may_create(struct inode *dir,
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
        ad.u.dentry = dentry;
+       ad.selinux_audit_data = &sad;
 
        rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
                          DIR__ADD_NAME | DIR__SEARCH,
@@ -1631,6 +1643,7 @@ static int may_link(struct inode *dir,
 {
        struct inode_security_struct *dsec, *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
        u32 av;
        int rc;
@@ -1640,6 +1653,7 @@ static int may_link(struct inode *dir,
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
        ad.u.dentry = dentry;
+       ad.selinux_audit_data = &sad;
 
        av = DIR__SEARCH;
        av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1674,6 +1688,7 @@ static inline int may_rename(struct inode *old_dir,
 {
        struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
        u32 av;
        int old_is_dir, new_is_dir;
@@ -1685,6 +1700,7 @@ static inline int may_rename(struct inode *old_dir,
        new_dsec = new_dir->i_security;
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+       ad.selinux_audit_data = &sad;
 
        ad.u.dentry = old_dentry;
        rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
@@ -1740,7 +1756,7 @@ static inline u32 file_mask_to_av(int mode, int mask)
 {
        u32 av = 0;
 
-       if ((mode & S_IFMT) != S_IFDIR) {
+       if (!S_ISDIR(mode)) {
                if (mask & MAY_EXEC)
                        av |= FILE__EXECUTE;
                if (mask & MAY_READ)
@@ -1811,7 +1827,7 @@ static int selinux_ptrace_access_check(struct task_struct *child,
        if (rc)
                return rc;
 
-       if (mode == PTRACE_MODE_READ) {
+       if (mode & PTRACE_MODE_READ) {
                u32 sid = current_sid();
                u32 csid = task_sid(child);
                return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL);
@@ -1868,16 +1884,16 @@ static int selinux_capset(struct cred *new, const struct cred *old,
  * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
  */
 
-static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
-                          struct user_namespace *ns, int cap, int audit)
+static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
+                          int cap, int audit)
 {
        int rc;
 
-       rc = cap_capable(tsk, cred, ns, cap, audit);
+       rc = cap_capable(cred, ns, cap, audit);
        if (rc)
                return rc;
 
-       return task_has_capability(tsk, cred, cap, audit);
+       return cred_has_capability(cred, cap, audit);
 }
 
 static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
@@ -1954,8 +1970,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
 {
        int rc, cap_sys_admin = 0;
 
-       rc = selinux_capable(current, current_cred(),
-                            &init_user_ns, CAP_SYS_ADMIN,
+       rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
                             SECURITY_CAP_NOAUDIT);
        if (rc == 0)
                cap_sys_admin = 1;
@@ -1971,6 +1986,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
        struct task_security_struct *new_tsec;
        struct inode_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        struct inode *inode = bprm->file->f_path.dentry->d_inode;
        int rc;
 
@@ -2010,6 +2026,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
        }
 
        COMMON_AUDIT_DATA_INIT(&ad, PATH);
+       ad.selinux_audit_data = &sad;
        ad.u.path = bprm->file->f_path;
 
        if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
@@ -2099,6 +2116,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
                                            struct files_struct *files)
 {
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        struct file *file, *devnull = NULL;
        struct tty_struct *tty;
        struct fdtable *fdt;
@@ -2136,6 +2154,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
        /* Revalidate access to inherited open files. */
 
        COMMON_AUDIT_DATA_INIT(&ad, INODE);
+       ad.selinux_audit_data = &sad;
 
        spin_lock(&files->file_lock);
        for (;;) {
@@ -2147,7 +2166,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
                fdt = files_fdtable(files);
                if (i >= fdt->max_fds)
                        break;
-               set = fdt->open_fds->fds_bits[j];
+               set = fdt->open_fds[j];
                if (!set)
                        continue;
                spin_unlock(&files->file_lock);
@@ -2473,6 +2492,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
 {
        const struct cred *cred = current_cred();
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        int rc;
 
        rc = superblock_doinit(sb, data);
@@ -2484,6 +2504,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
                return 0;
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+       ad.selinux_audit_data = &sad;
        ad.u.dentry = sb->s_root;
        return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
 }
@@ -2492,8 +2513,10 @@ static int selinux_sb_statfs(struct dentry *dentry)
 {
        const struct cred *cred = current_cred();
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+       ad.selinux_audit_data = &sad;
        ad.u.dentry = dentry->d_sb->s_root;
        return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
 }
@@ -2507,7 +2530,7 @@ static int selinux_mount(char *dev_name,
        const struct cred *cred = current_cred();
 
        if (flags & MS_REMOUNT)
-               return superblock_has_perm(cred, path->mnt->mnt_sb,
+               return superblock_has_perm(cred, path->dentry->d_sb,
                                           FILESYSTEM__REMOUNT, NULL);
        else
                return path_has_perm(cred, path, FILE__MOUNTON);
@@ -2657,6 +2680,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
 {
        const struct cred *cred = current_cred();
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 perms;
        bool from_access;
        unsigned flags = mask & MAY_NOT_BLOCK;
@@ -2669,10 +2693,11 @@ static int selinux_inode_permission(struct inode *inode, int mask)
                return 0;
 
        COMMON_AUDIT_DATA_INIT(&ad, INODE);
+       ad.selinux_audit_data = &sad;
        ad.u.inode = inode;
 
        if (from_access)
-               ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
+               ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS;
 
        perms = file_mask_to_av(inode->i_mode, mask);
 
@@ -2738,6 +2763,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
        struct inode_security_struct *isec = inode->i_security;
        struct superblock_security_struct *sbsec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 newsid, sid = current_sid();
        int rc = 0;
 
@@ -2752,6 +2778,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
                return -EPERM;
 
        COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+       ad.selinux_audit_data = &sad;
        ad.u.dentry = dentry;
 
        rc = avc_has_perm(sid, isec->sid, isec->sclass,
@@ -2859,8 +2886,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
         * and lack of permission just means that we fall back to the
         * in-core context value, not a denial.
         */
-       error = selinux_capable(current, current_cred(),
-                               &init_user_ns, CAP_MAC_ADMIN,
+       error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
                                SECURITY_CAP_NOAUDIT);
        if (!error)
                error = security_sid_to_context_force(isec->sid, &context,
@@ -2972,15 +2998,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
        /* fall through */
        case FIGETBSZ:
        /* fall through */
-       case EXT2_IOC_GETFLAGS:
+       case FS_IOC_GETFLAGS:
        /* fall through */
-       case EXT2_IOC_GETVERSION:
+       case FS_IOC_GETVERSION:
                error = file_has_perm(cred, file, FILE__GETATTR);
                break;
 
-       case EXT2_IOC_SETFLAGS:
+       case FS_IOC_SETFLAGS:
        /* fall through */
-       case EXT2_IOC_SETVERSION:
+       case FS_IOC_SETVERSION:
                error = file_has_perm(cred, file, FILE__SETATTR);
                break;
 
@@ -2993,8 +3019,8 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
 
        case KDSKBENT:
        case KDSKBSENT:
-               error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG,
-                                       SECURITY_CAP_AUDIT);
+               error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
+                                           SECURITY_CAP_AUDIT);
                break;
 
        /* default case assumes that the command will go
@@ -3347,10 +3373,12 @@ static int selinux_kernel_module_request(char *kmod_name)
 {
        u32 sid;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
 
        sid = task_sid(current);
 
        COMMON_AUDIT_DATA_INIT(&ad, KMOD);
+       ad.selinux_audit_data = &sad;
        ad.u.kmod_name = kmod_name;
 
        return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
@@ -3489,8 +3517,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
        if (ihlen < sizeof(_iph))
                goto out;
 
-       ad->u.net.v4info.saddr = ih->saddr;
-       ad->u.net.v4info.daddr = ih->daddr;
+       ad->u.net->v4info.saddr = ih->saddr;
+       ad->u.net->v4info.daddr = ih->daddr;
        ret = 0;
 
        if (proto)
@@ -3508,8 +3536,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
                if (th == NULL)
                        break;
 
-               ad->u.net.sport = th->source;
-               ad->u.net.dport = th->dest;
+               ad->u.net->sport = th->source;
+               ad->u.net->dport = th->dest;
                break;
        }
 
@@ -3524,8 +3552,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
                if (uh == NULL)
                        break;
 
-               ad->u.net.sport = uh->source;
-               ad->u.net.dport = uh->dest;
+               ad->u.net->sport = uh->source;
+               ad->u.net->dport = uh->dest;
                break;
        }
 
@@ -3540,8 +3568,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
                if (dh == NULL)
                        break;
 
-               ad->u.net.sport = dh->dccph_sport;
-               ad->u.net.dport = dh->dccph_dport;
+               ad->u.net->sport = dh->dccph_sport;
+               ad->u.net->dport = dh->dccph_dport;
                break;
        }
 
@@ -3561,19 +3589,20 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
        u8 nexthdr;
        int ret = -EINVAL, offset;
        struct ipv6hdr _ipv6h, *ip6;
+       __be16 frag_off;
 
        offset = skb_network_offset(skb);
        ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
        if (ip6 == NULL)
                goto out;
 
-       ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr);
-       ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr);
+       ad->u.net->v6info.saddr = ip6->saddr;
+       ad->u.net->v6info.daddr = ip6->daddr;
        ret = 0;
 
        nexthdr = ip6->nexthdr;
        offset += sizeof(_ipv6h);
-       offset = ipv6_skip_exthdr(skb, offset, &nexthdr);
+       offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
        if (offset < 0)
                goto out;
 
@@ -3588,8 +3617,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
                if (th == NULL)
                        break;
 
-               ad->u.net.sport = th->source;
-               ad->u.net.dport = th->dest;
+               ad->u.net->sport = th->source;
+               ad->u.net->dport = th->dest;
                break;
        }
 
@@ -3600,8 +3629,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
                if (uh == NULL)
                        break;
 
-               ad->u.net.sport = uh->source;
-               ad->u.net.dport = uh->dest;
+               ad->u.net->sport = uh->source;
+               ad->u.net->dport = uh->dest;
                break;
        }
 
@@ -3612,8 +3641,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
                if (dh == NULL)
                        break;
 
-               ad->u.net.sport = dh->dccph_sport;
-               ad->u.net.dport = dh->dccph_dport;
+               ad->u.net->sport = dh->dccph_sport;
+               ad->u.net->dport = dh->dccph_dport;
                break;
        }
 
@@ -3633,13 +3662,13 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
        char *addrp;
        int ret;
 
-       switch (ad->u.net.family) {
+       switch (ad->u.net->family) {
        case PF_INET:
                ret = selinux_parse_skb_ipv4(skb, ad, proto);
                if (ret)
                        goto parse_error;
-               addrp = (char *)(src ? &ad->u.net.v4info.saddr :
-                                      &ad->u.net.v4info.daddr);
+               addrp = (char *)(src ? &ad->u.net->v4info.saddr :
+                                      &ad->u.net->v4info.daddr);
                goto okay;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -3647,8 +3676,8 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
                ret = selinux_parse_skb_ipv6(skb, ad, proto);
                if (ret)
                        goto parse_error;
-               addrp = (char *)(src ? &ad->u.net.v6info.saddr :
-                                      &ad->u.net.v6info.daddr);
+               addrp = (char *)(src ? &ad->u.net->v6info.saddr :
+                                      &ad->u.net->v6info.daddr);
                goto okay;
 #endif /* IPV6 */
        default:
@@ -3722,13 +3751,17 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
 {
        struct sk_security_struct *sksec = sk->sk_security;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        u32 tsid = task_sid(task);
 
        if (sksec->sid == SECINITSID_KERNEL)
                return 0;
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.sk = sk;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->sk = sk;
 
        return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
 }
@@ -3806,6 +3839,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                char *addrp;
                struct sk_security_struct *sksec = sk->sk_security;
                struct common_audit_data ad;
+               struct selinux_audit_data sad = {0,};
+               struct lsm_network_audit net = {0,};
                struct sockaddr_in *addr4 = NULL;
                struct sockaddr_in6 *addr6 = NULL;
                unsigned short snum;
@@ -3832,8 +3867,10 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                                if (err)
                                        goto out;
                                COMMON_AUDIT_DATA_INIT(&ad, NET);
-                               ad.u.net.sport = htons(snum);
-                               ad.u.net.family = family;
+                               ad.selinux_audit_data = &sad;
+                               ad.u.net = &net;
+                               ad.u.net->sport = htons(snum);
+                               ad.u.net->family = family;
                                err = avc_has_perm(sksec->sid, sid,
                                                   sksec->sclass,
                                                   SOCKET__NAME_BIND, &ad);
@@ -3865,13 +3902,15 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                        goto out;
 
                COMMON_AUDIT_DATA_INIT(&ad, NET);
-               ad.u.net.sport = htons(snum);
-               ad.u.net.family = family;
+               ad.selinux_audit_data = &sad;
+               ad.u.net = &net;
+               ad.u.net->sport = htons(snum);
+               ad.u.net->family = family;
 
                if (family == PF_INET)
-                       ad.u.net.v4info.saddr = addr4->sin_addr.s_addr;
+                       ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
                else
-                       ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);
+                       ad.u.net->v6info.saddr = addr6->sin6_addr;
 
                err = avc_has_perm(sksec->sid, sid,
                                   sksec->sclass, node_perm, &ad);
@@ -3898,6 +3937,8 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
        if (sksec->sclass == SECCLASS_TCP_SOCKET ||
            sksec->sclass == SECCLASS_DCCP_SOCKET) {
                struct common_audit_data ad;
+               struct selinux_audit_data sad = {0,};
+               struct lsm_network_audit net = {0,};
                struct sockaddr_in *addr4 = NULL;
                struct sockaddr_in6 *addr6 = NULL;
                unsigned short snum;
@@ -3923,8 +3964,10 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
                       TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
 
                COMMON_AUDIT_DATA_INIT(&ad, NET);
-               ad.u.net.dport = htons(snum);
-               ad.u.net.family = sk->sk_family;
+               ad.selinux_audit_data = &sad;
+               ad.u.net = &net;
+               ad.u.net->dport = htons(snum);
+               ad.u.net->family = sk->sk_family;
                err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
                if (err)
                        goto out;
@@ -4013,10 +4056,14 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
        struct sk_security_struct *sksec_other = other->sk_security;
        struct sk_security_struct *sksec_new = newsk->sk_security;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        int err;
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.sk = other;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->sk = other;
 
        err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
                           sksec_other->sclass,
@@ -4043,9 +4090,13 @@ static int selinux_socket_unix_may_send(struct socket *sock,
        struct sk_security_struct *ssec = sock->sk->sk_security;
        struct sk_security_struct *osec = other->sk->sk_security;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.sk = other->sk;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->sk = other->sk;
 
        return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
                            &ad);
@@ -4081,11 +4132,15 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
        struct sk_security_struct *sksec = sk->sk_security;
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        char *addrp;
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.netif = skb->skb_iif;
-       ad.u.net.family = family;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->netif = skb->skb_iif;
+       ad.u.net->family = family;
        err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
        if (err)
                return err;
@@ -4112,6 +4167,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        u16 family = sk->sk_family;
        u32 sk_sid = sksec->sid;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        char *addrp;
        u8 secmark_active;
        u8 peerlbl_active;
@@ -4136,8 +4193,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
                return 0;
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.netif = skb->skb_iif;
-       ad.u.net.family = family;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->netif = skb->skb_iif;
+       ad.u.net->family = family;
        err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
        if (err)
                return err;
@@ -4472,6 +4531,8 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
        char *addrp;
        u32 peer_sid;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        u8 secmark_active;
        u8 netlbl_active;
        u8 peerlbl_active;
@@ -4489,8 +4550,10 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
                return NF_DROP;
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.netif = ifindex;
-       ad.u.net.family = family;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->netif = ifindex;
+       ad.u.net->family = family;
        if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
                return NF_DROP;
 
@@ -4577,6 +4640,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
        struct sock *sk = skb->sk;
        struct sk_security_struct *sksec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        char *addrp;
        u8 proto;
 
@@ -4585,8 +4650,10 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
        sksec = sk->sk_security;
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.netif = ifindex;
-       ad.u.net.family = family;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->netif = ifindex;
+       ad.u.net->family = family;
        if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
                return NF_DROP;
 
@@ -4608,6 +4675,8 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
        u32 peer_sid;
        struct sock *sk;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
+       struct lsm_network_audit net = {0,};
        char *addrp;
        u8 secmark_active;
        u8 peerlbl_active;
@@ -4654,8 +4723,10 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
        }
 
        COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.u.net.netif = ifindex;
-       ad.u.net.family = family;
+       ad.selinux_audit_data = &sad;
+       ad.u.net = &net;
+       ad.u.net->netif = ifindex;
+       ad.u.net->family = family;
        if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
                return NF_DROP;
 
@@ -4717,24 +4788,6 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
        return selinux_nlmsg_perm(sk, skb);
 }
 
-static int selinux_netlink_recv(struct sk_buff *skb, int capability)
-{
-       int err;
-       struct common_audit_data ad;
-       u32 sid;
-
-       err = cap_netlink_recv(skb, capability);
-       if (err)
-               return err;
-
-       COMMON_AUDIT_DATA_INIT(&ad, CAP);
-       ad.u.cap = capability;
-
-       security_task_getsecid(current, &sid);
-       return avc_has_perm(sid, sid, SECCLASS_CAPABILITY,
-                           CAP_TO_MASK(capability), &ad);
-}
-
 static int ipc_alloc_security(struct task_struct *task,
                              struct kern_ipc_perm *perm,
                              u16 sclass)
@@ -4788,11 +4841,13 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms,
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
 
        isec = ipc_perms->security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = ipc_perms->key;
 
        return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
@@ -4813,6 +4868,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
        int rc;
 
@@ -4823,6 +4879,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq)
        isec = msq->q_perm.security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4843,11 +4900,13 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg)
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
 
        isec = msq->q_perm.security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = msq->q_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4887,6 +4946,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 common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
        int rc;
 
@@ -4908,6 +4968,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
        }
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = msq->q_perm.key;
 
        /* Can this process write to the queue? */
@@ -4932,6 +4993,7 @@ 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 common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = task_sid(target);
        int rc;
 
@@ -4939,6 +5001,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg,
        msec = msg->security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid,
@@ -4954,6 +5017,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
        int rc;
 
@@ -4964,6 +5028,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp)
        isec = shp->shm_perm.security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = shp->shm_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -4984,11 +5049,13 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg)
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
 
        isec = shp->shm_perm.security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = shp->shm_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -5046,6 +5113,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
        int rc;
 
@@ -5056,6 +5124,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma)
        isec = sma->sem_perm.security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = sma->sem_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -5076,11 +5145,13 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg)
 {
        struct ipc_security_struct *isec;
        struct common_audit_data ad;
+       struct selinux_audit_data sad = {0,};
        u32 sid = current_sid();
 
        isec = sma->sem_perm.security;
 
        COMMON_AUDIT_DATA_INIT(&ad, IPC);
+       ad.selinux_audit_data = &sad;
        ad.u.ipc_id = sma->sem_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -5463,7 +5534,6 @@ static struct security_operations selinux_ops = {
        .vm_enough_memory =             selinux_vm_enough_memory,
 
        .netlink_send =                 selinux_netlink_send,
-       .netlink_recv =                 selinux_netlink_recv,
 
        .bprm_set_creds =               selinux_bprm_set_creds,
        .bprm_committing_creds =        selinux_bprm_committing_creds,