Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into next
James Morris [Tue, 22 May 2012 01:21:06 +0000 (11:21 +1000)]
Per pull request, for 3.5.

33 files changed:
fs/open.c
include/linux/lsm_audit.h
include/linux/security.h
net/xfrm/xfrm_policy.c
security/apparmor/audit.c
security/apparmor/capability.c
security/apparmor/file.c
security/apparmor/include/audit.h
security/apparmor/ipc.c
security/apparmor/lib.c
security/apparmor/lsm.c
security/apparmor/policy.c
security/apparmor/policy_unpack.c
security/apparmor/resource.c
security/capability.c
security/lsm_audit.c
security/security.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/avc.h
security/selinux/include/security.h
security/selinux/netif.c
security/selinux/netnode.c
security/selinux/netport.c
security/selinux/selinuxfs.c
security/selinux/ss/context.h
security/selinux/ss/mls.c
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c
security/smack/smack.h
security/smack/smack_lsm.c
security/tomoyo/tomoyo.c

index 5720854..5eccdce 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -681,7 +681,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
 
        f->f_op = fops_get(inode->i_fop);
 
-       error = security_dentry_open(f, cred);
+       error = security_file_open(f, cred);
        if (error)
                goto cleanup_all;
 
index fad48aa..1cc89e9 100644 (file)
@@ -53,7 +53,6 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_KMOD    8
 #define LSM_AUDIT_DATA_INODE   9
 #define LSM_AUDIT_DATA_DENTRY  10
-       struct task_struct *tsk;
        union   {
                struct path path;
                struct dentry *dentry;
@@ -93,11 +92,6 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 int ipv6_skb_to_auditdata(struct sk_buff *skb,
                struct common_audit_data *ad, u8 *proto);
 
-/* Initialize an LSM audit data structure. */
-#define COMMON_AUDIT_DATA_INIT(_d, _t) \
-       { memset((_d), 0, sizeof(struct common_audit_data)); \
-        (_d)->type = LSM_AUDIT_DATA_##_t; }
-
 void common_lsm_audit(struct common_audit_data *a,
        void (*pre_audit)(struct audit_buffer *, void *),
        void (*post_audit)(struct audit_buffer *, void *));
index 6e1dea9..ab0e091 100644 (file)
@@ -640,10 +640,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     to receive an open file descriptor via socket IPC.
  *     @file contains the file structure being received.
  *     Return 0 if permission is granted.
- *
- * Security hook for dentry
- *
- * @dentry_open
+ * @file_open
  *     Save open-time permission checking state for later use upon
  *     file_permission, and recheck access if anything has changed
  *     since inode_permission.
@@ -1498,7 +1495,7 @@ struct security_operations {
        int (*file_send_sigiotask) (struct task_struct *tsk,
                                    struct fown_struct *fown, int sig);
        int (*file_receive) (struct file *file);
-       int (*dentry_open) (struct file *file, const struct cred *cred);
+       int (*file_open) (struct file *file, const struct cred *cred);
 
        int (*task_create) (unsigned long clone_flags);
        void (*task_free) (struct task_struct *task);
@@ -1757,7 +1754,7 @@ int security_file_set_fowner(struct file *file);
 int security_file_send_sigiotask(struct task_struct *tsk,
                                 struct fown_struct *fown, int sig);
 int security_file_receive(struct file *file);
-int security_dentry_open(struct file *file, const struct cred *cred);
+int security_file_open(struct file *file, const struct cred *cred);
 int security_task_create(unsigned long clone_flags);
 void security_task_free(struct task_struct *task);
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
@@ -2228,8 +2225,8 @@ static inline int security_file_receive(struct file *file)
        return 0;
 }
 
-static inline int security_dentry_open(struct file *file,
-                                      const struct cred *cred)
+static inline int security_file_open(struct file *file,
+                                    const struct cred *cred)
 {
        return 0;
 }
index 7661576..596f125 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/cache.h>
 #include <linux/audit.h>
 #include <net/dst.h>
+#include <net/flow.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 #ifdef CONFIG_XFRM_STATISTICS
index cc3520d..3ae28db 100644 (file)
@@ -111,7 +111,7 @@ static const char *const aa_audit_type[] = {
 static void audit_pre(struct audit_buffer *ab, void *ca)
 {
        struct common_audit_data *sa = ca;
-       struct task_struct *tsk = sa->tsk ? sa->tsk : current;
+       struct task_struct *tsk = sa->aad->tsk ? sa->aad->tsk : current;
 
        if (aa_g_audit_header) {
                audit_log_format(ab, "apparmor=");
@@ -149,6 +149,12 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
                audit_log_format(ab, " name=");
                audit_log_untrustedstring(ab, sa->aad->name);
        }
+
+       if (sa->aad->tsk) {
+               audit_log_format(ab, " pid=%d comm=", tsk->pid);
+               audit_log_untrustedstring(ab, tsk->comm);
+       }
+
 }
 
 /**
@@ -205,7 +211,8 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp,
        aa_audit_msg(type, sa, cb);
 
        if (sa->aad->type == AUDIT_APPARMOR_KILL)
-               (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current);
+               (void)send_sig_info(SIGKILL, NULL,
+                                   sa->aad->tsk ?  sa->aad->tsk : current);
 
        if (sa->aad->type == AUDIT_APPARMOR_ALLOWED)
                return complain_error(sa->aad->error);
index 088dba3..887a5e9 100644 (file)
@@ -65,10 +65,10 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task,
        int type = AUDIT_APPARMOR_AUTO;
        struct common_audit_data sa;
        struct apparmor_audit_data aad = {0,};
-       COMMON_AUDIT_DATA_INIT(&sa, CAP);
+       sa.type = LSM_AUDIT_DATA_CAP;
        sa.aad = &aad;
-       sa.tsk = task;
        sa.u.cap = cap;
+       sa.aad->tsk = task;
        sa.aad->op = OP_CAPABLE;
        sa.aad->error = error;
 
index 2f8fcba..cf19d40 100644 (file)
@@ -108,7 +108,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
        int type = AUDIT_APPARMOR_AUTO;
        struct common_audit_data sa;
        struct apparmor_audit_data aad = {0,};
-       COMMON_AUDIT_DATA_INIT(&sa, NONE);
+       sa.type = LSM_AUDIT_DATA_NONE;
        sa.aad = &aad;
        aad.op = op,
        aad.fs.request = request;
index 3868b1e..4b7e189 100644 (file)
@@ -110,6 +110,7 @@ struct apparmor_audit_data {
        void *profile;
        const char *name;
        const char *info;
+       struct task_struct *tsk;
        union {
                void *target;
                struct {
index c3da93a..cf1071b 100644 (file)
@@ -42,7 +42,7 @@ static int aa_audit_ptrace(struct aa_profile *profile,
 {
        struct common_audit_data sa;
        struct apparmor_audit_data aad = {0,};
-       COMMON_AUDIT_DATA_INIT(&sa, NONE);
+       sa.type = LSM_AUDIT_DATA_NONE;
        sa.aad = &aad;
        aad.op = OP_PTRACE;
        aad.target = target;
index e75829b..7430298 100644 (file)
@@ -66,7 +66,7 @@ void aa_info_message(const char *str)
        if (audit_enabled) {
                struct common_audit_data sa;
                struct apparmor_audit_data aad = {0,};
-               COMMON_AUDIT_DATA_INIT(&sa, NONE);
+               sa.type = LSM_AUDIT_DATA_NONE;
                sa.aad = &aad;
                aad.info = str;
                aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
index ad05d39..032daab 100644 (file)
@@ -373,7 +373,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
                                      AA_MAY_META_READ);
 }
 
-static int apparmor_dentry_open(struct file *file, const struct cred *cred)
+static int apparmor_file_open(struct file *file, const struct cred *cred)
 {
        struct aa_file_cxt *fcxt = file->f_security;
        struct aa_profile *profile;
@@ -589,7 +589,7 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
                } else {
                        struct common_audit_data sa;
                        struct apparmor_audit_data aad = {0,};
-                       COMMON_AUDIT_DATA_INIT(&sa, NONE);
+                       sa.type = LSM_AUDIT_DATA_NONE;
                        sa.aad = &aad;
                        aad.op = OP_SETPROCATTR;
                        aad.info = name;
@@ -640,9 +640,9 @@ static struct security_operations apparmor_ops = {
        .path_chmod =                   apparmor_path_chmod,
        .path_chown =                   apparmor_path_chown,
        .path_truncate =                apparmor_path_truncate,
-       .dentry_open =                  apparmor_dentry_open,
        .inode_getattr =                apparmor_inode_getattr,
 
+       .file_open =                    apparmor_file_open,
        .file_permission =              apparmor_file_permission,
        .file_alloc_security =          apparmor_file_alloc_security,
        .file_free_security =           apparmor_file_free_security,
index 7f3f455..cf5fd22 100644 (file)
@@ -969,7 +969,7 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info,
 {
        struct common_audit_data sa;
        struct apparmor_audit_data aad = {0,};
-       COMMON_AUDIT_DATA_INIT(&sa, NONE);
+       sa.type = LSM_AUDIT_DATA_NONE;
        sa.aad = &aad;
        aad.op = op;
        aad.name = name;
index deab7c7..329b1fd 100644 (file)
@@ -95,7 +95,7 @@ static int audit_iface(struct aa_profile *new, const char *name,
        struct aa_profile *profile = __aa_current_profile();
        struct common_audit_data sa;
        struct apparmor_audit_data aad = {0,};
-       COMMON_AUDIT_DATA_INIT(&sa, NONE);
+       sa.type = LSM_AUDIT_DATA_NONE;
        sa.aad = &aad;
        if (e)
                aad.iface.pos = e->pos - e->start;
index 2fe8613..e1f3d7e 100644 (file)
@@ -52,7 +52,7 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource,
        struct common_audit_data sa;
        struct apparmor_audit_data aad = {0,};
 
-       COMMON_AUDIT_DATA_INIT(&sa, NONE);
+       sa.type = LSM_AUDIT_DATA_NONE;
        sa.aad = &aad;
        aad.op = OP_SETRLIMIT,
        aad.rlim.rlim = resource;
index 5bb21b1..fca8896 100644 (file)
@@ -348,7 +348,7 @@ static int cap_file_receive(struct file *file)
        return 0;
 }
 
-static int cap_dentry_open(struct file *file, const struct cred *cred)
+static int cap_file_open(struct file *file, const struct cred *cred)
 {
        return 0;
 }
@@ -956,7 +956,7 @@ void __init security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, file_set_fowner);
        set_to_cap_if_null(ops, file_send_sigiotask);
        set_to_cap_if_null(ops, file_receive);
-       set_to_cap_if_null(ops, dentry_open);
+       set_to_cap_if_null(ops, file_open);
        set_to_cap_if_null(ops, task_create);
        set_to_cap_if_null(ops, task_free);
        set_to_cap_if_null(ops, cred_alloc_blank);
index 90c129b..8d8d97d 100644 (file)
@@ -213,12 +213,15 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 {
        struct task_struct *tsk = current;
 
-       if (a->tsk)
-               tsk = a->tsk;
-       if (tsk && tsk->pid) {
-               audit_log_format(ab, " pid=%d comm=", tsk->pid);
-               audit_log_untrustedstring(ab, tsk->comm);
-       }
+       /*
+        * To keep stack sizes in check force programers to notice if they
+        * start making this union too large!  See struct lsm_network_audit
+        * as an example of how to deal with large data.
+        */
+       BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
+
+       audit_log_format(ab, " pid=%d comm=", tsk->pid);
+       audit_log_untrustedstring(ab, tsk->comm);
 
        switch (a->type) {
        case LSM_AUDIT_DATA_NONE:
index bf619ff..5497a57 100644 (file)
@@ -701,11 +701,11 @@ int security_file_receive(struct file *file)
        return security_ops->file_receive(file);
 }
 
-int security_dentry_open(struct file *file, const struct cred *cred)
+int security_file_open(struct file *file, const struct cred *cred)
 {
        int ret;
 
-       ret = security_ops->dentry_open(file, cred);
+       ret = security_ops->file_open(file, cred);
        if (ret)
                return ret;
 
index 8ee42b2..68d82da 100644 (file)
@@ -65,14 +65,8 @@ struct avc_cache {
 };
 
 struct avc_callback_node {
-       int (*callback) (u32 event, u32 ssid, u32 tsid,
-                        u16 tclass, u32 perms,
-                        u32 *out_retained);
+       int (*callback) (u32 event);
        u32 events;
-       u32 ssid;
-       u32 tsid;
-       u16 tclass;
-       u32 perms;
        struct avc_callback_node *next;
 };
 
@@ -436,9 +430,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
 {
        struct common_audit_data *ad = a;
        audit_log_format(ab, "avc:  %s ",
-                        ad->selinux_audit_data->slad->denied ? "denied" : "granted");
-       avc_dump_av(ab, ad->selinux_audit_data->slad->tclass,
-                       ad->selinux_audit_data->slad->audited);
+                        ad->selinux_audit_data->denied ? "denied" : "granted");
+       avc_dump_av(ab, ad->selinux_audit_data->tclass,
+                       ad->selinux_audit_data->audited);
        audit_log_format(ab, " for ");
 }
 
@@ -452,25 +446,23 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
 {
        struct common_audit_data *ad = a;
        audit_log_format(ab, " ");
-       avc_dump_query(ab, ad->selinux_audit_data->slad->ssid,
-                          ad->selinux_audit_data->slad->tsid,
-                          ad->selinux_audit_data->slad->tclass);
+       avc_dump_query(ab, ad->selinux_audit_data->ssid,
+                          ad->selinux_audit_data->tsid,
+                          ad->selinux_audit_data->tclass);
 }
 
 /* This is the slow part of avc audit with big stack footprint */
-static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
+noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
                u32 requested, u32 audited, u32 denied,
                struct common_audit_data *a,
                unsigned flags)
 {
        struct common_audit_data stack_data;
-       struct selinux_audit_data sad = {0,};
-       struct selinux_late_audit_data slad;
+       struct selinux_audit_data sad;
 
        if (!a) {
                a = &stack_data;
-               COMMON_AUDIT_DATA_INIT(a, NONE);
-               a->selinux_audit_data = &sad;
+               a->type = LSM_AUDIT_DATA_NONE;
        }
 
        /*
@@ -484,104 +476,34 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
            (flags & MAY_NOT_BLOCK))
                return -ECHILD;
 
-       slad.tclass = tclass;
-       slad.requested = requested;
-       slad.ssid = ssid;
-       slad.tsid = tsid;
-       slad.audited = audited;
-       slad.denied = denied;
+       sad.tclass = tclass;
+       sad.requested = requested;
+       sad.ssid = ssid;
+       sad.tsid = tsid;
+       sad.audited = audited;
+       sad.denied = denied;
+
+       a->selinux_audit_data = &sad;
 
-       a->selinux_audit_data->slad = &slad;
        common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
        return 0;
 }
 
 /**
- * avc_audit - Audit the granting or denial of permissions.
- * @ssid: source security identifier
- * @tsid: target security identifier
- * @tclass: target security class
- * @requested: requested permissions
- * @avd: access vector decisions
- * @result: result from avc_has_perm_noaudit
- * @a:  auxiliary audit data
- * @flags: VFS walk flags
- *
- * Audit the granting or denial of permissions in accordance
- * with the policy.  This function is typically called by
- * avc_has_perm() after a permission check, but can also be
- * called directly by callers who use avc_has_perm_noaudit()
- * in order to separate the permission check from the auditing.
- * For example, this separation is useful when the permission check must
- * be performed under a lock, to allow the lock to be released
- * before calling the auditing code.
- */
-inline int avc_audit(u32 ssid, u32 tsid,
-              u16 tclass, u32 requested,
-              struct av_decision *avd, int result, struct common_audit_data *a,
-              unsigned flags)
-{
-       u32 denied, audited;
-       denied = requested & ~avd->allowed;
-       if (unlikely(denied)) {
-               audited = denied & avd->auditdeny;
-               /*
-                * a->selinux_audit_data->auditdeny is TRICKY!  Setting a bit in
-                * this field means that ANY denials should NOT be audited if
-                * the policy contains an explicit dontaudit rule for that
-                * permission.  Take notice that this is unrelated to the
-                * actual permissions that were denied.  As an example lets
-                * assume:
-                *
-                * denied == READ
-                * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
-                * selinux_audit_data->auditdeny & ACCESS == 1
-                *
-                * We will NOT audit the denial even though the denied
-                * permission was READ and the auditdeny checks were for
-                * ACCESS
-                */
-               if (a &&
-                   a->selinux_audit_data->auditdeny &&
-                   !(a->selinux_audit_data->auditdeny & avd->auditdeny))
-                       audited = 0;
-       } else if (result)
-               audited = denied = requested;
-       else
-               audited = requested & avd->auditallow;
-       if (likely(!audited))
-               return 0;
-
-       return slow_avc_audit(ssid, tsid, tclass,
-               requested, audited, denied,
-               a, flags);
-}
-
-/**
  * avc_add_callback - Register a callback for security events.
  * @callback: callback function
  * @events: security events
- * @ssid: source security identifier or %SECSID_WILD
- * @tsid: target security identifier or %SECSID_WILD
- * @tclass: target security class
- * @perms: permissions
  *
- * Register a callback function for events in the set @events
- * related to the SID pair (@ssid, @tsid) 
- * and the permissions @perms, interpreting
- * @perms based on @tclass.  Returns %0 on success or
- * -%ENOMEM if insufficient memory exists to add the callback.
+ * Register a callback function for events in the set @events.
+ * Returns %0 on success or -%ENOMEM if insufficient memory
+ * exists to add the callback.
  */
-int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
-                                    u16 tclass, u32 perms,
-                                    u32 *out_retained),
-                    u32 events, u32 ssid, u32 tsid,
-                    u16 tclass, u32 perms)
+int __init avc_add_callback(int (*callback)(u32 event), u32 events)
 {
        struct avc_callback_node *c;
        int rc = 0;
 
-       c = kmalloc(sizeof(*c), GFP_ATOMIC);
+       c = kmalloc(sizeof(*c), GFP_KERNEL);
        if (!c) {
                rc = -ENOMEM;
                goto out;
@@ -589,9 +511,6 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
 
        c->callback = callback;
        c->events = events;
-       c->ssid = ssid;
-       c->tsid = tsid;
-       c->perms = perms;
        c->next = avc_callbacks;
        avc_callbacks = c;
 out:
@@ -731,8 +650,7 @@ int avc_ss_reset(u32 seqno)
 
        for (c = avc_callbacks; c; c = c->next) {
                if (c->events & AVC_CALLBACK_RESET) {
-                       tmprc = c->callback(AVC_CALLBACK_RESET,
-                                           0, 0, 0, 0, NULL);
+                       tmprc = c->callback(AVC_CALLBACK_RESET);
                        /* save the first error encountered for the return
                           value and continue processing the callbacks */
                        if (!rc)
index 0b06685..fa2341b 100644 (file)
@@ -1420,16 +1420,13 @@ 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);
        u32 av = CAP_TO_MASK(cap);
        int rc;
 
-       COMMON_AUDIT_DATA_INIT(&ad, CAP);
-       ad.selinux_audit_data = &sad;
-       ad.tsk = current;
+       ad.type = LSM_AUDIT_DATA_CAP;
        ad.u.cap = cap;
 
        switch (CAP_TO_INDEX(cap)) {
@@ -1488,20 +1485,6 @@ static int inode_has_perm(const struct cred *cred,
        return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
 }
 
-static int inode_has_perm_noadp(const struct cred *cred,
-                               struct inode *inode,
-                               u32 perms,
-                               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);
-}
-
 /* Same as inode_has_perm, but pass explicit audit data containing
    the dentry to help the auditing code to more easily generate the
    pathname if needed. */
@@ -1511,11 +1494,9 @@ 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.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
-       ad.selinux_audit_data = &sad;
        return inode_has_perm(cred, inode, av, &ad, 0);
 }
 
@@ -1528,11 +1509,9 @@ 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.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = *path;
-       ad.selinux_audit_data = &sad;
        return inode_has_perm(cred, inode, av, &ad, 0);
 }
 
@@ -1551,13 +1530,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 common_audit_data ad;
-       struct selinux_audit_data sad = {0,};
        u32 sid = cred_sid(cred);
        int rc;
 
-       COMMON_AUDIT_DATA_INIT(&ad, PATH);
+       ad.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = file->f_path;
-       ad.selinux_audit_data = &sad;
 
        if (sid != fsec->sid) {
                rc = avc_has_perm(sid, fsec->sid,
@@ -1587,7 +1564,6 @@ 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;
@@ -1596,9 +1572,8 @@ static int may_create(struct inode *dir,
        sid = tsec->sid;
        newsid = tsec->create_sid;
 
-       COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+       ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
-       ad.selinux_audit_data = &sad;
 
        rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
                          DIR__ADD_NAME | DIR__SEARCH,
@@ -1643,7 +1618,6 @@ 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;
@@ -1651,9 +1625,8 @@ static int may_link(struct inode *dir,
        dsec = dir->i_security;
        isec = dentry->d_inode->i_security;
 
-       COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
+       ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
-       ad.selinux_audit_data = &sad;
 
        av = DIR__SEARCH;
        av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1688,7 +1661,6 @@ 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;
@@ -1699,8 +1671,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;
 
-       COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_DENTRY;
 
        ad.u.dentry = old_dentry;
        rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
@@ -1986,7 +1957,6 @@ 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;
 
@@ -2032,8 +2002,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
                        return rc;
        }
 
-       COMMON_AUDIT_DATA_INIT(&ad, PATH);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = bprm->file->f_path;
 
        if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) ||
@@ -2123,8 +2092,6 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
 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,21 +2103,17 @@ static inline void flush_unauthorized_files(const struct cred *cred,
                spin_lock(&tty_files_lock);
                if (!list_empty(&tty->tty_files)) {
                        struct tty_file_private *file_priv;
-                       struct inode *inode;
 
                        /* Revalidate access to controlling tty.
-                          Use inode_has_perm on the tty inode directly rather
+                          Use path_has_perm on the tty path directly rather
                           than using file_has_perm, as this particular open
                           file may belong to another process and we are only
                           interested in the inode-based check here. */
                        file_priv = list_first_entry(&tty->tty_files,
                                                struct tty_file_private, list);
                        file = file_priv->file;
-                       inode = file->f_path.dentry->d_inode;
-                       if (inode_has_perm_noadp(cred, inode,
-                                          FILE__READ | FILE__WRITE, 0)) {
+                       if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE))
                                drop_tty = 1;
-                       }
                }
                spin_unlock(&tty_files_lock);
                tty_kref_put(tty);
@@ -2160,10 +2123,6 @@ static inline void flush_unauthorized_files(const struct cred *cred,
                no_tty();
 
        /* Revalidate access to inherited open files. */
-
-       COMMON_AUDIT_DATA_INIT(&ad, INODE);
-       ad.selinux_audit_data = &sad;
-
        spin_lock(&files->file_lock);
        for (;;) {
                unsigned long set, i;
@@ -2500,7 +2459,6 @@ 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);
@@ -2511,8 +2469,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
        if (flags & MS_KERNMOUNT)
                return 0;
 
-       COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = sb->s_root;
        return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
 }
@@ -2521,10 +2478,8 @@ 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.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry->d_sb->s_root;
        return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
 }
@@ -2684,14 +2639,35 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
        return dentry_has_perm(cred, dentry, FILE__READ);
 }
 
+static noinline int audit_inode_permission(struct inode *inode,
+                                          u32 perms, u32 audited, u32 denied,
+                                          unsigned flags)
+{
+       struct common_audit_data ad;
+       struct inode_security_struct *isec = inode->i_security;
+       int rc;
+
+       ad.type = LSM_AUDIT_DATA_INODE;
+       ad.u.inode = inode;
+
+       rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms,
+                           audited, denied, &ad, flags);
+       if (rc)
+               return rc;
+       return 0;
+}
+
 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;
+       struct inode_security_struct *isec;
+       u32 sid;
+       struct av_decision avd;
+       int rc, rc2;
+       u32 audited, denied;
 
        from_access = mask & MAY_ACCESS;
        mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
@@ -2700,22 +2676,34 @@ static int selinux_inode_permission(struct inode *inode, int mask)
        if (!mask)
                return 0;
 
-       COMMON_AUDIT_DATA_INIT(&ad, INODE);
-       ad.selinux_audit_data = &sad;
-       ad.u.inode = inode;
+       validate_creds(cred);
 
-       if (from_access)
-               ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS;
+       if (unlikely(IS_PRIVATE(inode)))
+               return 0;
 
        perms = file_mask_to_av(inode->i_mode, mask);
 
-       return inode_has_perm(cred, inode, perms, &ad, flags);
+       sid = cred_sid(cred);
+       isec = inode->i_security;
+
+       rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
+       audited = avc_audit_required(perms, &avd, rc,
+                                    from_access ? FILE__AUDIT_ACCESS : 0,
+                                    &denied);
+       if (likely(!audited))
+               return rc;
+
+       rc2 = audit_inode_permission(inode, perms, audited, denied, flags);
+       if (rc2)
+               return rc2;
+       return rc;
 }
 
 static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        const struct cred *cred = current_cred();
        unsigned int ia_valid = iattr->ia_valid;
+       __u32 av = FILE__WRITE;
 
        /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */
        if (ia_valid & ATTR_FORCE) {
@@ -2729,7 +2717,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
                        ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
                return dentry_has_perm(cred, dentry, FILE__SETATTR);
 
-       return dentry_has_perm(cred, dentry, FILE__WRITE);
+       if (ia_valid & ATTR_SIZE)
+               av |= FILE__OPEN;
+
+       return dentry_has_perm(cred, dentry, av);
 }
 
 static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
@@ -2771,7 +2762,6 @@ 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;
 
@@ -2785,8 +2775,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
        if (!inode_owner_or_capable(inode))
                return -EPERM;
 
-       COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
 
        rc = avc_has_perm(sid, isec->sid, isec->sclass,
@@ -2796,8 +2785,25 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
 
        rc = security_context_to_sid(value, size, &newsid);
        if (rc == -EINVAL) {
-               if (!capable(CAP_MAC_ADMIN))
+               if (!capable(CAP_MAC_ADMIN)) {
+                       struct audit_buffer *ab;
+                       size_t audit_size;
+                       const char *str;
+
+                       /* We strip a nul only if it is at the end, otherwise the
+                        * context contains a nul and we should audit that */
+                       str = value;
+                       if (str[size - 1] == '\0')
+                               audit_size = size - 1;
+                       else
+                               audit_size = size;
+                       ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
+                       audit_log_format(ab, "op=setxattr invalid_context=");
+                       audit_log_n_untrustedstring(ab, value, audit_size);
+                       audit_log_end(ab);
+
                        return rc;
+               }
                rc = security_context_to_sid_force(value, size, &newsid);
        }
        if (rc)
@@ -2977,7 +2983,7 @@ static int selinux_file_permission(struct file *file, int mask)
 
        if (sid == fsec->sid && fsec->isid == isec->sid &&
            fsec->pseqno == avc_policy_seqno())
-               /* No change since dentry_open check. */
+               /* No change since file_open check. */
                return 0;
 
        return selinux_revalidate_file_permission(file, mask);
@@ -3236,15 +3242,13 @@ static int selinux_file_receive(struct file *file)
        return file_has_perm(cred, file, file_to_av(file));
 }
 
-static int selinux_dentry_open(struct file *file, const struct cred *cred)
+static int selinux_file_open(struct file *file, const struct cred *cred)
 {
        struct file_security_struct *fsec;
-       struct inode *inode;
        struct inode_security_struct *isec;
 
-       inode = file->f_path.dentry->d_inode;
        fsec = file->f_security;
-       isec = inode->i_security;
+       isec = file->f_path.dentry->d_inode->i_security;
        /*
         * Save inode label and policy sequence number
         * at open-time so that selinux_file_permission
@@ -3262,7 +3266,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
         * new inode label or new policy.
         * This check is not redundant - do not remove.
         */
-       return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
+       return path_has_perm(cred, &file->f_path, open_file_to_av(file));
 }
 
 /* task security operations */
@@ -3381,12 +3385,10 @@ 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.type = LSM_AUDIT_DATA_KMOD;
        ad.u.kmod_name = kmod_name;
 
        return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
@@ -3759,15 +3761,13 @@ 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.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->sk = sk;
 
@@ -3847,7 +3847,6 @@ 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;
@@ -3874,8 +3873,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                                                      snum, &sid);
                                if (err)
                                        goto out;
-                               COMMON_AUDIT_DATA_INIT(&ad, NET);
-                               ad.selinux_audit_data = &sad;
+                               ad.type = LSM_AUDIT_DATA_NET;
                                ad.u.net = &net;
                                ad.u.net->sport = htons(snum);
                                ad.u.net->family = family;
@@ -3909,8 +3907,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
                if (err)
                        goto out;
 
-               COMMON_AUDIT_DATA_INIT(&ad, NET);
-               ad.selinux_audit_data = &sad;
+               ad.type = LSM_AUDIT_DATA_NET;
                ad.u.net = &net;
                ad.u.net->sport = htons(snum);
                ad.u.net->family = family;
@@ -3945,7 +3942,6 @@ 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;
@@ -3971,8 +3967,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
                perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
                       TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
 
-               COMMON_AUDIT_DATA_INIT(&ad, NET);
-               ad.selinux_audit_data = &sad;
+               ad.type = LSM_AUDIT_DATA_NET;
                ad.u.net = &net;
                ad.u.net->dport = htons(snum);
                ad.u.net->family = sk->sk_family;
@@ -4064,12 +4059,10 @@ 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.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->sk = other;
 
@@ -4098,11 +4091,9 @@ 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.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->sk = other->sk;
 
@@ -4140,12 +4131,10 @@ 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.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->netif = skb->skb_iif;
        ad.u.net->family = family;
@@ -4175,7 +4164,6 @@ 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;
@@ -4200,8 +4188,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
        if (!secmark_active && !peerlbl_active)
                return 0;
 
-       COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->netif = skb->skb_iif;
        ad.u.net->family = family;
@@ -4539,7 +4526,6 @@ 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;
@@ -4557,8 +4543,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;
 
-       COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->netif = ifindex;
        ad.u.net->family = family;
@@ -4648,7 +4633,6 @@ 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;
@@ -4657,8 +4641,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
                return NF_ACCEPT;
        sksec = sk->sk_security;
 
-       COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->netif = ifindex;
        ad.u.net->family = family;
@@ -4683,7 +4666,6 @@ 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;
@@ -4730,8 +4712,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
                secmark_perm = PACKET__SEND;
        }
 
-       COMMON_AUDIT_DATA_INIT(&ad, NET);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_NET;
        ad.u.net = &net;
        ad.u.net->netif = ifindex;
        ad.u.net->family = family;
@@ -4849,13 +4830,11 @@ 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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = ipc_perms->key;
 
        return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
@@ -4876,7 +4855,6 @@ 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;
 
@@ -4886,8 +4864,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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4908,13 +4885,11 @@ 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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ,
@@ -4954,7 +4929,6 @@ 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;
 
@@ -4975,8 +4949,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
                        return rc;
        }
 
-       COMMON_AUDIT_DATA_INIT(&ad, IPC);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
 
        /* Can this process write to the queue? */
@@ -5001,15 +4974,13 @@ 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;
 
        isec = msq->q_perm.security;
        msec = msg->security;
 
-       COMMON_AUDIT_DATA_INIT(&ad, IPC);
-       ad.selinux_audit_data = &sad;
+       ad.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = msq->q_perm.key;
 
        rc = avc_has_perm(sid, isec->sid,
@@ -5025,7 +4996,6 @@ 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;
 
@@ -5035,8 +5005,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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->shm_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -5057,13 +5026,11 @@ 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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = shp->shm_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_SHM,
@@ -5121,7 +5088,6 @@ 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;
 
@@ -5131,8 +5097,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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->sem_perm.key;
 
        rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -5153,13 +5118,11 @@ 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.type = LSM_AUDIT_DATA_IPC;
        ad.u.ipc_id = sma->sem_perm.key;
 
        return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
@@ -5339,8 +5302,23 @@ static int selinux_setprocattr(struct task_struct *p,
                }
                error = security_context_to_sid(value, size, &sid);
                if (error == -EINVAL && !strcmp(name, "fscreate")) {
-                       if (!capable(CAP_MAC_ADMIN))
+                       if (!capable(CAP_MAC_ADMIN)) {
+                               struct audit_buffer *ab;
+                               size_t audit_size;
+
+                               /* We strip a nul only if it is at the end, otherwise the
+                                * context contains a nul and we should audit that */
+                               if (str[size - 1] == '\0')
+                                       audit_size = size - 1;
+                               else
+                                       audit_size = size;
+                               ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR);
+                               audit_log_format(ab, "op=fscreate invalid_context=");
+                               audit_log_n_untrustedstring(ab, value, audit_size);
+                               audit_log_end(ab);
+
                                return error;
+                       }
                        error = security_context_to_sid_force(value, size,
                                                              &sid);
                }
@@ -5600,7 +5578,7 @@ static struct security_operations selinux_ops = {
        .file_send_sigiotask =          selinux_file_send_sigiotask,
        .file_receive =                 selinux_file_receive,
 
-       .dentry_open =                  selinux_dentry_open,
+       .file_open =                    selinux_file_open,
 
        .task_create =                  selinux_task_create,
        .cred_alloc_blank =             selinux_cred_alloc_blank,
index 1931370..92d0ab5 100644 (file)
@@ -49,7 +49,7 @@ struct avc_cache_stats {
 /*
  * We only need this data after we have decided to send an audit message.
  */
-struct selinux_late_audit_data {
+struct selinux_audit_data {
        u32 ssid;
        u32 tsid;
        u16 tclass;
@@ -60,28 +60,86 @@ struct selinux_late_audit_data {
 };
 
 /*
- * We collect this at the beginning or during an selinux security operation
- */
-struct selinux_audit_data {
-       /*
-        * auditdeny is a bit tricky and unintuitive.  See the
-        * comments in avc.c for it's meaning and usage.
-        */
-       u32 auditdeny;
-       struct selinux_late_audit_data *slad;
-};
-
-/*
  * AVC operations
  */
 
 void __init avc_init(void);
 
-int avc_audit(u32 ssid, u32 tsid,
-              u16 tclass, u32 requested,
-              struct av_decision *avd,
-              int result,
-             struct common_audit_data *a, unsigned flags);
+static inline u32 avc_audit_required(u32 requested,
+                             struct av_decision *avd,
+                             int result,
+                             u32 auditdeny,
+                             u32 *deniedp)
+{
+       u32 denied, audited;
+       denied = requested & ~avd->allowed;
+       if (unlikely(denied)) {
+               audited = denied & avd->auditdeny;
+               /*
+                * auditdeny is TRICKY!  Setting a bit in
+                * this field means that ANY denials should NOT be audited if
+                * the policy contains an explicit dontaudit rule for that
+                * permission.  Take notice that this is unrelated to the
+                * actual permissions that were denied.  As an example lets
+                * assume:
+                *
+                * denied == READ
+                * avd.auditdeny & ACCESS == 0 (not set means explicit rule)
+                * auditdeny & ACCESS == 1
+                *
+                * We will NOT audit the denial even though the denied
+                * permission was READ and the auditdeny checks were for
+                * ACCESS
+                */
+               if (auditdeny && !(auditdeny & avd->auditdeny))
+                       audited = 0;
+       } else if (result)
+               audited = denied = requested;
+       else
+               audited = requested & avd->auditallow;
+       *deniedp = denied;
+       return audited;
+}
+
+int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
+                  u32 requested, u32 audited, u32 denied,
+                  struct common_audit_data *a,
+                  unsigned flags);
+
+/**
+ * avc_audit - Audit the granting or denial of permissions.
+ * @ssid: source security identifier
+ * @tsid: target security identifier
+ * @tclass: target security class
+ * @requested: requested permissions
+ * @avd: access vector decisions
+ * @result: result from avc_has_perm_noaudit
+ * @a:  auxiliary audit data
+ * @flags: VFS walk flags
+ *
+ * Audit the granting or denial of permissions in accordance
+ * with the policy.  This function is typically called by
+ * avc_has_perm() after a permission check, but can also be
+ * called directly by callers who use avc_has_perm_noaudit()
+ * in order to separate the permission check from the auditing.
+ * For example, this separation is useful when the permission check must
+ * be performed under a lock, to allow the lock to be released
+ * before calling the auditing code.
+ */
+static inline int avc_audit(u32 ssid, u32 tsid,
+                           u16 tclass, u32 requested,
+                           struct av_decision *avd,
+                           int result,
+                           struct common_audit_data *a, unsigned flags)
+{
+       u32 audited, denied;
+       audited = avc_audit_required(requested, avd, result, 0, &denied);
+       if (likely(!audited))
+               return 0;
+       return slow_avc_audit(ssid, tsid, tclass,
+                             requested, audited, denied,
+                             a, flags);
+}
 
 #define AVC_STRICT 1 /* Ignore permissive mode. */
 int avc_has_perm_noaudit(u32 ssid, u32 tsid,
@@ -112,11 +170,7 @@ u32 avc_policy_seqno(void);
 #define AVC_CALLBACK_AUDITDENY_ENABLE  64
 #define AVC_CALLBACK_AUDITDENY_DISABLE 128
 
-int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid,
-                                    u16 tclass, u32 perms,
-                                    u32 *out_retained),
-                    u32 events, u32 ssid, u32 tsid,
-                    u16 tclass, u32 perms);
+int avc_add_callback(int (*callback)(u32 event), u32 events);
 
 /* Exported to selinuxfs */
 int avc_get_hash_stats(char *page);
index d871e8a..dde2005 100644 (file)
 #define POLICYDB_VERSION_BOUNDARY      24
 #define POLICYDB_VERSION_FILENAME_TRANS        25
 #define POLICYDB_VERSION_ROLETRANS     26
+#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS   27
+#define POLICYDB_VERSION_DEFAULT_TYPE  28
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX   CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_ROLETRANS
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_DEFAULT_TYPE
 #endif
 
 /* Mask for just the mount related flags */
index 326f22c..47a49d1 100644 (file)
@@ -252,8 +252,7 @@ static void sel_netif_flush(void)
        spin_unlock_bh(&sel_netif_lock);
 }
 
-static int sel_netif_avc_callback(u32 event, u32 ssid, u32 tsid,
-                                 u16 class, u32 perms, u32 *retained)
+static int sel_netif_avc_callback(u32 event)
 {
        if (event == AVC_CALLBACK_RESET) {
                sel_netif_flush();
@@ -292,8 +291,7 @@ static __init int sel_netif_init(void)
 
        register_netdevice_notifier(&sel_netif_netdev_notifier);
 
-       err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET,
-                              SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
+       err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
        if (err)
                panic("avc_add_callback() failed, error %d\n", err);
 
index 8636585..28f911c 100644 (file)
@@ -297,8 +297,7 @@ static void sel_netnode_flush(void)
        spin_unlock_bh(&sel_netnode_lock);
 }
 
-static int sel_netnode_avc_callback(u32 event, u32 ssid, u32 tsid,
-                                   u16 class, u32 perms, u32 *retained)
+static int sel_netnode_avc_callback(u32 event)
 {
        if (event == AVC_CALLBACK_RESET) {
                sel_netnode_flush();
@@ -320,8 +319,7 @@ static __init int sel_netnode_init(void)
                sel_netnode_hash[iter].size = 0;
        }
 
-       ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET,
-                              SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
+       ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
        if (ret != 0)
                panic("avc_add_callback() failed, error %d\n", ret);
 
index 7b9eb1f..d353797 100644 (file)
@@ -234,8 +234,7 @@ static void sel_netport_flush(void)
        spin_unlock_bh(&sel_netport_lock);
 }
 
-static int sel_netport_avc_callback(u32 event, u32 ssid, u32 tsid,
-                                   u16 class, u32 perms, u32 *retained)
+static int sel_netport_avc_callback(u32 event)
 {
        if (event == AVC_CALLBACK_RESET) {
                sel_netport_flush();
@@ -257,8 +256,7 @@ static __init int sel_netport_init(void)
                sel_netport_hash[iter].size = 0;
        }
 
-       ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET,
-                              SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
+       ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
        if (ret != 0)
                panic("avc_add_callback() failed, error %d\n", ret);
 
index d7018bf..4e93f9e 100644 (file)
@@ -496,6 +496,7 @@ static const struct file_operations sel_policy_ops = {
        .read           = sel_read_policy,
        .mmap           = sel_mmap_policy,
        .release        = sel_release_policy,
+       .llseek         = generic_file_llseek,
 };
 
 static ssize_t sel_write_load(struct file *file, const char __user *buf,
@@ -1232,6 +1233,7 @@ static int sel_make_bools(void)
                kfree(bool_pending_names[i]);
        kfree(bool_pending_names);
        kfree(bool_pending_values);
+       bool_num = 0;
        bool_pending_names = NULL;
        bool_pending_values = NULL;
 
@@ -1532,11 +1534,6 @@ static int sel_make_initcon_files(struct dentry *dir)
        return 0;
 }
 
-static inline unsigned int sel_div(unsigned long a, unsigned long b)
-{
-       return a / b - (a % b < 0);
-}
-
 static inline unsigned long sel_class_to_ino(u16 class)
 {
        return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
@@ -1544,7 +1541,7 @@ static inline unsigned long sel_class_to_ino(u16 class)
 
 static inline u16 sel_ino_to_class(unsigned long ino)
 {
-       return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
+       return (ino & SEL_INO_MASK) / (SEL_VEC_MAX + 1);
 }
 
 static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
@@ -1831,7 +1828,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
                [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
                [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
                [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
-               [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR},
+               [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
                /* last one */ {""}
        };
        ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
index 45e8fb0..212e347 100644 (file)
@@ -74,6 +74,26 @@ out:
        return rc;
 }
 
+/*
+ * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
+ */
+static inline int mls_context_cpy_high(struct context *dst, struct context *src)
+{
+       int rc;
+
+       dst->range.level[0].sens = src->range.level[1].sens;
+       rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
+       if (rc)
+               goto out;
+
+       dst->range.level[1].sens = src->range.level[1].sens;
+       rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
+       if (rc)
+               ebitmap_destroy(&dst->range.level[0].cat);
+out:
+       return rc;
+}
+
 static inline int mls_context_cmp(struct context *c1, struct context *c2)
 {
        return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
index fbf9c58..40de8d3 100644 (file)
@@ -517,6 +517,8 @@ int mls_compute_sid(struct context *scontext,
 {
        struct range_trans rtr;
        struct mls_range *r;
+       struct class_datum *cladatum;
+       int default_range = 0;
 
        if (!policydb.mls_enabled)
                return 0;
@@ -530,6 +532,28 @@ int mls_compute_sid(struct context *scontext,
                r = hashtab_search(policydb.range_tr, &rtr);
                if (r)
                        return mls_range_set(newcontext, r);
+
+               if (tclass && tclass <= policydb.p_classes.nprim) {
+                       cladatum = policydb.class_val_to_struct[tclass - 1];
+                       if (cladatum)
+                               default_range = cladatum->default_range;
+               }
+
+               switch (default_range) {
+               case DEFAULT_SOURCE_LOW:
+                       return mls_context_cpy_low(newcontext, scontext);
+               case DEFAULT_SOURCE_HIGH:
+                       return mls_context_cpy_high(newcontext, scontext);
+               case DEFAULT_SOURCE_LOW_HIGH:
+                       return mls_context_cpy(newcontext, scontext);
+               case DEFAULT_TARGET_LOW:
+                       return mls_context_cpy_low(newcontext, tcontext);
+               case DEFAULT_TARGET_HIGH:
+                       return mls_context_cpy_high(newcontext, tcontext);
+               case DEFAULT_TARGET_LOW_HIGH:
+                       return mls_context_cpy(newcontext, tcontext);
+               }
+
                /* Fallthrough */
        case AVTAB_CHANGE:
                if ((tclass == policydb.process_class) || (sock == true))
index a7f61d5..9cd9b7c 100644 (file)
@@ -133,6 +133,16 @@ static struct policydb_compat_info policydb_compat[] = {
                .sym_num        = SYM_NUM,
                .ocon_num       = OCON_NUM,
        },
+       {
+               .version        = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
+               .sym_num        = SYM_NUM,
+               .ocon_num       = OCON_NUM,
+       },
+       {
+               .version        = POLICYDB_VERSION_DEFAULT_TYPE,
+               .sym_num        = SYM_NUM,
+               .ocon_num       = OCON_NUM,
+       },
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -1306,6 +1316,23 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                        goto bad;
        }
 
+       if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) {
+               rc = next_entry(buf, fp, sizeof(u32) * 3);
+               if (rc)
+                       goto bad;
+
+               cladatum->default_user = le32_to_cpu(buf[0]);
+               cladatum->default_role = le32_to_cpu(buf[1]);
+               cladatum->default_range = le32_to_cpu(buf[2]);
+       }
+
+       if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
+               rc = next_entry(buf, fp, sizeof(u32) * 1);
+               if (rc)
+                       goto bad;
+               cladatum->default_type = le32_to_cpu(buf[0]);
+       }
+
        rc = hashtab_insert(h, key, cladatum);
        if (rc)
                goto bad;
@@ -2832,6 +2859,23 @@ static int class_write(void *vkey, void *datum, void *ptr)
        if (rc)
                return rc;
 
+       if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) {
+               buf[0] = cpu_to_le32(cladatum->default_user);
+               buf[1] = cpu_to_le32(cladatum->default_role);
+               buf[2] = cpu_to_le32(cladatum->default_range);
+
+               rc = put_entry(buf, sizeof(uint32_t), 3, fp);
+               if (rc)
+                       return rc;
+       }
+
+       if (p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) {
+               buf[0] = cpu_to_le32(cladatum->default_type);
+               rc = put_entry(buf, sizeof(uint32_t), 1, fp);
+               if (rc)
+                       return rc;
+       }
+
        return 0;
 }
 
index b846c03..da63747 100644 (file)
@@ -60,6 +60,20 @@ struct class_datum {
        struct symtab permissions;      /* class-specific permission symbol table */
        struct constraint_node *constraints;    /* constraints on class permissions */
        struct constraint_node *validatetrans;  /* special transition rules */
+/* Options how a new object user, role, and type should be decided */
+#define DEFAULT_SOURCE         1
+#define DEFAULT_TARGET         2
+       char default_user;
+       char default_role;
+       char default_type;
+/* Options how a new object range should be decided */
+#define DEFAULT_SOURCE_LOW     1
+#define DEFAULT_SOURCE_HIGH    2
+#define DEFAULT_SOURCE_LOW_HIGH        3
+#define DEFAULT_TARGET_LOW     4
+#define DEFAULT_TARGET_HIGH    5
+#define DEFAULT_TARGET_LOW_HIGH        6
+       char default_range;
 };
 
 /* Role attributes */
index 185f849..4321b8f 100644 (file)
@@ -1018,9 +1018,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
 
        if (context->len) {
                *scontext_len = context->len;
-               *scontext = kstrdup(context->str, GFP_ATOMIC);
-               if (!(*scontext))
-                       return -ENOMEM;
+               if (scontext) {
+                       *scontext = kstrdup(context->str, GFP_ATOMIC);
+                       if (!(*scontext))
+                               return -ENOMEM;
+               }
                return 0;
        }
 
@@ -1389,6 +1391,7 @@ static int security_compute_sid(u32 ssid,
                                u32 *out_sid,
                                bool kern)
 {
+       struct class_datum *cladatum = NULL;
        struct context *scontext = NULL, *tcontext = NULL, newcontext;
        struct role_trans *roletr = NULL;
        struct avtab_key avkey;
@@ -1437,12 +1440,20 @@ static int security_compute_sid(u32 ssid,
                goto out_unlock;
        }
 
+       if (tclass && tclass <= policydb.p_classes.nprim)
+               cladatum = policydb.class_val_to_struct[tclass - 1];
+
        /* Set the user identity. */
        switch (specified) {
        case AVTAB_TRANSITION:
        case AVTAB_CHANGE:
-               /* Use the process user identity. */
-               newcontext.user = scontext->user;
+               if (cladatum && cladatum->default_user == DEFAULT_TARGET) {
+                       newcontext.user = tcontext->user;
+               } else {
+                       /* notice this gets both DEFAULT_SOURCE and unset */
+                       /* Use the process user identity. */
+                       newcontext.user = scontext->user;
+               }
                break;
        case AVTAB_MEMBER:
                /* Use the related object owner. */
@@ -1450,16 +1461,31 @@ static int security_compute_sid(u32 ssid,
                break;
        }
 
-       /* Set the role and type to default values. */
-       if ((tclass == policydb.process_class) || (sock == true)) {
-               /* Use the current role and type of process. */
+       /* Set the role to default values. */
+       if (cladatum && cladatum->default_role == DEFAULT_SOURCE) {
                newcontext.role = scontext->role;
-               newcontext.type = scontext->type;
+       } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) {
+               newcontext.role = tcontext->role;
        } else {
-               /* Use the well-defined object role. */
-               newcontext.role = OBJECT_R_VAL;
-               /* Use the type of the related object. */
+               if ((tclass == policydb.process_class) || (sock == true))
+                       newcontext.role = scontext->role;
+               else
+                       newcontext.role = OBJECT_R_VAL;
+       }
+
+       /* Set the type to default values. */
+       if (cladatum && cladatum->default_type == DEFAULT_SOURCE) {
+               newcontext.type = scontext->type;
+       } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) {
                newcontext.type = tcontext->type;
+       } else {
+               if ((tclass == policydb.process_class) || (sock == true)) {
+                       /* Use the type of process. */
+                       newcontext.type = scontext->type;
+               } else {
+                       /* Use the type of the related object. */
+                       newcontext.type = tcontext->type;
+               }
        }
 
        /* Look for a type transition/member/change rule. */
@@ -3018,8 +3044,7 @@ out:
 
 static int (*aurule_callback)(void) = audit_update_lsm_rules;
 
-static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid,
-                              u16 class, u32 perms, u32 *retained)
+static int aurule_avc_callback(u32 event)
 {
        int err = 0;
 
@@ -3032,8 +3057,7 @@ static int __init aurule_init(void)
 {
        int err;
 
-       err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET,
-                              SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
+       err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET);
        if (err)
                panic("avc_add_callback() failed, error %d\n", err);
 
index 5e031a2..cc361b8 100644 (file)
@@ -304,7 +304,7 @@ void smack_log(char *subject_label, char *object_label,
 static inline void smk_ad_init(struct smk_audit_info *a, const char *func,
                               char type)
 {
-       memset(a, 0, sizeof(*a));
+       memset(&a->sad, 0, sizeof(a->sad));
        a->a.type = type;
        a->a.smack_audit_data = &a->sad;
        a->a.smack_audit_data->function = func;
index 952b1f4..d583c05 100644 (file)
@@ -1359,7 +1359,7 @@ static int smack_file_receive(struct file *file)
 }
 
 /**
- * smack_dentry_open - Smack dentry open processing
+ * smack_file_open - Smack dentry open processing
  * @file: the object
  * @cred: unused
  *
@@ -1367,7 +1367,7 @@ static int smack_file_receive(struct file *file)
  *
  * Returns 0
  */
-static int smack_dentry_open(struct file *file, const struct cred *cred)
+static int smack_file_open(struct file *file, const struct cred *cred)
 {
        struct inode_smack *isp = file->f_path.dentry->d_inode->i_security;
 
@@ -3487,7 +3487,7 @@ struct security_operations smack_ops = {
        .file_send_sigiotask =          smack_file_send_sigiotask,
        .file_receive =                 smack_file_receive,
 
-       .dentry_open =                  smack_dentry_open,
+       .file_open =                    smack_file_open,
 
        .cred_alloc_blank =             smack_cred_alloc_blank,
        .cred_free =                    smack_cred_free,
index 620d37c..c2d04a5 100644 (file)
@@ -319,14 +319,14 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
 }
 
 /**
- * tomoyo_dentry_open - Target for security_dentry_open().
+ * tomoyo_file_open - Target for security_file_open().
  *
  * @f:    Pointer to "struct file".
  * @cred: Pointer to "struct cred".
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
+static int tomoyo_file_open(struct file *f, const struct cred *cred)
 {
        int flags = f->f_flags;
        /* Don't check read permission here if called from do_execve(). */
@@ -510,7 +510,7 @@ static struct security_operations tomoyo_security_ops = {
        .bprm_set_creds      = tomoyo_bprm_set_creds,
        .bprm_check_security = tomoyo_bprm_check_security,
        .file_fcntl          = tomoyo_file_fcntl,
-       .dentry_open         = tomoyo_dentry_open,
+       .file_open           = tomoyo_file_open,
        .path_truncate       = tomoyo_path_truncate,
        .path_unlink         = tomoyo_path_unlink,
        .path_mkdir          = tomoyo_path_mkdir,