-diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
-new file mode 100644
-index 0000000..fbbc961
---- /dev/null
-+++ b/security/apparmor/include/apparmor.h
-@@ -0,0 +1,65 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor basic global and lib definitions
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __APPARMOR_H
-+#define __APPARMOR_H
-+
-+#include <linux/fs.h>
-+
-+/* Control parameters settable thru module/boot flags or
-+ * via /sys/kernel/security/apparmor/control */
-+extern enum audit_mode g_apparmor_audit;
-+extern int g_apparmor_audit_header;
-+extern int g_apparmor_debug;
-+extern int g_apparmor_lock_policy;
-+extern int g_apparmor_logsyscall;
-+extern unsigned int g_apparmor_path_max;
-+
-+
-+/*
-+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
-+ * which is not related to profile accesses.
-+ */
-+
-+#define AA_DEBUG(fmt, args...) \
-+ do { \
-+ if (g_apparmor_debug && printk_ratelimit()) \
-+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
-+ } while (0)
-+
-+#define AA_ERROR(fmt, args...) \
-+ do { \
-+ if (printk_ratelimit()) \
-+ printk(KERN_ERR "AppArmor: " fmt, ##args); \
-+ } while (0)
-+
-+/* Flag indicating whether initialization completed */
-+extern int apparmor_initialized;
-+void apparmor_disable(void);
-+
-+/* fn's in lib */
-+void info_message(const char *str);
-+char *aa_split_name_from_ns(char *args, char **ns_name);
-+char *new_compound_name(const char *n1, const char *n2);
-+int aa_strneq(const char *str, const char *sub, int len);
-+char *strchrnul(const char *s, int c);
-+const char *fqname_subname(const char *name);
-+
-+static inline int mediated_filesystem(struct inode *inode)
-+{
-+ return !(inode->i_sb->s_flags & MS_NOUSER);
-+}
-+
-+#endif /* __APPARMOR_H */
-+
-diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
-new file mode 100644
-index 0000000..1af7723
---- /dev/null
-+++ b/security/apparmor/include/apparmorfs.h
-@@ -0,0 +1,24 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor filesystem definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_APPARMORFS_H
-+#define __AA_APPARMORFS_H
-+
-+extern struct dentry *apparmorfs_null;
-+extern struct vfsmount *apparmorfs_mnt;
-+
-+extern int create_apparmorfs(void);
-+extern void destroy_apparmorfs(void);
-+
-+#endif /* __AA_APPARMORFS_H */
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-new file mode 100644
-index 0000000..2180dd7
---- /dev/null
-+++ b/security/apparmor/include/audit.h
-@@ -0,0 +1,59 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor auditing function definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_AUDIT_H
-+#define __AA_AUDIT_H
-+
-+#include <linux/audit.h>
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+
-+struct aa_profile;
-+
-+
-+extern const char *audit_mode_names[];
-+#define AUDIT_MAX_INDEX 5
-+
-+#define AUDIT_APPARMOR_AUTO 0 /* auto choose audit message type */
-+
-+enum audit_mode {
-+ AUDIT_NORMAL, /* follow normal auditing of accesses */
-+ AUDIT_QUIET_DENIED, /* quiet all denied access messages */
-+ AUDIT_QUIET, /* quiet all messages */
-+ AUDIT_NOQUIET, /* do not quiet audit messages */
-+ AUDIT_ALL /* audit all accesses */
-+};
-+
-+/*
-+ * aa_audit - AppArmor auditing structure
-+ * Structure is populated by access control code and passed to aa_audit which
-+ * provides for a single point of logging.
-+ */
-+struct aa_audit {
-+ struct task_struct *task;
-+ gfp_t gfp_mask;
-+ int error;
-+ const char *operation;
-+ const char *info;
-+};
-+
-+int aa_audit(int type, struct aa_profile *profile, struct aa_audit *sa,
-+ void(*cb)(struct audit_buffer *, void *));
-+
-+int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, const char *,
-+ void(*cb)(struct audit_buffer *, void *));
-+
-+
-+#endif /* __AA_AUDIT_H */
-diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
-new file mode 100644
-index 0000000..43bb7eb
---- /dev/null
-+++ b/security/apparmor/include/capability.h
-@@ -0,0 +1,45 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor capability mediation definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_CAPABILITY_H
-+#define __AA_CAPABILITY_H
-+
-+#include <linux/sched.h>
-+
-+struct aa_profile;
-+
-+/* aa_caps - confinement data for capabilities
-+ * @set_caps: capabilities that are being set
-+ * @capabilities: capabilities mask
-+ * @audit_caps: caps that are to be audited
-+ * @quiet_caps: caps that should not be audited
-+ */
-+struct aa_caps {
-+ kernel_cap_t set;
-+ kernel_cap_t allowed;
-+ kernel_cap_t audit;
-+ kernel_cap_t quiet;
-+ kernel_cap_t kill;
-+};
-+
-+int aa_profile_capable(struct aa_profile *profile, int cap);
-+int aa_capable(struct task_struct *task, struct aa_profile *profile, int cap,
-+ int audit);
-+
-+static inline void aa_free_cap_rules(struct aa_caps *caps)
-+{
-+ /* NOP */
-+}
-+
-+#endif /* __AA_CAPBILITY_H */
-diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
-new file mode 100644
-index 0000000..202a66a
---- /dev/null
-+++ b/security/apparmor/include/context.h
-@@ -0,0 +1,153 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor contexts used to associate "labels" to objects.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_CONTEXT_H
-+#define __AA_CONTEXT_H
-+
-+#include <linux/cred.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+
-+#include "policy.h"
-+
-+
-+/* struct aa_file_cxt - the AppArmor context the file was opened in
-+ * @profile: the profile the file was opened under
-+ * @perms: the permission the file was opened with
-+ */
-+struct aa_file_cxt {
-+ struct aa_profile *profile;
-+ u16 allowed;
-+};
-+
-+static inline struct aa_file_cxt *aa_alloc_file_context(gfp_t gfp)
-+{
-+ return kzalloc(sizeof(struct aa_file_cxt), gfp);
-+}
-+
-+static inline void aa_free_file_context(struct aa_file_cxt *cxt)
-+{
-+ aa_put_profile(cxt->profile);
-+ memset(cxt, 0, sizeof(struct aa_file_cxt));
-+ kfree(cxt);
-+}
-+
-+
-+
-+
-+
-+/* struct aa_task_cxt_group - a grouping label data for confined tasks
-+ * @profile: the current profile
-+ * @exec: profile to transition to on next exec
-+ * @previous: profile the task may return to
-+ * @token: magic value the task must know for returning to @previous_profile
-+ *
-+ * Contains the task's current profile (which could change due to
-+ * change_hat). Plus the hat_magic needed during change_hat.
-+ */
-+struct aa_task_cxt_group {
-+ struct aa_profile *profile;
-+ struct aa_profile *onexec;
-+ struct aa_profile *previous;
-+ u64 token;
-+};
-+
-+/**
-+ * struct aa_task_context - primary label for confined tasks
-+ * @sys: the system labeling for the task
-+ *
-+ * A task is confined by the intersection of its system and user profiles
-+ */
-+struct aa_task_context {
-+ struct aa_task_cxt_group sys;
-+};
-+
-+struct aa_task_context *aa_alloc_task_context(gfp_t flags);
-+void aa_free_task_context(struct aa_task_context *cxt);
-+struct aa_task_context *aa_dup_task_context(struct aa_task_context *old_cxt,
-+ gfp_t gfp);
-+void aa_cred_policy(const struct cred *cred, struct aa_profile **sys);
-+struct cred *aa_get_task_policy(const struct task_struct *task,
-+ struct aa_profile **sys);
-+int aa_replace_current_profiles(struct aa_profile *sys);
-+void aa_put_task_policy(struct cred *cred);
-+int aa_set_current_onexec(struct aa_profile *sys);
-+int aa_set_current_hat(struct aa_profile *profile, u64 token);
-+int aa_restore_previous_profile(u64 cookie);
-+
-+
-+static inline struct aa_task_context *__aa_task_cxt(struct task_struct *task)
-+{
-+ return __task_cred(task)->security;
-+}
-+
-+/**
-+ * __aa_task_is_confined - determine if @task has any confinement
-+ * @task: task to check confinement of
-+ *
-+ * If @task != current needs to be in RCU safe critical section
-+ */
-+static inline int __aa_task_is_confined(struct task_struct *task)
-+{
-+ struct aa_task_context *cxt;
-+ int rc = 1;
-+
-+ cxt = __aa_task_cxt(task);
-+ if (!cxt || (cxt->sys.profile->flags & PFLAG_UNCONFINED))
-+ rc = 0;
-+
-+ return rc;
-+}
-+
-+static inline const struct cred *aa_current_policy(struct aa_profile **sys)
-+{
-+ const struct cred *cred = current_cred();
-+ struct aa_task_context *cxt = cred->security;
-+ BUG_ON(!cxt);
-+ *sys = aa_filtered_profile(aa_profile_newest(cxt->sys.profile));
-+
-+ return cred;
-+}
-+
-+static inline const struct cred *aa_current_policy_wupd(struct aa_profile **sys)
-+{
-+ const struct cred *cred = current_cred();
-+ struct aa_task_context *cxt = cred->security;
-+ BUG_ON(!cxt);
-+
-+ *sys = aa_profile_newest(cxt->sys.profile);
-+ if (unlikely((cxt->sys.profile != *sys)))
-+ aa_replace_current_profiles(*sys);
-+ *sys = aa_filtered_profile(*sys);
-+
-+ return cred;
-+}
-+
-+static inline struct aa_profile *aa_current_profile(void)
-+{
-+ const struct cred *cred = current_cred();
-+ struct aa_task_context *cxt = cred->security;
-+ BUG_ON(!cxt);
-+ return aa_filtered_profile(aa_profile_newest(cxt->sys.profile));
-+}
-+
-+static inline struct aa_profile *aa_current_profile_wupd(void)
-+{
-+ struct aa_profile *p;
-+ aa_current_policy_wupd(&p);
-+ return p;
-+}
-+
-+
-+#endif /* __AA_CONTEXT_H */
-diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
-new file mode 100644
-index 0000000..a340e62
---- /dev/null
-+++ b/security/apparmor/include/domain.h
-@@ -0,0 +1,37 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor security domain transition function definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/binfmts.h>
-+#include <linux/types.h>
-+
-+#ifndef __AA_DOMAIN_H
-+#define __AA_DOMAIN_H
-+
-+struct aa_domain {
-+ int size;
-+ char **table;
-+};
-+
-+int apparmor_bprm_set_creds(struct linux_binprm *bprm);
-+int apparmor_bprm_secureexec(struct linux_binprm *bprm);
-+int apparmor_bprm_committing_creds(struct linux_binprm *bprm);
-+void apparmor_bprm_committed_creds(struct linux_binprm *bprm);
-+
-+void aa_free_domain_entries(struct aa_domain *domain);
-+int aa_change_hat(const char *hat_name, u64 token, int permtest);
-+int aa_change_profile(const char *ns_name, const char *name, int onexec,
-+ int permtest);
-+
-+
-+#endif /* __AA_DOMAIN_H */
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-new file mode 100644
-index 0000000..e99e6fe
---- /dev/null
-+++ b/security/apparmor/include/file.h
-@@ -0,0 +1,227 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor file mediation function definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_FILE_H
-+#define __AA_FILE_H
-+
-+#include <linux/path.h>
-+
-+#include "audit.h"
-+#include "domain.h"
-+#include "match.h"
-+
-+struct aa_profile;
-+
-+/*
-+ * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
-+ * for profile permissions
-+ */
-+#define AA_MAY_LINK 0x0010
-+#define AA_MAY_LOCK 0x0020
-+#define AA_EXEC_MMAP 0x0040
-+
-+#define AA_MAY_CREATE 0x0080
-+#define AA_LINK_SUBSET 0x0100
-+#define AA_MAY_DELEGATE 0x0200
-+#define AA_EXEC_DELEGATE 0x0400 /*exec allows delegate*/
-+
-+#define AA_MAY_CHANGEHAT 0x2000 /* ctrl auditing only */
-+#define AA_MAY_ONEXEC 0x4000 /* exec allows onexec */
-+#define AA_MAY_CHANGE_PROFILE 0x8000
-+
-+
-+#define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
-+ AA_MAY_LINK | AA_MAY_LOCK | AA_EXEC_MMAP | \
-+ AA_MAY_CREATE)
-+
-+/*
-+ * The xindex is broken into 3 parts
-+ * - index - an index into either the exec name table or the variable table
-+ * - exec type - which determines how the executable name and index are used
-+ * - flags - which modify how the destination name is applied
-+ */
-+#define AA_X_INDEX_MASK 0x03ff
-+
-+#define AA_X_TYPE_MASK 0x0c00
-+#define AA_X_TYPE_SHIFT 10
-+#define AA_X_NONE 0x0000
-+#define AA_X_NAME 0x0400 /* use executable name px */
-+#define AA_X_TABLE 0x0800 /* use a specified name ->n# */
-+
-+#define AA_X_UNSAFE 0x1000
-+#define AA_X_CHILD 0x2000 /* make >AA_X_NONE apply to children */
-+#define AA_X_INHERIT 0x4000
-+#define AA_X_UNCONFINED 0x8000
-+
-+
-+/* AA_SECURE_X_NEEDED - is passed in the bprm->unsafe field */
-+#define AA_SECURE_X_NEEDED 0x8000
-+
-+/* need to conditionalize which ones are being set */
-+struct path_cond {
-+ uid_t uid;
-+ umode_t mode;
-+};
-+
-+/* struct file_perms - file permission fo
-+ * @allowed: mask of permissions that are allowed
-+ * @audit: mask of permissions to force an audit message for
-+ * @quiet: mask of permissions to quiet audit messages for
-+ * @kill: mask of permissions that when matched will kill the task
-+ * @xindex: exec transition index if @allowed contains MAY_EXEC
-+ * @dindex: delegate table index if @allowed contain AA_MAY_DELEGATE
-+ *
-+ * The @audit and @queit mask should be mutually exclusive.
-+ */
-+struct file_perms {
-+ u16 allowed;
-+ u16 audit;
-+ u16 quiet;
-+ u16 kill;
-+ u16 xindex;
-+ u16 dindex;
-+};
-+
-+extern struct file_perms nullperms;
-+
-+#define COMBINED_PERM_MASK(X) ((X).allowed | (X).audit | (X).quiet | (X).kill)
-+
-+/* FIXME: split perms from dfa and match this to description
-+ * also add delegation info.
-+ */
-+static inline u16 dfa_map_xindex(u16 mask)
-+{
-+ u16 old_index = (mask >> 10) & 0xf;
-+ u16 index = 0;
-+
-+//printk("mask x%x\n", mask);
-+ if (mask & 0x100)
-+ index |= AA_X_UNSAFE;
-+ if (mask & 0x200)
-+ index |= AA_X_INHERIT;
-+
-+ if (old_index == 1) {
-+ index |= AA_X_UNCONFINED;
-+ } else if (old_index == 2) {
-+ index |= AA_X_NAME;
-+ } else if (old_index == 3) {
-+ index |= AA_X_NAME | AA_X_CHILD;
-+ } else {
-+ index |= AA_X_TABLE;
-+ index |= old_index - 4;
-+ }
-+
-+ return index;
-+}
-+
-+/*
-+ * map old dfa inline permissions to new format
-+ */
-+#define dfa_user_allow(dfa, state) ((ACCEPT_TABLE(dfa)[state]) & 0x7f)
-+#define dfa_user_audit(dfa, state) ((ACCEPT_TABLE2(dfa)[state]) & 0x7f)
-+#define dfa_user_quiet(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 7) & 0x7f)
-+#define dfa_user_xindex(dfa, state) \
-+ (dfa_map_xindex(ACCEPT_TABLE(dfa)[state] & 0x3fff))
-+
-+#define dfa_other_allow(dfa, state) (((ACCEPT_TABLE(dfa)[state]) >> 14) & 0x7f)
-+#define dfa_other_audit(dfa, state) (((ACCEPT_TABLE2(dfa)[state]) >> 14) & 0x7f)
-+#define dfa_other_quiet(dfa, state) ((((ACCEPT_TABLE2(dfa)[state]) >> 7) >> 14) & 0x7f)
-+#define dfa_other_xindex(dfa, state) \
-+ dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
-+
-+
-+struct aa_audit_file {
-+ struct aa_audit base;
-+
-+ const char *name;
-+ const char *name2;
-+ const char *name3;
-+ struct file_perms perms;
-+ u16 request;
-+ struct path_cond *cond;
-+};
-+
-+int aa_audit_file(struct aa_profile *profile, struct aa_audit_file *sa);
-+void file_audit_cb(struct audit_buffer *ab, void *va);
-+
-+/**
-+ * struct aa_file_rules - components used for file rule permissions
-+ * @dfa: dfa to match path names and conditionals against
-+ * @perms: permission table indexed by the matched state accept entry of @dfa
-+ * @trans: transition table for indexed by named x transitions
-+ *
-+ * File permission are determined by matching a path against @dfa and then
-+ * then using the value of the accept entry for the matching state as
-+ * an index into @perms. If a named exec transition is required it is
-+ * looked up in the transition table.
-+ */
-+struct aa_file_rules {
-+ struct aa_dfa *dfa;
-+ /* struct perms perms; */
-+ struct aa_domain trans;
-+ /* TODO: add delegate table */
-+};
-+
-+struct file_perms aa_str_perms(struct aa_dfa *dfa, unsigned int start,
-+ const char *name, struct path_cond *cond,
-+ unsigned int *rstate);
-+
-+int aa_pathstr_perm(struct aa_profile *profile, const char *op,
-+ const char *name, u16 request, struct path_cond *cond);
-+
-+int aa_path_perm(struct aa_profile *profile, const char *operation,
-+ struct path *path, u16 request, struct path_cond *cond);
-+
-+int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
-+ struct path *new_dir, struct dentry *new_dentry);
-+
-+int aa_file_common_perm(struct aa_profile *profile, const char *operation,
-+ struct file *file, u16 request, const char *name,
-+ int error);
-+
-+int aa_file_perm(struct aa_profile *profile, const char *operation,
-+ struct file *file, u16 request);
-+
-+
-+static inline void aa_free_file_rules(struct aa_file_rules *rules)
-+{
-+ aa_match_free(rules->dfa);
-+ aa_free_domain_entries(&rules->trans);
-+}
-+
-+#define ACC_FMODE(x) (("\000\004\002\006"[(x)&O_ACCMODE]) | (((x) << 1) & 0x40))
-+
-+/* from namei.c */
-+#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
-+#define MAP_OPEN_FLAGS(x) ((((x) + 1) & O_ACCMODE) ? (x) + 1 : (x))
-+/*
-+ * map file flags to AppArmor permissions
-+ */
-+static inline u16 aa_map_file_to_perms(struct file *file)
-+{
-+ int flags = MAP_OPEN_FLAGS(file->f_flags);
-+ u16 perms = ACC_FMODE(file->f_mode);
-+
-+ if ((flags & O_APPEND) && (perms & MAY_WRITE))
-+ perms = (perms & ~MAY_WRITE) | MAY_APPEND;
-+ /* trunc implies write permission */
-+ if (flags & O_TRUNC)
-+ perms |= MAY_WRITE;
-+ if (flags & O_CREAT)
-+ perms |= AA_MAY_CREATE;
-+
-+ return perms;
-+}
-+
-+#endif /* __AA_FILE_H */
-diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
-new file mode 100644
-index 0000000..e80a95e
---- /dev/null
-+++ b/security/apparmor/include/ipc.h
-@@ -0,0 +1,28 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor ipc mediation function definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_IPC_H
-+#define __AA_IPC_H
-+
-+#include <linux/sched.h>
-+
-+struct aa_profile;
-+
-+int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer,
-+ struct aa_profile *tracee, unsigned int mode);
-+
-+int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
-+ unsigned int mode);
-+
-+#endif /* __AA_IPC_H */
-diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
-new file mode 100644
-index 0000000..8a0f59c
---- /dev/null
-+++ b/security/apparmor/include/match.h
-@@ -0,0 +1,105 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor policy dfa matching engine definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_MATCH_H
-+#define __AA_MATCH_H
-+
-+#define DFA_NOMATCH 0
-+#define DFA_START 1
-+
-+#define DFA_VALID_PERM_MASK 0xffffffff
-+#define DFA_VALID_PERM2_MASK 0xffffffff
-+
-+
-+/**
-+ * The format used for transition tables is based on the GNU flex table
-+ * file format (--tables-file option; see Table File Format in the flex
-+ * info pages and the flex sources for documentation). The magic number
-+ * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because
-+ * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used
-+ * slightly differently (see the apparmor-parser package).
-+ */
-+
-+#define YYTH_MAGIC 0x1B5E783D
-+
-+struct table_set_header {
-+ u32 th_magic; /* YYTH_MAGIC */
-+ u32 th_hsize;
-+ u32 th_ssize;
-+ u16 th_flags;
-+ char th_version[];
-+};
-+
-+#define YYTD_ID_ACCEPT 1
-+#define YYTD_ID_BASE 2
-+#define YYTD_ID_CHK 3
-+#define YYTD_ID_DEF 4
-+#define YYTD_ID_EC 5
-+#define YYTD_ID_META 6
-+#define YYTD_ID_ACCEPT2 7
-+#define YYTD_ID_NXT 8
-+
-+
-+#define YYTD_DATA8 1
-+#define YYTD_DATA16 2
-+#define YYTD_DATA32 4
-+
-+struct table_header {
-+ u16 td_id;
-+ u16 td_flags;
-+ u32 td_hilen;
-+ u32 td_lolen;
-+ char td_data[];
-+};
-+
-+#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data))
-+#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data))
-+#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data))
-+#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data))
-+#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data))
-+#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data))
-+#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 - 1]->td_data))
-+
-+struct aa_dfa {
-+ struct table_header *tables[YYTD_ID_NXT];
-+};
-+
-+#define byte_to_byte(X) (X)
-+
-+#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
-+ do { \
-+ typeof(LEN) __i; \
-+ TYPE *__t = (TYPE *) TABLE; \
-+ TYPE *__b = (TYPE *) BLOB; \
-+ for (__i = 0; __i < LEN; __i++) { \
-+ __t[__i] = NTOHX(__b[__i]); \
-+ } \
-+ } while (0)
-+
-+static inline size_t table_size(size_t len, size_t el_size)
-+{
-+ return ALIGN(sizeof(struct table_header) + len * el_size, 8);
-+}
-+
-+struct aa_dfa *aa_match_alloc(void);
-+void aa_match_free(struct aa_dfa *dfa);
-+int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size);
-+int verify_dfa(struct aa_dfa *dfa);
-+unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
-+ const char *str, int len);
-+unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
-+ const char *str);
-+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start);
-+
-+#endif /* __AA_MATCH_H */
-diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
-new file mode 100644
-index 0000000..ece94b2
---- /dev/null
-+++ b/security/apparmor/include/net.h
-@@ -0,0 +1,40 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor network mediation definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_NET_H
-+#define __AA_NET_H
-+
-+#include <net/sock.h>
-+
-+/* struct aa_net - network confinement data
-+ * @allowed: basic network families permissions
-+ * @audit_network: which network permissions to force audit
-+ * @quiet_network: which network permissions to quiet rejects
-+ */
-+struct aa_net {
-+ u16 allowed[AF_MAX];
-+ u16 audit[AF_MAX];
-+ u16 quiet[AF_MAX];
-+};
-+
-+extern int aa_net_perm(struct aa_profile *profile, char *operation,
-+ int family, int type, int protocol);
-+extern int aa_revalidate_sk(struct sock *sk, char *operation);
-+
-+static inline void aa_free_net_rules(struct aa_net *new)
-+{
-+ /* NOP */
-+}
-+
-+#endif /* __AA_NET_H */
-diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
-new file mode 100644
-index 0000000..d238e42
---- /dev/null
-+++ b/security/apparmor/include/path.h
-@@ -0,0 +1,24 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor basic path manipulation function definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_PATH_H
-+#define __AA_PATH_H
-+
-+int aa_get_name_to_buffer(struct path *path, int is_dir, char *buffer, int size,
-+ char **name);
-+int aa_get_name(struct path *path, int is_dir, char **buffer, char **name);
-+int d_namespace_path(struct path *path, char *buf, int buflen, char **name);
-+char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen);
-+
-+#endif /* __AA_PATH_H */
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
-new file mode 100644
-index 0000000..98cd0d9
---- /dev/null
-+++ b/security/apparmor/include/policy.h
-@@ -0,0 +1,301 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor policy definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_POLICY_H
-+#define __AA_POLICY_H
-+
-+#include <linux/capability.h>
-+#include <linux/cred.h>
-+#include <linux/kref.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/socket.h>
-+
-+#include "apparmor.h"
-+#include "audit.h"
-+#include "capability.h"
-+#include "domain.h"
-+#include "file.h"
-+#include "net.h"
-+#include "resource.h"
-+
-+extern const char *profile_mode_names[];
-+#define APPARMOR_NAMES_MAX_INDEX 3
-+
-+#define PROFILE_COMPLAIN(_profile) \
-+ ((g_profile_mode == APPARMOR_COMPLAIN) || ((_profile) && \
-+ (_profile)->mode == APPARMOR_COMPLAIN))
-+
-+#define PROFILE_KILL(_profile) \
-+ ((g_profile_mode == APPARMOR_KILL) || ((_profile) && \
-+ (_profile)->mode == APPARMOR_KILL))
-+
-+#define PROFILE_IS_HAT(_profile) \
-+ ((_profile) && (_profile)->flags & PFLAG_HAT)
-+
-+
-+/*
-+ * FIXME: currently need a clean way to replace and remove profiles as a
-+ * set. It should be done at the namespace level.
-+ * Either, with a set of profiles loaded at the namespace level or via
-+ * a mark and remove marked interface.
-+ */
-+enum profile_mode {
-+ APPARMOR_ENFORCE, /* enforce access rules */
-+ APPARMOR_COMPLAIN, /* allow and log access violations */
-+ APPARMOR_KILL, /* kill task on access violation */
-+};
-+
-+enum profile_flags {
-+ PFLAG_HAT = 1, /* profile is a hat */
-+ PFLAG_UNCONFINED = 2, /* profile is the unconfined profile */
-+ PFLAG_NULL = 4, /* profile is null learning profile */
-+ PFLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */
-+ PFLAG_IMMUTABLE = 0x10, /* don't allow changes/replacement */
-+ PFLAG_USER_DEFINED = 0x20, /* user based profile */
-+ PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
-+};
-+
-+#define AA_NEW_SID 0
-+
-+struct aa_profile;
-+
-+/* struct aa_policy_common - common part of both namespaces and profiles
-+ * @name: name of the object
-+ * @count: reference count of the obj
-+ * lock: lock for modifying the object
-+ * @list: list object is on
-+ * @profiles: head of the profiles list contained in the object
-+ */
-+struct aa_policy_common {
-+ char *name;
-+ struct kref count;
-+ rwlock_t lock;
-+ struct list_head list;
-+ struct list_head profiles;
-+};
-+
-+/* struct aa_ns_acct - accounting of profiles in namespace
-+ * @max_size: maximum space allowed for all profiles in namespace
-+ * @max_count: maximum number of profiles that can be in this namespace
-+ * @size: current size of profiles
-+ * @count: current count of profiles (includes null profiles)
-+ */
-+struct aa_ns_acct {
-+ int max_size;
-+ int max_count;
-+ int size;
-+ int count;
-+};
-+
-+/* struct aa_namespace - namespace for a set of profiles
-+ * @name: the name of the namespace
-+ * @list: list the namespace is on
-+ * @profiles: list of profile in the namespace
-+ * @acct: accounting for the namespace
-+ * @profile_count: count of profiles on @profiles list
-+ * @size: accounting of how much memory is consumed by the contained profiles
-+ * @unconfined: special unconfined profile for the namespace
-+ * @count: reference count on the namespace
-+ * @lock: lock for adding/removing profile to the namespace
-+ *
-+ * An aa_namespace defines the set profiles that are searched to determine
-+ * which profile to attach to a task. Profiles can not be shared between
-+ * aa_namespaces and profile names within a namespace are guarenteed to be
-+ * unique. When profiles in seperate namespaces have the same name they
-+ * are NOT considered to be equivalent.
-+ *
-+ * Namespace names must be unique and can not contain the characters :/\0
-+ *
-+ * FIXME TODO: add vserver support so a vserer gets a default namespace
-+ */
-+struct aa_namespace {
-+ struct aa_policy_common base;
-+ struct aa_ns_acct acct;
-+ int is_stale;
-+ struct aa_profile *unconfined;
-+};
-+
-+
-+/* struct aa_profile - basic confinement data
-+ * @base - base componets of the profile (name, refcount, lists, lock ...)
-+ * @fqname - The fully qualified profile name, less the namespace name
-+ * @ns: namespace the profile is in
-+ * @parent: parent profile of this profile, if one exists
-+ * @replacedby: is set profile that replaced this profile
-+ * @xmatch: optional extended matching for unconfined executables names
-+ * @xmatch_plen: xmatch prefix len, used to determine xmatch priority
-+ * @sid: the unique security id number of this profile
-+ * @audit: the auditing mode of the profile
-+ * @mode: the enforcement mode of the profile
-+ * @flags: flags controlling profile behavior
-+ * @size: the memory consumed by this profiles rules
-+ * @file: The set of rules governing basic file access and domain transitions
-+ * @caps: capabilities for the profile
-+ * @net: network controls for the profile
-+ * @rlimits: rlimits for the profile
-+ *
-+ * The AppArmor profile contains the basic confinement data. Each profile
-+ * has a name, and exist in a namespace. The @name and @exec_match are
-+ * used to determine profile attachment against unconfined tasks. All other
-+ * attachments are determined by in profile X transition rules.
-+ *
-+ * The @replacedby field is write protected by the profile lock. Reads
-+ * are assumed to be atomic, and are done without locking.
-+ *
-+ * Profiles have a hierachy where hats and children profiles keep
-+ * a reference to their parent.
-+ *
-+ * Profile names can not begin with a : and can not contain the \0
-+ * character. If a profile name begins with / it will be considered when
-+ * determining profile attachment on "unconfined" tasks.
-+ */
-+struct aa_profile {
-+ struct aa_policy_common base;
-+ char *fqname;
-+
-+ struct aa_namespace *ns;
-+ struct aa_profile *parent;
-+ struct aa_profile *replacedby;
-+
-+ struct aa_dfa *xmatch;
-+ int xmatch_len;
-+ u32 sid;
-+ enum audit_mode audit;
-+ enum profile_mode mode;
-+ u32 flags;
-+ int size;
-+
-+ struct aa_file_rules file;
-+ struct aa_caps caps;
-+ struct aa_net net;
-+ struct aa_rlimit rlimits;
-+};
-+
-+
-+extern struct list_head ns_list;
-+extern rwlock_t ns_list_lock;
-+
-+extern struct aa_namespace *default_namespace;
-+extern enum profile_mode g_profile_mode;
-+
-+
-+void aa_add_profile(struct aa_policy_common *common,
-+ struct aa_profile *profile);
-+
-+int alloc_default_namespace(void);
-+void free_default_namespace(void);
-+struct aa_namespace *alloc_aa_namespace(const char *name);
-+void free_aa_namespace_kref(struct kref *kref);
-+void free_aa_namespace(struct aa_namespace *ns);
-+struct aa_namespace *__aa_find_namespace(struct list_head *head,
-+ const char *name);
-+
-+struct aa_namespace *aa_find_namespace(const char *name);
-+struct aa_namespace *aa_prepare_namespace(const char *name);
-+void aa_remove_namespace(struct aa_namespace *ns);
-+struct aa_namespace *aa_prepare_namespace(const char *name);
-+void aa_profile_list_release(struct list_head *head);
-+void aa_profile_ns_list_release(void);
-+void __aa_remove_namespace(struct aa_namespace *ns);
-+
-+
-+static inline struct aa_policy_common *aa_get_common(struct aa_policy_common *c)
-+{
-+ if (c)
-+ kref_get(&c->count);
-+
-+ return c;
-+}
-+
-+static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns)
-+{
-+ if (ns)
-+ kref_get(&(ns->base.count));
-+
-+ return ns;
-+}
-+
-+static inline void aa_put_namespace(struct aa_namespace *ns)
-+{
-+ if (ns)
-+ kref_put(&ns->base.count, free_aa_namespace_kref);
-+}
-+
-+
-+
-+struct aa_profile *alloc_aa_profile(const char *name);
-+struct aa_profile *aa_alloc_null_profile(struct aa_profile *parent, int hat);
-+void free_aa_profile_kref(struct kref *kref);
-+void free_aa_profile(struct aa_profile *profile);
-+struct aa_profile *__aa_find_profile(struct list_head *head, const char *name);
-+struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
-+struct aa_policy_common *__aa_find_parent_by_fqname(struct aa_namespace *ns,
-+ const char *fqname);
-+struct aa_profile *__aa_find_profile_by_fqname(struct aa_namespace *ns,
-+ const char *fqname);
-+struct aa_profile *aa_find_profile_by_fqname(struct aa_namespace *ns,
-+ const char *name);
-+struct aa_profile *aa_match_profile(struct aa_namespace *ns, const char *name);
-+struct aa_profile *aa_profile_newest(struct aa_profile *profile);
-+struct aa_profile *aa_sys_find_attach(struct aa_namespace *ns,
-+ const char *name);
-+void __aa_add_profile(struct aa_policy_common *common,
-+ struct aa_profile *profile);
-+void __aa_remove_profile(struct aa_profile *profile,
-+ struct aa_profile *replacement);
-+void __aa_replace_profile(struct aa_profile *profile,
-+ struct aa_profile *replacement);
-+void __aa_profile_list_release(struct list_head *head);
-+
-+static inline struct aa_profile *aa_filtered_profile(struct aa_profile *profile)
-+{
-+ if (profile->flags & PFLAG_UNCONFINED)
-+ return NULL;
-+ return profile;
-+}
-+
-+/**
-+ * aa_get_profile - increment refcount on profile @p
-+ * @p: profile
-+ */
-+static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
-+{
-+ if (p)
-+ kref_get(&(p->base.count));
-+
-+ return p;
-+}
-+
-+/**
-+ * aa_put_profile - decrement refcount on profile @p
-+ * @p: profile
-+ */
-+static inline void aa_put_profile(struct aa_profile *p)
-+{
-+ if (p)
-+ kref_put(&p->base.count, free_aa_profile_kref);
-+}
-+
-+static inline int PROFILE_AUDIT_MODE(struct aa_profile *profile)
-+{
-+ if (g_apparmor_audit != AUDIT_NORMAL)
-+ return g_apparmor_audit;
-+ if (profile)
-+ return profile->audit;
-+ return AUDIT_NORMAL;
-+}
-+
-+#endif /* __AA_POLICY_H */
-+
-diff --git a/security/apparmor/include/policy_interface.h b/security/apparmor/include/policy_interface.h
-new file mode 100644
-index 0000000..1440876
---- /dev/null
-+++ b/security/apparmor/include/policy_interface.h
-@@ -0,0 +1,22 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor policy loading interface function definitions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __POLICY_INTERFACE_H
-+#define __POLICY_INTERFACE_H
-+
-+ssize_t aa_interface_add_profiles(void *data, size_t size);
-+ssize_t aa_interface_replace_profiles(void *udata, size_t size);
-+ssize_t aa_interface_remove_profiles(char *name, size_t size);
-+
-+#endif /* __POLICY_INTERFACE_H */
-diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
-new file mode 100644
-index 0000000..52e46c5
---- /dev/null
-+++ b/security/apparmor/include/procattr.h
-@@ -0,0 +1,26 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor /proc/<pid>/attr/ interface function defintions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_PROCATTR_H
-+#define __AA_PROCATTR_H
-+
-+#define AA_DO_TEST 1
-+
-+int aa_getprocattr(struct aa_namespace *ns, struct aa_profile *profile,
-+ char **string);
-+int aa_setprocattr_changehat(char *args, int test);
-+int aa_setprocattr_changeprofile(char *args, int onexec, int test);
-+int aa_setprocattr_permipc(char *args);
-+
-+#endif /* __AA_PROCATTR_H */
-diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
-new file mode 100644
-index 0000000..0662c91
---- /dev/null
-+++ b/security/apparmor/include/resource.h
-@@ -0,0 +1,46 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor resource limits function defintions.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_RESOURCE_H
-+#define __AA_RESOURCE_H
-+
-+#include <linux/resource.h>
-+#include <linux/sched.h>
-+
-+struct aa_profile;
-+
-+/* struct aa_rlimit - rlimits settings for the profile
-+ * @mask: which hard limits to set
-+ * @limits: rlimit values that override task limits
-+ *
-+ * AppArmor rlimits are used to set confined task rlimits. Only the
-+ * limits specified in @mask will be controlled by apparmor.
-+ */
-+struct aa_rlimit {
-+ unsigned int mask;
-+ struct rlimit limits[RLIM_NLIMITS];
-+};
-+
-+
-+int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
-+ struct rlimit *new_rlim);
-+
-+void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new);
-+
-+static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
-+{
-+ /* NOP */
-+}
-+
-+#endif /* __AA_RESOURCE_H */
-diff --git a/security/apparmor/include/sid.h b/security/apparmor/include/sid.h
-new file mode 100644
-index 0000000..83e3590
---- /dev/null
-+++ b/security/apparmor/include/sid.h
-@@ -0,0 +1,46 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor security identifier (sid) definitions
-+ *
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#ifndef __AA_SID_H
-+#define __AA_SID_H
-+
-+#include <linux/types.h>
-+
-+struct aa_profile;
-+
-+#define AA_ALLOC_USR_SID 1
-+#define AA_ALLOC_SYS_SID 0
-+
-+u32 aa_alloc_sid(int is_usr);
-+void aa_free_sid(u32 sid);
-+int aa_add_sid_profile(u32 sid, struct aa_profile *profile);
-+int aa_replace_sid_profile(u32 sid, struct aa_profile *profile);
-+struct aa_profile *aa_get_sid_profile(u32 sid);
-+
-+
-+static inline u32 aa_compound_sid(u32 sys, u32 usr)
-+{
-+ return sys | usr;
-+}
-+
-+static inline u32 aa_usr_sid(u32 sid)
-+{
-+ return sid & 0xffff0000;
-+}
-+
-+static inline u32 aa_sys_sid(u32 sid)
-+{
-+ return sid & 0xffff;
-+}
-+
-+#endif /* __AA_SID_H */
-diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
-new file mode 100644
-index 0000000..381c164
---- /dev/null
-+++ b/security/apparmor/ipc.c
-@@ -0,0 +1,106 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor ipc mediation
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/gfp.h>
-+#include <linux/ptrace.h>
-+
-+#include "include/audit.h"
-+#include "include/capability.h"
-+#include "include/context.h"
-+#include "include/policy.h"
-+
-+
-+struct aa_audit_ptrace {
-+ struct aa_audit base;
-+
-+ pid_t tracer, tracee;
-+};
-+
-+/* call back to audit ptrace fields */
-+static void audit_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct aa_audit_ptrace *sa = va;
-+ audit_log_format(ab, " tracer=%d tracee=%d", sa->tracer, sa->tracee);
-+}
-+
-+static int aa_audit_ptrace(struct aa_profile *profile,
-+ struct aa_audit_ptrace *sa)
-+{
-+ return aa_audit(AUDIT_APPARMOR_AUTO, profile, (struct aa_audit *)sa,
-+ audit_cb);
-+}
-+
-+int aa_may_ptrace(struct task_struct *tracer_task, struct aa_profile *tracer,
-+ struct aa_profile *tracee, unsigned int mode)
-+{
-+ /* TODO: currently only based on capability, not extended ptrace
-+ * rules,
-+ * Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH
-+ */
-+
-+ if (!tracer || tracer == tracee)
-+ return 0;
-+ /* log this capability request */
-+ return aa_capable(tracer_task, tracer, CAP_SYS_PTRACE, 1);
-+}
-+
-+int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
-+ unsigned int mode)
-+{
-+ /*
-+ * tracer can ptrace tracee when
-+ * - tracer is unconfined ||
-+ * - tracer & tracee are in the same namespace &&
-+ * - tracer is in complain mode
-+ * - tracer has rules allowing it to trace tracee currently this is:
-+ * - confined by the same profile ||
-+ * - tracer profile has CAP_SYS_PTRACE
-+ */
-+
-+ struct aa_profile *tracer_p;
-+ const struct cred *cred = aa_get_task_policy(tracer, &tracer_p);
-+ int error = 0;
-+
-+ if (tracer_p) {
-+ struct aa_audit_ptrace sa;
-+ memset(&sa, 0, sizeof(sa));
-+ sa.base.operation = "ptrace";
-+ sa.base.gfp_mask = GFP_ATOMIC;
-+ sa.tracer = tracer->pid;
-+ sa.tracee = tracee->pid;
-+ /* FIXME: different namespace restriction can be lifted
-+ * if, namespace are matched to AppArmor namespaces
-+ */
-+ if (tracer->nsproxy != tracee->nsproxy) {
-+ sa.base.info = "different namespaces";
-+ sa.base.error = -EPERM;
-+ aa_audit(AUDIT_APPARMOR_DENIED, tracer_p, &sa.base,
-+ audit_cb);
-+ } else {
-+ struct aa_profile *tracee_p;
-+ struct cred *lcred = aa_get_task_policy(tracee,
-+ &tracee_p);
-+
-+ sa.base.error = aa_may_ptrace(tracer, tracer_p,
-+ tracee_p, mode);
-+ sa.base.error = aa_audit_ptrace(tracer_p, &sa);
-+
-+ put_cred(lcred);
-+ }
-+ error = sa.base.error;
-+ }
-+ put_cred(cred);
-+
-+ return error;
-+}
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-new file mode 100644
-index 0000000..5dbd16d
---- /dev/null
-+++ b/security/apparmor/lib.c
-@@ -0,0 +1,100 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains basic common functions used in AppArmor
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+
-+#include "include/audit.h"
-+
-+void info_message(const char *str)
-+{
-+ struct aa_audit sa;
-+ memset(&sa, 0, sizeof(sa));
-+ sa.gfp_mask = GFP_KERNEL;
-+ sa.info = str;
-+ printk(KERN_INFO "AppArmor: %s\n", str);
-+ if (audit_enabled)
-+ aa_audit(AUDIT_APPARMOR_STATUS, NULL, &sa, NULL);
-+}
-+
-+char *strchrnul(const char *s, int c)
-+{
-+ for (; *s != (char)c && *s != '\0'; ++s)
-+ ;
-+ return (char *)s;
-+}
-+
-+char *aa_split_name_from_ns(char *args, char **ns_name)
-+{
-+ char *name = strstrip(args);
-+
-+ *ns_name = NULL;
-+ if (args[0] == ':') {
-+ char *split = strstrip(strchr(&args[1], ':'));
-+
-+ if (!split)
-+ return NULL;
-+
-+ *split = 0;
-+ *ns_name = &args[1];
-+ name = strstrip(split + 1);
-+ }
-+ if (*name == 0)
-+ name = NULL;
-+
-+ return name;
-+}
-+
-+char *new_compound_name(const char *n1, const char *n2)
-+{
-+ char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL);
-+ if (name)
-+ sprintf(name, "%s//%s", n1, n2);
-+ return name;
-+}
-+
-+/**
-+ * aa_strneq - compare null terminated @str to a non null terminated substring
-+ * @str: a null terminated string
-+ * @sub: a substring, not necessarily null terminated
-+ * @len: length of @sub to compare
-+ *
-+ * The @str string must be full consumed for this to be considered a match
-+ */
-+int aa_strneq(const char *str, const char *sub, int len)
-+{
-+ int res = strncmp(str, sub, len);
-+ if (res)
-+ return 0;
-+ if (str[len] == 0)
-+ return 1;
-+ return 0;
-+}
-+
-+const char *fqname_subname(const char *name)
-+{
-+ char *split;
-+ /* check for namespace which begins with a : and ends with : or \0 */
-+ name = strstrip((char *) name);
-+ if (*name == ':') {
-+ split = strchrnul(name + 1, ':');
-+ if (*split == '\0')
-+ return NULL;
-+ name = strstrip(split + 1);
-+ }
-+ for (split = strstr(name, "//"); split; split = strstr(name, "//")) {
-+ name = split + 2;
-+ }
-+ return name;
-+}
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-new file mode 100644
-index 0000000..5becf5e
---- /dev/null
-+++ b/security/apparmor/lsm.c
-@@ -0,0 +1,1063 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor LSM hooks.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/security.h>
-+#include <linux/moduleparam.h>
-+#include <linux/mm.h>
-+#include <linux/mman.h>
-+#include <linux/mount.h>
-+#include <linux/namei.h>
-+#include <linux/ptrace.h>
-+#include <linux/ctype.h>
-+#include <linux/sysctl.h>
-+#include <linux/audit.h>
-+#include <net/sock.h>
-+
-+#include "include/apparmor.h"
-+#include "include/apparmorfs.h"
-+#include "include/audit.h"
-+#include "include/capability.h"
-+#include "include/context.h"
-+#include "include/file.h"
-+#include "include/ipc.h"
-+#include "include/net.h"
-+#include "include/path.h"
-+#include "include/policy.h"
-+#include "include/procattr.h"
-+
-+/* Flag indicating whether initialization completed */
-+int apparmor_initialized;
-+
-+
-+/*
-+ * LSM hook functions
-+ */
-+
-+/*
-+ * prepare new aa_task_context for modification by prepare_cred block
-+ */
-+static int apparmor_cred_prepare(struct cred *new, const struct cred *old,
-+ gfp_t gfp)
-+{
-+ struct aa_task_context *cxt = aa_dup_task_context(old->security, gfp);
-+ if (!cxt)
-+ return -ENOMEM;
-+ new->security = cxt;
-+ return 0;
-+}
-+
-+/*
-+ * free the associated aa_task_context and put its profiles
-+ */
-+static void apparmor_cred_free(struct cred *cred)
-+{
-+ struct aa_task_context *cxt = cred->security;
-+ cred->security = NULL;
-+ aa_free_task_context(cxt);
-+}
-+
-+
-+static int apparmor_ptrace_may_access(struct task_struct *child,
-+ unsigned int mode)
-+{
-+ return aa_ptrace(current, child, mode);
-+}
-+
-+
-+static int apparmor_ptrace_traceme(struct task_struct *parent)
-+{
-+ return aa_ptrace(parent, current, PTRACE_MODE_ATTACH);
-+}
-+
-+/* Derived from security/commoncap.c:cap_capget */
-+static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
-+ kernel_cap_t *inheritable, kernel_cap_t *permitted)
-+{
-+ struct aa_profile *profile;
-+ const struct cred *cred;
-+
-+ rcu_read_lock();
-+ cred = __task_cred(target);
-+ aa_cred_policy(cred, &profile);
-+
-+ *effective = cred->cap_effective;
-+ *inheritable = cred->cap_inheritable;
-+ *permitted = cred->cap_permitted;
-+
-+ if (profile) {
-+ *effective = cap_combine(*effective, profile->caps.set);
-+ *effective = cap_intersect(*effective, profile->caps.allowed);
-+ }
-+ rcu_read_unlock();
-+
-+ return 0;
-+}
-+
-+static int apparmor_capable(struct task_struct *task, const struct cred *cred,
-+ int cap, int audit)
-+{
-+ struct aa_profile *profile;
-+ /* cap_capable returns 0 on success, else -EPERM */
-+ int error = cap_capable(task, cred, cap, audit);
-+
-+ aa_cred_policy(cred, &profile);
-+ if (profile && (!error || cap_raised(profile->caps.set, cap)))
-+ error = aa_capable(task, profile, cap, audit);
-+
-+ return error;
-+}
-+
-+static int apparmor_sysctl(struct ctl_table *table, int op)
-+{
-+ int error = 0;
-+ struct aa_profile *profile = aa_current_profile_wupd();
-+
-+ if (profile) {
-+ char *buffer, *name;
-+ int mask;
-+
-+ mask = 0;
-+ if (op & 4)
-+ mask |= MAY_READ;
-+ if (op & 2)
-+ mask |= MAY_WRITE;
-+
-+ error = -ENOMEM;
-+ buffer = (char *)__get_free_page(GFP_KERNEL);
-+ if (!buffer)
-+ goto out;
-+
-+ /*
-+ * TODO: convert this over to using a global or per
-+ * namespace control instead of a hard coded /proc
-+ */
-+ name = sysctl_pathname(table, buffer, PAGE_SIZE);
-+ if (name && name - buffer >= 5) {
-+ struct path_cond cond = { 0, S_IFREG };
-+ name -= 5;
-+ memcpy(name, "/proc", 5);
-+ error = aa_pathstr_perm(profile, "sysctl", name, mask,
-+ &cond);
-+ }
-+ free_page((unsigned long)buffer);
-+ }
-+
-+out:
-+ return error;
-+}
-+
-+static int common_perm(const char *op, struct path *path, u16 mask,
-+ struct path_cond *cond)
-+{
-+ struct aa_profile *profile;
-+ int error = 0;
-+
-+ profile = aa_current_profile();
-+ if (profile)
-+ error = aa_path_perm(profile, op, path, mask, cond);
-+
-+ return error;
-+}
-+
-+static int common_perm_dentry(const char *op, struct path *dir,
-+ struct dentry *dentry, u16 mask,
-+ struct path_cond *cond)
-+{
-+ struct path path = { dir->mnt, dentry };
-+
-+ return common_perm(op, &path, mask, cond);
-+}
-+
-+static int common_perm_rm(const char *op, struct path *dir,
-+ struct dentry *dentry, u16 mask)
-+{
-+ struct inode *inode = dentry->d_inode;
-+ struct path_cond cond = {};
-+
-+ if (!dir->mnt || !inode || !mediated_filesystem(inode))
-+ return 0;
-+
-+ cond.uid = inode->i_uid;
-+ cond.mode = inode->i_mode;
-+
-+ return common_perm_dentry(op, dir, dentry, mask, &cond);
-+}
-+
-+static int common_perm_create(const char *op, struct path *dir,
-+ struct dentry *dentry, u16 mask, umode_t mode)
-+{
-+ struct path_cond cond = { current_fsuid(), mode };
-+
-+ if (!dir->mnt || !mediated_filesystem(dir->dentry->d_inode))
-+ return 0;
-+
-+ return common_perm_dentry(op, dir, dentry, mask, &cond);
-+}
-+
-+static int apparmor_path_unlink(struct path *dir, struct dentry *dentry)
-+{
-+ return common_perm_rm("unlink", dir, dentry, MAY_WRITE);
-+}
-+
-+static int apparmor_path_mkdir(struct path *dir, struct dentry *dentry,
-+ int mode)
-+{
-+ return common_perm_create("mkdir", dir, dentry, AA_MAY_CREATE, S_IFDIR);
-+}
-+
-+static int apparmor_path_rmdir(struct path *dir, struct dentry *dentry)
-+{
-+ return common_perm_rm("rmdir", dir, dentry, MAY_WRITE);
-+}
-+
-+static int apparmor_path_mknod(struct path *dir, struct dentry *dentry,
-+ int mode, unsigned int dev)
-+{
-+ return common_perm_create("mknod", dir, dentry, AA_MAY_CREATE, mode);
-+}
-+
-+static int apparmor_path_truncate(struct path *path, loff_t length,
-+ unsigned int time_attrs)
-+{
-+ struct path_cond cond = { path->dentry->d_inode->i_uid,
-+ path->dentry->d_inode->i_mode };
-+
-+ if (!path->mnt || !mediated_filesystem(path->dentry->d_inode))
-+ return 0;
-+ return common_perm("truncate", path, MAY_WRITE, &cond);
-+}
-+
-+static int apparmor_path_symlink(struct path *dir, struct dentry *dentry,
-+ const char *old_name)
-+{
-+ return common_perm_create("symlink_create", dir, dentry, AA_MAY_CREATE,
-+ S_IFLNK);
-+}
-+
-+static int apparmor_path_link(struct dentry *old_dentry, struct path *new_dir,
-+ struct dentry *new_dentry)
-+{
-+ struct aa_profile *profile;
-+ int error = 0;
-+
-+ if (!mediated_filesystem(old_dentry->d_inode))
-+ return 0;
-+
-+ profile = aa_current_profile_wupd();
-+ if (profile)
-+ error = aa_path_link(profile, old_dentry, new_dir, new_dentry);
-+ return error;
-+}
-+
-+static int apparmor_path_rename(struct path *old_dir, struct dentry *old_dentry,
-+ struct path *new_dir, struct dentry *new_dentry)
-+{
-+ struct aa_profile *profile;
-+ int error = 0;
-+
-+ if (!mediated_filesystem(old_dentry->d_inode))
-+ return 0;
-+
-+ profile = aa_current_profile_wupd();
-+ if (profile) {
-+ struct path old_path = { old_dir->mnt, old_dentry };
-+ struct path new_path = { new_dir->mnt, new_dentry };
-+ struct path_cond cond = { old_dentry->d_inode->i_uid,
-+ old_dentry->d_inode->i_mode };
-+
-+ error = aa_path_perm(profile, "rename_src", &old_path,
-+ MAY_READ | MAY_WRITE, &cond);
-+ if (!error)
-+ error = aa_path_perm(profile, "rename_dest", &new_path,
-+ AA_MAY_CREATE | MAY_WRITE, &cond);
-+
-+ }
-+ return error;
-+}
-+
-+static int apparmor_dentry_open(struct file *file, const struct cred *cred)
-+{
-+ struct aa_profile *profile;
-+ int error = 0;
-+
-+ /* If in exec permission is handled by bprm hooks */
-+ if (current->in_execve ||
-+ !mediated_filesystem(file->f_path.dentry->d_inode))
-+ return 0;
-+
-+ aa_cred_policy(cred, &profile);
-+ if (profile) {
-+ struct aa_file_cxt *fcxt = file->f_security;
-+ struct inode *inode = file->f_path.dentry->d_inode;
-+ struct path_cond cond = { inode->i_uid, inode->i_mode };
-+
-+ error = aa_path_perm(profile, "open", &file->f_path,
-+ aa_map_file_to_perms(file), &cond);
-+ fcxt->profile = aa_get_profile(profile);
-+ /* todo cache actual allowed permissions */
-+ fcxt->allowed = 0;
-+ }
-+
-+ return error;
-+}
-+
-+static int apparmor_file_alloc_security(struct file *file)
-+{
-+ file->f_security = aa_alloc_file_context(GFP_KERNEL);
-+ if (!file->f_security)
-+ return -ENOMEM;
-+ return 0;
-+
-+}
-+
-+static void apparmor_file_free_security(struct file *file)
-+{
-+ struct aa_file_cxt *cxt = file->f_security;
-+
-+ aa_free_file_context(cxt);
-+}
-+
-+static int apparmor_file_permission(struct file *file, int mask)
-+{
-+ /*
-+ * Most basic (rw) file access is revalidated at exec.
-+ * The revalidation done here is for parent/child hat
-+ * file accesses.
-+ *
-+ * Currently profile replacement does not cause revalidation
-+ * or file revocation.
-+ *
-+ * TODO: cache profiles that have revalidated?
-+ */
-+ struct aa_file_cxt *fcxt = file->f_security;
-+ struct aa_profile *profile, *fprofile = fcxt->profile;
-+ int error = 0;
-+
-+ if (!fprofile || !file->f_path.mnt ||
-+ !mediated_filesystem(file->f_path.dentry->d_inode))
-+ return 0;
-+
-+ profile = aa_current_profile();
-+ /* TODO: Enable at exec time revalidation of files
-+ if (profile && (fprofile != profile) &&
-+ ((PROFILE_IS_HAT(profile) && (profile->parent == fprofile)) ||
-+ (PROFILE_IS_HAT(fprofile) && (fprofile->parent == profile))))
-+ error = aa_file_perm(profile, "file_perm", file, mask);
-+ */
-+ if (profile && ((fprofile != profile) || (mask & ~fcxt->allowed)))
-+ error = aa_file_perm(profile, "file_perm", file, mask);
-+
-+ return error;
-+}
-+
-+static int common_file_perm(const char *op, struct file *file, u16 mask)
-+{
-+ const struct aa_file_cxt *fcxt = file->f_security;
-+ struct aa_profile *profile, *fprofile = fcxt->profile;
-+ int error = 0;
-+
-+ if (!fprofile || !file->f_path.mnt ||
-+ !mediated_filesystem(file->f_path.dentry->d_inode))
-+ return 0;
-+
-+ profile = aa_current_profile_wupd();
-+ if (profile && ((fprofile != profile) || (mask & ~fcxt->allowed)))
-+ error = aa_file_perm(profile, op, file, mask);
-+
-+ return error;
-+}
-+
-+static int apparmor_file_lock(struct file *file, unsigned int cmd)
-+{
-+ u16 mask = AA_MAY_LOCK;
-+
-+ if (cmd == F_WRLCK)
-+ mask |= MAY_WRITE;
-+
-+ return common_file_perm("file_lock", file, mask);
-+}
-+
-+
-+/*
-+ * AppArmor doesn't current use the fcntl hook.
-+ *
-+ * FIXME - these are not implemented yet - REMOVE file_fcntl hook
-+ * NOTE: some of the file control commands are further mediated
-+ * by other hooks
-+ * F_SETOWN - security_file_set_fowner
-+ * F_SETLK - security_file_lock
-+ * F_SETLKW - security_file_lock
-+ * O_APPEND - AppArmor mediates append as a subset of full write
-+ * so changing from full write to appending write is
-+ * dropping priviledge and not restricted.
-+
-+
-+static int apparmor_file_fcntl(struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ return 0;
-+}
-+*/
-+
-+static int common_mmap(struct file *file, const char *operation,
-+ unsigned long prot, unsigned long flags)
-+{
-+ struct dentry *dentry;
-+ int mask = 0;
-+
-+ if (!file || !file->f_security)
-+ return 0;
-+
-+ if (prot & PROT_READ)
-+ mask |= MAY_READ;
-+ /* Private mappings don't require write perms since they don't
-+ * write back to the files */
-+ if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
-+ mask |= MAY_WRITE;
-+ if (prot & PROT_EXEC)
-+ mask |= AA_EXEC_MMAP;
-+
-+ dentry = file->f_path.dentry;
-+ return common_file_perm(operation, file, mask);
-+}
-+
-+static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
-+ unsigned long prot, unsigned long flags,
-+ unsigned long addr, unsigned long addr_only)
-+{
-+ if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) {
-+ struct aa_profile *profile = aa_current_profile_wupd();
-+ if (profile)
-+ /* future control check here */
-+ return -EACCES;
-+ else
-+ return -EACCES;
-+ }
-+
-+ return common_mmap(file, "file_mmap", prot, flags);
-+}
-+
-+static int apparmor_file_mprotect(struct vm_area_struct *vma,
-+ unsigned long reqprot, unsigned long prot)
-+{
-+ return common_mmap(vma->vm_file, "file_mprotect", prot,
-+ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
-+}
-+
-+static int apparmor_getprocattr(struct task_struct *task, char *name,
-+ char **value)
-+{
-+ int error = -ENOENT;
-+ struct aa_namespace *ns;
-+ struct aa_profile *profile, *onexec, *prev;
-+ const struct cred *cred = aa_get_task_policy(task, &profile);
-+ struct aa_task_context *cxt = cred->security;
-+ ns = cxt->sys.profile->ns;
-+ onexec = cxt->sys.onexec;
-+ prev = cxt->sys.previous;
-+
-+ /* task must be either querying itself, unconfined or can ptrace */
-+ if (current != task && profile && !capable(CAP_SYS_PTRACE)) {
-+ error = -EPERM;
-+ } else {
-+ if (strcmp(name, "current") == 0) {
-+ error = aa_getprocattr(ns, profile, value);
-+ } else if (strcmp(name, "prev") == 0) {
-+ if (prev)
-+ error = aa_getprocattr(ns, prev, value);
-+ } else if (strcmp(name, "exec") == 0) {
-+ if (onexec)
-+ error = aa_getprocattr(ns, onexec, value);
-+ } else {
-+ error = -EINVAL;
-+ }
-+ }
-+
-+ put_cred(cred);
-+
-+ return error;
-+}
-+
-+static int apparmor_setprocattr(struct task_struct *task, char *name,
-+ void *value, size_t size)
-+{
-+ char *command, *args;
-+ int error;
-+
-+ if (size == 0 || size >= PAGE_SIZE)
-+ return -EINVAL;
-+
-+ /* task can only write its own attributes */
-+ if (current != task)
-+ return -EACCES;
-+
-+ args = value;
-+ args[size] = '\0';
-+ args = strstrip(args);
-+ command = strsep(&args, " ");
-+ if (!args)
-+ return -EINVAL;
-+ while (isspace(*args))
-+ args++;
-+ if (!*args)
-+ return -EINVAL;
-+
-+ if (strcmp(name, "current") == 0) {
-+ if (strcmp(command, "changehat") == 0) {
-+ error = aa_setprocattr_changehat(args, !AA_DO_TEST);
-+ } else if (strcmp(command, "permhat") == 0) {
-+ error = aa_setprocattr_changehat(args, AA_DO_TEST);
-+ } else if (strcmp(command, "changeprofile") == 0) {
-+ error = aa_setprocattr_changeprofile(args, 0,
-+ !AA_DO_TEST);
-+ } else if (strcmp(command, "permprofile") == 0) {
-+ error = aa_setprocattr_changeprofile(args, 0,
-+ AA_DO_TEST);
-+ } else if (strcmp(command, "permipc") == 0) {
-+ error = aa_setprocattr_permipc(args);
-+ } else {
-+ struct aa_audit sa;
-+ memset(&sa, 0, sizeof(sa));
-+ sa.operation = "setprocattr";
-+ sa.gfp_mask = GFP_KERNEL;
-+ sa.info = name;
-+ sa.error = -EINVAL;
-+ return aa_audit(AUDIT_APPARMOR_DENIED, NULL, &sa, NULL);
-+ }
-+ } else if (strcmp(name, "exec") == 0) {
-+ error = aa_setprocattr_changeprofile(strstrip(args), 1,
-+ !AA_DO_TEST);
-+ } else {
-+ /* only support the "current" and "exec" process attributes */
-+ return -EINVAL;
-+ }
-+ if (!error)
-+ error = size;
-+ return error;
-+}
-+
-+static int apparmor_task_setrlimit(unsigned int resource,
-+ struct rlimit *new_rlim)
-+{
-+ struct aa_profile *profile = aa_current_profile_wupd();
-+ int error = 0;
-+
-+ if (profile) {
-+ error = aa_task_setrlimit(profile, resource, new_rlim);
-+ }
-+
-+ return error;
-+}
-+
-+#ifdef CONFIG_SECURITY_APPARMOR_NETWORK
-+static int apparmor_socket_create(int family, int type, int protocol, int kern){
-+ struct aa_profile *profile;
-+ int error = 0;
-+
-+ if (kern)
-+ return 0;
-+
-+ profile = aa_current_profile();
-+ if (profile)
-+ error = aa_net_perm(profile, "socket_create", family,
-+ type, protocol);
-+ return error;
-+}
-+
-+static int apparmor_socket_post_create(struct socket *sock, int family,
-+ int type, int protocol, int kern)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ if (kern)
-+ return 0;
-+
-+ return aa_revalidate_sk(sk, "socket_post_create");
-+}
-+
-+static int apparmor_socket_bind(struct socket *sock,
-+ struct sockaddr *address, int addrlen)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_bind");
-+}
-+
-+static int apparmor_socket_connect(struct socket *sock,
-+ struct sockaddr *address, int addrlen)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_connect");
-+}
-+
-+static int apparmor_socket_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_listen");
-+}
-+
-+static int apparmor_socket_accept(struct socket *sock, struct socket *newsock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_accept");
-+}
-+
-+static int apparmor_socket_sendmsg(struct socket *sock,
-+ struct msghdr *msg, int size)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_sendmsg");
-+}
-+
-+static int apparmor_socket_recvmsg(struct socket *sock,
-+ struct msghdr *msg, int size, int flags)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_recvmsg");
-+}
-+
-+static int apparmor_socket_getsockname(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_getsockname");
-+}
-+
-+static int apparmor_socket_getpeername(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_getpeername");
-+}
-+
-+static int apparmor_socket_getsockopt(struct socket *sock, int level,
-+ int optname)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_getsockopt");
-+}
-+
-+static int apparmor_socket_setsockopt(struct socket *sock, int level,
-+ int optname)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_setsockopt");
-+}
-+
-+static int apparmor_socket_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ return aa_revalidate_sk(sk, "socket_shutdown");
-+}
-+#endif
-+
-+static struct security_operations apparmor_ops = {
-+ .name = "apparmor",
-+
-+ .ptrace_may_access = apparmor_ptrace_may_access,
-+ .ptrace_traceme = apparmor_ptrace_traceme,
-+ .capget = apparmor_capget,
-+ .sysctl = apparmor_sysctl,
-+ .capable = apparmor_capable,
-+/*
-+ .inode_create = apparmor_inode_create,
-+ .inode_setattr = apparmor_inode_setattr,
-+ .inode_setxattr = apparmor_inode_setxattr,
-+ .inode_getxattr = apparmor_inode_getxattr,
-+ .inode_listxattr = apparmor_inode_listxattr,
-+ .inode_removexattr = apparmor_inode_removexattr,
-+ .inode_permission = ??? use to mediate owner access to non-mediated fs
-+*/
-+
-+ .path_link = apparmor_path_link,
-+ .path_unlink = apparmor_path_unlink,
-+ .path_symlink = apparmor_path_symlink,
-+ .path_mkdir = apparmor_path_mkdir,
-+ .path_rmdir = apparmor_path_rmdir,
-+ .path_mknod = apparmor_path_mknod,
-+ .path_rename = apparmor_path_rename,
-+ .path_truncate = apparmor_path_truncate,
-+ .dentry_open = apparmor_dentry_open,
-+
-+ .file_permission = apparmor_file_permission,
-+ .file_alloc_security = apparmor_file_alloc_security,
-+ .file_free_security = apparmor_file_free_security,
-+ .file_mmap = apparmor_file_mmap,
-+ .file_mprotect = apparmor_file_mprotect,
-+ .file_lock = apparmor_file_lock,
-+
-+/* .file_fcntl = apparmor_file_fcntl, */
-+
-+ .getprocattr = apparmor_getprocattr,
-+ .setprocattr = apparmor_setprocattr,
-+
-+#ifdef CONFIG_SECURITY_APPARMOR_NETWORK
-+ .socket_create = apparmor_socket_create,
-+ .socket_post_create = apparmor_socket_post_create,
-+ .socket_bind = apparmor_socket_bind,
-+ .socket_connect = apparmor_socket_connect,
-+ .socket_listen = apparmor_socket_listen,
-+ .socket_accept = apparmor_socket_accept,
-+ .socket_sendmsg = apparmor_socket_sendmsg,
-+ .socket_recvmsg = apparmor_socket_recvmsg,
-+ .socket_getsockname = apparmor_socket_getsockname,
-+ .socket_getpeername = apparmor_socket_getpeername,
-+ .socket_getsockopt = apparmor_socket_getsockopt,
-+ .socket_setsockopt = apparmor_socket_setsockopt,
-+ .socket_shutdown = apparmor_socket_shutdown,
-+#endif
-+
-+ .cred_free = apparmor_cred_free,
-+ .cred_prepare = apparmor_cred_prepare,
-+
-+ .bprm_set_creds = apparmor_bprm_set_creds,
-+ // .bprm_committing_creds = apparmor_bprm_committing_creds,
-+ .bprm_committed_creds = apparmor_bprm_committed_creds,
-+ .bprm_secureexec = apparmor_bprm_secureexec,
-+
-+ .task_setrlimit = apparmor_task_setrlimit,
-+};
-+
-+
-+/*
-+ * AppArmor sysfs module parameters
-+ */
-+
-+static int param_set_aabool(const char *val, struct kernel_param *kp);
-+static int param_get_aabool(char *buffer, struct kernel_param *kp);
-+#define param_check_aabool(name, p) __param_check(name, p, int)
-+
-+static int param_set_aauint(const char *val, struct kernel_param *kp);
-+static int param_get_aauint(char *buffer, struct kernel_param *kp);
-+#define param_check_aauint(name, p) __param_check(name, p, int)
-+
-+static int param_set_aalockpolicy(const char *val, struct kernel_param *kp);
-+static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp);
-+#define param_check_aalockpolicy(name, p) __param_check(name, p, int)
-+
-+static int param_set_audit(const char *val, struct kernel_param *kp);
-+static int param_get_audit(char *buffer, struct kernel_param *kp);
-+#define param_check_audit(name, p) __param_check(name, p, int)
-+
-+static int param_set_mode(const char *val, struct kernel_param *kp);
-+static int param_get_mode(char *buffer, struct kernel_param *kp);
-+#define param_check_mode(name, p) __param_check(name, p, int)
-+
-+/* Flag values, also controllable via /sys/module/apparmor/parameters
-+ * We define special types as we want to do additional mediation.
-+ */
-+
-+/* AppArmor global enforcement switch - complain, enforce, kill */
-+enum profile_mode g_profile_mode = APPARMOR_ENFORCE;
-+module_param_call(mode, param_set_mode, param_get_mode,
-+ &g_profile_mode, S_IRUSR | S_IWUSR);
-+
-+/* Debug mode */
-+int g_apparmor_debug;
-+module_param_named(debug, g_apparmor_debug, aabool, S_IRUSR | S_IWUSR);
-+
-+/* Audit mode */
-+enum audit_mode g_apparmor_audit;
-+module_param_call(audit, param_set_audit, param_get_audit,
-+ &g_apparmor_audit, S_IRUSR | S_IWUSR);
-+
-+/* Determines if audit header is included in audited messages. This
-+ * provides more context if the audit daemon is not running
-+ */
-+int g_apparmor_audit_header;
-+module_param_named(audit_header, g_apparmor_audit_header, aabool,
-+ S_IRUSR | S_IWUSR);
-+
-+/* lock out loading/removal of policy
-+ * TODO: add in at boot loading of policy, which is the only way to
-+ * load policy, if lock_policy is set
-+ */
-+int g_apparmor_lock_policy;
-+module_param_named(lock_policy, g_apparmor_lock_policy, aalockpolicy,
-+ S_IRUSR | S_IWUSR);
-+
-+/* Syscall logging mode */
-+int g_apparmor_logsyscall;
-+module_param_named(logsyscall, g_apparmor_logsyscall, aabool,
-+ S_IRUSR | S_IWUSR);
-+
-+/* Maximum pathname length before accesses will start getting rejected */
-+unsigned int g_apparmor_path_max = 2 * PATH_MAX;
-+module_param_named(path_max, g_apparmor_path_max, aauint, S_IRUSR | S_IWUSR);
-+
-+/* Boot time disable flag */
-+#ifdef CONFIG_SECURITY_APPARMOR_DISABLE
-+#define AA_ENABLED_PERMS 0600
-+#else
-+#define AA_ENABLED_PERMS 0400
-+#endif
-+static int param_set_aa_enabled(const char *val, struct kernel_param *kp);
-+static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
-+module_param_call(enabled, param_set_aa_enabled, param_get_aauint,
-+ &apparmor_enabled, AA_ENABLED_PERMS);
-+
-+static int __init apparmor_enabled_setup(char *str)
-+{
-+ apparmor_enabled = simple_strtol(str, NULL, 0);
-+ return 1;
-+}
-+__setup("apparmor=", apparmor_enabled_setup);
-+
-+static int param_set_aalockpolicy(const char *val, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+ if (g_apparmor_lock_policy)
-+ return -EACCES;
-+ return param_set_bool(val, kp);
-+}
-+
-+static int param_get_aalockpolicy(char *buffer, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+ return param_get_bool(buffer, kp);
-+}
-+
-+static int param_set_aabool(const char *val, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+ return param_set_bool(val, kp);
-+}
-+
-+static int param_get_aabool(char *buffer, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+ return param_get_bool(buffer, kp);
-+}
-+
-+static int param_set_aauint(const char *val, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+ return param_set_uint(val, kp);
-+}
-+
-+static int param_get_aauint(char *buffer, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+ return param_get_uint(buffer, kp);
-+}
-+
-+/* allow run time disabling of apparmor */
-+static int param_set_aa_enabled(const char *val, struct kernel_param *kp)
-+{
-+ unsigned long l;
-+
-+ if (!apparmor_initialized) {
-+ apparmor_enabled = 0;
-+ return 0;
-+ }
-+
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+
-+ if (!apparmor_enabled)
-+ return -EINVAL;
-+
-+ if (!val)
-+ return -EINVAL;
-+
-+ if (strict_strtoul(val, 0, &l) || l != 0)
-+ return -EINVAL;
-+
-+ apparmor_enabled = 0;
-+ apparmor_disable();
-+ return 0;
-+}
-+
-+static int param_get_audit(char *buffer, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+
-+ if (!apparmor_enabled)
-+ return -EINVAL;
-+
-+ return sprintf(buffer, "%s", audit_mode_names[g_apparmor_audit]);
-+}
-+
-+static int param_set_audit(const char *val, struct kernel_param *kp)
-+{
-+ int i;
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+
-+ if (!apparmor_enabled)
-+ return -EINVAL;
-+
-+ if (!val)
-+ return -EINVAL;
-+
-+ for (i = 0; i < AUDIT_MAX_INDEX; i++) {
-+ if (strcmp(val, audit_mode_names[i]) == 0) {
-+ g_apparmor_audit = i;
-+ return 0;
-+ }
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int param_get_mode(char *buffer, struct kernel_param *kp)
-+{
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+
-+ if (!apparmor_enabled)
-+ return -EINVAL;
-+
-+ return sprintf(buffer, "%s", profile_mode_names[g_profile_mode]);
-+}
-+
-+static int param_set_mode(const char *val, struct kernel_param *kp)
-+{
-+ int i;
-+ if (__aa_task_is_confined(current))
-+ return -EPERM;
-+
-+ if (!apparmor_enabled)
-+ return -EINVAL;
-+
-+ if (!val)
-+ return -EINVAL;
-+
-+ for (i = 0; i < APPARMOR_NAMES_MAX_INDEX; i++) {
-+ if (strcmp(val, profile_mode_names[i]) == 0) {
-+ g_profile_mode = i;
-+ return 0;
-+ }
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+
-+/*
-+ * AppArmor init functions
-+ */
-+
-+static int set_init_cxt(void)
-+{
-+ struct cred *cred = (struct cred *) current->real_cred;
-+ struct aa_task_context *cxt;
-+
-+ cxt = aa_alloc_task_context(GFP_KERNEL);
-+ if (!cxt)
-+ return -ENOMEM;
-+
-+ cxt->sys.profile = aa_get_profile(default_namespace->unconfined);
-+ cred->security = cxt;
-+
-+ return 0;
-+}
-+
-+static int __init apparmor_init(void)
-+{
-+ int error;
-+
-+ if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) {
-+ info_message("AppArmor disabled by boot time parameter\n");
-+ apparmor_enabled = 0;
-+ return 0;
-+ }
-+
-+ /*
-+ * Activated with fs_initcall
-+ error = create_apparmorfs();
-+ if (error) {
-+ AA_ERROR("Unable to activate AppArmor filesystem\n");
-+ goto createfs_out;
-+ }
-+ */
-+
-+ error = alloc_default_namespace();
-+ if (error) {
-+ AA_ERROR("Unable to allocate default profile namespace\n");
-+ goto alloc_out;
-+ }
-+
-+ error = set_init_cxt();
-+ if (error) {
-+ AA_ERROR("Failed to set context on init task\n");
-+ goto alloc_out;
-+ }
-+
-+ error = register_security(&apparmor_ops);
-+ if (error) {
-+ AA_ERROR("Unable to register AppArmor\n");
-+ goto register_security_out;
-+ }
-+
-+ /* Report that AppArmor successfully initialized */
-+ apparmor_initialized = 1;
-+ if (g_profile_mode == APPARMOR_COMPLAIN)
-+ info_message("AppArmor initialized: complain mode enabled");
-+ else if (g_profile_mode == APPARMOR_KILL)
-+ info_message("AppArmor initialized: kill mode enabled");
-+ else
-+ info_message("AppArmor initialized");
-+
-+ return error;
-+
-+register_security_out:
-+ free_default_namespace();
-+
-+alloc_out:
-+ destroy_apparmorfs();
-+
-+/*createfs_out:*/
-+ apparmor_enabled = 0;
-+ return error;
-+
-+}
-+
-+security_initcall(apparmor_init);
-+
-+void apparmor_disable(void)
-+{
-+ /* Remove and release all the profiles on the profile list. */
-+ aa_profile_ns_list_release();
-+
-+ /* FIXME: cleanup profiles references on files */
-+ free_default_namespace();
-+
-+ /*
-+ * Delay for an rcu cycle to make sure that all active task
-+ * context readers have finished, and all profiles have been
-+ * freed by their rcu callbacks.
-+ */
-+ synchronize_rcu();
-+ destroy_apparmorfs();
-+ apparmor_initialized = 0;
-+
-+ info_message("AppArmor protection disabled");
-+}
-+
-diff --git a/security/apparmor/match.c b/security/apparmor/match.c
-new file mode 100644
-index 0000000..a22d106
---- /dev/null
-+++ b/security/apparmor/match.c
-@@ -0,0 +1,293 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor dfa based regular expression matching engine
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+
-+/* TODO: remove !!!! */
-+// #include <linux/fs.h>
-+
-+#include "include/apparmor.h"
-+#include "include/match.h"
-+#include "include/file.h"
-+
-+static struct table_header *unpack_table(void *blob, size_t bsize)
-+{
-+ struct table_header *table = NULL;
-+ struct table_header th;
-+ size_t tsize;
-+
-+ if (bsize < sizeof(struct table_header))
-+ goto out;
-+
-+ th.td_id = be16_to_cpu(*(u16 *) (blob));
-+ th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
-+ th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
-+ blob += sizeof(struct table_header);
-+
-+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
-+ th.td_flags == YYTD_DATA8))
-+ goto out;
-+
-+ tsize = table_size(th.td_lolen, th.td_flags);
-+ if (bsize < tsize)
-+ goto out;
-+
-+ table = kmalloc(tsize, GFP_KERNEL);
-+ if (table) {
-+ *table = th;
-+ if (th.td_flags == YYTD_DATA8)
-+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
-+ u8, byte_to_byte);
-+ else if (th.td_flags == YYTD_DATA16)
-+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
-+ u16, be16_to_cpu);
-+ else
-+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
-+ u32, be32_to_cpu);
-+ }
-+
-+out:
-+ return table;
-+}
-+
-+int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
-+{
-+ int hsize, i;
-+ int error = -ENOMEM;
-+
-+ /* get dfa table set header */
-+ if (size < sizeof(struct table_set_header))
-+ goto fail;
-+
-+ if (ntohl(*(u32 *)blob) != YYTH_MAGIC)
-+ goto fail;
-+
-+ hsize = ntohl(*(u32 *)(blob + 4));
-+ if (size < hsize)
-+ goto fail;
-+
-+ blob += hsize;
-+ size -= hsize;
-+
-+ error = -EPROTO;
-+ while (size > 0) {
-+ struct table_header *table;
-+ table = unpack_table(blob, size);
-+ if (!table)
-+ goto fail;
-+
-+ switch (table->td_id) {
-+ case YYTD_ID_ACCEPT:
-+ case YYTD_ID_ACCEPT2:
-+ case YYTD_ID_BASE:
-+ dfa->tables[table->td_id - 1] = table;
-+ if (table->td_flags != YYTD_DATA32)
-+ goto fail;
-+ break;
-+ case YYTD_ID_DEF:
-+ case YYTD_ID_NXT:
-+ case YYTD_ID_CHK:
-+ dfa->tables[table->td_id - 1] = table;
-+ if (table->td_flags != YYTD_DATA16)
-+ goto fail;
-+ break;
-+ case YYTD_ID_EC:
-+ dfa->tables[table->td_id - 1] = table;
-+ if (table->td_flags != YYTD_DATA8)
-+ goto fail;
-+ break;
-+ default:
-+ kfree(table);
-+ goto fail;
-+ }
-+
-+ blob += table_size(table->td_lolen, table->td_flags);
-+ size -= table_size(table->td_lolen, table->td_flags);
-+ }
-+
-+ return 0;
-+
-+fail:
-+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
-+ kfree(dfa->tables[i]);
-+ dfa->tables[i] = NULL;
-+ }
-+ return error;
-+}
-+
-+/**
-+ * verify_dfa - verify that all the transitions and states in the dfa tables
-+ * are in bounds.
-+ * @dfa: dfa to test
-+ *
-+ * assumes dfa has gone through the verification done by unpacking
-+ */
-+int verify_dfa(struct aa_dfa *dfa)
-+{
-+ size_t i, state_count, trans_count;
-+ int error = -EPROTO;
-+
-+ /* check that required tables exist */
-+ if (!(dfa->tables[YYTD_ID_ACCEPT - 1] &&
-+ dfa->tables[YYTD_ID_ACCEPT2 - 1] &&
-+ dfa->tables[YYTD_ID_DEF - 1] &&
-+ dfa->tables[YYTD_ID_BASE - 1] &&
-+ dfa->tables[YYTD_ID_NXT - 1] &&
-+ dfa->tables[YYTD_ID_CHK - 1]))
-+ goto out;
-+
-+ /* accept.size == default.size == base.size */
-+ state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen;
-+ if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen &&
-+ state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen &&
-+ state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen))
-+ goto out;
-+
-+ /* next.size == chk.size */
-+ trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen;
-+ if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen)
-+ goto out;
-+
-+ /* if equivalence classes then its table size must be 256 */
-+ if (dfa->tables[YYTD_ID_EC - 1] &&
-+ dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256)
-+ goto out;
-+
-+ for (i = 0; i < state_count; i++) {
-+ if (DEFAULT_TABLE(dfa)[i] >= state_count)
-+ goto out;
-+ if (BASE_TABLE(dfa)[i] >= trans_count + 256)
-+ goto out;
-+ }
-+
-+ for (i = 0; i < trans_count ; i++) {
-+ if (NEXT_TABLE(dfa)[i] >= state_count)
-+ goto out;
-+ if (CHECK_TABLE(dfa)[i] >= state_count)
-+ goto out;
-+ }
-+
-+ /* verify accept permissions */
-+ for (i = 0; i < state_count; i++) {
-+ int mode = ACCEPT_TABLE(dfa)[i];
-+
-+ if (mode & ~DFA_VALID_PERM_MASK)
-+ goto out;
-+ if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
-+ goto out;
-+
-+ }
-+
-+ error = 0;
-+out:
-+ return error;
-+}
-+
-+struct aa_dfa *aa_match_alloc(void)
-+{
-+ return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
-+}
-+
-+void aa_match_free(struct aa_dfa *dfa)
-+{
-+ if (dfa) {
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++)
-+ kfree(dfa->tables[i]);
-+ }
-+ kfree(dfa);
-+}
-+
-+/**
-+ * aa_dfa_match_len - traverse @dfa to find state @str stops at
-+ * @dfa: the dfa to match @str against
-+ * @start: the state of the dfa to start matching in
-+ * @str: the string of bytes to match against the dfa
-+ * @len: length of the string of bytes to match
-+ *
-+ * aa_dfa_match_len will match @str against the dfa and return the state it
-+ * finished matching in. The final state can be used to look up the accepting
-+ * label, or as the start state of a continuing match.
-+ *
-+ * This function will happily match again the 0 byte and only finishes
-+ * when @len input is consumed.
-+ */
-+unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
-+ const char *str, int len)
-+{
-+ u16 *def = DEFAULT_TABLE(dfa);
-+ u32 *base = BASE_TABLE(dfa);
-+ u16 *next = NEXT_TABLE(dfa);
-+ u16 *check = CHECK_TABLE(dfa);
-+ unsigned int state = start, pos;
-+
-+ if (state == 0)
-+ return 0;
-+
-+ /* current state is <state>, matching character *str */
-+ if (dfa->tables[YYTD_ID_EC - 1]) {
-+ u8 *equiv = EQUIV_TABLE(dfa);
-+ for (; len; len--) {
-+ pos = base[state] + equiv[(u8)*str++];
-+ if (check[pos] == state)
-+ state = next[pos];
-+ else
-+ state = def[state];
-+ }
-+ } else {
-+ for (; len; len--) {
-+ pos = base[state] + (u8)*str++;
-+ if (check[pos] == state)
-+ state = next[pos];
-+ else
-+ state = def[state];
-+ }
-+ }
-+ return state;
-+}
-+
-+
-+/**
-+ * aa_dfa_next_state - traverse @dfa to find state @str stops at
-+ * @dfa: the dfa to match @str against
-+ * @start: the state of the dfa to start matching in
-+ * @str: the null terminated string of bytes to match against the dfa
-+ *
-+ * aa_dfa_next_state will match @str against the dfa and return the state it
-+ * finished matching in. The final state can be used to look up the accepting
-+ * label, or as the start state of a continuing match.
-+ */
-+unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
-+ const char *str)
-+{
-+ return aa_dfa_match_len(dfa, start, str, strlen(str));
-+}
-+
-+/**
-+ * aa_dfa_null_transition - step to next state after null character
-+ * @dfa: the dfa to match against
-+ * @start: the state of the dfa to start matching in
-+ *
-+ * aa_dfa_null_transition transitions to the next state after a null
-+ * character which is not used in standard matching and is only
-+ * used to seperate pairs.
-+ */
-+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start)
-+{
-+ return aa_dfa_match_len(dfa, start, "", 1);
-+}
-+
-diff --git a/security/apparmor/net.c b/security/apparmor/net.c
-new file mode 100644
-index 0000000..beb8715
---- /dev/null
-+++ b/security/apparmor/net.c
-@@ -0,0 +1,146 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor network mediation
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include "include/apparmor.h"
-+#include "include/audit.h"
-+#include "include/context.h"
-+#include "include/net.h"
-+#include "include/policy.h"
-+
-+#include "af_names.h"
-+
-+static const char *sock_type_names[] = {
-+ "unknown(0)",
-+ "stream",
-+ "dgram",
-+ "raw",
-+ "rdm",
-+ "seqpacket",
-+ "dccp",
-+ "unknown(7)",
-+ "unknown(8)",
-+ "unknown(9)",
-+ "packet",
-+};
-+
-+struct aa_audit_net {
-+ struct aa_audit base;
-+
-+ int family, type, protocol;
-+
-+};
-+
-+static void audit_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct aa_audit_net *sa = va;
-+
-+ if (sa->family || sa->type) {
-+ if (address_family_names[sa->family])
-+ audit_log_format(ab, " family=\"%s\"",
-+ address_family_names[sa->family]);
-+ else
-+ audit_log_format(ab, " family=\"unknown(%d)\"",
-+ sa->family);
-+
-+ if (sock_type_names[sa->type])
-+ audit_log_format(ab, " sock_type=\"%s\"",
-+ sock_type_names[sa->type]);
-+ else
-+ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
-+ sa->type);
-+
-+ audit_log_format(ab, " protocol=%d", sa->protocol);
-+ }
-+
-+}
-+
-+static int aa_audit_net(struct aa_profile *profile, struct aa_audit_net *sa)
-+{
-+ int type = AUDIT_APPARMOR_AUTO;
-+
-+ if (likely(!sa->base.error)) {
-+ u16 audit_mask = profile->net.audit[sa->family];
-+ if (likely((PROFILE_AUDIT_MODE(profile) != AUDIT_ALL) &&
-+ !(1 << sa->type & audit_mask)))
-+ return 0;
-+ } else {
-+ u16 quiet_mask = profile->net.quiet[sa->family];
-+ u16 kill_mask = 0;
-+ u16 denied = (1 << sa->type) & ~quiet_mask;
-+
-+ if (denied & kill_mask)
-+ type = AUDIT_APPARMOR_KILL;
-+
-+ if ((denied & quiet_mask) &&
-+ PROFILE_AUDIT_MODE(profile) != AUDIT_NOQUIET &&
-+ PROFILE_AUDIT_MODE(profile) != AUDIT_ALL)
-+ return PROFILE_COMPLAIN(profile) ? 0 : sa->base.error;
-+ }
-+
-+ return aa_audit(type, profile, (struct aa_audit *)sa, audit_cb);
-+}
-+
-+int aa_net_perm(struct aa_profile *profile, char *operation,
-+ int family, int type, int protocol)
-+{
-+ struct aa_audit_net sa;
-+ u16 family_mask;
-+
-+ if ((family < 0) || (family >= AF_MAX))
-+ return -EINVAL;
-+
-+ if ((type < 0) || (type >= SOCK_MAX))
-+ return -EINVAL;
-+
-+ /* unix domain and netlink sockets are handled by ipc */
-+ if (family == AF_UNIX || family == AF_NETLINK)
-+ return 0;
-+
-+ family_mask = profile->net.allowed[family];
-+
-+ sa.base.error = (family_mask & (1 << type)) ? 0 : -EACCES;
-+
-+ memset(&sa, 0, sizeof(sa));
-+ sa.base.operation = operation;
-+ sa.base.gfp_mask = GFP_KERNEL;
-+ sa.family = family;
-+ sa.type = type;
-+ sa.protocol = protocol;
-+
-+ return aa_audit_net(profile, &sa);
-+}
-+
-+int aa_revalidate_sk(struct sock *sk, char *operation)
-+{
-+ struct aa_profile *profile;
-+ struct cred *cred;
-+ int error = 0;
-+
-+ /* this is some debugging code to flush out the network hooks that
-+ that are called in interrupt context */
-+ if (in_interrupt()) {
-+ printk(KERN_WARNING "AppArmor Debug: Hook being called from interrupt context\n");
-+ dump_stack();
-+ return 0;
-+ }
-+
-+ cred = aa_get_task_policy(current, &profile);
-+ if (profile)
-+ error = aa_net_perm(profile, operation,
-+ sk->sk_family, sk->sk_type,
-+ sk->sk_protocol);
-+ put_cred(cred);
-+
-+ return error;
-+}
-diff --git a/security/apparmor/path.c b/security/apparmor/path.c
-new file mode 100644
-index 0000000..21f3e67
---- /dev/null
-+++ b/security/apparmor/path.c
-@@ -0,0 +1,155 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor function for pathnames
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/mnt_namespace.h>
-+#include <linux/mount.h>
-+#include <linux/namei.h>
-+#include <linux/path.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/fs_struct.h>
-+
-+#include "include/apparmor.h"
-+#include "include/path.h"
-+
-+int aa_get_name_to_buffer(struct path *path, int is_dir, char *buffer, int size,
-+ char **name)
-+{
-+ int error = d_namespace_path(path, buffer, size - is_dir, name);
-+
-+ if (!error && is_dir && (*name)[1] != '\0')
-+ /*
-+ * Append "/" to the pathname. The root directory is a special
-+ * case; it already ends in slash.
-+ */
-+ strcpy(&buffer[size - 2], "/");
-+
-+ return error;
-+}
-+
-+/**
-+ * aa_get_name - compute the pathname of a file
-+ * @path: path the file
-+ * @is_dir: set if the file is a directory
-+ * @buffer: buffer that aa_get_name() allocated
-+ * @name: the error code indicating whether aa_get_name failed
-+ *
-+ * Returns an error code if the there was a failure in obtaining the
-+ * name.
-+ *
-+ * @name is apointer to the beginning of the pathname (which usually differs
-+ * from the beginning of the buffer), or NULL. If there is an error @name
-+ * may contain a partial or invalid name (in the case of a deleted file), that
-+ * can be used for audit purposes, but it can not be used for mediation.
-+ *
-+ * We need @is_dir to indicate whether the file is a directory or not because
-+ * the file may not yet exist, and so we cannot check the inode's file type.
-+ */
-+int aa_get_name(struct path *path, int is_dir, char **buffer, char **name)
-+{
-+ char *buf, *str = NULL;
-+ int size = 256;
-+ int error;
-+
-+ *name = NULL;
-+ *buffer = NULL;
-+ for (;;) {
-+ buf = kmalloc(size, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ error = aa_get_name_to_buffer(path, is_dir, buf, size, &str);
-+ if (!error || (error == -ENOENT) || (error == -ESTALE))
-+ break;
-+
-+ kfree(buf);
-+ size <<= 1;
-+ if (size > g_apparmor_path_max)
-+ return -ENAMETOOLONG;
-+ }
-+ *buffer = buf;
-+ *name = str;
-+
-+ return error;
-+}
-+
-+int d_namespace_path(struct path *path, char *buf, int buflen, char **name)
-+{
-+ struct path root, tmp, ns_root = { };
-+ char *res;
-+ int error = 0;
-+
-+ read_lock(¤t->fs->lock);
-+ root = current->fs->root;
-+ path_get(¤t->fs->root);
-+ read_unlock(¤t->fs->lock);
-+ spin_lock(&vfsmount_lock);
-+ if (root.mnt && root.mnt->mnt_ns)
-+ ns_root.mnt = mntget(root.mnt->mnt_ns->root);
-+ if (ns_root.mnt)
-+ ns_root.dentry = dget(ns_root.mnt->mnt_root);
-+ spin_unlock(&vfsmount_lock);
-+ spin_lock(&dcache_lock);
-+ tmp = ns_root;
-+ res = __d_path(path, &tmp, buf, buflen);
-+
-+ *name = res;
-+ /* handle error conditions - and still allow a partial path to
-+ * be returned */
-+ if (IS_ERR(res)) {
-+ error = PTR_ERR(res);
-+ *name = buf;
-+ } else if (!IS_ROOT(path->dentry) && d_unhashed(path->dentry)) {
-+ error = -ENOENT;
-+#if 0
-+ } else if (tmp.dentry != ns_root.dentry && tmp.mnt != ns_root.mnt) {
-+ /* disconnected path don return pathname starting with '/' */
-+ error = -ESTALE;
-+ if (*res == '/')
-+ *name = res + 1;
-+#endif
-+ }
-+
-+ spin_unlock(&dcache_lock);
-+ path_put(&root);
-+ path_put(&ns_root);
-+
-+ return error;
-+}
-+
-+char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen)
-+{
-+ if (buflen < 1)
-+ return NULL;
-+ buffer += --buflen;
-+ *buffer = '\0';
-+
-+ while (table) {
-+ int namelen = strlen(table->procname);
-+
-+ if (buflen < namelen + 1)
-+ return NULL;
-+ buflen -= namelen + 1;
-+ buffer -= namelen;
-+ memcpy(buffer, table->procname, namelen);
-+ *--buffer = '/';
-+ table = table->parent;
-+ }
-+ if (buflen < 4)
-+ return NULL;
-+ buffer -= 4;
-+ memcpy(buffer, "/sys", 4);
-+
-+ return buffer;
-+}
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-new file mode 100644
-index 0000000..3ba2642
---- /dev/null
-+++ b/security/apparmor/policy.c
-@@ -0,0 +1,727 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor policy manipulation functions
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ *
-+ *
-+ * AppArmor policy is based around profiles, which contain the rules a
-+ * task is confined by. Every task in the sytem has a profile attached
-+ * to it determined either by matching "unconfined" tasks against the
-+ * visible set of profiles or by following a profiles attachment rules.
-+ *
-+ * Each profile exists in an AppArmor profile namespace which is a
-+ * container of related profiles. Each namespace contains a special
-+ * "unconfined" profile, which doesn't efforce any confinement on
-+ * a task beyond DAC.
-+ *
-+ * Namespace and profile names can be written together in either
-+ * of two syntaxes.
-+ * :namespace:profile - used by kernel interfaces for easy detection
-+ * namespace://profile - used by policy
-+ *
-+ * Profile names name not start with : or @ and may not contain \0
-+ * a // in a profile name indicates a compound name with the name before
-+ * the // being the parent profile and the name after the child
-+ *
-+ * Reserved profile names
-+ * unconfined - special automatically generated unconfined profile
-+ * inherit - special name to indicate profile inheritance
-+ * null-XXXX-YYYY - special automically generated learning profiles
-+ *
-+ * Namespace names may not start with / or @ and may not contain \0 or //
-+ * it is recommend that they do not contain any '/' characters
-+ * Reserved namespace namespace
-+ * default - the default namespace setup by AppArmor
-+ * user-XXXX - user defined profiles
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/spinlock.h>
-+#include <linux/string.h>
-+
-+#include "include/apparmor.h"
-+#include "include/capability.h"
-+#include "include/file.h"
-+#include "include/ipc.h"
-+#include "include/match.h"
-+#include "include/policy.h"
-+#include "include/resource.h"
-+#include "include/sid.h"
-+
-+/* list of profile namespaces and lock */
-+LIST_HEAD(ns_list);
-+DEFINE_RWLOCK(ns_list_lock);
-+
-+struct aa_namespace *default_namespace;
-+
-+const char *profile_mode_names[] = {
-+ "enforce",
-+ "complain",
-+ "kill",
-+};
-+
-+#define AA_SYS_SID 0
-+#define AA_USR_SID 1
-+
-+
-+static int common_init(struct aa_policy_common *common, const char *name)
-+{
-+ common->name = kstrdup(name, GFP_KERNEL);
-+ if (!common->name)
-+ return 0;
-+ INIT_LIST_HEAD(&common->list);
-+ INIT_LIST_HEAD(&common->profiles);
-+ kref_init(&common->count);
-+ rwlock_init(&common->lock);
-+
-+ return 1;
-+}
-+
-+static void common_free(struct aa_policy_common *common)
-+{
-+ /* still contains profiles -- invalid */
-+ if (!list_empty(&common->profiles)) {
-+ AA_ERROR("%s: internal error, "
-+ "policy '%s' still contains profiles\n",
-+ __func__, common->name);
-+ BUG();
-+ }
-+ if (!list_empty(&common->list)) {
-+ AA_ERROR("%s: internal error, policy '%s' still on list\n",
-+ __func__, common->name);
-+ BUG();
-+ }
-+
-+ kfree(common->name);
-+}
-+
-+static struct aa_policy_common *__common_find(struct list_head *head,
-+ const char *name)
-+
-+{
-+ struct aa_policy_common *common;
-+
-+ list_for_each_entry(common, head, list) {
-+ if (!strcmp(common->name, name))
-+ return common;
-+ }
-+ return NULL;
-+}
-+
-+static struct aa_policy_common *__common_find_strn(struct list_head *head,
-+ const char *str, int len)
-+{
-+ struct aa_policy_common *common;
-+
-+ list_for_each_entry(common, head, list) {
-+ if (aa_strneq(common->name, str, len))
-+ return common;
-+ }
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Routines for AppArmor namespaces
-+ */
-+
-+int alloc_default_namespace(void)
-+{
-+ struct aa_namespace *ns;
-+ ns = alloc_aa_namespace("default");
-+ if (!ns)
-+ return -ENOMEM;
-+
-+ default_namespace = aa_get_namespace(ns);
-+ write_lock(&ns_list_lock);
-+ list_add(&ns->base.list, &ns_list);
-+ write_unlock(&ns_list_lock);
-+
-+ return 0;
-+}
-+
-+void free_default_namespace(void)
-+{
-+ write_lock(&ns_list_lock);
-+ list_del_init(&default_namespace->base.list);
-+ aa_put_namespace(default_namespace);
-+ write_unlock(&ns_list_lock);
-+ aa_put_namespace(default_namespace);
-+ default_namespace = NULL;
-+}
-+
-+/**
-+ * alloc_aa_namespace - allocate, initialize and return a new namespace
-+ * @name: a preallocated name
-+ * Returns NULL on failure.
-+ */
-+struct aa_namespace *alloc_aa_namespace(const char *name)
-+{
-+ struct aa_namespace *ns;
-+
-+ ns = kzalloc(sizeof(*ns), GFP_KERNEL);
-+ AA_DEBUG("%s(%p)\n", __func__, ns);
-+ if (!ns)
-+ return NULL;
-+
-+ if (!common_init(&ns->base, name))
-+ goto fail_ns;
-+
-+ /* null profile is not added to the profile list */
-+ ns->unconfined = alloc_aa_profile("unconfined");
-+ if (!ns->unconfined)
-+ goto fail_unconfined;
-+
-+ ns->unconfined->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
-+ ns->unconfined->flags = PFLAG_UNCONFINED | PFLAG_IX_ON_NAME_ERROR |
-+ PFLAG_IMMUTABLE;
-+ ns->unconfined->ns = aa_get_namespace(ns);
-+
-+ return ns;
-+
-+fail_unconfined:
-+ if (ns->base.name)
-+ kfree(ns->base.name);
-+fail_ns:
-+ kfree(ns);
-+ return NULL;
-+}
-+
-+/**
-+ * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
-+ * @kr: kref callback for freeing of a namespace
-+ */
-+void free_aa_namespace_kref(struct kref *kref)
-+{
-+ free_aa_namespace(container_of(kref, struct aa_namespace, base.count));
-+}
-+
-+/**
-+ * free_aa_namespace - free a profile namespace
-+ * @namespace: the namespace to free
-+ *
-+ * Free a namespace. All references to the namespace must have been put.
-+ * If the namespace was referenced by a profile confining a task,
-+ */
-+void free_aa_namespace(struct aa_namespace *ns)
-+{
-+ if (!ns)
-+ return;
-+
-+ common_free(&ns->base);
-+
-+ if (ns->unconfined && ns->unconfined->ns == ns)
-+ ns->unconfined->ns = NULL;
-+
-+ aa_put_profile(ns->unconfined);
-+ memset(ns, 0, sizeof(*ns));
-+ kfree(ns);
-+}
-+
-+struct aa_namespace *__aa_find_namespace(struct list_head *head,
-+ const char *name)
-+
-+{
-+ return (struct aa_namespace *) __common_find(head, name);
-+}
-+
-+/**
-+ * aa_find_namespace - look up a profile namespace on the namespace list
-+ * @name: name of namespace to find
-+ *
-+ * Returns a pointer to the namespace on the list, or NULL if no namespace
-+ * called @name exists.
-+ */
-+struct aa_namespace *aa_find_namespace(const char *name)
-+{
-+ struct aa_namespace *ns = NULL;
-+
-+ read_lock(&ns_list_lock);
-+ ns = aa_get_namespace(__aa_find_namespace(&ns_list, name));
-+ read_unlock(&ns_list_lock);
-+
-+ return ns;
-+}
-+
-+static struct aa_namespace *__aa_find_namespace_by_strn(struct list_head *head,
-+ const char *name,
-+ int len)
-+{
-+ return (struct aa_namespace *) __common_find_strn(head, name, len);
-+}
-+
-+struct aa_namespace *aa_find_namespace_by_strn(const char *name, int len)
-+{
-+ struct aa_namespace *ns = NULL;
-+
-+ read_lock(&ns_list_lock);
-+ ns = aa_get_namespace(__aa_find_namespace_by_strn(&ns_list, name, len));
-+ read_unlock(&ns_list_lock);
-+
-+ return ns;
-+}
-+
-+/**
-+ * aa_prepare_namespace - find an existing or create a new namespace of @name
-+ * @name: the namespace to find or add
-+ */
-+struct aa_namespace *aa_prepare_namespace(const char *name)
-+{
-+ struct aa_namespace *ns;
-+
-+ write_lock(&ns_list_lock);
-+ if (name)
-+ ns = aa_get_namespace(__aa_find_namespace(&ns_list, name));
-+ else
-+ ns = aa_get_namespace(default_namespace);
-+ if (!ns) {
-+ struct aa_namespace *new_ns;
-+ write_unlock(&ns_list_lock);
-+ new_ns = alloc_aa_namespace(name);
-+ if (!new_ns)
-+ return NULL;
-+ write_lock(&ns_list_lock);
-+ ns = __aa_find_namespace(&ns_list, name);
-+ if (!ns) {
-+ list_add(&new_ns->base.list, &ns_list);
-+ ns = new_ns;
-+ } else {
-+ /* raced so free the new one */
-+ free_aa_namespace(new_ns);
-+ aa_get_namespace(ns);
-+ }
-+ }
-+ write_unlock(&ns_list_lock);
-+
-+ return ns;
-+}
-+
-+/*
-+ * requires profile->ns set first, takes profiles refcount
-+ * TODO: add accounting
-+ */
-+void __aa_add_profile(struct aa_policy_common *common,
-+ struct aa_profile *profile)
-+{
-+ list_add(&profile->base.list, &common->profiles);
-+ if (!(profile->flags & PFLAG_NO_LIST_REF))
-+ aa_get_profile(profile);
-+}
-+
-+void __aa_remove_profile(struct aa_profile *profile,
-+ struct aa_profile *replacement)
-+{
-+ if (replacement)
-+ profile->replacedby = aa_get_profile(replacement);
-+ else
-+ profile->replacedby = ERR_PTR(-EINVAL);
-+ list_del_init(&profile->base.list);
-+ if (!(profile->flags & PFLAG_NO_LIST_REF))
-+ aa_put_profile(profile);
-+}
-+
-+/* TODO: add accounting */
-+void __aa_replace_profile(struct aa_profile *profile,
-+ struct aa_profile *replacement)
-+{
-+ if (replacement) {
-+ struct aa_policy_common *common;
-+
-+ if (profile->parent)
-+ common = &profile->parent->base;
-+ else
-+ common = &profile->ns->base;
-+
-+ __aa_remove_profile(profile, replacement);
-+ __aa_add_profile(common, replacement);
-+ } else
-+ __aa_remove_profile(profile, NULL);
-+}
-+
-+/**
-+ * __aa_profile_list_release - remove all profiles on the list and put refs
-+ * @head: list of profiles
-+ */
-+void __aa_profile_list_release(struct list_head *head)
-+{
-+ struct aa_profile *profile, *tmp;
-+ list_for_each_entry_safe(profile, tmp, head, base.list) {
-+ __aa_profile_list_release(&profile->base.profiles);
-+ __aa_remove_profile(profile, NULL);
-+ }
-+}
-+
-+void __aa_remove_namespace(struct aa_namespace *ns)
-+{
-+ struct aa_profile *unconfined = ns->unconfined;
-+ list_del_init(&ns->base.list);
-+
-+ /*
-+ * break the ns, unconfined profile cyclic reference and forward
-+ * all new unconfined profiles requests to the default namespace
-+ */
-+ ns->unconfined = aa_get_profile(default_namespace->unconfined);
-+ __aa_profile_list_release(&ns->base.profiles);
-+ aa_put_profile(unconfined);
-+ aa_put_namespace(ns);
-+}
-+
-+/**
-+ * aa_remove_namespace = Remove namespace from the list
-+ * @ns: namespace to remove
-+ */
-+void aa_remove_namespace(struct aa_namespace *ns)
-+{
-+ write_lock(&ns_list_lock);
-+ write_lock(&ns->base.lock);
-+ __aa_remove_namespace(ns);
-+ write_unlock(&ns->base.lock);
-+ write_unlock(&ns_list_lock);
-+}
-+
-+/**
-+ * aa_profilelist_release - remove all namespaces and all associated profiles
-+ */
-+void aa_profile_ns_list_release(void)
-+{
-+ struct aa_namespace *ns, *tmp;
-+
-+ /* Remove and release all the profiles on namespace profile lists. */
-+ write_lock(&ns_list_lock);
-+ list_for_each_entry_safe(ns, tmp, &ns_list, base.list) {
-+ write_lock(&ns->base.lock);
-+ __aa_remove_namespace(ns);
-+ write_unlock(&ns->base.lock);
-+ }
-+ write_unlock(&ns_list_lock);
-+}
-+
-+/**
-+ * alloc_aa_profile - allocate, initialize and return a new profile
-+ * @fqname: name of the profile
-+ *
-+ * Returns NULL on failure.
-+ */
-+struct aa_profile *alloc_aa_profile(const char *fqname)
-+{
-+ struct aa_profile *profile;
-+
-+ profile = kzalloc(sizeof(*profile), GFP_KERNEL);
-+ if (!profile)
-+ return NULL;
-+
-+ if (!common_init(&profile->base, fqname)) {
-+ kfree(profile);
-+ return NULL;
-+ }
-+
-+ profile->fqname = profile->base.name;
-+ profile->base.name = (char *) fqname_subname((const char *) profile->fqname);
-+ return profile;
-+}
-+
-+/**
-+ * aa_new_null_profile - create a new null-X learning profile
-+ * @parent: profile that caused this profile to be created
-+ * @hat: true if the null- learning profile is a hat
-+ *
-+ * Create a null- complain mode profile used in learning mode. The name of
-+ * the profile is unique and follows the format of parent//null-sid.
-+ *
-+ * null profiles are added to the profile list but the list does not
-+ * hold a count on them so that they are automatically released when
-+ * not in use.
-+ */
-+struct aa_profile *aa_alloc_null_profile(struct aa_profile *parent, int hat)
-+{
-+ struct aa_profile *profile = NULL;
-+ char *name;
-+ u32 sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
-+
-+ name = kmalloc(strlen(parent->fqname) + 2 + 7 + 8, GFP_KERNEL);
-+ if (!name)
-+ goto fail;
-+ sprintf(name, "%s//null-%x", parent->fqname, sid);
-+
-+ profile = alloc_aa_profile(name);
-+ kfree(name);
-+ if (!profile)
-+ goto fail;
-+
-+ profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
-+ profile->mode = APPARMOR_COMPLAIN;
-+ profile->flags = PFLAG_NULL | PFLAG_NO_LIST_REF;
-+ if (hat)
-+ profile->flags |= PFLAG_HAT;
-+
-+ profile->parent = aa_get_profile(parent);
-+ profile->ns = aa_get_namespace(parent->ns);
-+
-+ write_lock(&profile->ns->base.lock);
-+ __aa_add_profile(&parent->base, profile);
-+ write_unlock(&profile->ns->base.lock);
-+
-+ return profile;
-+
-+fail:
-+ aa_free_sid(sid);
-+ return NULL;
-+}
-+
-+/**
-+ * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile)
-+ * @kr: kref callback for freeing of a profile
-+ */
-+void free_aa_profile_kref(struct kref *kref)
-+{
-+ struct aa_profile *p = container_of(kref, struct aa_profile,
-+ base.count);
-+
-+ free_aa_profile(p);
-+}
-+
-+/**
-+ * free_aa_profile - free a profile
-+ * @profile: the profile to free
-+ *
-+ * Free a profile, its hats and null_profile. All references to the profile,
-+ * its hats and null_profile must have been put.
-+ *
-+ * If the profile was referenced from a task context, free_aa_profile() will
-+ * be called from an rcu callback routine, so we must not sleep here.
-+ */
-+void free_aa_profile(struct aa_profile *profile)
-+{
-+ AA_DEBUG("%s(%p)\n", __func__, profile);
-+
-+ if (!profile)
-+ return;
-+
-+ /*
-+ * profile can still be on the list if the list doesn't hold a
-+ * reference. There is no race as NULL profiles can't be attached
-+ */
-+ if (!list_empty(&profile->base.list)) {
-+ if ((profile->flags & PFLAG_NULL) && profile->ns) {
-+ write_lock(&profile->ns->base.lock);
-+ list_del_init(&profile->base.list);
-+ write_unlock(&profile->ns->base.lock);
-+ } else {
-+ AA_ERROR("%s: internal error, "
-+ "profile '%s' still on ns list\n",
-+ __func__, profile->base.name);
-+ BUG();
-+ }
-+ }
-+
-+ /* profile->name is a substring of fqname */
-+ profile->base.name = NULL;
-+ common_free(&profile->base);
-+
-+ BUG_ON(!list_empty(&profile->base.profiles));
-+
-+ kfree(profile->fqname);
-+
-+ aa_put_namespace(profile->ns);
-+ aa_put_profile(profile->parent);
-+
-+ aa_free_file_rules(&profile->file);
-+ aa_free_cap_rules(&profile->caps);
-+ aa_free_net_rules(&profile->net);
-+ aa_free_rlimit_rules(&profile->rlimits);
-+
-+ aa_free_sid(profile->sid);
-+ aa_match_free(profile->xmatch);
-+
-+ if (profile->replacedby && !PTR_ERR(profile->replacedby))
-+ aa_put_profile(profile->replacedby);
-+
-+ memset(profile, 0, sizeof(profile));
-+ kfree(profile);
-+}
-+
-+
-+/* TODO: profile count accounting - setup in remove */
-+
-+
-+struct aa_profile *__aa_find_profile(struct list_head *head, const char *name)
-+{
-+ return (struct aa_profile *) __common_find(head, name);
-+}
-+
-+struct aa_profile *__aa_find_profile_by_strn(struct list_head *head,
-+ const char *name, int len)
-+{
-+ return (struct aa_profile *) __common_find_strn(head, name, len);
-+}
-+
-+
-+/**
-+ * aa_find_child - find a profile by @name in @parent
-+ * @parent: profile to search
-+ * @name: profile name to search for
-+ *
-+ * Returns a ref counted profile or NULL if not found
-+ */
-+struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name)
-+{
-+ struct aa_profile *profile;
-+
-+ read_lock(&parent->ns->base.lock);
-+ profile = aa_get_profile(__aa_find_profile(&parent->base.profiles,
-+ name));
-+ read_unlock(&parent->ns->base.lock);
-+
-+ return profile;
-+}
-+
-+
-+struct aa_policy_common *__aa_find_parent_by_fqname(struct aa_namespace *ns,
-+ const char *fqname)
-+{
-+ struct aa_policy_common *common;
-+ struct aa_profile *profile = NULL;
-+ char *split;
-+
-+ common = &ns->base;
-+
-+
-+ for (split = strstr(fqname, "//"); split; ) {
-+ profile = __aa_find_profile_by_strn(&common->profiles, fqname,
-+ split - fqname);
-+ if (!profile)
-+ return NULL;
-+ common = &profile->base;
-+ fqname = split + 2;
-+ split = strstr(fqname, "//");
-+ }
-+ if (!profile)
-+ return &ns->base;
-+ return &profile->base;
-+}
-+
-+struct aa_profile *__aa_find_profile_by_fqname(struct aa_namespace *ns,
-+ const char *fqname)
-+{
-+ struct aa_policy_common *common;
-+ struct aa_profile *profile = NULL;
-+ char *split;
-+
-+ common = &ns->base;
-+ for (split = strstr(fqname, "//"); split; ) {
-+ profile = __aa_find_profile_by_strn(&common->profiles, fqname,
-+ split - fqname);
-+ if (!profile)
-+ return NULL;
-+
-+ common = &profile->base;
-+ fqname = split + 2;
-+ split = strstr(fqname, "//");
-+ }
-+
-+ profile = __aa_find_profile(&common->profiles, fqname);
-+
-+ return profile;
-+}
-+
-+/**
-+ * aa_find_profile_by_name - find a profile by its full or partial name
-+ * @ns: the namespace to start from
-+ * @fqname: name to do lookup on. Does not contain namespace prefix
-+ */
-+struct aa_profile *aa_find_profile_by_fqname(struct aa_namespace *ns,
-+ const char *fqname)
-+{
-+ struct aa_profile *profile;
-+
-+ read_lock(&ns->base.lock);
-+ profile = aa_get_profile(__aa_find_profile_by_fqname(ns, fqname));
-+ read_unlock(&ns->base.lock);
-+ return profile;
-+}
-+
-+
-+/* __aa_attach_match_ - find an attachment match
-+ * @name - to match against
-+ * @head - profile list to walk
-+ *
-+ * Do a linear search on the profiles in the list. There is a matching
-+ * preference where an exact match is prefered over a name which uses
-+ * expressions to match, and matching expressions with the greatest
-+ * xmatch_len are prefered.
-+ */
-+static struct aa_profile *__aa_attach_match(const char *name,
-+ struct list_head *head)
-+{
-+ int len = 0;
-+ struct aa_profile *profile, *candidate = NULL;
-+
-+ list_for_each_entry(profile, head, base.list) {
-+ if (profile->flags & PFLAG_NULL)
-+ continue;
-+ if (profile->xmatch && profile->xmatch_len > len) {
-+ unsigned int state = aa_dfa_match(profile->xmatch,
-+ DFA_START, name);
-+ /* any accepting state means a valid match */
-+ if (state > DFA_START) {
-+ candidate = profile;
-+ len = profile->xmatch_len;
-+ }
-+ } else if (!strcmp(profile->base.name, name))
-+ /* exact non-re match, no more searching required */
-+ return profile;
-+ }
-+
-+ return candidate;
-+}
-+
-+/**
-+ * aa_sys_find_attach - do attachment search for sys unconfined processes
-+ * @ns: the namespace to search
-+ * name: the executable name to match against
-+ */
-+struct aa_profile *aa_sys_find_attach(struct aa_namespace *ns, const char *name)
-+{
-+ struct aa_profile *profile;
-+
-+ read_lock(&ns->base.lock);
-+ profile = aa_get_profile(__aa_attach_match(name, &ns->base.profiles));
-+ read_unlock(&ns->base.lock);
-+
-+ return profile;
-+}
-+
-+/**
-+ * aa_profile_newest - find the newest version of @profile
-+ * @profile: the profile to check for newer versions of
-+ *
-+ * Find the newest version of @profile, if @profile is the newest version
-+ * return @profile. If @profile has been removed return NULL.
-+ *
-+ * NOTE: the profile returned is not refcounted, The refcount on @profile
-+ * must be held until the caller decides what to do with the returned newest
-+ * version.
-+ */
-+struct aa_profile *aa_profile_newest(struct aa_profile *profile)
-+{
-+ if (unlikely(profile && profile->replacedby)) {
-+ for (;profile->replacedby; profile = profile->replacedby) {
-+ if (IS_ERR(profile->replacedby)) {
-+ /* profile has been removed */
-+ profile = NULL;
-+ break;
-+ }
-+ }
-+ }
-+
-+ return profile;
-+}
-+
-diff --git a/security/apparmor/policy_interface.c b/security/apparmor/policy_interface.c
-new file mode 100644
-index 0000000..24277dc
---- /dev/null
-+++ b/security/apparmor/policy_interface.c
-@@ -0,0 +1,850 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor functions for unpacking policy loaded from
-+ * userspace.
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ *
-+ * AppArmor uses a serialized binary format for loading policy.
-+ * The policy format is documented in Documentation/???
-+ * All policy is validated all before it is used.
-+ */
-+
-+#include <asm/unaligned.h>
-+#include <linux/errno.h>
-+
-+#include "include/apparmor.h"
-+#include "include/audit.h"
-+#include "include/context.h"
-+#include "include/match.h"
-+#include "include/policy.h"
-+#include "include/policy_interface.h"
-+#include "include/sid.h"
-+
-+/* FIXME: convert profiles to internal hieracy, accounting
-+ * FIXME: have replacement routines set replaced_by profile instead of error
-+ * FIXME: name mapping to hierarchy
-+ */
-+
-+/*
-+ * The AppArmor interface treats data as a type byte followed by the
-+ * actual data. The interface has the notion of a a named entry
-+ * which has a name (AA_NAME typecode followed by name string) followed by
-+ * the entries typecode and data. Named types allow for optional
-+ * elements and extensions to be added and tested for without breaking
-+ * backwards compatability.
-+ */
-+
-+enum aa_code {
-+ AA_U8,
-+ AA_U16,
-+ AA_U32,
-+ AA_U64,
-+ AA_NAME, /* same as string except it is items name */
-+ AA_STRING,
-+ AA_BLOB,
-+ AA_STRUCT,
-+ AA_STRUCTEND,
-+ AA_LIST,
-+ AA_LISTEND,
-+ AA_ARRAY,
-+ AA_ARRAYEND,
-+};
-+
-+/*
-+ * aa_ext is the read of the buffer containing the serialized profile. The
-+ * data is copied into a kernel buffer in apparmorfs and then handed off to
-+ * the unpack routines.
-+ */
-+struct aa_ext {
-+ void *start;
-+ void *end;
-+ void *pos; /* pointer to current position in the buffer */
-+ u32 version;
-+ char *ns_name;
-+};
-+
-+
-+struct aa_audit_iface {
-+ struct aa_audit base;
-+
-+ const char *name;
-+ const char *name2;
-+ const struct aa_ext *e;
-+};
-+
-+static void aa_audit_init(struct aa_audit_iface *sa, const char *operation,
-+ struct aa_ext *e)
-+{
-+ memset(sa, 0, sizeof(*sa));
-+ sa->base.operation = operation;
-+ sa->base.gfp_mask = GFP_KERNEL;
-+ sa->e = e;
-+}
-+
-+static void audit_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct aa_audit_iface *sa = va;
-+
-+ if (sa->name)
-+ audit_log_format(ab, " name=%s", sa->name);
-+ if (sa->name2)
-+ audit_log_format(ab, " namespace=%s", sa->name2);
-+ if (sa->base.error && sa->e)
-+ audit_log_format(ab, " offset=%d", sa->e->pos - sa->e->start);
-+}
-+
-+static int aa_audit_iface(struct aa_audit_iface *sa)
-+{
-+ struct aa_profile *profile;
-+ struct cred *cred = aa_get_task_policy(current, &profile);
-+ int error = aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa->base,
-+ audit_cb);
-+ put_cred(cred);
-+ return error;
-+}
-+
-+static int aa_inbounds(struct aa_ext *e, size_t size)
-+{
-+ return (size <= e->end - e->pos);
-+}
-+
-+/**
-+ * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
-+ * @e: serialized data read head
-+ * @chunk: start address for chunk of data
-+ *
-+ * return the size of chunk found with the read head at the end of
-+ * the chunk.
-+ */
-+static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk)
-+{
-+ void *pos = e->pos;
-+ size_t size = 0;
-+
-+ if (!aa_inbounds(e, sizeof(u16)))
-+ goto fail;
-+ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
-+ e->pos += sizeof(u16);
-+ if (!aa_inbounds(e, size))
-+ goto fail;
-+ *chunk = e->pos;
-+ e->pos += size;
-+ return size;
-+
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static int aa_is_X(struct aa_ext *e, enum aa_code code)
-+{
-+ if (!aa_inbounds(e, 1))
-+ return 0;
-+ if (*(u8 *) e->pos != code)
-+ return 0;
-+ e->pos++;
-+ return 1;
-+}
-+
-+/**
-+ * aa_is_nameX - check is the next element is of type X with a name of @name
-+ * @e: serialized data extent information
-+ * @code: type code
-+ * @name: name to match to the serialized element.
-+ *
-+ * check that the next serialized data element is of type X and has a tag
-+ * name @name. If @name is specified then there must be a matching
-+ * name element in the stream. If @name is NULL any name element will be
-+ * skipped and only the typecode will be tested.
-+ * returns 1 on success (both type code and name tests match) and the read
-+ * head is advanced past the headers
-+ * returns %0 if either match failes, the read head does not move
-+ */
-+static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name)
-+{
-+ void *pos = e->pos;
-+ /*
-+ * Check for presence of a tagname, and if present name size
-+ * AA_NAME tag value is a u16.
-+ */
-+ if (aa_is_X(e, AA_NAME)) {
-+ char *tag = NULL;
-+ size_t size = aa_is_u16_chunk(e, &tag);
-+ /* if a name is specified it must match. otherwise skip tag */
-+ if (name && (!size || strcmp(name, tag)))
-+ goto fail;
-+ } else if (name) {
-+ /* if a name is specified and there is no name tag fail */
-+ goto fail;
-+ }
-+
-+ /* now check if type code matches */
-+ if (aa_is_X(e, code))
-+ return 1;
-+
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name)
-+{
-+ void *pos = e->pos;
-+ if (aa_is_nameX(e, AA_U16, name)) {
-+ if (!aa_inbounds(e, sizeof(u16)))
-+ goto fail;
-+ if (data)
-+ *data = le16_to_cpu(get_unaligned((u16 *)e->pos));
-+ e->pos += sizeof(u16);
-+ return 1;
-+ }
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name)
-+{
-+ void *pos = e->pos;
-+ if (aa_is_nameX(e, AA_U32, name)) {
-+ if (!aa_inbounds(e, sizeof(u32)))
-+ goto fail;
-+ if (data)
-+ *data = le32_to_cpu(get_unaligned((u32 *)e->pos));
-+ e->pos += sizeof(u32);
-+ return 1;
-+ }
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name)
-+{
-+ void *pos = e->pos;
-+ if (aa_is_nameX(e, AA_U64, name)) {
-+ if (!aa_inbounds(e, sizeof(u64)))
-+ goto fail;
-+ if (data)
-+ *data = le64_to_cpu(get_unaligned((u64 *)e->pos));
-+ e->pos += sizeof(u64);
-+ return 1;
-+ }
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static size_t aa_is_array(struct aa_ext *e, const char *name)
-+{
-+ void *pos = e->pos;
-+ if (aa_is_nameX(e, AA_ARRAY, name)) {
-+ int size;
-+ if (!aa_inbounds(e, sizeof(u16)))
-+ goto fail;
-+ size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos));
-+ e->pos += sizeof(u16);
-+ return size;
-+ }
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name)
-+{
-+ void *pos = e->pos;
-+ if (aa_is_nameX(e, AA_BLOB, name)) {
-+ u32 size;
-+ if (!aa_inbounds(e, sizeof(u32)))
-+ goto fail;
-+ size = le32_to_cpu(get_unaligned((u32 *)e->pos));
-+ e->pos += sizeof(u32);
-+ if (aa_inbounds(e, (size_t) size)) {
-+ *blob = e->pos;
-+ e->pos += size;
-+ return size;
-+ }
-+ }
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static int aa_is_string(struct aa_ext *e, char **string, const char *name)
-+{
-+ char *src_str;
-+ size_t size = 0;
-+ void *pos = e->pos;
-+ *string = NULL;
-+ if (aa_is_nameX(e, AA_STRING, name) &&
-+ (size = aa_is_u16_chunk(e, &src_str))) {
-+ /* strings are null terminated, length is size - 1 */
-+ if (src_str[size - 1] != 0)
-+ goto fail;
-+ *string = src_str;
-+ }
-+
-+ return size;
-+
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name)
-+{
-+ char *tmp;
-+ void *pos = e->pos;
-+ int res = aa_is_string(e, &tmp, name);
-+ *string = NULL;
-+
-+ if (!res)
-+ return res;
-+
-+ *string = kstrdup(tmp, GFP_KERNEL);
-+ if (!*string) {
-+ e->pos = pos;
-+ return 0;
-+ }
-+
-+ return res;
-+}
-+
-+/**
-+ * aa_unpack_dfa - unpack a file rule dfa
-+ * @e: serialized data extent information
-+ *
-+ * returns dfa or ERR_PTR
-+ */
-+static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e)
-+{
-+ char *blob = NULL;
-+ size_t size, error = 0;
-+ struct aa_dfa *dfa = NULL;
-+
-+ size = aa_is_blob(e, &blob, "aadfa");
-+ if (size) {
-+ dfa = aa_match_alloc();
-+ if (dfa) {
-+ /*
-+ * The dfa is aligned with in the blob to 8 bytes
-+ * from the beginning of the stream.
-+ */
-+ size_t sz = blob - (char *) e->start;
-+ size_t pad = ALIGN(sz, 8) - sz;
-+ error = unpack_dfa(dfa, blob + pad, size - pad);
-+ if (!error)
-+ error = verify_dfa(dfa);
-+ } else {
-+ error = -ENOMEM;
-+ }
-+
-+ if (error) {
-+ aa_match_free(dfa);
-+ dfa = ERR_PTR(error);
-+ }
-+ }
-+
-+ return dfa;
-+}
-+
-+static int aa_unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
-+{
-+ void *pos = e->pos;
-+
-+ /* exec table is optional */
-+ if (aa_is_nameX(e, AA_STRUCT, "xtable")) {
-+ int i, size;
-+
-+ size = aa_is_array(e, NULL);
-+ /* currently 4 exec bits and entries 0-3 are reserved iupcx */
-+ if (size > 16 - 4)
-+ goto fail;
-+ profile->file.trans.table = kzalloc(sizeof(char *) * size,
-+ GFP_KERNEL);
-+ if (!profile->file.trans.table)
-+ goto fail;
-+
-+ for (i = 0; i < size; i++) {
-+ char *tmp;
-+ if (!aa_is_dynstring(e, &tmp, NULL))
-+ goto fail;
-+ /* note: strings beginning with a : have an embedded
-+ \0 seperating the profile ns name from the profile
-+ name */
-+ profile->file.trans.table[i] = tmp;
-+ }
-+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
-+ goto fail;
-+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
-+ goto fail;
-+ profile->file.trans.size = size;
-+ }
-+ return 1;
-+
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
-+{
-+ void *pos = e->pos;
-+
-+ /* rlimits are optional */
-+ if (aa_is_nameX(e, AA_STRUCT, "rlimits")) {
-+ int i, size;
-+ u32 tmp = 0;
-+ if (!aa_is_u32(e, &tmp, NULL))
-+ goto fail;
-+ profile->rlimits.mask = tmp;
-+
-+ size = aa_is_array(e, NULL);
-+ if (size > RLIM_NLIMITS)
-+ goto fail;
-+ for (i = 0; i < size; i++) {
-+ u64 tmp = 0;
-+ if (!aa_is_u64(e, &tmp, NULL))
-+ goto fail;
-+ profile->rlimits.limits[i].rlim_max = tmp;
-+ }
-+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
-+ goto fail;
-+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
-+ goto fail;
-+ }
-+ return 1;
-+
-+fail:
-+ e->pos = pos;
-+ return 0;
-+}
-+
-+/**
-+ * aa_unpack_profile - unpack a serialized profile
-+ * @e: serialized data extent information
-+ * @sa: audit struct for the operation
-+ */
-+static struct aa_profile *aa_unpack_profile(struct aa_ext *e,
-+ struct aa_audit_iface *sa)
-+{
-+ struct aa_profile *profile = NULL;
-+ char *name;
-+ size_t size = 0;
-+ int i, error = -EPROTO;
-+ u32 tmp;
-+
-+ /* check that we have the right struct being passed */
-+ if (!aa_is_nameX(e, AA_STRUCT, "profile"))
-+ goto fail;
-+ if (!aa_is_string(e, &name, NULL))
-+ goto fail;
-+
-+ profile = alloc_aa_profile(name);
-+ if (!profile)
-+ return ERR_PTR(-ENOMEM);
-+
-+ /* xmatch is optional and may be NULL */
-+ profile->xmatch = aa_unpack_dfa(e);
-+ if (IS_ERR(profile->xmatch)) {
-+ error = PTR_ERR(profile->xmatch);
-+ profile->xmatch = NULL;
-+ goto fail;
-+ }
-+ /* xmatch_len is not optional is xmatch is set */
-+ if (profile->xmatch && !aa_is_u32(e, &tmp, NULL))
-+ goto fail;
-+ profile->xmatch_len = tmp;
-+
-+ /* per profile debug flags (complain, audit) */
-+ if (!aa_is_nameX(e, AA_STRUCT, "flags"))
-+ goto fail;
-+ if (!aa_is_u32(e, &tmp, NULL))
-+ goto fail;
-+ if (tmp)
-+ profile->flags |= PFLAG_HAT;
-+ if (!aa_is_u32(e, &tmp, NULL))
-+ goto fail;
-+ if (tmp)
-+ profile->mode = APPARMOR_COMPLAIN;
-+ if (!aa_is_u32(e, &tmp, NULL))
-+ goto fail;
-+ if (tmp)
-+ profile->audit = AUDIT_ALL;
-+
-+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
-+ goto fail;
-+
-+ if (!aa_is_u32(e, &(profile->caps.allowed.cap[0]), NULL))
-+ goto fail;
-+ if (!aa_is_u32(e, &(profile->caps.audit.cap[0]), NULL))
-+ goto fail;
-+ if (!aa_is_u32(e, &(profile->caps.quiet.cap[0]), NULL))
-+ goto fail;
-+ if (!aa_is_u32(e, &(profile->caps.set.cap[0]), NULL))
-+ goto fail;
-+
-+ if (aa_is_nameX(e, AA_STRUCT, "caps64")) {
-+ /* optional upper half of 64 bit caps */
-+ if (!aa_is_u32(e, &(profile->caps.allowed.cap[1]), NULL))
-+ goto fail;
-+ if (!aa_is_u32(e, &(profile->caps.audit.cap[1]), NULL))
-+ goto fail;
-+ if (!aa_is_u32(e, &(profile->caps.quiet.cap[1]), NULL))
-+ goto fail;
-+ if (!aa_is_u32(e, &(profile->caps.set.cap[1]), NULL))
-+ goto fail;
-+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
-+ goto fail;
-+ }
-+
-+ if (!aa_unpack_rlimits(e, profile))
-+ goto fail;
-+
-+ size = aa_is_array(e, "net_allowed_af");
-+ if (size) {
-+ if (size > AF_MAX)
-+ goto fail;
-+
-+ for (i = 0; i < size; i++) {
-+ if (!aa_is_u16(e, &profile->net.allowed[i], NULL))
-+ goto fail;
-+ if (!aa_is_u16(e, &profile->net.audit[i], NULL))
-+ goto fail;
-+ if (!aa_is_u16(e, &profile->net.quiet[i], NULL))
-+ goto fail;
-+ }
-+ if (!aa_is_nameX(e, AA_ARRAYEND, NULL))
-+ goto fail;
-+ /* allow unix domain and netlink sockets they are handled
-+ * by IPC
-+ */
-+ }
-+ profile->net.allowed[AF_UNIX] = 0xffff;
-+ profile->net.allowed[AF_NETLINK] = 0xffff;
-+
-+ /* get file rules */
-+ profile->file.dfa = aa_unpack_dfa(e);
-+ if (IS_ERR(profile->file.dfa)) {
-+ error = PTR_ERR(profile->file.dfa);
-+ profile->file.dfa = NULL;
-+ goto fail;
-+ }
-+
-+ if (!aa_unpack_trans_table(e, profile))
-+ goto fail;
-+
-+ if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
-+ goto fail;
-+
-+ return profile;
-+
-+fail:
-+ sa->name = profile && profile->base.name ? profile->base.name :
-+ "unknown";
-+ if (!sa->base.info)
-+ sa->base.info = "failed to unpack profile";
-+ aa_audit_iface(sa);
-+
-+ free_aa_profile(profile);
-+
-+ return ERR_PTR(error);
-+}
-+
-+/**
-+ * aa_verify_head - unpack serialized stream header
-+ * @e: serialized data read head
-+ * @operation: operation header is being verified for
-+ *
-+ * returns error or 0 if header is good
-+ */
-+static int aa_verify_header(struct aa_ext *e, struct aa_audit_iface *sa)
-+{
-+ /* get the interface version */
-+ if (!aa_is_u32(e, &e->version, "version")) {
-+ sa->base.info = "invalid profile format";
-+ aa_audit_iface(sa);
-+ return -EPROTONOSUPPORT;
-+ }
-+
-+ /* check that the interface version is currently supported */
-+ if (e->version != 5) {
-+ sa->base.info = "unsupported interface version";
-+ aa_audit_iface(sa);
-+ return -EPROTONOSUPPORT;
-+ }
-+
-+ /* read the namespace if present */
-+ if (!aa_is_string(e, &e->ns_name, "namespace"))
-+ e->ns_name = NULL;
-+
-+ return 0;
-+}
-+
-+
-+
-+/**
-+ * aa_interface_add_profiles - Unpack and add new profile(s) to the profile list
-+ * @data: serialized data stream
-+ * @size: size of the serialized data stream
-+ */
-+ssize_t aa_interface_add_profiles(void *data, size_t size)
-+{
-+ struct aa_profile *profile;
-+ struct aa_namespace *ns = NULL;
-+ struct aa_policy_common *common;
-+ struct aa_ext e = {
-+ .start = data,
-+ .end = data + size,
-+ .pos = data,
-+ .ns_name = NULL
-+ };
-+ ssize_t error;
-+ struct aa_audit_iface sa;
-+ aa_audit_init(&sa, "profile_load", &e);
-+
-+ error = aa_verify_header(&e, &sa);
-+ if (error)
-+ return error;
-+
-+ profile = aa_unpack_profile(&e, &sa);
-+ if (IS_ERR(profile))
-+ return PTR_ERR(profile);
-+
-+ sa.name2 = e.ns_name;
-+ ns = aa_prepare_namespace(e.ns_name);
-+ if (IS_ERR(ns)) {
-+ sa.base.info = "failed to prepare namespace";
-+ sa.base.error = PTR_ERR(ns);
-+ goto fail;
-+ }
-+ /* profiles are currently loaded flat with fqnames */
-+ sa.name = profile->fqname;
-+
-+ write_lock(&ns->base.lock);
-+
-+ common = __aa_find_parent_by_fqname(ns, sa.name);
-+ if (!common) {
-+ sa.base.info = "parent does not exist";
-+ sa.base.error = -ENOENT;
-+ goto fail2;
-+ }
-+
-+ if (common != &ns->base)
-+ profile->parent = aa_get_profile((struct aa_profile *) common);
-+
-+ if (__aa_find_profile(&common->profiles, profile->base.name)) {
-+ /* A profile with this name exists already. */
-+ sa.base.info = "profile already exists";
-+ goto fail2;
-+ }
-+ profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
-+ profile->ns = aa_get_namespace(ns);
-+
-+ __aa_add_profile(common, profile);
-+ write_unlock(&ns->base.lock);
-+
-+ aa_audit_iface(&sa);
-+ aa_put_namespace(ns);
-+ kfree(e.ns_name);
-+ return size;
-+
-+fail2:
-+ write_unlock(&ns->base.lock);
-+ sa.base.error = -EEXIST;
-+
-+fail:
-+ error = aa_audit_iface(&sa);
-+ aa_put_namespace(ns);
-+ aa_put_profile(profile);
-+ kfree(e.ns_name);
-+ return error;
-+}
-+
-+/**
-+ * aa_interface_replace_profiles - replace profile(s) on the profile list
-+ * @udata: serialized data stream
-+ * @size: size of the serialized data stream
-+ *
-+ * unpack and replace a profile on the profile list and uses of that profile
-+ * by any aa_task_context. If the profile does not exist on the profile list
-+ * it is added. Return %0 or error.
-+ */
-+ssize_t aa_interface_replace_profiles(void *udata, size_t size)
-+{
-+ struct aa_policy_common *common;
-+ struct aa_profile *old_profile = NULL, *new_profile;
-+ struct aa_namespace *ns;
-+ struct aa_ext e = {
-+ .start = udata,
-+ .end = udata + size,
-+ .pos = udata,
-+ .ns_name = NULL
-+ };
-+ ssize_t error;
-+ struct aa_audit_iface sa;
-+ aa_audit_init(&sa, "profile_replace", &e);
-+
-+ if (g_apparmor_lock_policy)
-+ return -EACCES;
-+
-+ error = aa_verify_header(&e, &sa);
-+ if (error)
-+ return error;
-+
-+ new_profile = aa_unpack_profile(&e, &sa);
-+ if (IS_ERR(new_profile))
-+ return PTR_ERR(new_profile);
-+
-+ sa.name2 = e.ns_name;
-+ ns = aa_prepare_namespace(e.ns_name);
-+ if (!ns) {
-+ sa.base.info = "failed to prepare namespace";
-+ sa.base.error = -ENOMEM;
-+ goto fail;
-+ }
-+
-+ sa.name = new_profile->fqname;
-+
-+ write_lock(&ns->base.lock);
-+ common = __aa_find_parent_by_fqname(ns, sa.name);
-+
-+ if (!common) {
-+ sa.base.info = "parent does not exist";
-+ sa.base.error = -ENOENT;
-+ goto fail2;
-+ }
-+
-+ if (common != &ns->base)
-+ new_profile->parent = aa_get_profile((struct aa_profile *)
-+ common);
-+
-+ old_profile = __aa_find_profile(&common->profiles,
-+ new_profile->base.name);
-+ aa_get_profile(old_profile);
-+ if (old_profile && old_profile->flags & PFLAG_IMMUTABLE) {
-+ sa.base.info = "cannot replace immutible profile";
-+ sa.base.error = -EPERM;
-+ goto fail2;
-+ } else if (old_profile) {
-+ // __aa_profile_list_release(&old_profile->base.profiles);
-+ /* TODO: remove for new interface
-+ * move children profiles over to the new profile so
-+ * that replacement behaves correctly
-+ */
-+ // list_replace_init(&old_profile->base.profiles,
-+ // &new_profile->base.profiles);
-+ struct aa_profile *profile, *tmp;
-+ list_for_each_entry_safe(profile, tmp, &old_profile->base.profiles,
-+ base.list) {
-+ aa_put_profile(profile->parent);
-+ list_del(&profile->base.list);
-+ profile->parent = aa_get_profile(new_profile);
-+ list_add(&profile->base.list,
-+ &new_profile->base.profiles);
-+ }
-+ __aa_replace_profile(old_profile, new_profile);
-+ new_profile->sid = old_profile->sid;
-+ } else {
-+ __aa_add_profile(common, new_profile);
-+ new_profile->sid = aa_alloc_sid(AA_ALLOC_SYS_SID);
-+ }
-+
-+ new_profile->ns = aa_get_namespace(ns);
-+
-+ write_unlock(&ns->base.lock);
-+
-+ if (!old_profile)
-+ sa.base.operation = "profile_load";
-+
-+ aa_audit_iface(&sa);
-+ aa_put_namespace(ns);
-+ aa_put_profile(old_profile);
-+ kfree(e.ns_name);
-+ return size;
-+
-+fail2:
-+ write_unlock(&ns->base.lock);
-+fail:
-+ error = aa_audit_iface(&sa);
-+ aa_put_namespace(ns);
-+ aa_put_profile(old_profile);
-+ aa_put_profile(new_profile);
-+ kfree(e.ns_name);
-+ return error;
-+}
-+
-+/**
-+ * aa_interface_remove_profiles - remove profile(s) from the system
-+ * @name: name of the profile to remove
-+ * @size: size of the name
-+ *
-+ * remove a profile from the profile list and all aa_task_context references
-+ * to said profile.
-+ * NOTE: removing confinement does not restore rlimits to preconfinemnet values
-+ */
-+ssize_t aa_interface_remove_profiles(char *name, size_t size)
-+{
-+ struct aa_namespace *ns;
-+ struct aa_profile *profile;
-+ struct aa_audit_iface sa;
-+ aa_audit_init(&sa, "profile_remove", NULL);
-+
-+ if (g_apparmor_lock_policy)
-+ return -EACCES;
-+
-+ write_lock(&ns_list_lock);
-+ if (name[0] == ':') {
-+ char *ns_name;
-+ name = aa_split_name_from_ns(name, &ns_name);
-+ ns = __aa_find_namespace(&ns_list, ns_name);
-+ } else {
-+ ns = aa_get_namespace(default_namespace);
-+ }
-+
-+ if (!ns) {
-+ sa.base.info = "failed: namespace does not exist";
-+ goto fail_ns_list_lock;
-+ }
-+
-+ sa.name2 = ns->base.name;
-+ write_lock(&ns->base.lock);
-+ if (!name) {
-+ /* remove namespace */
-+ // __aa_remove_namespace(ns);
-+ } else {
-+ /* remove profile */
-+ profile = __aa_find_profile_by_fqname(ns, name);
-+ if (!profile) {
-+ sa.name = name;
-+ sa.base.info = "failed: profile does not exist";
-+ goto fail_ns_lock;
-+ }
-+ sa.name = profile->fqname;
-+ __aa_profile_list_release(&profile->base.profiles);
-+ __aa_remove_profile(profile, profile->ns->unconfined);
-+ }
-+ write_unlock(&ns->base.lock);
-+ write_unlock(&ns_list_lock);
-+
-+ aa_audit_iface(&sa);
-+ aa_put_namespace(ns);
-+ return size;
-+
-+fail_ns_lock:
-+ write_unlock(&ns->base.lock);
-+
-+fail_ns_list_lock:
-+ write_unlock(&ns_list_lock);
-+ aa_audit_iface(&sa);
-+ return 0; //-ENOENT;
-+}
-diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
-new file mode 100644
-index 0000000..834cfab
---- /dev/null
-+++ b/security/apparmor/procattr.c
-@@ -0,0 +1,117 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor /proc/<pid>/attr/ interface functions
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include "include/apparmor.h"
-+#include "include/policy.h"
-+#include "include/domain.h"
-+
-+/* FIXME show profile multiplexing */
-+int aa_getprocattr(struct aa_namespace *ns, struct aa_profile *profile,
-+ char **string)
-+{
-+ char *str;
-+ int len = 0;
-+
-+ if (profile) {
-+ int mode_len, name_len, ns_len = 0;
-+ const char *mode_str = profile_mode_names[profile->mode];
-+ char *s;
-+
-+ mode_len = strlen(mode_str) + 3; /* _(mode_str)\n */
-+ name_len = strlen(profile->fqname);
-+ if (ns != default_namespace)
-+ ns_len = strlen(ns->base.name) + 3;
-+ len = mode_len + ns_len + name_len + 1;
-+ s = str = kmalloc(len + 1, GFP_ATOMIC);
-+ if (!str)
-+ return -ENOMEM;
-+
-+ if (ns_len) {
-+ sprintf(s, "%s://", ns->base.name);
-+ s += ns_len;
-+ }
-+ memcpy(s, profile->fqname, name_len);
-+ s += name_len;
-+ sprintf(s, " (%s)\n", mode_str);
-+ } else {
-+ const char *unconfined_str = "unconfined\n";
-+
-+ len = strlen(unconfined_str);
-+ if (ns != default_namespace)
-+ len += strlen(ns->base.name) + 1;
-+
-+ str = kmalloc(len + 1, GFP_ATOMIC);
-+ if (!str)
-+ return -ENOMEM;
-+
-+ if (ns != default_namespace)
-+ sprintf(str, "%s://%s", ns->base.name, unconfined_str);
-+ else
-+ memcpy(str, unconfined_str, len);
-+ }
-+ *string = str;
-+
-+ return len;
-+}
-+
-+static char *split_token_from_name(const char *op, char *args, u64 *token)
-+{
-+ char *name;
-+
-+ *token = simple_strtoull(args, &name, 16);
-+ if ((name == args) || *name != '^') {
-+ AA_ERROR("%s: Invalid input '%s'", op, args);
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ name++; /* skip ^ */
-+ if (!*name)
-+ name = NULL;
-+ return name;
-+}
-+
-+int aa_setprocattr_changehat(char *args, int test)
-+{
-+ char *hat;
-+ u64 token;
-+
-+ hat = split_token_from_name("change_hat", args, &token);
-+ if (IS_ERR(hat))
-+ return PTR_ERR(hat);
-+
-+ if (!hat && !token) {
-+ AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
-+ return -EINVAL;
-+ }
-+
-+ AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n",
-+ __func__, token, hat ? hat : NULL);
-+
-+ return aa_change_hat(hat, token, test);
-+}
-+
-+int aa_setprocattr_changeprofile(char *args, int onexec, int test)
-+{
-+ char *name, *ns_name;
-+
-+ name = aa_split_name_from_ns(args, &ns_name);
-+ return aa_change_profile(ns_name, name, onexec, test);
-+}
-+
-+
-+int aa_setprocattr_permipc(char *args)
-+{
-+ /* TODO: add ipc permission querying */
-+ return -ENOTSUPP;
-+}
-diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
-new file mode 100644
-index 0000000..f00165b
---- /dev/null
-+++ b/security/apparmor/resource.c
-@@ -0,0 +1,104 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor resource mediation and attachment
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ */
-+
-+#include <linux/audit.h>
-+
-+#include "include/audit.h"
-+#include "include/resource.h"
-+#include "include/policy.h"
-+
-+struct aa_audit_resource {
-+ struct aa_audit base;
-+
-+ int rlimit;
-+};
-+
-+static void audit_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct aa_audit_resource *sa = va;
-+
-+ if (sa->rlimit)
-+ audit_log_format(ab, " rlimit=%d", sa->rlimit - 1);
-+}
-+
-+static int aa_audit_resource(struct aa_profile *profile,
-+ struct aa_audit_resource *sa)
-+{
-+ return aa_audit(AUDIT_APPARMOR_AUTO, profile, (struct aa_audit *)sa,
-+ audit_cb);
-+}
-+
-+/**
-+ * aa_task_setrlimit - test permission to set an rlimit
-+ * @profile - profile confining the task
-+ * @resource - the resource being set
-+ * @new_rlim - the new resource limit
-+ *
-+ * Control raising the processes hard limit.
-+ */
-+int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource,
-+ struct rlimit *new_rlim)
-+{
-+ struct aa_audit_resource sa;
-+ int error = 0;
-+
-+ memset(&sa, 0, sizeof(sa));
-+ sa.base.operation = "setrlimit";
-+ sa.base.gfp_mask = GFP_KERNEL;
-+ sa.rlimit = resource + 1;
-+
-+ if (profile->rlimits.mask & (1 << resource) &&
-+ new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) {
-+ sa.base.error = -EACCES;
-+
-+ error = aa_audit_resource(profile, &sa);
-+ }
-+
-+ return error;
-+}
-+
-+void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new)
-+{
-+ unsigned int mask = 0;
-+ struct rlimit *rlim, *initrlim;
-+ int i;
-+
-+ /* for any rlimits the profile controlled reset the soft limit
-+ * to the less of the tasks hard limit and the init tasks soft limit
-+ */
-+ if (old && old->rlimits.mask) {
-+ for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<=1) {
-+ if (old->rlimits.mask & mask) {
-+ rlim = current->signal->rlim + i;
-+ initrlim = init_task.signal->rlim + i;
-+ rlim->rlim_cur = min(rlim->rlim_max,
-+ initrlim->rlim_cur);
-+ }
-+ }
-+ }
-+
-+ /* set any new hard limits as dictated by the new profile */
-+ if (!(new && new->rlimits.mask))
-+ return;
-+ for (i = 0, mask = 1; i < RLIM_NLIMITS; i++, mask <<=1) {
-+ if (!(new->rlimits.mask & mask))
-+ continue;
-+
-+ rlim = current->signal->rlim + i;
-+ rlim->rlim_max = min(rlim->rlim_max,
-+ new->rlimits.limits[i].rlim_max);
-+ /* soft limit should not exceed hard limit */
-+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
-+ }
-+}
-diff --git a/security/apparmor/sid.c b/security/apparmor/sid.c
-new file mode 100644
-index 0000000..aa41a35
---- /dev/null
-+++ b/security/apparmor/sid.c
-@@ -0,0 +1,113 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor security identifier (sid) manipulation fns
-+ *
-+ * Copyright 2009 Canonical Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation, version 2 of the
-+ * License.
-+ *
-+ *
-+ * AppArmor allocates a unique sid for every profile loaded. If a profile
-+ * is replaced it receive the sid of the profile it is replacing. Each sid
-+ * is a u32 with the lower u16 being sids of system profiles and the
-+ * upper u16 being user profile sids.
-+ *
-+ * The sid value of 0 is invalid for system sids and is used to indicate
-+ * unconfined for user sids.
-+ *
-+ * A compound sid is a pair of user and system sids that is used to identify
-+ * both profiles confining a task.
-+ *
-+ * Both system and user sids are globally unique with all users pulling
-+ * from the same sid pool. User sid allocation is limited by the
-+ * user controls, that can limit how many profiles are loaded by a user.
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/errno.h>
-+#include <linux/err.h>
-+
-+#include "include/sid.h"
-+
-+/* global counter from which sids are allocated */
-+static u16 global_sys_sid;
-+static u16 global_usr_sid;
-+static DEFINE_SPINLOCK(sid_lock);
-+
-+
-+/* TODO FIXME: add sid to profile mapping, and sid recycling */
-+
-+
-+/**
-+ * aa_alloc_sid - allocate a new sid for a profile
-+ * @is_usr: true if the new sid is a user based sid
-+ */
-+u32 aa_alloc_sid(int is_usr)
-+{
-+ u32 sid;
-+
-+ /*
-+ * TODO FIXME: sid recycling - part of profile mapping table
-+ */
-+ spin_lock(&sid_lock);
-+ if (is_usr) {
-+ sid = (++global_usr_sid) << 16;
-+
-+ } else {
-+ sid = ++global_sys_sid;
-+ }
-+ spin_unlock(&sid_lock);
-+ return sid;
-+}
-+
-+/**
-+ * aa_free_sid - free a sid
-+ * @sid: sid to free
-+ */
-+void aa_free_sid(u32 sid)
-+{
-+ ; /* NOP ATM */
-+}
-+
-+/**
-+ * aa_add_sid_profile - associate a profile to a sid for sid -> profile lookup
-+ * @sid: sid of te profile
-+ * @profile: profile to associate
-+ *
-+ * return 0 or error
-+ */
-+int aa_add_sid_profile(u32 sid, struct aa_profile *profile)
-+{
-+ /* NOP ATM */
-+ return 0;
-+}
-+
-+/**
-+ * aa_replace_sid_profile - replace the profile associated with a sid
-+ * @sid: sid to associate a new profile with
-+ * @profile: profile to associate with side
-+ *
-+ * return 0 or error
-+ */
-+int aa_replace_sid_profile(u32 sid, struct aa_profile *profile)
-+{
-+ /* NOP ATM */
-+ return 0;
-+}
-+
-+/**
-+ * aa_get_sid_profile - get the profile associated with the sid
-+ * @sid: sid to lookup
-+ *
-+ * returns - the profile, or NULL for unconfined user.
-+ * - if there is an error -ENOENT, -EINVAL
-+ */
-+struct aa_profile *aa_get_sid_profile(u32 sid)
-+{
-+ return ERR_PTR(-EINVAL);
-+}
-+