__e;                                    \
 })
 
+struct aa_secmark {
+       u8 audit;
+       u8 deny;
+       u32 secid;
+       char *label;
+};
+
 extern struct aa_sfs_entry aa_sfs_entry_network[];
 
 void audit_net_cb(struct audit_buffer *ab, void *va);
 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
                      struct socket *sock);
 
+int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
+                          u32 secid, struct sock *sk);
+
 #endif /* __AA_NET_H */
 
        for (i = 0; i < profile->xattr_count; i++)
                kzfree(profile->xattrs[i]);
        kzfree(profile->xattrs);
+       for (i=0; i < profile->secmark_count; i++)
+               kzfree(profile->secmark[i].label);
+       kzfree(profile->secmark);
        kzfree(profile->dirname);
        aa_put_dfa(profile->xmatch);
        aa_put_dfa(profile->policy.dfa);
 
        return 0;
 }
 
+static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
+{
+       if (unpack_nameX(e, AA_U8, name)) {
+               if (!inbounds(e, sizeof(u8)))
+                       return 0;
+               if (data)
+                       *data = get_unaligned((u8 *)e->pos);
+               e->pos += sizeof(u8);
+               return 1;
+       }
+       return 0;
+}
+
 static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
 {
        if (unpack_nameX(e, AA_U32, name)) {
        return 0;
 }
 
+static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
+{
+       void *pos = e->pos;
+       int i, size;
+
+       if (unpack_nameX(e, AA_STRUCT, "secmark")) {
+               size = unpack_array(e, NULL);
+
+               profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
+                                          GFP_KERNEL);
+               if (!profile->secmark)
+                       goto fail;
+
+               profile->secmark_count = size;
+
+               for (i = 0; i < size; i++) {
+                       if (!unpack_u8(e, &profile->secmark[i].audit, NULL))
+                               goto fail;
+                       if (!unpack_u8(e, &profile->secmark[i].deny, NULL))
+                               goto fail;
+                       if (!unpack_strdup(e, &profile->secmark[i].label, NULL))
+                               goto fail;
+               }
+               if (!unpack_nameX(e, AA_ARRAYEND, NULL))
+                       goto fail;
+               if (!unpack_nameX(e, AA_STRUCTEND, NULL))
+                       goto fail;
+       }
+
+       return 1;
+
+fail:
+       if (profile->secmark) {
+               for (i = 0; i < size; i++)
+                       kfree(profile->secmark[i].label);
+               kfree(profile->secmark);
+               profile->secmark_count = 0;
+       }
+
+       e->pos = pos;
+       return 0;
+}
+
 static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
 {
        void *pos = e->pos;
                goto fail;
        }
 
+       if (!unpack_secmark(e, profile)) {
+               info = "failed to unpack profile secmark rules";
+               goto fail;
+       }
+
        if (unpack_nameX(e, AA_STRUCT, "policydb")) {
                /* generic policy dfa - optional and may be NULL */
                info = "failed to unpack policydb";