Home Home > GIT Browse > linux-next
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Thumshirn <jthumshirn@suse.de>2018-09-14 16:41:07 +0200
committerJohannes Thumshirn <jthumshirn@suse.de>2018-09-14 16:41:07 +0200
commit07d5db05cd6058a13afaa801d110a4206abdd0a5 (patch)
treeb439e34f6d7e9e47269fd91662856fb2332d80bb
parent728b1ddbe1d7a562ef7ff89d1179efdd81c186a6 (diff)
parentae83857f3af81d08f29ae6e785fd779ed7163fb8 (diff)
Pull AppArmor updates from Goldwyn Rodrigues. Conflicts: series.conf
-rw-r--r--patches.apparmor/0001-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch50
-rw-r--r--patches.apparmor/0001-apparmor-fix-profile-attachment-for-special-unconfin.patch34
-rw-r--r--patches.apparmor/0001-securityfs-add-the-ability-to-support-symlinks.patch267
-rw-r--r--patches.apparmor/0002-apparmor-Fix-logical-error-in-verify_header.patch35
-rw-r--r--patches.apparmor/0002-apparmor-fix-leak-of-null-profile-name-if-profile-al.patch40
-rw-r--r--patches.apparmor/0002-apparmorfs-Combine-two-function-calls-into-one-in-aa.patch40
-rw-r--r--patches.apparmor/0003-apparmor-Fix-an-error-code-in-aafs_create.patch40
-rw-r--r--patches.apparmor/0003-apparmor-fix-locking-when-creating-a-new-complain-pr.patch182
-rw-r--r--patches.apparmor/0003-doc-ReSTify-apparmor.txt.patch48
-rw-r--r--patches.apparmor/0004-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch31
-rw-r--r--patches.apparmor/0004-apparmor-fix-off-by-one-comparison-on-MAXMAPPED_SIG.patch52
-rw-r--r--patches.apparmor/0004-apparmorfs-Use-seq_putc-in-two-functions.patch45
-rw-r--r--patches.apparmor/0005-apparmor-Fix-error-cod-in-__aa_fs_profile_mkdir.patch40
-rw-r--r--patches.apparmor/0005-apparmor-add-the-ability-to-mediate-signals.patch400
-rw-r--r--patches.apparmor/0006-apparmor-add-mount-mediation.patch1054
-rw-r--r--patches.apparmor/0006-security-apparmor-Use-POSIX-compatible-printf-s.patch43
-rw-r--r--patches.apparmor/0007-apparmor-cleanup-conditional-check-for-label-in-labe.patch73
-rw-r--r--patches.apparmor/0007-apparmor-move-file-context-into-file.h.patch104
-rw-r--r--patches.apparmor/0008-apparmor-add-support-for-absolute-root-view-based-la.patch65
-rw-r--r--patches.apparmor/0008-apparmor-make-internal-lib-fn-skipn_spaces-available.patch44
-rw-r--r--patches.apparmor/0009-apparmor-allow-profiles-to-provide-info-to-disconnec.patch224
-rw-r--r--patches.apparmor/0009-apparmor-make-policy_unpack-able-to-audit-different-.patch221
-rw-r--r--patches.apparmor/0010-apparmor-Move-path-lookup-to-using-preallocated-buff.patch316
-rw-r--r--patches.apparmor/0010-apparmor-add-more-debug-asserts-to-apparmorfs.patch81
-rw-r--r--patches.apparmor/0011-apparmor-move-to-per-loaddata-files-instead-of-repli.patch786
-rw-r--r--patches.apparmor/0012-apparmor-move-new_null_profile-to-after-profile-look.patch196
-rw-r--r--patches.apparmor/0012-apparmor-use-macro-template-to-simplify-profile-seq_.patch193
-rw-r--r--patches.apparmor/0013-apparmor-fix-race-condition-in-null-profile-creation.patch63
-rw-r--r--patches.apparmor/0013-apparmor-use-macro-template-to-simplify-namespace-se.patch107
-rw-r--r--patches.apparmor/0014-apparmor-add-custom-apparmorfs-that-will-be-used-by-.patch487
-rw-r--r--patches.apparmor/0014-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch38
-rw-r--r--patches.apparmor/0015-apparmor-fix-incorrect-type-assignment-when-freeing-.patch41
-rw-r--r--patches.apparmor/0015-apparmor-rename-apparmor-file-fns-and-data-to-indica.patch775
-rw-r--r--patches.apparmor/0016-apparmor-allow-specifying-an-already-created-dir-to-.patch87
-rw-r--r--patches.apparmor/0016-apparmor-fix-build-failure-on-sparc-caused-by-undecl.patch55
-rw-r--r--patches.apparmor/0017-apparmor-convert-from-securityfs-to-apparmorfs-for-p.patch236
-rw-r--r--patches.apparmor/0017-apparmor-fix-apparmorfs-DAC-access-permissions.patch49
-rw-r--r--patches.apparmor/0018-apparmor-move-permissions-into-their-own-file-to-be-.patch127
-rw-r--r--patches.apparmor/0019-apparmor-rework-perm-mapping-to-a-slightly-broader-s.patch311
-rw-r--r--patches.apparmor/0020-apparmor-provide-finer-control-over-policy-managemen.patch199
-rw-r--r--patches.apparmor/0021-apparmor-add-policy-revision-file-interface.patch242
-rw-r--r--patches.apparmor/0022-apparmor-add-mkdir-rmdir-interface-to-manage-policy-.patch138
-rw-r--r--patches.apparmor/0023-apparmor-add-label-data-availability-to-the-feature-.patch54
-rw-r--r--patches.apparmor/0024-apparmor-speed-up-transactional-queries.patch201
-rw-r--r--patches.apparmor/0025-apparmor-add-fn-to-test-if-profile-supports-a-given-.patch39
-rw-r--r--patches.apparmor/0026-apparmor-add-gerneric-permissions-struct-and-support.patch281
-rw-r--r--patches.apparmor/0027-apparmor-switch-from-file_perms-to-aa_perms.patch250
-rw-r--r--patches.apparmor/0028-apparmor-add-profile-permission-query-ability.patch163
-rw-r--r--patches.apparmor/0029-apparmor-provide-information-about-path-buffer-size-.patch43
-rw-r--r--patches.apparmor/0030-apparmor-cleanup-__find_child.patch63
-rw-r--r--patches.apparmor/0031-apparmor-add-namespace-lookup-fns.patch156
-rw-r--r--patches.apparmor/0032-apparmor-fix-policy-load-remove-semantics.patch136
-rw-r--r--patches.apparmor/0033-apparmor-fix-apparmor_query-data.patch53
-rw-r--r--patches.apparmor/0034-apparmor-fix-display-of-ns-name.patch32
-rw-r--r--patches.apparmor/0035-apparmor-move-bprm_committing_creds-committed_creds-.patch119
-rw-r--r--patches.apparmor/0036-apparmor-convert-to-profile-block-critical-sections.patch609
-rw-r--r--patches.apparmor/0037-apparmor-share-profile-name-on-replacement.patch171
-rw-r--r--patches.apparmor/0038-apparmor-refactor-updating-profiles-to-the-newest-pa.patch71
-rw-r--r--patches.apparmor/0039-apparmor-cleanup-remove-unused-and-not-fully-impleme.patch85
-rw-r--r--patches.apparmor/0040-apparmor-convert-aa_change_XXX-bool-parameters-to-fl.patch230
-rw-r--r--patches.apparmor/0041-apparmor-cleanup-rename-XXX_file_context-to-XXX_file.patch91
-rw-r--r--patches.apparmor/0042-apparmor-revalidate-files-during-exec.patch163
-rw-r--r--patches.apparmor/0043-apparmor-add-the-base-fns-for-domain-labels.patch2597
-rw-r--r--patches.apparmor/0044-apparmor-switch-from-profiles-to-using-labels-on-con.patch2908
-rw-r--r--patches.apparmor/0045-apparmor-switch-getprocattr-to-using-label_print-fns.patch126
-rw-r--r--patches.apparmor/0046-apparmor-update-query-interface-to-support-label-que.patch133
-rw-r--r--patches.apparmor/0047-apparmor-move-capability-checks-to-using-labels.patch244
-rw-r--r--patches.apparmor/0048-apparmor-move-resource-checks-to-using-labels.patch247
-rw-r--r--patches.apparmor/0049-apparmor-add-cross-check-permission-helper-macros.patch73
-rw-r--r--patches.apparmor/0050-apparmor-move-ptrace-checks-to-using-labels.patch288
-rw-r--r--patches.apparmor/0051-apparmor-allow-ptrace-checks-to-be-finer-grained-tha.patch142
-rw-r--r--patches.apparmor/0052-apparmor-move-aa_file_perm-to-use-labels.patch236
-rw-r--r--patches.apparmor/0053-apparmor-update-aa_audit_file-to-use-labels.patch139
-rw-r--r--patches.apparmor/0054-apparmor-refactor-path-name-lookup-and-permission-ch.patch235
-rw-r--r--patches.apparmor/0055-apparmor-move-path_link-mediation-to-using-labels.patch201
-rw-r--r--patches.apparmor/0056-apparmor-rework-file-permission-to-cache-file-access.patch129
-rw-r--r--patches.apparmor/0057-apparmor-mediate-files-when-they-are-received.patch54
-rw-r--r--patches.apparmor/0058-apparmor-support-v7-transition-format-compatible-wit.patch77
-rw-r--r--patches.apparmor/0059-apparmor-move-exec-domain-mediation-to-using-labels.patch1118
-rw-r--r--patches.apparmor/0060-apparmor-move-change_hat-mediation-to-using-labels.patch385
-rw-r--r--patches.apparmor/0061-apparmor-move-change_profile-mediation-to-using-labe.patch268
-rw-r--r--patches.apparmor/0062-apparmor-add-domain-label-stacking-info-to-apparmorf.patch101
-rw-r--r--patches.apparmor/0063-apparmor-add-stacked-domain-labels-interface.patch62
-rw-r--r--patches.apparmor/0064-apparmor-export-that-basic-profile-namespaces-are-su.patch46
-rw-r--r--patches.apparmor/0065-apparmor-put-back-designators-in-struct-initialisers.patch36
-rw-r--r--patches.apparmor/apparmor-Fix-regression-in-profile-conflict-logic.patch48
-rw-r--r--patches.apparmor/apparmor-basic-networking-rules-4.11-rc1.patch47
-rw-r--r--patches.apparmor/apparmor-basic-networking-rules.patch155
-rw-r--r--patches.apparmor/apparmor-check-all-net-profiles.patch97
-rw-r--r--patches.apparmor/apparmor-ensure-that-undecidable-profile-attachments-fail.patch138
-rw-r--r--patches.apparmor/apparmor-fix-an-error-code-in-__aa_create_ns.patch30
-rw-r--r--patches.apparmor/apparmor-fix-dangling-symlinks-to-policy-rawdata-aft.patch215
-rw-r--r--patches.apparmor/apparmor-fix-display-of-.ns_name-for-containers.patch41
-rw-r--r--patches.apparmor/apparmor-fix-logging-of-the-existence-test-for-signa.patch65
-rw-r--r--patches.apparmor/apparmor-fix-memory-leak-on-buffer-on-error-exit-path.patch34
-rw-r--r--patches.apparmor/apparmor-fix-oops-in-audit_signal_cb-hook.patch136
-rw-r--r--patches.apparmor/apparmor-fix-possible-recursive-lock-warning-in-__aa.patch303
-rw-r--r--patches.apparmor/apparmor-fix-ptrace-label-match-when-matching-stacke.patch140
-rw-r--r--patches.apparmor/apparmor-fix-regression-in-mount-mediation-when-feat.patch71
-rw-r--r--patches.apparmor/apparmor-fix-resource-audit-messages-when-auditing-peer.patch46
-rw-r--r--patches.apparmor/apparmor-remove-no-op-permission-check-in-policy_unpack.patch102
-rw-r--r--series.conf99
102 files changed, 109 insertions, 22172 deletions
diff --git a/patches.apparmor/0001-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch b/patches.apparmor/0001-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch
deleted file mode 100644
index 95d197083e..0000000000
--- a/patches.apparmor/0001-apparmor-Fix-shadowed-local-variable-in-unpack_trans.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 9dcf6985ceb2d46bec2ce7fd602f1cede3cce04d Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert@linux-m68k.org>
-Date: Thu, 6 Jul 2017 10:56:21 +0200
-Subject: [PATCH 01/17] apparmor: Fix shadowed local variable in unpack_trans_table()
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 19fe43a54fb67b6cc8857e65c78e1dc8aa2e97a3
-
-with W=2:
-
- security/apparmor/policy_unpack.c: In function ‘unpack_trans_table’:
- security/apparmor/policy_unpack.c:469: warning: declaration of ‘pos’ shadows a previous local
- security/apparmor/policy_unpack.c:451: warning: shadowed declaration is here
-
-Rename the old "pos" to "saved_pos" to fix this.
-
-Fixes: 5379a3312024a8be ("apparmor: support v7 transition format compatible with label_parse")
-Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-Reviewed-by: Serge Hallyn <serge@hallyn.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy_unpack.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index c600f4dd1783..2d5a1a007b06 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -448,7 +448,7 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e)
- */
- static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
- {
-- void *pos = e->pos;
-+ void *saved_pos = e->pos;
-
- /* exec table is optional */
- if (unpack_nameX(e, AA_STRUCT, "xtable")) {
-@@ -511,7 +511,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
-
- fail:
- aa_free_domain_entries(&profile->file.trans);
-- e->pos = pos;
-+ e->pos = saved_pos;
- return 0;
- }
-
---
-2.14.1
-
diff --git a/patches.apparmor/0001-apparmor-fix-profile-attachment-for-special-unconfin.patch b/patches.apparmor/0001-apparmor-fix-profile-attachment-for-special-unconfin.patch
deleted file mode 100644
index 44417e250a..0000000000
--- a/patches.apparmor/0001-apparmor-fix-profile-attachment-for-special-unconfin.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 4eaafeb72be65caaee2a742f5bb2e9bfa279405f Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 17 Nov 2017 18:04:37 -0800
-Subject: [PATCH] apparmor: fix profile attachment for special unconfined profiles
-References: bsc#1071035
-Git-commit: 06d426d113fe0b3107939e81db920ca7b097e97c
-Patch-mainline: v4.15-rc1
-
-It used to be that unconfined would never attach. However that is not
-the case anymore as some special profiles can be marked as unconfined,
-that are not the namespaces unconfined profile, and may have an
-attachment.
-
-Fixes: f1bd904175e8 ("apparmor: add the base fns() for domain labels")
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -325,8 +325,10 @@ static struct aa_profile *__attach_match
- struct aa_profile *profile, *candidate = NULL;
-
- list_for_each_entry_rcu(profile, head, base.list) {
-- if (profile->label.flags & FLAG_NULL)
-+ if (profile->label.flags & FLAG_NULL &&
-+ &profile->label == ns_unconfined(profile->ns))
- continue;
-+
- if (profile->xmatch) {
- if (profile->xmatch_len == len) {
- conflict = true;
diff --git a/patches.apparmor/0001-securityfs-add-the-ability-to-support-symlinks.patch b/patches.apparmor/0001-securityfs-add-the-ability-to-support-symlinks.patch
deleted file mode 100644
index 7de0519147..0000000000
--- a/patches.apparmor/0001-securityfs-add-the-ability-to-support-symlinks.patch
+++ /dev/null
@@ -1,267 +0,0 @@
-From 93aa5f375b29a18ae7c8a6d1971c1998cc448380 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Sun, 7 May 2017 05:53:37 -0700
-Subject: [PATCH 01/65] securityfs: add the ability to support symlinks
-Git-commit: 6623ec7c4dbe18a5a2878e2d888be70d08a91826
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-apparmor: 4.13 dependency
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- include/linux/security.h | 12 ++++
- security/inode.c | 144 ++++++++++++++++++++++++++++++++++++++++-------
- 2 files changed, 135 insertions(+), 21 deletions(-)
-
-diff --git a/include/linux/security.h b/include/linux/security.h
-index af675b576645..caf8b64d8b5c 100644
---- a/include/linux/security.h
-+++ b/include/linux/security.h
-@@ -1651,6 +1651,10 @@ extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
- struct dentry *parent, void *data,
- const struct file_operations *fops);
- extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent);
-+struct dentry *securityfs_create_symlink(const char *name,
-+ struct dentry *parent,
-+ const char *target,
-+ const struct inode_operations *iops);
- extern void securityfs_remove(struct dentry *dentry);
-
- #else /* CONFIG_SECURITYFS */
-@@ -1670,6 +1674,14 @@ static inline struct dentry *securityfs_create_file(const char *name,
- return ERR_PTR(-ENODEV);
- }
-
-+static inline struct dentry *securityfs_create_symlink(const char *name,
-+ struct dentry *parent,
-+ const char *target,
-+ const struct inode_operations *iops)
-+{
-+ return ERR_PTR(-ENODEV);
-+}
-+
- static inline void securityfs_remove(struct dentry *dentry)
- {}
-
-diff --git a/security/inode.c b/security/inode.c
-index eccd58ef2ae8..8dd9ca8848e4 100644
---- a/security/inode.c
-+++ b/security/inode.c
-@@ -26,11 +26,31 @@
- static struct vfsmount *mount;
- static int mount_count;
-
-+static void securityfs_evict_inode(struct inode *inode)
-+{
-+ truncate_inode_pages_final(&inode->i_data);
-+ clear_inode(inode);
-+ if (S_ISLNK(inode->i_mode))
-+ kfree(inode->i_link);
-+}
-+
-+static const struct super_operations securityfs_super_operations = {
-+ .statfs = simple_statfs,
-+ .evict_inode = securityfs_evict_inode,
-+};
-+
- static int fill_super(struct super_block *sb, void *data, int silent)
- {
- static const struct tree_descr files[] = {{""}};
-+ int error;
-+
-+ error = simple_fill_super(sb, SECURITYFS_MAGIC, files);
-+ if (error)
-+ return error;
-+
-+ sb->s_op = &securityfs_super_operations;
-
-- return simple_fill_super(sb, SECURITYFS_MAGIC, files);
-+ return 0;
- }
-
- static struct dentry *get_sb(struct file_system_type *fs_type,
-@@ -48,7 +68,7 @@ static struct file_system_type fs_type = {
- };
-
- /**
-- * securityfs_create_file - create a file in the securityfs filesystem
-+ * securityfs_create_dentry - create a dentry in the securityfs filesystem
- *
- * @name: a pointer to a string containing the name of the file to create.
- * @mode: the permission that the file should have
-@@ -60,34 +80,35 @@ static struct file_system_type fs_type = {
- * the open() call.
- * @fops: a pointer to a struct file_operations that should be used for
- * this file.
-+ * @iops: a point to a struct of inode_operations that should be used for
-+ * this file/dir
- *
-- * This is the basic "create a file" function for securityfs. It allows for a
-- * wide range of flexibility in creating a file, or a directory (if you
-- * want to create a directory, the securityfs_create_dir() function is
-- * recommended to be used instead).
-+ * This is the basic "create a file/dir/symlink" function for
-+ * securityfs. It allows for a wide range of flexibility in creating
-+ * a file, or a directory (if you want to create a directory, the
-+ * securityfs_create_dir() function is recommended to be used
-+ * instead).
- *
- * This function returns a pointer to a dentry if it succeeds. This
-- * pointer must be passed to the securityfs_remove() function when the file is
-- * to be removed (no automatic cleanup happens if your module is unloaded,
-- * you are responsible here). If an error occurs, the function will return
-- * the error value (via ERR_PTR).
-+ * pointer must be passed to the securityfs_remove() function when the
-+ * file is to be removed (no automatic cleanup happens if your module
-+ * is unloaded, you are responsible here). If an error occurs, the
-+ * function will return the error value (via ERR_PTR).
- *
- * If securityfs is not enabled in the kernel, the value %-ENODEV is
- * returned.
- */
--struct dentry *securityfs_create_file(const char *name, umode_t mode,
-- struct dentry *parent, void *data,
-- const struct file_operations *fops)
-+static struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
-+ struct dentry *parent, void *data,
-+ const struct file_operations *fops,
-+ const struct inode_operations *iops)
- {
- struct dentry *dentry;
-- int is_dir = S_ISDIR(mode);
- struct inode *dir, *inode;
- int error;
-
-- if (!is_dir) {
-- BUG_ON(!fops);
-+ if (!(mode & S_IFMT))
- mode = (mode & S_IALLUGO) | S_IFREG;
-- }
-
- pr_debug("securityfs: creating file '%s'\n",name);
-
-@@ -120,11 +141,14 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode,
- inode->i_mode = mode;
- inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
- inode->i_private = data;
-- if (is_dir) {
-+ if (S_ISDIR(mode)) {
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
- inc_nlink(inode);
- inc_nlink(dir);
-+ } else if (S_ISLNK(mode)) {
-+ inode->i_op = iops ? iops : &simple_symlink_inode_operations;
-+ inode->i_link = data;
- } else {
- inode->i_fop = fops;
- }
-@@ -141,6 +165,38 @@ struct dentry *securityfs_create_file(const char *name, umode_t mode,
- simple_release_fs(&mount, &mount_count);
- return dentry;
- }
-+
-+/**
-+ * securityfs_create_file - create a file in the securityfs filesystem
-+ *
-+ * @name: a pointer to a string containing the name of the file to create.
-+ * @mode: the permission that the file should have
-+ * @parent: a pointer to the parent dentry for this file. This should be a
-+ * directory dentry if set. If this parameter is %NULL, then the
-+ * file will be created in the root of the securityfs filesystem.
-+ * @data: a pointer to something that the caller will want to get to later
-+ * on. The inode.i_private pointer will point to this value on
-+ * the open() call.
-+ * @fops: a pointer to a struct file_operations that should be used for
-+ * this file.
-+ *
-+ * This function creates a file in securityfs with the given @name.
-+ *
-+ * This function returns a pointer to a dentry if it succeeds. This
-+ * pointer must be passed to the securityfs_remove() function when the file is
-+ * to be removed (no automatic cleanup happens if your module is unloaded,
-+ * you are responsible here). If an error occurs, the function will return
-+ * the error value (via ERR_PTR).
-+ *
-+ * If securityfs is not enabled in the kernel, the value %-ENODEV is
-+ * returned.
-+ */
-+struct dentry *securityfs_create_file(const char *name, umode_t mode,
-+ struct dentry *parent, void *data,
-+ const struct file_operations *fops)
-+{
-+ return securityfs_create_dentry(name, mode, parent, data, fops, NULL);
-+}
- EXPORT_SYMBOL_GPL(securityfs_create_file);
-
- /**
-@@ -165,13 +221,59 @@ EXPORT_SYMBOL_GPL(securityfs_create_file);
- */
- struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
- {
-- return securityfs_create_file(name,
-- S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-- parent, NULL, NULL);
-+ return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL);
- }
- EXPORT_SYMBOL_GPL(securityfs_create_dir);
-
- /**
-+ * securityfs_create_symlink - create a symlink in the securityfs filesystem
-+ *
-+ * @name: a pointer to a string containing the name of the symlink to
-+ * create.
-+ * @parent: a pointer to the parent dentry for the symlink. This should be a
-+ * directory dentry if set. If this parameter is %NULL, then the
-+ * directory will be created in the root of the securityfs filesystem.
-+ * @target: a pointer to a string containing the name of the symlink's target.
-+ * If this parameter is %NULL, then the @iops parameter needs to be
-+ * setup to handle .readlink and .get_link inode_operations.
-+ * @iops: a pointer to the struct inode_operations to use for the symlink. If
-+ * this parameter is %NULL, then the default simple_symlink_inode
-+ * operations will be used.
-+ *
-+ * This function creates a symlink in securityfs with the given @name.
-+ *
-+ * This function returns a pointer to a dentry if it succeeds. This
-+ * pointer must be passed to the securityfs_remove() function when the file is
-+ * to be removed (no automatic cleanup happens if your module is unloaded,
-+ * you are responsible here). If an error occurs, the function will return
-+ * the error value (via ERR_PTR).
-+ *
-+ * If securityfs is not enabled in the kernel, the value %-ENODEV is
-+ * returned.
-+ */
-+struct dentry *securityfs_create_symlink(const char *name,
-+ struct dentry *parent,
-+ const char *target,
-+ const struct inode_operations *iops)
-+{
-+ struct dentry *dent;
-+ char *link = NULL;
-+
-+ if (target) {
-+ link = kstrdup(target, GFP_KERNEL);
-+ if (!link)
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent,
-+ link, NULL, iops);
-+ if (IS_ERR(dent))
-+ kfree(link);
-+
-+ return dent;
-+}
-+EXPORT_SYMBOL_GPL(securityfs_create_symlink);
-+
-+/**
- * securityfs_remove - removes a file or directory from the securityfs filesystem
- *
- * @dentry: a pointer to a the dentry of the file or directory to be removed.
---
-2.12.3
-
diff --git a/patches.apparmor/0002-apparmor-Fix-logical-error-in-verify_header.patch b/patches.apparmor/0002-apparmor-Fix-logical-error-in-verify_header.patch
deleted file mode 100644
index f3d7c04453..0000000000
--- a/patches.apparmor/0002-apparmor-Fix-logical-error-in-verify_header.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 85d1b984ba65c0424d57ec24027fa3ffa899eb86 Mon Sep 17 00:00:00 2001
-From: Christos Gkekas <chris.gekas@gmail.com>
-Date: Sat, 8 Jul 2017 20:50:21 +0100
-Subject: [PATCH 02/17] apparmor: Fix logical error in verify_header()
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 86aea56f14929ff1c05eca1776e9068e907429d5
-
-verify_header() is currently checking whether interface version is less
-than 5 *and* greater than 7, which always evaluates to false. Instead it
-should check whether it is less than 5 *or* greater than 7.
-
-Signed-off-by: Christos Gkekas <chris.gekas@gmail.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy_unpack.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index 2d5a1a007b06..bda0dce3b582 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -832,7 +832,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
- * if not specified use previous version
- * Mask off everything that is not kernel abi version
- */
-- if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) {
-+ if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
- audit_iface(NULL, NULL, NULL, "unsupported interface version",
- e, error);
- return error;
---
-2.14.1
-
diff --git a/patches.apparmor/0002-apparmor-fix-leak-of-null-profile-name-if-profile-al.patch b/patches.apparmor/0002-apparmor-fix-leak-of-null-profile-name-if-profile-al.patch
deleted file mode 100644
index 130dc67640..0000000000
--- a/patches.apparmor/0002-apparmor-fix-leak-of-null-profile-name-if-profile-al.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 3218a24ad0b4787055aa665e3a33004e506d2402 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 15 Nov 2017 15:25:30 -0800
-Subject: [PATCH] apparmor: fix leak of null profile name if profile allocation fails
-References: bsc#1071057
-Git-commit: 4633307e5ed6128975595df43f796a10c41d11c1
-Patch-mainline: v4.15-rc1
-
-Fixes: d07881d2edb0 ("apparmor: move new_null_profile to after profile lookup fns()")
-Reported-by: Seth Arnold <seth.arnold@canonical.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index ea8acc9fcfda..877983014b5b 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -503,7 +503,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- {
- struct aa_profile *p, *profile;
- const char *bname;
-- char *name;
-+ char *name = NULL;
-
- AA_BUG(!parent);
-
-@@ -563,6 +563,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- return profile;
-
- fail:
-+ kfree(name);
- aa_free_profile(profile);
- return NULL;
- }
---
-2.14.2
-
diff --git a/patches.apparmor/0002-apparmorfs-Combine-two-function-calls-into-one-in-aa.patch b/patches.apparmor/0002-apparmorfs-Combine-two-function-calls-into-one-in-aa.patch
deleted file mode 100644
index c253bc1dcf..0000000000
--- a/patches.apparmor/0002-apparmorfs-Combine-two-function-calls-into-one-in-aa.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From d952bc9966116ab5dba22d4a0c6d646e3b37235e Mon Sep 17 00:00:00 2001
-From: Markus Elfring <elfring@users.sourceforge.net>
-Date: Sun, 7 May 2017 13:43:50 +0200
-Subject: [PATCH 02/65] apparmorfs: Combine two function calls into one in
- aa_fs_seq_raw_abi_show()
-References: FATE#323500
-Patch-mainline: v4.13-rc1
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-Git-commit: 0ff3d97f7676d9f513288a2d30582dcd2b34d238
-
-A bit of data was put into a sequence by two separate function calls.
-Print the same data by a single function call instead.
-
-Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
----
- security/apparmor/apparmorfs.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 4f6ac9dbc65d..b4d83e0bc651 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -572,10 +572,9 @@ static int aa_fs_seq_raw_abi_show(struct seq_file *seq, void *v)
- struct aa_proxy *proxy = seq->private;
- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-
-- if (profile->rawdata->abi) {
-- seq_printf(seq, "v%d", profile->rawdata->abi);
-- seq_puts(seq, "\n");
-- }
-+ if (profile->rawdata->abi)
-+ seq_printf(seq, "v%d\n", profile->rawdata->abi);
-+
- aa_put_profile(profile);
-
- return 0;
---
-2.12.3
-
diff --git a/patches.apparmor/0003-apparmor-Fix-an-error-code-in-aafs_create.patch b/patches.apparmor/0003-apparmor-Fix-an-error-code-in-aafs_create.patch
deleted file mode 100644
index 7b0ee75cdc..0000000000
--- a/patches.apparmor/0003-apparmor-Fix-an-error-code-in-aafs_create.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 19ea40c85443af3d34e33a5660eb2c7da0e85857 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Thu, 13 Jul 2017 10:39:20 +0300
-Subject: [PATCH 03/17] apparmor: Fix an error code in aafs_create()
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 5d314a81eca29b01939930c1c596dfa44937e970
-
-We accidentally forgot to set the error code on this path. It means we
-return NULL instead of an error pointer. I looked through a bunch of
-callers and I don't think it really causes a big issue, but the
-documentation says we're supposed to return error pointers here.
-
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Acked-by: Serge Hallyn <serge@hallyn.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 853c2ec8e0c9..2caeb748070c 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -248,8 +248,10 @@ static struct dentry *aafs_create(const char *name, umode_t mode,
-
- inode_lock(dir);
- dentry = lookup_one_len(name, parent, strlen(name));
-- if (IS_ERR(dentry))
-+ if (IS_ERR(dentry)) {
-+ error = PTR_ERR(dentry);
- goto fail_lock;
-+ }
-
- if (d_really_is_positive(dentry)) {
- error = -EEXIST;
---
-2.14.1
-
diff --git a/patches.apparmor/0003-apparmor-fix-locking-when-creating-a-new-complain-pr.patch b/patches.apparmor/0003-apparmor-fix-locking-when-creating-a-new-complain-pr.patch
deleted file mode 100644
index 8e10bb6b98..0000000000
--- a/patches.apparmor/0003-apparmor-fix-locking-when-creating-a-new-complain-pr.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-From d88c0461174a1afcc9aad91ee2b50dbbe2c0791c Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 20 Nov 2017 22:26:12 -0800
-Subject: [PATCH] apparmor: fix locking when creating a new complain profile.
-References: bsc#1071061
-Git-commit: 5d7c44ef5e4f0149c9fb99faeae41e930485a1ec
-Patch-mainline: v4.15-rc1
-
-Break the per cpu buffer atomic section when creating a new null
-complain profile. In learning mode this won't matter and we can
-safely re-aquire the buffer.
-
-This fixes the following lockdep BUG trace
- nov. 14 14:09:09 cyclope audit[7152]: AVC apparmor="ALLOWED" operation="exec" profile="/usr/sbin/sssd" name="/usr/sbin/adcli" pid=7152 comm="sssd_be" requested_mask="x" denied_mask="x" fsuid=0 ouid=0 target="/usr/sbin/sssd//null-/usr/sbin/adcli"
- nov. 14 14:09:09 cyclope kernel: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:747
- nov. 14 14:09:09 cyclope kernel: in_atomic(): 1, irqs_disabled(): 0, pid: 7152, name: sssd_be
- nov. 14 14:09:09 cyclope kernel: 1 lock held by sssd_be/7152:
- nov. 14 14:09:09 cyclope kernel: #0: (&sig->cred_guard_mutex){....}, at: [<ffffffff8182d53e>] prepare_bprm_creds+0x4e/0x100
- nov. 14 14:09:09 cyclope kernel: CPU: 3 PID: 7152 Comm: sssd_be Not tainted 4.14.0prahal+intel #150
- nov. 14 14:09:09 cyclope kernel: Hardware name: LENOVO 20CDCTO1WW/20CDCTO1WW, BIOS GQET53WW (1.33 ) 09/15/2017
- nov. 14 14:09:09 cyclope kernel: Call Trace:
- nov. 14 14:09:09 cyclope kernel: dump_stack+0xb0/0x135
- nov. 14 14:09:09 cyclope kernel: ? _atomic_dec_and_lock+0x15b/0x15b
- nov. 14 14:09:09 cyclope kernel: ? lockdep_print_held_locks+0xc4/0x130
- nov. 14 14:09:09 cyclope kernel: ___might_sleep+0x29c/0x320
- nov. 14 14:09:09 cyclope kernel: ? rq_clock+0xf0/0xf0
- nov. 14 14:09:09 cyclope kernel: ? __kernel_text_address+0xd/0x40
- nov. 14 14:09:09 cyclope kernel: __might_sleep+0x95/0x190
- nov. 14 14:09:09 cyclope kernel: ? aa_new_null_profile+0x50a/0x960
- nov. 14 14:09:09 cyclope kernel: __mutex_lock+0x13e/0x1a20
- nov. 14 14:09:09 cyclope kernel: ? aa_new_null_profile+0x50a/0x960
- nov. 14 14:09:09 cyclope kernel: ? save_stack+0x43/0xd0
- nov. 14 14:09:09 cyclope kernel: ? kmem_cache_alloc_trace+0x13f/0x290
- nov. 14 14:09:09 cyclope kernel: ? mutex_lock_io_nested+0x1880/0x1880
- nov. 14 14:09:09 cyclope kernel: ? profile_transition+0x932/0x2d40
- nov. 14 14:09:09 cyclope kernel: ? apparmor_bprm_set_creds+0x1479/0x1f70
- nov. 14 14:09:09 cyclope kernel: ? security_bprm_set_creds+0x5a/0x80
- nov. 14 14:09:09 cyclope kernel: ? prepare_binprm+0x366/0x980
- nov. 14 14:09:09 cyclope kernel: ? do_execveat_common.isra.30+0x12a9/0x2350
- nov. 14 14:09:09 cyclope kernel: ? SyS_execve+0x2c/0x40
- nov. 14 14:09:09 cyclope kernel: ? do_syscall_64+0x228/0x650
- nov. 14 14:09:09 cyclope kernel: ? entry_SYSCALL64_slow_path+0x25/0x25
- nov. 14 14:09:09 cyclope kernel: ? deactivate_slab.isra.62+0x49d/0x5e0
- nov. 14 14:09:09 cyclope kernel: ? save_stack_trace+0x16/0x20
- nov. 14 14:09:09 cyclope kernel: ? init_object+0x88/0x90
- nov. 14 14:09:09 cyclope kernel: ? ___slab_alloc+0x520/0x590
- nov. 14 14:09:09 cyclope kernel: ? ___slab_alloc+0x520/0x590
- nov. 14 14:09:09 cyclope kernel: ? aa_alloc_proxy+0xab/0x200
- nov. 14 14:09:09 cyclope kernel: ? lock_downgrade+0x7e0/0x7e0
- nov. 14 14:09:09 cyclope kernel: ? memcg_kmem_get_cache+0x970/0x970
- nov. 14 14:09:09 cyclope kernel: ? kasan_unpoison_shadow+0x35/0x50
- nov. 14 14:09:09 cyclope kernel: ? kasan_unpoison_shadow+0x35/0x50
- nov. 14 14:09:09 cyclope kernel: ? kasan_kmalloc+0xad/0xe0
- nov. 14 14:09:09 cyclope kernel: ? aa_alloc_proxy+0xab/0x200
- nov. 14 14:09:09 cyclope kernel: ? kmem_cache_alloc_trace+0x13f/0x290
- nov. 14 14:09:09 cyclope kernel: ? aa_alloc_proxy+0xab/0x200
- nov. 14 14:09:09 cyclope kernel: ? aa_alloc_proxy+0xab/0x200
- nov. 14 14:09:09 cyclope kernel: ? _raw_spin_unlock+0x22/0x30
- nov. 14 14:09:09 cyclope kernel: ? vec_find+0xa0/0xa0
- nov. 14 14:09:09 cyclope kernel: ? aa_label_init+0x6f/0x230
- nov. 14 14:09:09 cyclope kernel: ? __label_insert+0x3e0/0x3e0
- nov. 14 14:09:09 cyclope kernel: ? kmem_cache_alloc_trace+0x13f/0x290
- nov. 14 14:09:09 cyclope kernel: ? aa_alloc_profile+0x58/0x200
- nov. 14 14:09:09 cyclope kernel: mutex_lock_nested+0x16/0x20
- nov. 14 14:09:09 cyclope kernel: ? mutex_lock_nested+0x16/0x20
- nov. 14 14:09:09 cyclope kernel: aa_new_null_profile+0x50a/0x960
- nov. 14 14:09:09 cyclope kernel: ? aa_fqlookupn_profile+0xdc0/0xdc0
- nov. 14 14:09:09 cyclope kernel: ? aa_compute_fperms+0x4b5/0x640
- nov. 14 14:09:09 cyclope kernel: ? disconnect.isra.2+0x1b0/0x1b0
- nov. 14 14:09:09 cyclope kernel: ? aa_str_perms+0x8d/0xe0
- nov. 14 14:09:09 cyclope kernel: profile_transition+0x932/0x2d40
- nov. 14 14:09:09 cyclope kernel: ? up_read+0x1a/0x40
- nov. 14 14:09:09 cyclope kernel: ? ext4_xattr_get+0x15c/0xaf0 [ext4]
- nov. 14 14:09:09 cyclope kernel: ? x_table_lookup+0x190/0x190
- nov. 14 14:09:09 cyclope kernel: ? ext4_xattr_ibody_get+0x590/0x590 [ext4]
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? ext4_xattr_security_get+0x1a/0x20 [ext4]
- nov. 14 14:09:09 cyclope kernel: ? __vfs_getxattr+0x6d/0xa0
- nov. 14 14:09:09 cyclope kernel: ? get_vfs_caps_from_disk+0x114/0x720
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? tsc_resume+0x10/0x10
- nov. 14 14:09:09 cyclope kernel: ? get_vfs_caps_from_disk+0x720/0x720
- nov. 14 14:09:09 cyclope kernel: ? native_sched_clock_from_tsc+0x201/0x2b0
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? sched_clock_cpu+0x1b/0x170
- nov. 14 14:09:09 cyclope kernel: ? find_held_lock+0x3c/0x1e0
- nov. 14 14:09:09 cyclope kernel: ? rb_insert_color_cached+0x1660/0x1660
- nov. 14 14:09:09 cyclope kernel: apparmor_bprm_set_creds+0x1479/0x1f70
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? handle_onexec+0x31d0/0x31d0
- nov. 14 14:09:09 cyclope kernel: ? tsc_resume+0x10/0x10
- nov. 14 14:09:09 cyclope kernel: ? graph_lock+0xd0/0xd0
- nov. 14 14:09:09 cyclope kernel: ? tsc_resume+0x10/0x10
- nov. 14 14:09:09 cyclope kernel: ? sched_clock_cpu+0x1b/0x170
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? sched_clock+0x9/0x10
- nov. 14 14:09:09 cyclope kernel: ? sched_clock_cpu+0x1b/0x170
- nov. 14 14:09:09 cyclope kernel: ? find_held_lock+0x3c/0x1e0
- nov. 14 14:09:09 cyclope kernel: security_bprm_set_creds+0x5a/0x80
- nov. 14 14:09:09 cyclope kernel: prepare_binprm+0x366/0x980
- nov. 14 14:09:09 cyclope kernel: ? install_exec_creds+0x150/0x150
- nov. 14 14:09:09 cyclope kernel: ? __might_fault+0x89/0xb0
- nov. 14 14:09:09 cyclope kernel: ? up_read+0x40/0x40
- nov. 14 14:09:09 cyclope kernel: ? get_user_arg_ptr.isra.18+0x2c/0x70
- nov. 14 14:09:09 cyclope kernel: ? count.isra.20.constprop.32+0x7c/0xf0
- nov. 14 14:09:09 cyclope kernel: do_execveat_common.isra.30+0x12a9/0x2350
- nov. 14 14:09:09 cyclope kernel: ? prepare_bprm_creds+0x100/0x100
- nov. 14 14:09:09 cyclope kernel: ? _raw_spin_unlock+0x22/0x30
- nov. 14 14:09:09 cyclope kernel: ? deactivate_slab.isra.62+0x49d/0x5e0
- nov. 14 14:09:09 cyclope kernel: ? save_stack_trace+0x16/0x20
- nov. 14 14:09:09 cyclope kernel: ? init_object+0x88/0x90
- nov. 14 14:09:09 cyclope kernel: ? ___slab_alloc+0x520/0x590
- nov. 14 14:09:09 cyclope kernel: ? ___slab_alloc+0x520/0x590
- nov. 14 14:09:09 cyclope kernel: ? kasan_check_write+0x14/0x20
- nov. 14 14:09:09 cyclope kernel: ? memcg_kmem_get_cache+0x970/0x970
- nov. 14 14:09:09 cyclope kernel: ? kasan_unpoison_shadow+0x35/0x50
- nov. 14 14:09:09 cyclope kernel: ? glob_match+0x730/0x730
- nov. 14 14:09:09 cyclope kernel: ? kmem_cache_alloc+0x225/0x280
- nov. 14 14:09:09 cyclope kernel: ? getname_flags+0xb8/0x510
- nov. 14 14:09:09 cyclope kernel: ? mm_fault_error+0x2e0/0x2e0
- nov. 14 14:09:09 cyclope kernel: ? getname_flags+0xf6/0x510
- nov. 14 14:09:09 cyclope kernel: ? ptregs_sys_vfork+0x10/0x10
- nov. 14 14:09:09 cyclope kernel: SyS_execve+0x2c/0x40
- nov. 14 14:09:09 cyclope kernel: do_syscall_64+0x228/0x650
- nov. 14 14:09:09 cyclope kernel: ? syscall_return_slowpath+0x2f0/0x2f0
- nov. 14 14:09:09 cyclope kernel: ? syscall_return_slowpath+0x167/0x2f0
- nov. 14 14:09:09 cyclope kernel: ? prepare_exit_to_usermode+0x220/0x220
- nov. 14 14:09:09 cyclope kernel: ? prepare_exit_to_usermode+0xda/0x220
- nov. 14 14:09:09 cyclope kernel: ? perf_trace_sys_enter+0x1060/0x1060
- nov. 14 14:09:09 cyclope kernel: ? __put_user_4+0x1c/0x30
- nov. 14 14:09:09 cyclope kernel: entry_SYSCALL64_slow_path+0x25/0x25
- nov. 14 14:09:09 cyclope kernel: RIP: 0033:0x7f9320f23637
- nov. 14 14:09:09 cyclope kernel: RSP: 002b:00007fff783be338 EFLAGS: 00000202 ORIG_RAX: 000000000000003b
- nov. 14 14:09:09 cyclope kernel: RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9320f23637
- nov. 14 14:09:09 cyclope kernel: RDX: 0000558c35002a70 RSI: 0000558c3505bd10 RDI: 0000558c35018b90
- nov. 14 14:09:09 cyclope kernel: RBP: 0000558c34b63ae8 R08: 0000558c3505bd10 R09: 0000000000000080
- nov. 14 14:09:09 cyclope kernel: R10: 0000000000000095 R11: 0000000000000202 R12: 0000000000000001
- nov. 14 14:09:09 cyclope kernel: R13: 0000558c35018b90 R14: 0000558c3505bd18 R15: 0000558c3505bd10
-
-Fixes: 4227c333f65c ("apparmor: Move path lookup to using preallocated buffers")
-BugLink: http://bugs.launchpad.net/bugs/173228
-Reported-by: Alban Browaeys <prahal@yahoo.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index 61dbdcf15a64..d6e88b2231e4 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -543,9 +543,21 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
- }
- } else if (COMPLAIN_MODE(profile)) {
- /* no exec permission - learning mode */
-- struct aa_profile *new_profile = aa_new_null_profile(profile,
-- false, name,
-- GFP_ATOMIC);
-+ struct aa_profile *new_profile = NULL;
-+ char *n = kstrdup(name, GFP_ATOMIC);
-+
-+ if (n) {
-+ /* name is ptr into buffer */
-+ long pos = name - buffer;
-+ /* break per cpu buffer hold */
-+ put_buffers(buffer);
-+ new_profile = aa_new_null_profile(profile, false, n,
-+ GFP_KERNEL);
-+ get_buffers(buffer);
-+ name = buffer + pos;
-+ strcpy((char *)name, n);
-+ kfree(n);
-+ }
- if (!new_profile) {
- error = -ENOMEM;
- info = "could not create null profile";
---
-2.14.2
-
diff --git a/patches.apparmor/0003-doc-ReSTify-apparmor.txt.patch b/patches.apparmor/0003-doc-ReSTify-apparmor.txt.patch
deleted file mode 100644
index 11897aab59..0000000000
--- a/patches.apparmor/0003-doc-ReSTify-apparmor.txt.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 0993c534c86a9019546af0e1f187ba989d25f606 Mon Sep 17 00:00:00 2001
-From: Kees Cook <keescook@chromium.org>
-Date: Sat, 13 May 2017 04:51:45 -0700
-Subject: [PATCH 03/65] doc: ReSTify apparmor.txt
-Git-commit: 26fccd9ed2e283add2849858c28bd14f84d9c48e
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Adjusts for ReST markup and moves under LSM admin guide.
-
-Acked-by: John Johansen <john.johansen@canonical.com>
-Signed-off-by: Kees Cook <keescook@chromium.org>
-Signed-off-by: Jonathan Corbet <corbet@lwn.net>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/match.c | 2 +-
- security/apparmor/policy_unpack.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/match.c b/security/apparmor/match.c
-index 960c913381e2..72c604350e80 100644
---- a/security/apparmor/match.c
-+++ b/security/apparmor/match.c
-@@ -226,7 +226,7 @@ void aa_dfa_free_kref(struct kref *kref)
- * @flags: flags controlling what type of accept tables are acceptable
- *
- * Unpack a dfa that has been serialized. To find information on the dfa
-- * format look in Documentation/security/apparmor.txt
-+ * format look in Documentation/admin-guide/LSM/apparmor.rst
- * Assumes the dfa @blob stream has been aligned on a 8 byte boundary
- *
- * Returns: an unpacked dfa ready for matching or ERR_PTR on failure
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index f3422a91353c..981d570eebba 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -13,7 +13,7 @@
- * License.
- *
- * AppArmor uses a serialized binary format for loading policy. To find
-- * policy format documentation look in Documentation/security/apparmor.txt
-+ * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
- * All policy is validated before it is used.
- */
-
---
-2.12.3
-
diff --git a/patches.apparmor/0004-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch b/patches.apparmor/0004-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch
deleted file mode 100644
index 5c673e3bb7..0000000000
--- a/patches.apparmor/0004-apparmor-Redundant-condition-prev_ns.-in-label.c-149.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From e6ace4325d85f080ea107233e6ff26195ad117c7 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 31 Jul 2017 23:44:37 -0700
-Subject: [PATCH 04/17] apparmor: Redundant condition: prev_ns. in [label.c:1498]
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: c5561700c9cb951ec3a33a0914c840423b09d7c9
-
-Reported-by: David Binderman <dcb314@hotmail.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/label.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index e052eaba1cf6..e324f4df3e34 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -1495,7 +1495,7 @@ static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view,
- view = profiles_ns(profile);
-
- if (view != profile->ns &&
-- (!prev_ns || (prev_ns && *prev_ns != profile->ns))) {
-+ (!prev_ns || (*prev_ns != profile->ns))) {
- if (prev_ns)
- *prev_ns = profile->ns;
- ns_name = aa_ns_name(view, profile->ns,
---
-2.14.1
-
diff --git a/patches.apparmor/0004-apparmor-fix-off-by-one-comparison-on-MAXMAPPED_SIG.patch b/patches.apparmor/0004-apparmor-fix-off-by-one-comparison-on-MAXMAPPED_SIG.patch
deleted file mode 100644
index 541385e3ad..0000000000
--- a/patches.apparmor/0004-apparmor-fix-off-by-one-comparison-on-MAXMAPPED_SIG.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 8731435ab7253baa9d92463a7d6e1d0c1e66d533 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 8 Nov 2017 08:09:52 -0800
-Subject: [PATCH] apparmor: fix off-by-one comparison on MAXMAPPED_SIG
-References: bsc#1071070
-Git-commit: f7dc4c9a855a13dbb33294c9fc94f17af03f6291
-Patch-mainline: v4.14
-
-This came in yesterday, and I have verified our regression tests
-were missing this and it can cause an oops. Please apply.
-
-There is a an off-by-one comparision on sig against MAXMAPPED_SIG
-that can lead to a read outside the sig_map array if sig
-is MAXMAPPED_SIG. Fix this.
-
-Verified that the check is an out of bounds case that can cause an oops.
-
-Revised: add comparison fix to second case
-Fixes: cd1dbf76b23d ("apparmor: add the ability to mediate signals")
-Signed-off-by: Colin Ian King <colin.king@canonical.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/ipc.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
-index 66fb9ede9447..7ca0032e7ba9 100644
---- a/security/apparmor/ipc.c
-+++ b/security/apparmor/ipc.c
-@@ -128,7 +128,7 @@ static inline int map_signal_num(int sig)
- return SIGUNKNOWN;
- else if (sig >= SIGRTMIN)
- return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */
-- else if (sig <= MAXMAPPED_SIG)
-+ else if (sig < MAXMAPPED_SIG)
- return sig_map[sig];
- return SIGUNKNOWN;
- }
-@@ -163,7 +163,7 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)
- audit_signal_mask(ab, aad(sa)->denied);
- }
- }
-- if (aad(sa)->signal <= MAXMAPPED_SIG)
-+ if (aad(sa)->signal < MAXMAPPED_SIG)
- audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
- else
- audit_log_format(ab, " signal=rtmin+%d",
---
-2.14.2
-
diff --git a/patches.apparmor/0004-apparmorfs-Use-seq_putc-in-two-functions.patch b/patches.apparmor/0004-apparmorfs-Use-seq_putc-in-two-functions.patch
deleted file mode 100644
index 46b7151307..0000000000
--- a/patches.apparmor/0004-apparmorfs-Use-seq_putc-in-two-functions.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From dba5a52fead7a98a0a13a98ca43000718321b3bd Mon Sep 17 00:00:00 2001
-From: Markus Elfring <elfring@users.sourceforge.net>
-Date: Sun, 7 May 2017 13:50:28 +0200
-Subject: [PATCH 04/65] apparmorfs: Use seq_putc()
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com> in two functions
-Git-commit: 47dbd1cdbb4e74d656e444deb6675ee38ca1b1f3
-
-Two single characters (line breaks) should be put into a sequence.
-Thus use the corresponding function "seq_putc".
-
-This issue was detected by using the Coccinelle software.
-
-Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
----
- security/apparmor/apparmorfs.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index b4d83e0bc651..41e427a4f051 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -494,7 +494,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
- if (profile->hash) {
- for (i = 0; i < size; i++)
- seq_printf(seq, "%.2x", profile->hash[i]);
-- seq_puts(seq, "\n");
-+ seq_putc(seq, '\n');
- }
- aa_put_profile(profile);
-
-@@ -602,7 +602,7 @@ static int aa_fs_seq_raw_hash_show(struct seq_file *seq, void *v)
- if (profile->rawdata->hash) {
- for (i = 0; i < size; i++)
- seq_printf(seq, "%.2x", profile->rawdata->hash[i]);
-- seq_puts(seq, "\n");
-+ seq_putc(seq, '\n');
- }
- aa_put_profile(profile);
-
---
-2.12.3
-
diff --git a/patches.apparmor/0005-apparmor-Fix-error-cod-in-__aa_fs_profile_mkdir.patch b/patches.apparmor/0005-apparmor-Fix-error-cod-in-__aa_fs_profile_mkdir.patch
deleted file mode 100644
index 9508becfaa..0000000000
--- a/patches.apparmor/0005-apparmor-Fix-error-cod-in-__aa_fs_profile_mkdir.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 71197508dc73905a2a7e6edc3e1e5b053bdd39c6 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Tue, 23 May 2017 17:33:46 +0300
-Subject: [PATCH 05/65] apparmor: Fix error cod in __aa_fs_profile_mkdir()
-Git-commit: ffac1de6cf6f84e47cdb6d6de0629bc534f60961
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-
-We can either return PTR_ERR(NULL) or a PTR_ERR(a valid pointer) here.
-Returning NULL is probably not good, but since this happens at boot
-then we are probably already toasted if we were to hit this bug in real
-life. In other words, it seems like a very low severity bug to me.
-
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
----
- security/apparmor/apparmorfs.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 41e427a4f051..26ad1a370632 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -727,8 +727,10 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
-
- profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
-- if (!profile->dirname)
-- goto fail;
-+ if (!profile->dirname) {
-+ error = -ENOMEM;
-+ goto fail2;
-+ }
-
- mangle_name(profile->base.name, profile->dirname);
- sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
---
-2.12.3
-
diff --git a/patches.apparmor/0005-apparmor-add-the-ability-to-mediate-signals.patch b/patches.apparmor/0005-apparmor-add-the-ability-to-mediate-signals.patch
deleted file mode 100644
index 46f374c241..0000000000
--- a/patches.apparmor/0005-apparmor-add-the-ability-to-mediate-signals.patch
+++ /dev/null
@@ -1,400 +0,0 @@
-From 5f840316deac0e4c2d6226c48c1c513412cd2112 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Tue, 18 Jul 2017 22:56:22 -0700
-Subject: [PATCH 05/17] apparmor: add the ability to mediate signals
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: cd1dbf76b23d5ab2cba5e657fe20b1e236a408cc
-
-Add signal mediation where the signal can be mediated based on the
-signal, direction, or the label or the peer/target. The signal perms
-are verified on a cross check to ensure policy consistency in the case
-of incremental policy load/replacement.
-
-The optimization of skipping the cross check when policy is guaranteed
-to be consistent (single compile unit) remains to be done.
-
-policy rules have the form of
- SIGNAL_RULE = [ QUALIFIERS ] 'signal' [ SIGNAL ACCESS PERMISSIONS ]
- [ SIGNAL SET ] [ SIGNAL PEER ]
-
- SIGNAL ACCESS PERMISSIONS = SIGNAL ACCESS | SIGNAL ACCESS LIST
-
- SIGNAL ACCESS LIST = '(' Comma or space separated list of SIGNAL
- ACCESS ')'
-
- SIGNAL ACCESS = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'send' |
- 'receive' )
-
- SIGNAL SET = 'set' '=' '(' SIGNAL LIST ')'
-
- SIGNAL LIST = Comma or space separated list of SIGNALS
-
- SIGNALS = ( 'hup' | 'int' | 'quit' | 'ill' | 'trap' | 'abrt' |
- 'bus' | 'fpe' | 'kill' | 'usr1' | 'segv' | 'usr2' |
- 'pipe' | 'alrm' | 'term' | 'stkflt' | 'chld' | 'cont' |
- 'stop' | 'stp' | 'ttin' | 'ttou' | 'urg' | 'xcpu' |
- 'xfsz' | 'vtalrm' | 'prof' | 'winch' | 'io' | 'pwr' |
- 'sys' | 'emt' | 'exists' | 'rtmin+0' ... 'rtmin+32'
- )
-
- SIGNAL PEER = 'peer' '=' AARE
-
-eg.
- signal, # allow all signals
- signal send set=(hup, kill) peer=foo,
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 7 +++
- security/apparmor/include/apparmor.h | 1 +
- security/apparmor/include/audit.h | 2 +
- security/apparmor/include/ipc.h | 6 +++
- security/apparmor/include/sig_names.h | 95 +++++++++++++++++++++++++++++++++
- security/apparmor/ipc.c | 99 +++++++++++++++++++++++++++++++++++
- security/apparmor/lsm.c | 21 ++++++++
- 7 files changed, 231 insertions(+)
- create mode 100644 security/apparmor/include/sig_names.h
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 2caeb748070c..a5f9e1aa51f7 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -32,6 +32,7 @@
- #include "include/audit.h"
- #include "include/context.h"
- #include "include/crypto.h"
-+#include "include/ipc.h"
- #include "include/policy_ns.h"
- #include "include/label.h"
- #include "include/policy.h"
-@@ -2129,6 +2130,11 @@ static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
- { }
- };
-
-+static struct aa_sfs_entry aa_sfs_entry_signal[] = {
-+ AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
-+ { }
-+};
-+
- static struct aa_sfs_entry aa_sfs_entry_domain[] = {
- AA_SFS_FILE_BOOLEAN("change_hat", 1),
- AA_SFS_FILE_BOOLEAN("change_hatv", 1),
-@@ -2179,6 +2185,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
- AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
- AA_SFS_DIR("caps", aa_sfs_entry_caps),
- AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
-+ AA_SFS_DIR("signal", aa_sfs_entry_signal),
- AA_SFS_DIR("query", aa_sfs_entry_query),
- { }
- };
-diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
-index aaf893f4e4f5..962a20a75e01 100644
---- a/security/apparmor/include/apparmor.h
-+++ b/security/apparmor/include/apparmor.h
-@@ -28,6 +28,7 @@
- #define AA_CLASS_RLIMITS 5
- #define AA_CLASS_DOMAIN 6
- #define AA_CLASS_PTRACE 9
-+#define AA_CLASS_SIGNAL 10
- #define AA_CLASS_LABEL 16
-
- #define AA_CLASS_LAST AA_CLASS_LABEL
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index c68839a44351..d9a156ae11b9 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -86,6 +86,7 @@ enum audit_type {
- #define OP_SHUTDOWN "socket_shutdown"
-
- #define OP_PTRACE "ptrace"
-+#define OP_SIGNAL "signal"
-
- #define OP_EXEC "exec"
-
-@@ -126,6 +127,7 @@ struct apparmor_audit_data {
- long pos;
- const char *ns;
- } iface;
-+ int signal;
- struct {
- int rlim;
- unsigned long max;
-diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
-index 656fdb81c8a0..5ffc218d1e74 100644
---- a/security/apparmor/include/ipc.h
-+++ b/security/apparmor/include/ipc.h
-@@ -27,8 +27,14 @@ struct aa_profile;
-
- #define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \
- AA_MAY_BE_READ | AA_MAY_BE_TRACED)
-+#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE)
-+
-+#define AA_SFS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \
-+ "segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
-+ "xcpu xfsz vtalrm prof winch io pwr sys emt lost"
-
- int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- u32 request);
-+int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
-
- #endif /* __AA_IPC_H */
-diff --git a/security/apparmor/include/sig_names.h b/security/apparmor/include/sig_names.h
-new file mode 100644
-index 000000000000..0d4395f231ca
---- /dev/null
-+++ b/security/apparmor/include/sig_names.h
-@@ -0,0 +1,95 @@
-+#include <linux/signal.h>
-+
-+#define SIGUNKNOWN 0
-+#define MAXMAPPED_SIG 35
-+/* provide a mapping of arch signal to internal signal # for mediation
-+ * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO
-+ * map to the same entry those that may/or may not get a separate entry
-+ */
-+static const int sig_map[MAXMAPPED_SIG] = {
-+ [0] = MAXMAPPED_SIG, /* existence test */
-+ [SIGHUP] = 1,
-+ [SIGINT] = 2,
-+ [SIGQUIT] = 3,
-+ [SIGILL] = 4,
-+ [SIGTRAP] = 5, /* -, 5, - */
-+ [SIGABRT] = 6, /* SIGIOT: -, 6, - */
-+ [SIGBUS] = 7, /* 10, 7, 10 */
-+ [SIGFPE] = 8,
-+ [SIGKILL] = 9,
-+ [SIGUSR1] = 10, /* 30, 10, 16 */
-+ [SIGSEGV] = 11,
-+ [SIGUSR2] = 12, /* 31, 12, 17 */
-+ [SIGPIPE] = 13,
-+ [SIGALRM] = 14,
-+ [SIGTERM] = 15,
-+ [SIGSTKFLT] = 16, /* -, 16, - */
-+ [SIGCHLD] = 17, /* 20, 17, 18. SIGCHLD -, -, 18 */
-+ [SIGCONT] = 18, /* 19, 18, 25 */
-+ [SIGSTOP] = 19, /* 17, 19, 23 */
-+ [SIGTSTP] = 20, /* 18, 20, 24 */
-+ [SIGTTIN] = 21, /* 21, 21, 26 */
-+ [SIGTTOU] = 22, /* 22, 22, 27 */
-+ [SIGURG] = 23, /* 16, 23, 21 */
-+ [SIGXCPU] = 24, /* 24, 24, 30 */
-+ [SIGXFSZ] = 25, /* 25, 25, 31 */
-+ [SIGVTALRM] = 26, /* 26, 26, 28 */
-+ [SIGPROF] = 27, /* 27, 27, 29 */
-+ [SIGWINCH] = 28, /* 28, 28, 20 */
-+ [SIGIO] = 29, /* SIGPOLL: 23, 29, 22 */
-+ [SIGPWR] = 30, /* 29, 30, 19. SIGINFO 29, -, - */
-+#ifdef SIGSYS
-+ [SIGSYS] = 31, /* 12, 31, 12. often SIG LOST/UNUSED */
-+#endif
-+#ifdef SIGEMT
-+ [SIGEMT] = 32, /* 7, - , 7 */
-+#endif
-+#if defined(SIGLOST) && SIGPWR != SIGLOST /* sparc */
-+ [SIGLOST] = 33, /* unused on Linux */
-+#endif
-+#if defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
-+ [SIGUNUSED] = 34, /* -, 31, - */
-+#endif
-+};
-+
-+/* this table is ordered post sig_map[sig] mapping */
-+static const char *const sig_names[MAXMAPPED_SIG + 1] = {
-+ "unknown",
-+ "hup",
-+ "int",
-+ "quit",
-+ "ill",
-+ "trap",
-+ "abrt",
-+ "bus",
-+ "fpe",
-+ "kill",
-+ "usr1",
-+ "segv",
-+ "usr2",
-+ "pipe",
-+ "alrm",
-+ "term",
-+ "stkflt",
-+ "chld",
-+ "cont",
-+ "stop",
-+ "stp",
-+ "ttin",
-+ "ttou",
-+ "urg",
-+ "xcpu",
-+ "xfsz",
-+ "vtalrm",
-+ "prof",
-+ "winch",
-+ "io",
-+ "pwr",
-+ "sys",
-+ "emt",
-+ "lost",
-+ "unused",
-+
-+ "exists", /* always last existence test mapped to MAXMAPPED_SIG */
-+};
-+
-diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
-index 11e66b5bbc42..66fb9ede9447 100644
---- a/security/apparmor/ipc.c
-+++ b/security/apparmor/ipc.c
-@@ -20,6 +20,7 @@
- #include "include/context.h"
- #include "include/policy.h"
- #include "include/ipc.h"
-+#include "include/sig_names.h"
-
- /**
- * audit_ptrace_mask - convert mask to permission string
-@@ -121,3 +122,101 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- }
-
-
-+static inline int map_signal_num(int sig)
-+{
-+ if (sig > SIGRTMAX)
-+ return SIGUNKNOWN;
-+ else if (sig >= SIGRTMIN)
-+ return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */
-+ else if (sig <= MAXMAPPED_SIG)
-+ return sig_map[sig];
-+ return SIGUNKNOWN;
-+}
-+
-+/**
-+ * audit_file_mask - convert mask to permission string
-+ * @buffer: buffer to write string to (NOT NULL)
-+ * @mask: permission mask to convert
-+ */
-+static void audit_signal_mask(struct audit_buffer *ab, u32 mask)
-+{
-+ if (mask & MAY_READ)
-+ audit_log_string(ab, "receive");
-+ if (mask & MAY_WRITE)
-+ audit_log_string(ab, "send");
-+}
-+
-+/**
-+ * audit_cb - call back for signal specific audit fields
-+ * @ab: audit_buffer (NOT NULL)
-+ * @va: audit struct to audit values of (NOT NULL)
-+ */
-+static void audit_signal_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct common_audit_data *sa = va;
-+
-+ if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
-+ audit_log_format(ab, " requested_mask=");
-+ audit_signal_mask(ab, aad(sa)->request);
-+ if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
-+ audit_log_format(ab, " denied_mask=");
-+ audit_signal_mask(ab, aad(sa)->denied);
-+ }
-+ }
-+ if (aad(sa)->signal <= MAXMAPPED_SIG)
-+ audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
-+ else
-+ audit_log_format(ab, " signal=rtmin+%d",
-+ aad(sa)->signal - 128);
-+ audit_log_format(ab, " peer=");
-+ aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
-+ FLAGS_NONE, GFP_ATOMIC);
-+}
-+
-+/* TODO: update to handle compound name&name2, conditionals */
-+static void profile_match_signal(struct aa_profile *profile, const char *label,
-+ int signal, struct aa_perms *perms)
-+{
-+ unsigned int state;
-+
-+ /* TODO: secondary cache check <profile, profile, perm> */
-+ state = aa_dfa_next(profile->policy.dfa,
-+ profile->policy.start[AA_CLASS_SIGNAL],
-+ signal);
-+ state = aa_dfa_match(profile->policy.dfa, state, label);
-+ aa_compute_perms(profile->policy.dfa, state, perms);
-+}
-+
-+static int profile_signal_perm(struct aa_profile *profile,
-+ struct aa_profile *peer, u32 request,
-+ struct common_audit_data *sa)
-+{
-+ struct aa_perms perms;
-+
-+ if (profile_unconfined(profile) ||
-+ !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL))
-+ return 0;
-+
-+ aad(sa)->peer = &peer->label;
-+ profile_match_signal(profile, peer->base.hname, aad(sa)->signal,
-+ &perms);
-+ aa_apply_modes_to_perms(profile, &perms);
-+ return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
-+}
-+
-+static int aa_signal_cross_perm(struct aa_profile *sender,
-+ struct aa_profile *target,
-+ struct common_audit_data *sa)
-+{
-+ return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa),
-+ profile_signal_perm(target, sender, MAY_READ, sa));
-+}
-+
-+int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
-+{
-+ DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL);
-+
-+ aad(&sa)->signal = map_signal_num(sig);
-+ return xcheck_labels_profiles(sender, target, aa_signal_cross_perm,
-+ &sa);
-+}
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 867bcd154c7e..af22f3dfbcce 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -656,6 +656,26 @@ static int apparmor_task_setrlimit(struct task_struct *task,
- return error;
- }
-
-+static int apparmor_task_kill(struct task_struct *target, struct siginfo *info,
-+ int sig, u32 secid)
-+{
-+ struct aa_label *cl, *tl;
-+ int error;
-+
-+ if (secid)
-+ /* TODO: after secid to label mapping is done.
-+ * Dealing with USB IO specific behavior
-+ */
-+ return 0;
-+ cl = __begin_current_label_crit_section();
-+ tl = aa_get_task_label(target);
-+ error = aa_may_signal(cl, tl, sig);
-+ aa_put_label(tl);
-+ __end_current_label_crit_section(cl);
-+
-+ return error;
-+}
-+
- static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
- LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
- LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
-@@ -697,6 +717,7 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
- LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec),
-
- LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
-+ LSM_HOOK_INIT(task_kill, apparmor_task_kill),
- };
-
- /*
---
-2.14.1
-
diff --git a/patches.apparmor/0006-apparmor-add-mount-mediation.patch b/patches.apparmor/0006-apparmor-add-mount-mediation.patch
deleted file mode 100644
index 7446f46219..0000000000
--- a/patches.apparmor/0006-apparmor-add-mount-mediation.patch
+++ /dev/null
@@ -1,1054 +0,0 @@
-From 644d641569e060735a06232b53f321c6c62c0947 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Tue, 18 Jul 2017 23:04:47 -0700
-Subject: [PATCH 06/17] apparmor: add mount mediation
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 2ea3ffb7782a84da33a8382f13ebd016da50079b
-
-Add basic mount mediation. That allows controlling based on basic
-mount parameters. It does not include special mount parameters for
-apparmor, super block labeling, or any triggers for apparmor namespace
-parameter modifications on pivot root.
-
-default userspace policy rules have the form of
- MOUNT RULE = ( MOUNT | REMOUNT | UMOUNT )
-
- MOUNT = [ QUALIFIERS ] 'mount' [ MOUNT CONDITIONS ] [ SOURCE FILEGLOB ]
- [ '->' MOUNTPOINT FILEGLOB ]
-
- REMOUNT = [ QUALIFIERS ] 'remount' [ MOUNT CONDITIONS ]
- MOUNTPOINT FILEGLOB
-
- UMOUNT = [ QUALIFIERS ] 'umount' [ MOUNT CONDITIONS ] MOUNTPOINT FILEGLOB
-
- MOUNT CONDITIONS = [ ( 'fstype' | 'vfstype' ) ( '=' | 'in' )
- MOUNT FSTYPE EXPRESSION ]
- [ 'options' ( '=' | 'in' ) MOUNT FLAGS EXPRESSION ]
-
- MOUNT FSTYPE EXPRESSION = ( MOUNT FSTYPE LIST | MOUNT EXPRESSION )
-
- MOUNT FSTYPE LIST = Comma separated list of valid filesystem and
- virtual filesystem types (eg ext4, debugfs, etc)
-
- MOUNT FLAGS EXPRESSION = ( MOUNT FLAGS LIST | MOUNT EXPRESSION )
-
- MOUNT FLAGS LIST = Comma separated list of MOUNT FLAGS.
-
- MOUNT FLAGS = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' |
- 'noexec' | 'exec' | 'sync' | 'async' | 'remount' |
- 'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' |
- 'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' |
- 'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' |
- 'unbindable' | 'runbindable' | 'private' | 'rprivate' |
- 'slave' | 'rslave' | 'shared' | 'rshared' |
- 'relatime' | 'norelatime' | 'iversion' | 'noiversion' |
- 'strictatime' | 'nouser' | 'user' )
-
- MOUNT EXPRESSION = ( ALPHANUMERIC | AARE ) ...
-
- PIVOT ROOT RULE = [ QUALIFIERS ] pivot_root [ oldroot=OLD PUT FILEGLOB ]
- [ NEW ROOT FILEGLOB ]
-
- SOURCE FILEGLOB = FILEGLOB
-
- MOUNTPOINT FILEGLOB = FILEGLOB
-
-eg.
- mount,
- mount /dev/foo,
- mount options=ro /dev/foo -> /mnt/,
- mount options in (ro,atime) /dev/foo -> /mnt/,
- mount options=ro options=atime,
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/Makefile | 2 +-
- security/apparmor/apparmorfs.c | 8 +-
- security/apparmor/domain.c | 4 +-
- security/apparmor/include/apparmor.h | 1 +
- security/apparmor/include/audit.h | 11 +
- security/apparmor/include/domain.h | 5 +
- security/apparmor/include/mount.h | 54 +++
- security/apparmor/lsm.c | 64 ++++
- security/apparmor/mount.c | 696 +++++++++++++++++++++++++++++++++++
- 9 files changed, 841 insertions(+), 4 deletions(-)
- create mode 100644 security/apparmor/include/mount.h
- create mode 100644 security/apparmor/mount.c
-
-diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
-index a16b195274de..81a34426d024 100644
---- a/security/apparmor/Makefile
-+++ b/security/apparmor/Makefile
-@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
-
- apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
- path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-- resource.o secid.o file.o policy_ns.o label.o
-+ resource.o secid.o file.o policy_ns.o label.o mount.o
- apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
-
- clean-files := capability_names.h rlim_names.h
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index a5f9e1aa51f7..8fa6c898c44b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -2159,9 +2159,14 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
- { }
- };
-
-+static struct aa_sfs_entry aa_sfs_entry_mount[] = {
-+ AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
-+ { }
-+};
-+
- static struct aa_sfs_entry aa_sfs_entry_ns[] = {
- AA_SFS_FILE_BOOLEAN("profile", 1),
-- AA_SFS_FILE_BOOLEAN("pivot_root", 1),
-+ AA_SFS_FILE_BOOLEAN("pivot_root", 0),
- { }
- };
-
-@@ -2180,6 +2185,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
- AA_SFS_DIR("policy", aa_sfs_entry_policy),
- AA_SFS_DIR("domain", aa_sfs_entry_domain),
- AA_SFS_DIR("file", aa_sfs_entry_file),
-+ AA_SFS_DIR("mount", aa_sfs_entry_mount),
- AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
- AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
- AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index d0594446ae3f..ffc8c75a6785 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -374,8 +374,8 @@ static const char *next_name(int xtype, const char *name)
- *
- * Returns: refcounted label, or NULL on failure (MAYBE NULL)
- */
--static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
-- const char **name)
-+struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
-+ const char **name)
- {
- struct aa_label *label = NULL;
- u32 xtype = xindex & AA_X_TYPE_MASK;
-diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
-index 962a20a75e01..829082c35faa 100644
---- a/security/apparmor/include/apparmor.h
-+++ b/security/apparmor/include/apparmor.h
-@@ -27,6 +27,7 @@
- #define AA_CLASS_NET 4
- #define AA_CLASS_RLIMITS 5
- #define AA_CLASS_DOMAIN 6
-+#define AA_CLASS_MOUNT 7
- #define AA_CLASS_PTRACE 9
- #define AA_CLASS_SIGNAL 10
- #define AA_CLASS_LABEL 16
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index d9a156ae11b9..c3fe1c5ef3bc 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -71,6 +71,10 @@ enum audit_type {
- #define OP_FMPROT "file_mprotect"
- #define OP_INHERIT "file_inherit"
-
-+#define OP_PIVOTROOT "pivotroot"
-+#define OP_MOUNT "mount"
-+#define OP_UMOUNT "umount"
-+
- #define OP_CREATE "create"
- #define OP_POST_CREATE "post_create"
- #define OP_BIND "bind"
-@@ -132,6 +136,13 @@ struct apparmor_audit_data {
- int rlim;
- unsigned long max;
- } rlim;
-+ struct {
-+ const char *src_name;
-+ const char *type;
-+ const char *trans;
-+ const char *data;
-+ unsigned long flags;
-+ } mnt;
- };
- };
-
-diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
-index bab5810b6e9a..db27403346c5 100644
---- a/security/apparmor/include/domain.h
-+++ b/security/apparmor/include/domain.h
-@@ -15,6 +15,8 @@
- #include <linux/binfmts.h>
- #include <linux/types.h>
-
-+#include "label.h"
-+
- #ifndef __AA_DOMAIN_H
- #define __AA_DOMAIN_H
-
-@@ -29,6 +31,9 @@ struct aa_domain {
- #define AA_CHANGE_ONEXEC 4
- #define AA_CHANGE_STACK 8
-
-+struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
-+ const char **name);
-+
- int apparmor_bprm_set_creds(struct linux_binprm *bprm);
- int apparmor_bprm_secureexec(struct linux_binprm *bprm);
-
-diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
-new file mode 100644
-index 000000000000..25d6067fa6ef
---- /dev/null
-+++ b/security/apparmor/include/mount.h
-@@ -0,0 +1,54 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor file mediation function definitions.
-+ *
-+ * Copyright 2017 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_MOUNT_H
-+#define __AA_MOUNT_H
-+
-+#include <linux/fs.h>
-+#include <linux/path.h>
-+
-+#include "domain.h"
-+#include "policy.h"
-+
-+/* mount perms */
-+#define AA_MAY_PIVOTROOT 0x01
-+#define AA_MAY_MOUNT 0x02
-+#define AA_MAY_UMOUNT 0x04
-+#define AA_AUDIT_DATA 0x40
-+#define AA_MNT_CONT_MATCH 0x40
-+
-+#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
-+
-+int aa_remount(struct aa_label *label, const struct path *path,
-+ unsigned long flags, void *data);
-+
-+int aa_bind_mount(struct aa_label *label, const struct path *path,
-+ const char *old_name, unsigned long flags);
-+
-+
-+int aa_mount_change_type(struct aa_label *label, const struct path *path,
-+ unsigned long flags);
-+
-+int aa_move_mount(struct aa_label *label, const struct path *path,
-+ const char *old_name);
-+
-+int aa_new_mount(struct aa_label *label, const char *dev_name,
-+ const struct path *path, const char *type, unsigned long flags,
-+ void *data);
-+
-+int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags);
-+
-+int aa_pivotroot(struct aa_label *label, const struct path *old_path,
-+ const struct path *new_path);
-+
-+#endif /* __AA_MOUNT_H */
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index af22f3dfbcce..4ad0b3a45142 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -38,6 +38,7 @@
- #include "include/policy.h"
- #include "include/policy_ns.h"
- #include "include/procattr.h"
-+#include "include/mount.h"
-
- /* Flag indicating whether initialization completed */
- int apparmor_initialized;
-@@ -511,6 +512,65 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma,
- !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
- }
-
-+static int apparmor_sb_mount(const char *dev_name, const struct path *path,
-+ const char *type, unsigned long flags, void *data)
-+{
-+ struct aa_label *label;
-+ int error = 0;
-+
-+ /* Discard magic */
-+ if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
-+ flags &= ~MS_MGC_MSK;
-+
-+ flags &= ~AA_MS_IGNORE_MASK;
-+
-+ label = __begin_current_label_crit_section();
-+ if (!unconfined(label)) {
-+ if (flags & MS_REMOUNT)
-+ error = aa_remount(label, path, flags, data);
-+ else if (flags & MS_BIND)
-+ error = aa_bind_mount(label, path, dev_name, flags);
-+ else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
-+ MS_UNBINDABLE))
-+ error = aa_mount_change_type(label, path, flags);
-+ else if (flags & MS_MOVE)
-+ error = aa_move_mount(label, path, dev_name);
-+ else
-+ error = aa_new_mount(label, dev_name, path, type,
-+ flags, data);
-+ }
-+ __end_current_label_crit_section(label);
-+
-+ return error;
-+}
-+
-+static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
-+{
-+ struct aa_label *label;
-+ int error = 0;
-+
-+ label = __begin_current_label_crit_section();
-+ if (!unconfined(label))
-+ error = aa_umount(label, mnt, flags);
-+ __end_current_label_crit_section(label);
-+
-+ return error;
-+}
-+
-+static int apparmor_sb_pivotroot(const struct path *old_path,
-+ const struct path *new_path)
-+{
-+ struct aa_label *label;
-+ int error = 0;
-+
-+ label = aa_get_current_label();
-+ if (!unconfined(label))
-+ error = aa_pivotroot(label, old_path, new_path);
-+ aa_put_label(label);
-+
-+ return error;
-+}
-+
- static int apparmor_getprocattr(struct task_struct *task, char *name,
- char **value)
- {
-@@ -682,6 +742,10 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
- LSM_HOOK_INIT(capget, apparmor_capget),
- LSM_HOOK_INIT(capable, apparmor_capable),
-
-+ LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
-+ LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
-+ LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
-+
- LSM_HOOK_INIT(path_link, apparmor_path_link),
- LSM_HOOK_INIT(path_unlink, apparmor_path_unlink),
- LSM_HOOK_INIT(path_symlink, apparmor_path_symlink),
-diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
-new file mode 100644
-index 000000000000..82a64b58041d
---- /dev/null
-+++ b/security/apparmor/mount.c
-@@ -0,0 +1,696 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor mediation of files
-+ *
-+ * Copyright (C) 1998-2008 Novell/SUSE
-+ * Copyright 2009-2017 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/fs.h>
-+#include <linux/mount.h>
-+#include <linux/namei.h>
-+
-+#include "include/apparmor.h"
-+#include "include/audit.h"
-+#include "include/context.h"
-+#include "include/domain.h"
-+#include "include/file.h"
-+#include "include/match.h"
-+#include "include/mount.h"
-+#include "include/path.h"
-+#include "include/policy.h"
-+
-+
-+static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
-+{
-+ if (flags & MS_RDONLY)
-+ audit_log_format(ab, "ro");
-+ else
-+ audit_log_format(ab, "rw");
-+ if (flags & MS_NOSUID)
-+ audit_log_format(ab, ", nosuid");
-+ if (flags & MS_NODEV)
-+ audit_log_format(ab, ", nodev");
-+ if (flags & MS_NOEXEC)
-+ audit_log_format(ab, ", noexec");
-+ if (flags & MS_SYNCHRONOUS)
-+ audit_log_format(ab, ", sync");
-+ if (flags & MS_REMOUNT)
-+ audit_log_format(ab, ", remount");
-+ if (flags & MS_MANDLOCK)
-+ audit_log_format(ab, ", mand");
-+ if (flags & MS_DIRSYNC)
-+ audit_log_format(ab, ", dirsync");
-+ if (flags & MS_NOATIME)
-+ audit_log_format(ab, ", noatime");
-+ if (flags & MS_NODIRATIME)
-+ audit_log_format(ab, ", nodiratime");
-+ if (flags & MS_BIND)
-+ audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind");
-+ if (flags & MS_MOVE)
-+ audit_log_format(ab, ", move");
-+ if (flags & MS_SILENT)
-+ audit_log_format(ab, ", silent");
-+ if (flags & MS_POSIXACL)
-+ audit_log_format(ab, ", acl");
-+ if (flags & MS_UNBINDABLE)
-+ audit_log_format(ab, flags & MS_REC ? ", runbindable" :
-+ ", unbindable");
-+ if (flags & MS_PRIVATE)
-+ audit_log_format(ab, flags & MS_REC ? ", rprivate" :
-+ ", private");
-+ if (flags & MS_SLAVE)
-+ audit_log_format(ab, flags & MS_REC ? ", rslave" :
-+ ", slave");
-+ if (flags & MS_SHARED)
-+ audit_log_format(ab, flags & MS_REC ? ", rshared" :
-+ ", shared");
-+ if (flags & MS_RELATIME)
-+ audit_log_format(ab, ", relatime");
-+ if (flags & MS_I_VERSION)
-+ audit_log_format(ab, ", iversion");
-+ if (flags & MS_STRICTATIME)
-+ audit_log_format(ab, ", strictatime");
-+ if (flags & MS_NOUSER)
-+ audit_log_format(ab, ", nouser");
-+}
-+
-+/**
-+ * audit_cb - call back for mount specific audit fields
-+ * @ab: audit_buffer (NOT NULL)
-+ * @va: audit struct to audit values of (NOT NULL)
-+ */
-+static void audit_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct common_audit_data *sa = va;
-+
-+ if (aad(sa)->mnt.type) {
-+ audit_log_format(ab, " fstype=");
-+ audit_log_untrustedstring(ab, aad(sa)->mnt.type);
-+ }
-+ if (aad(sa)->mnt.src_name) {
-+ audit_log_format(ab, " srcname=");
-+ audit_log_untrustedstring(ab, aad(sa)->mnt.src_name);
-+ }
-+ if (aad(sa)->mnt.trans) {
-+ audit_log_format(ab, " trans=");
-+ audit_log_untrustedstring(ab, aad(sa)->mnt.trans);
-+ }
-+ if (aad(sa)->mnt.flags) {
-+ audit_log_format(ab, " flags=\"");
-+ audit_mnt_flags(ab, aad(sa)->mnt.flags);
-+ audit_log_format(ab, "\"");
-+ }
-+ if (aad(sa)->mnt.data) {
-+ audit_log_format(ab, " options=");
-+ audit_log_untrustedstring(ab, aad(sa)->mnt.data);
-+ }
-+}
-+
-+/**
-+ * audit_mount - handle the auditing of mount operations
-+ * @profile: the profile being enforced (NOT NULL)
-+ * @op: operation being mediated (NOT NULL)
-+ * @name: name of object being mediated (MAYBE NULL)
-+ * @src_name: src_name of object being mediated (MAYBE_NULL)
-+ * @type: type of filesystem (MAYBE_NULL)
-+ * @trans: name of trans (MAYBE NULL)
-+ * @flags: filesystem idependent mount flags
-+ * @data: filesystem mount flags
-+ * @request: permissions requested
-+ * @perms: the permissions computed for the request (NOT NULL)
-+ * @info: extra information message (MAYBE NULL)
-+ * @error: 0 if operation allowed else failure error code
-+ *
-+ * Returns: %0 or error on failure
-+ */
-+static int audit_mount(struct aa_profile *profile, const char *op,
-+ const char *name, const char *src_name,
-+ const char *type, const char *trans,
-+ unsigned long flags, const void *data, u32 request,
-+ struct aa_perms *perms, const char *info, int error)
-+{
-+ int audit_type = AUDIT_APPARMOR_AUTO;
-+ DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
-+
-+ if (likely(!error)) {
-+ u32 mask = perms->audit;
-+
-+ if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
-+ mask = 0xffff;
-+
-+ /* mask off perms that are not being force audited */
-+ request &= mask;
-+
-+ if (likely(!request))
-+ return 0;
-+ audit_type = AUDIT_APPARMOR_AUDIT;
-+ } else {
-+ /* only report permissions that were denied */
-+ request = request & ~perms->allow;
-+
-+ if (request & perms->kill)
-+ audit_type = AUDIT_APPARMOR_KILL;
-+
-+ /* quiet known rejects, assumes quiet and kill do not overlap */
-+ if ((request & perms->quiet) &&
-+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
-+ AUDIT_MODE(profile) != AUDIT_ALL)
-+ request &= ~perms->quiet;
-+
-+ if (!request)
-+ return error;
-+ }
-+
-+ aad(&sa)->name = name;
-+ aad(&sa)->mnt.src_name = src_name;
-+ aad(&sa)->mnt.type = type;
-+ aad(&sa)->mnt.trans = trans;
-+ aad(&sa)->mnt.flags = flags;
-+ if (data && (perms->audit & AA_AUDIT_DATA))
-+ aad(&sa)->mnt.data = data;
-+ aad(&sa)->info = info;
-+ aad(&sa)->error = error;
-+
-+ return aa_audit(audit_type, profile, &sa, audit_cb);
-+}
-+
-+/**
-+ * match_mnt_flags - Do an ordered match on mount flags
-+ * @dfa: dfa to match against
-+ * @state: state to start in
-+ * @flags: mount flags to match against
-+ *
-+ * Mount flags are encoded as an ordered match. This is done instead of
-+ * checking against a simple bitmask, to allow for logical operations
-+ * on the flags.
-+ *
-+ * Returns: next state after flags match
-+ */
-+static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state,
-+ unsigned long flags)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i <= 31 ; ++i) {
-+ if ((1 << i) & flags)
-+ state = aa_dfa_next(dfa, state, i + 1);
-+ }
-+
-+ return state;
-+}
-+
-+/**
-+ * compute_mnt_perms - compute mount permission associated with @state
-+ * @dfa: dfa to match against (NOT NULL)
-+ * @state: state match finished in
-+ *
-+ * Returns: mount permissions
-+ */
-+static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa,
-+ unsigned int state)
-+{
-+ struct aa_perms perms;
-+
-+ perms.kill = 0;
-+ perms.allow = dfa_user_allow(dfa, state);
-+ perms.audit = dfa_user_audit(dfa, state);
-+ perms.quiet = dfa_user_quiet(dfa, state);
-+ perms.xindex = dfa_user_xindex(dfa, state);
-+
-+ return perms;
-+}
-+
-+static const char * const mnt_info_table[] = {
-+ "match succeeded",
-+ "failed mntpnt match",
-+ "failed srcname match",
-+ "failed type match",
-+ "failed flags match",
-+ "failed data match"
-+};
-+
-+/*
-+ * Returns 0 on success else element that match failed in, this is the
-+ * index into the mnt_info_table above
-+ */
-+static int do_match_mnt(struct aa_dfa *dfa, unsigned int start,
-+ const char *mntpnt, const char *devname,
-+ const char *type, unsigned long flags,
-+ void *data, bool binary, struct aa_perms *perms)
-+{
-+ unsigned int state;
-+
-+ AA_BUG(!dfa);
-+ AA_BUG(!perms);
-+
-+ state = aa_dfa_match(dfa, start, mntpnt);
-+ state = aa_dfa_null_transition(dfa, state);
-+ if (!state)
-+ return 1;
-+
-+ if (devname)
-+ state = aa_dfa_match(dfa, state, devname);
-+ state = aa_dfa_null_transition(dfa, state);
-+ if (!state)
-+ return 2;
-+
-+ if (type)
-+ state = aa_dfa_match(dfa, state, type);
-+ state = aa_dfa_null_transition(dfa, state);
-+ if (!state)
-+ return 3;
-+
-+ state = match_mnt_flags(dfa, state, flags);
-+ if (!state)
-+ return 4;
-+ *perms = compute_mnt_perms(dfa, state);
-+ if (perms->allow & AA_MAY_MOUNT)
-+ return 0;
-+
-+ /* only match data if not binary and the DFA flags data is expected */
-+ if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) {
-+ state = aa_dfa_null_transition(dfa, state);
-+ if (!state)
-+ return 4;
-+
-+ state = aa_dfa_match(dfa, state, data);
-+ if (!state)
-+ return 5;
-+ *perms = compute_mnt_perms(dfa, state);
-+ if (perms->allow & AA_MAY_MOUNT)
-+ return 0;
-+ }
-+
-+ /* failed at end of flags match */
-+ return 4;
-+}
-+
-+
-+static int path_flags(struct aa_profile *profile, const struct path *path)
-+{
-+ AA_BUG(!profile);
-+ AA_BUG(!path);
-+
-+ return profile->path_flags |
-+ (S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0);
-+}
-+
-+/**
-+ * match_mnt_path_str - handle path matching for mount
-+ * @profile: the confining profile
-+ * @mntpath: for the mntpnt (NOT NULL)
-+ * @buffer: buffer to be used to lookup mntpath
-+ * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR)
-+ * @type: string for the dev type (MAYBE NULL)
-+ * @flags: mount flags to match
-+ * @data: fs mount data (MAYBE NULL)
-+ * @binary: whether @data is binary
-+ * @devinfo: error str if (IS_ERR(@devname))
-+ *
-+ * Returns: 0 on success else error
-+ */
-+static int match_mnt_path_str(struct aa_profile *profile,
-+ const struct path *mntpath, char *buffer,
-+ const char *devname, const char *type,
-+ unsigned long flags, void *data, bool binary,
-+ const char *devinfo)
-+{
-+ struct aa_perms perms = { };
-+ const char *mntpnt = NULL, *info = NULL;
-+ int pos, error;
-+
-+ AA_BUG(!profile);
-+ AA_BUG(!mntpath);
-+ AA_BUG(!buffer);
-+
-+ error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer,
-+ &mntpnt, &info, profile->disconnected);
-+ if (error)
-+ goto audit;
-+ if (IS_ERR(devname)) {
-+ error = PTR_ERR(devname);
-+ devname = NULL;
-+ info = devinfo;
-+ goto audit;
-+ }
-+
-+ error = -EACCES;
-+ pos = do_match_mnt(profile->policy.dfa,
-+ profile->policy.start[AA_CLASS_MOUNT],
-+ mntpnt, devname, type, flags, data, binary, &perms);
-+ if (pos) {
-+ info = mnt_info_table[pos];
-+ goto audit;
-+ }
-+ error = 0;
-+
-+audit:
-+ return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL,
-+ flags, data, AA_MAY_MOUNT, &perms, info, error);
-+}
-+
-+/**
-+ * match_mnt - handle path matching for mount
-+ * @profile: the confining profile
-+ * @mntpath: for the mntpnt (NOT NULL)
-+ * @buffer: buffer to be used to lookup mntpath
-+ * @devpath: path devname/src_name (MAYBE NULL)
-+ * @devbuffer: buffer to be used to lookup devname/src_name
-+ * @type: string for the dev type (MAYBE NULL)
-+ * @flags: mount flags to match
-+ * @data: fs mount data (MAYBE NULL)
-+ * @binary: whether @data is binary
-+ *
-+ * Returns: 0 on success else error
-+ */
-+static int match_mnt(struct aa_profile *profile, const struct path *path,
-+ char *buffer, struct path *devpath, char *devbuffer,
-+ const char *type, unsigned long flags, void *data,
-+ bool binary)
-+{
-+ const char *devname = NULL, *info = NULL;
-+ int error = -EACCES;
-+
-+ AA_BUG(!profile);
-+ AA_BUG(devpath && !devbuffer);
-+
-+ if (devpath) {
-+ error = aa_path_name(devpath, path_flags(profile, devpath),
-+ devbuffer, &devname, &info,
-+ profile->disconnected);
-+ if (error)
-+ devname = ERR_PTR(error);
-+ }
-+
-+ return match_mnt_path_str(profile, path, buffer, devname, type, flags,
-+ data, binary, info);
-+}
-+
-+int aa_remount(struct aa_label *label, const struct path *path,
-+ unsigned long flags, void *data)
-+{
-+ struct aa_profile *profile;
-+ char *buffer = NULL;
-+ bool binary;
-+ int error;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!path);
-+
-+ binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA;
-+
-+ get_buffers(buffer);
-+ error = fn_for_each_confined(label, profile,
-+ match_mnt(profile, path, buffer, NULL, NULL, NULL,
-+ flags, data, binary));
-+ put_buffers(buffer);
-+
-+ return error;
-+}
-+
-+int aa_bind_mount(struct aa_label *label, const struct path *path,
-+ const char *dev_name, unsigned long flags)
-+{
-+ struct aa_profile *profile;
-+ char *buffer = NULL, *old_buffer = NULL;
-+ struct path old_path;
-+ int error;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!path);
-+
-+ if (!dev_name || !*dev_name)
-+ return -EINVAL;
-+
-+ flags &= MS_REC | MS_BIND;
-+
-+ error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
-+ if (error)
-+ return error;
-+
-+ get_buffers(buffer, old_buffer);
-+ error = fn_for_each_confined(label, profile,
-+ match_mnt(profile, path, buffer, &old_path, old_buffer,
-+ NULL, flags, NULL, false));
-+ put_buffers(buffer, old_buffer);
-+ path_put(&old_path);
-+
-+ return error;
-+}
-+
-+int aa_mount_change_type(struct aa_label *label, const struct path *path,
-+ unsigned long flags)
-+{
-+ struct aa_profile *profile;
-+ char *buffer = NULL;
-+ int error;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!path);
-+
-+ /* These are the flags allowed by do_change_type() */
-+ flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE |
-+ MS_UNBINDABLE);
-+
-+ get_buffers(buffer);
-+ error = fn_for_each_confined(label, profile,
-+ match_mnt(profile, path, buffer, NULL, NULL, NULL,
-+ flags, NULL, false));
-+ put_buffers(buffer);
-+
-+ return error;
-+}
-+
-+int aa_move_mount(struct aa_label *label, const struct path *path,
-+ const char *orig_name)
-+{
-+ struct aa_profile *profile;
-+ char *buffer = NULL, *old_buffer = NULL;
-+ struct path old_path;
-+ int error;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!path);
-+
-+ if (!orig_name || !*orig_name)
-+ return -EINVAL;
-+
-+ error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
-+ if (error)
-+ return error;
-+
-+ get_buffers(buffer, old_buffer);
-+ error = fn_for_each_confined(label, profile,
-+ match_mnt(profile, path, buffer, &old_path, old_buffer,
-+ NULL, MS_MOVE, NULL, false));
-+ put_buffers(buffer, old_buffer);
-+ path_put(&old_path);
-+
-+ return error;
-+}
-+
-+int aa_new_mount(struct aa_label *label, const char *dev_name,
-+ const struct path *path, const char *type, unsigned long flags,
-+ void *data)
-+{
-+ struct aa_profile *profile;
-+ char *buffer = NULL, *dev_buffer = NULL;
-+ bool binary = true;
-+ int error;
-+ int requires_dev = 0;
-+ struct path tmp_path, *dev_path = NULL;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!path);
-+
-+ if (type) {
-+ struct file_system_type *fstype;
-+
-+ fstype = get_fs_type(type);
-+ if (!fstype)
-+ return -ENODEV;
-+ binary = fstype->fs_flags & FS_BINARY_MOUNTDATA;
-+ requires_dev = fstype->fs_flags & FS_REQUIRES_DEV;
-+ put_filesystem(fstype);
-+
-+ if (requires_dev) {
-+ if (!dev_name || !*dev_name)
-+ return -ENOENT;
-+
-+ error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path);
-+ if (error)
-+ return error;
-+ dev_path = &tmp_path;
-+ }
-+ }
-+
-+ get_buffers(buffer, dev_buffer);
-+ if (dev_path) {
-+ error = fn_for_each_confined(label, profile,
-+ match_mnt(profile, path, buffer, dev_path, dev_buffer,
-+ type, flags, data, binary));
-+ } else {
-+ error = fn_for_each_confined(label, profile,
-+ match_mnt_path_str(profile, path, buffer, dev_name,
-+ type, flags, data, binary, NULL));
-+ }
-+ put_buffers(buffer, dev_buffer);
-+ if (dev_path)
-+ path_put(dev_path);
-+
-+ return error;
-+}
-+
-+static int profile_umount(struct aa_profile *profile, struct path *path,
-+ char *buffer)
-+{
-+ struct aa_perms perms = { };
-+ const char *name = NULL, *info = NULL;
-+ unsigned int state;
-+ int error;
-+
-+ AA_BUG(!profile);
-+ AA_BUG(!path);
-+
-+ error = aa_path_name(path, path_flags(profile, path), buffer, &name,
-+ &info, profile->disconnected);
-+ if (error)
-+ goto audit;
-+
-+ state = aa_dfa_match(profile->policy.dfa,
-+ profile->policy.start[AA_CLASS_MOUNT],
-+ name);
-+ perms = compute_mnt_perms(profile->policy.dfa, state);
-+ if (AA_MAY_UMOUNT & ~perms.allow)
-+ error = -EACCES;
-+
-+audit:
-+ return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL,
-+ AA_MAY_UMOUNT, &perms, info, error);
-+}
-+
-+int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
-+{
-+ struct aa_profile *profile;
-+ char *buffer = NULL;
-+ int error;
-+ struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
-+
-+ AA_BUG(!label);
-+ AA_BUG(!mnt);
-+
-+ get_buffers(buffer);
-+ error = fn_for_each_confined(label, profile,
-+ profile_umount(profile, &path, buffer));
-+ put_buffers(buffer);
-+
-+ return error;
-+}
-+
-+/* helper fn for transition on pivotroot
-+ *
-+ * Returns: label for transition or ERR_PTR. Does not return NULL
-+ */
-+static struct aa_label *build_pivotroot(struct aa_profile *profile,
-+ const struct path *new_path,
-+ char *new_buffer,
-+ const struct path *old_path,
-+ char *old_buffer)
-+{
-+ const char *old_name, *new_name = NULL, *info = NULL;
-+ const char *trans_name = NULL;
-+ struct aa_perms perms = { };
-+ unsigned int state;
-+ int error;
-+
-+ AA_BUG(!profile);
-+ AA_BUG(!new_path);
-+ AA_BUG(!old_path);
-+
-+ if (profile_unconfined(profile))
-+ return aa_get_newest_label(&profile->label);
-+
-+ error = aa_path_name(old_path, path_flags(profile, old_path),
-+ old_buffer, &old_name, &info,
-+ profile->disconnected);
-+ if (error)
-+ goto audit;
-+ error = aa_path_name(new_path, path_flags(profile, new_path),
-+ new_buffer, &new_name, &info,
-+ profile->disconnected);
-+ if (error)
-+ goto audit;
-+
-+ error = -EACCES;
-+ state = aa_dfa_match(profile->policy.dfa,
-+ profile->policy.start[AA_CLASS_MOUNT],
-+ new_name);
-+ state = aa_dfa_null_transition(profile->policy.dfa, state);
-+ state = aa_dfa_match(profile->policy.dfa, state, old_name);
-+ perms = compute_mnt_perms(profile->policy.dfa, state);
-+
-+ if (AA_MAY_PIVOTROOT & perms.allow)
-+ error = 0;
-+
-+audit:
-+ error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
-+ NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
-+ &perms, info, error);
-+ if (error)
-+ return ERR_PTR(error);
-+
-+ return aa_get_newest_label(&profile->label);
-+}
-+
-+int aa_pivotroot(struct aa_label *label, const struct path *old_path,
-+ const struct path *new_path)
-+{
-+ struct aa_profile *profile;
-+ struct aa_label *target = NULL;
-+ char *old_buffer = NULL, *new_buffer = NULL, *info = NULL;
-+ int error;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!old_path);
-+ AA_BUG(!new_path);
-+
-+ get_buffers(old_buffer, new_buffer);
-+ target = fn_label_build(label, profile, GFP_ATOMIC,
-+ build_pivotroot(profile, new_path, new_buffer,
-+ old_path, old_buffer));
-+ if (!target) {
-+ info = "label build failed";
-+ error = -ENOMEM;
-+ goto fail;
-+ } else if (!IS_ERR(target)) {
-+ error = aa_replace_current_label(target);
-+ if (error) {
-+ /* TODO: audit target */
-+ aa_put_label(target);
-+ goto out;
-+ }
-+ } else
-+ /* already audited error */
-+ error = PTR_ERR(target);
-+out:
-+ put_buffers(old_buffer, new_buffer);
-+
-+ return error;
-+
-+fail:
-+ /* TODO: add back in auditing of new_name and old_name */
-+ error = fn_for_each(label, profile,
-+ audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
-+ NULL /* old_name */,
-+ NULL, NULL,
-+ 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
-+ error));
-+ goto out;
-+}
---
-2.14.1
-
diff --git a/patches.apparmor/0006-security-apparmor-Use-POSIX-compatible-printf-s.patch b/patches.apparmor/0006-security-apparmor-Use-POSIX-compatible-printf-s.patch
deleted file mode 100644
index 9f16fa6890..0000000000
--- a/patches.apparmor/0006-security-apparmor-Use-POSIX-compatible-printf-s.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 80e3c5c516a4d9b6653456399fa13a46a66fd3c9 Mon Sep 17 00:00:00 2001
-From: Thomas Schneider <qsx@qsx.re>
-Date: Fri, 14 Oct 2016 21:29:49 +0200
-Subject: [PATCH 06/65] security/apparmor: Use POSIX-compatible "printf '%s'"
-Git-commit: 651e54953b5d4ad103f0efa54fc6b380807fca3a
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-When using a strictly POSIX-compliant shell, "-n #define ..." gets
-written into the file. Use "printf '%s'" to avoid this.
-
-Signed-off-by: Thomas Schneider <qsx@qsx.re>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
-index ad369a7aac24..2ded2f1be98b 100644
---- a/security/apparmor/Makefile
-+++ b/security/apparmor/Makefile
-@@ -20,7 +20,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
- sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \
- -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
- echo "};" >> $@ ;\
-- echo -n '\#define AA_FS_CAPS_MASK "' >> $@ ;\
-+ printf '%s' '\#define AA_FS_CAPS_MASK "' >> $@ ;\
- sed $< -r -n -e '/CAP_FS_MASK/d' \
- -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
- tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
-@@ -56,7 +56,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
- echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\
- sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
- echo "};" >> $@ ; \
-- echo -n '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\
-+ printf '%s' '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\
- sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \
- tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
-
---
-2.12.3
-
diff --git a/patches.apparmor/0007-apparmor-cleanup-conditional-check-for-label-in-labe.patch b/patches.apparmor/0007-apparmor-cleanup-conditional-check-for-label-in-labe.patch
deleted file mode 100644
index da0503106e..0000000000
--- a/patches.apparmor/0007-apparmor-cleanup-conditional-check-for-label-in-labe.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 05842051f418debd2a3ed633a93da96bd4c39ff7 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Sun, 6 Aug 2017 05:36:40 -0700
-Subject: [PATCH 07/17] apparmor: cleanup conditional check for label in label_print
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: f872af75d325cc449b6621a0d30a4f2ba77dd092
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/label.c | 22 ++++++++--------------
- 1 file changed, 8 insertions(+), 14 deletions(-)
-
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index e324f4df3e34..38be7a89cc31 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -1450,9 +1450,11 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
- * cached label name is present and visible
- * @label->hname only exists if label is namespace hierachical
- */
--static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label)
-+static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label,
-+ int flags)
- {
-- if (label->hname && labels_ns(label) == ns)
-+ if (label->hname && (!ns || labels_ns(label) == ns) &&
-+ !(flags & ~FLAG_SHOW_MODE))
- return true;
-
- return false;
-@@ -1710,10 +1712,8 @@ void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
- AA_BUG(!ab);
- AA_BUG(!label);
-
-- if (!ns)
-- ns = labels_ns(label);
--
-- if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) {
-+ if (!use_label_hname(ns, label, flags) ||
-+ display_mode(ns, label, flags)) {
- len = aa_label_asxprint(&name, ns, label, flags, gfp);
- if (len == -1) {
- AA_DEBUG("label print error");
-@@ -1738,10 +1738,7 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
- AA_BUG(!f);
- AA_BUG(!label);
-
-- if (!ns)
-- ns = labels_ns(label);
--
-- if (!use_label_hname(ns, label)) {
-+ if (!use_label_hname(ns, label, flags)) {
- char *str;
- int len;
-
-@@ -1764,10 +1761,7 @@ void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
- {
- AA_BUG(!label);
-
-- if (!ns)
-- ns = labels_ns(label);
--
-- if (!use_label_hname(ns, label)) {
-+ if (!use_label_hname(ns, label, flags)) {
- char *str;
- int len;
-
---
-2.14.1
-
diff --git a/patches.apparmor/0007-apparmor-move-file-context-into-file.h.patch b/patches.apparmor/0007-apparmor-move-file-context-into-file.h.patch
deleted file mode 100644
index bb441548c8..0000000000
--- a/patches.apparmor/0007-apparmor-move-file-context-into-file.h.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From ebb6be0172b361652679954159484f966675db5f Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Sun, 21 May 2017 17:15:28 -0700
-Subject: [PATCH 07/65] apparmor: move file context into file.h
-Git-commit: af7caa8f8dd1b45e38a3653a69ed4d708286bc83
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/context.h | 32 --------------------------------
- security/apparmor/include/file.h | 32 ++++++++++++++++++++++++++++++++
- 2 files changed, 32 insertions(+), 32 deletions(-)
-
-diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
-index 5b18fedab4c8..420cfd041218 100644
---- a/security/apparmor/include/context.h
-+++ b/security/apparmor/include/context.h
-@@ -25,38 +25,6 @@
- #define cred_ctx(X) ((X)->security)
- #define current_ctx() cred_ctx(current_cred())
-
--/* struct aa_file_ctx - the AppArmor context the file was opened in
-- * @perms: the permission the file was opened with
-- *
-- * The file_ctx could currently be directly stored in file->f_security
-- * as the profile reference is now stored in the f_cred. However the
-- * ctx struct will expand in the future so we keep the struct.
-- */
--struct aa_file_ctx {
-- u16 allow;
--};
--
--/**
-- * aa_alloc_file_context - allocate file_ctx
-- * @gfp: gfp flags for allocation
-- *
-- * Returns: file_ctx or NULL on failure
-- */
--static inline struct aa_file_ctx *aa_alloc_file_context(gfp_t gfp)
--{
-- return kzalloc(sizeof(struct aa_file_ctx), gfp);
--}
--
--/**
-- * aa_free_file_context - free a file_ctx
-- * @ctx: file_ctx to free (MAYBE_NULL)
-- */
--static inline void aa_free_file_context(struct aa_file_ctx *ctx)
--{
-- if (ctx)
-- kzfree(ctx);
--}
--
- /**
- * struct aa_task_ctx - primary label for confined tasks
- * @profile: the current profile (NOT NULL)
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-index 38f821bf49b6..eba39cb25f02 100644
---- a/security/apparmor/include/file.h
-+++ b/security/apparmor/include/file.h
-@@ -47,6 +47,38 @@ struct path;
- AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
- AA_EXEC_MMAP | AA_MAY_LINK)
-
-+/* struct aa_file_ctx - the AppArmor context the file was opened in
-+ * @perms: the permission the file was opened with
-+ *
-+ * The file_ctx could currently be directly stored in file->f_security
-+ * as the profile reference is now stored in the f_cred. However the
-+ * ctx struct will expand in the future so we keep the struct.
-+ */
-+struct aa_file_ctx {
-+ u16 allow;
-+};
-+
-+/**
-+ * aa_alloc_file_context - allocate file_ctx
-+ * @gfp: gfp flags for allocation
-+ *
-+ * Returns: file_ctx or NULL on failure
-+ */
-+static inline struct aa_file_ctx *aa_alloc_file_context(gfp_t gfp)
-+{
-+ return kzalloc(sizeof(struct aa_file_ctx), gfp);
-+}
-+
-+/**
-+ * aa_free_file_context - free a file_ctx
-+ * @ctx: file_ctx to free (MAYBE_NULL)
-+ */
-+static inline void aa_free_file_context(struct aa_file_ctx *ctx)
-+{
-+ if (ctx)
-+ kzfree(ctx);
-+}
-+
- /*
- * The xindex is broken into 3 parts
- * - index - an index into either the exec name table or the variable table
---
-2.12.3
-
diff --git a/patches.apparmor/0008-apparmor-add-support-for-absolute-root-view-based-la.patch b/patches.apparmor/0008-apparmor-add-support-for-absolute-root-view-based-la.patch
deleted file mode 100644
index 1f24326fcf..0000000000
--- a/patches.apparmor/0008-apparmor-add-support-for-absolute-root-view-based-la.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 0d09c5b5363e1e4a506352dd6eec63d48858d9af Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Sun, 6 Aug 2017 05:39:08 -0700
-Subject: [PATCH 08/17] apparmor: add support for absolute root view based labels
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 26b7899510ae243e392960704ebdba52d05fbb13
-
-With apparmor policy virtualization based on policy namespace View's
-we don't generally want/need absolute root based views, however there
-are cases like debugging and some secid based conversions where
-using a root based view is important.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/label.h | 1 +
- security/apparmor/label.c | 10 +++++++++-
- 2 files changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
-index 9a283b722755..af22dcbbcb8a 100644
---- a/security/apparmor/include/label.h
-+++ b/security/apparmor/include/label.h
-@@ -310,6 +310,7 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
- #define FLAG_SHOW_MODE 1
- #define FLAG_VIEW_SUBNS 2
- #define FLAG_HIDDEN_UNCONFINED 4
-+#define FLAG_ABS_ROOT 8
- int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
- struct aa_label *label, int flags);
- int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index 38be7a89cc31..52b4ef14840d 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -1607,8 +1607,13 @@ int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
- AA_BUG(!str && size != 0);
- AA_BUG(!label);
-
-- if (!ns)
-+ if (flags & FLAG_ABS_ROOT) {
-+ ns = root_ns;
-+ len = snprintf(str, size, "=");
-+ update_for_len(total, len, size, str);
-+ } else if (!ns) {
- ns = labels_ns(label);
-+ }
-
- label_for_each(i, label, profile) {
- if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
-@@ -1868,6 +1873,9 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
- if (*str == '&')
- str++;
- }
-+ if (*str == '=')
-+ base = &root_ns->unconfined->label;
-+
- error = vec_setup(profile, vec, len, gfp);
- if (error)
- return ERR_PTR(error);
---
-2.14.1
-
diff --git a/patches.apparmor/0008-apparmor-make-internal-lib-fn-skipn_spaces-available.patch b/patches.apparmor/0008-apparmor-make-internal-lib-fn-skipn_spaces-available.patch
deleted file mode 100644
index d2fc2ae2e7..0000000000
--- a/patches.apparmor/0008-apparmor-make-internal-lib-fn-skipn_spaces-available.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From d65673a60608bb3222416ae16d2533ee5679d9a4 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 22 May 2017 02:47:22 -0700
-Subject: [PATCH 08/65] apparmor: make internal lib fn skipn_spaces available
- to the rest of apparmor
-Git-commit: b91deb9db12851c18ccb55719f1cd55c2400aca1
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/lib.h | 1 +
- security/apparmor/lib.c | 2 +-
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
-index 550a700563b4..89524aade657 100644
---- a/security/apparmor/include/lib.h
-+++ b/security/apparmor/include/lib.h
-@@ -60,6 +60,7 @@
- extern int apparmor_initialized;
-
- /* fn's in lib */
-+const char *skipn_spaces(const char *str, size_t n);
- char *aa_split_fqname(char *args, char **ns_name);
- const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
- size_t *ns_len);
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index 7cd788a9445b..864b2fa45852 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -69,7 +69,7 @@ char *aa_split_fqname(char *fqname, char **ns_name)
- * if all whitespace will return NULL
- */
-
--static const char *skipn_spaces(const char *str, size_t n)
-+const char *skipn_spaces(const char *str, size_t n)
- {
- for (; n && isspace(*str); --n)
- ++str;
---
-2.12.3
-
diff --git a/patches.apparmor/0009-apparmor-allow-profiles-to-provide-info-to-disconnec.patch b/patches.apparmor/0009-apparmor-allow-profiles-to-provide-info-to-disconnec.patch
deleted file mode 100644
index de666ec4cf..0000000000
--- a/patches.apparmor/0009-apparmor-allow-profiles-to-provide-info-to-disconnec.patch
+++ /dev/null
@@ -1,224 +0,0 @@
-From 2b1d572f01ffd76a23967d5ffead7036c82dc8da Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 22 May 2017 03:06:52 -0700
-Subject: [PATCH 09/65] apparmor: allow profiles to provide info to
- disconnected paths
-Git-commit: 72c8a768641dc6ee8d1d9dcebd51bbec2817459b
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 2 +-
- security/apparmor/file.c | 7 ++++---
- security/apparmor/include/path.h | 3 ++-
- security/apparmor/include/policy.h | 2 ++
- security/apparmor/path.c | 34 ++++++++++++++++++++++------------
- security/apparmor/policy_unpack.c | 3 +++
- 6 files changed, 34 insertions(+), 17 deletions(-)
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index 001e133a3c8c..c92fd0e7b33c 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -366,7 +366,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
-
- /* buffer freed below, name is pointer into buffer */
- error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
-- &name, &info);
-+ &name, &info, profile->disconnected);
- if (error) {
- if (unconfined(profile) ||
- (profile->flags & PFLAG_IX_ON_NAME_ERROR))
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index 750564c3ab71..83d43ac72134 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -285,7 +285,8 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
- int error;
-
- flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
-- error = aa_path_name(path, flags, &buffer, &name, &info);
-+ error = aa_path_name(path, flags, &buffer, &name, &info,
-+ profile->disconnected);
- if (error) {
- if (error == -ENOENT && is_deleted(path->dentry)) {
- /* Access to open files that are deleted are
-@@ -366,13 +367,13 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
-
- /* buffer freed below, lname is pointer in buffer */
- error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
-- &info);
-+ &info, profile->disconnected);
- if (error)
- goto audit;
-
- /* buffer2 freed below, tname is pointer in buffer2 */
- error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
-- &info);
-+ &info, profile->disconnected);
- if (error)
- goto audit;
-
-diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
-index 0444fdde3918..78e4909dcc6a 100644
---- a/security/apparmor/include/path.h
-+++ b/security/apparmor/include/path.h
-@@ -27,7 +27,8 @@ enum path_flags {
- };
-
- int aa_path_name(const struct path *path, int flags, char **buffer,
-- const char **name, const char **info);
-+ const char **name, const char **info,
-+ const char *disconnected);
-
- #define MAX_PATH_BUFFERS 2
-
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
-index 67bc96afe541..dffa01c018c8 100644
---- a/security/apparmor/include/policy.h
-+++ b/security/apparmor/include/policy.h
-@@ -128,6 +128,7 @@ struct aa_data {
- * @mode: the enforcement mode of the profile
- * @flags: flags controlling profile behavior
- * @path_flags: flags controlling path generation behavior
-+ * @disconnected: what to prepend if attach_disconnected is specified
- * @size: the memory consumed by this profiles rules
- * @policy: general match rules governing policy
- * @file: The set of rules governing basic file access and domain transitions
-@@ -169,6 +170,7 @@ struct aa_profile {
- long mode;
- long flags;
- u32 path_flags;
-+ const char *disconnected;
- int size;
-
- struct aa_policydb policy;
-diff --git a/security/apparmor/path.c b/security/apparmor/path.c
-index a8fc7d08c144..9490f8e89630 100644
---- a/security/apparmor/path.c
-+++ b/security/apparmor/path.c
-@@ -50,7 +50,7 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen)
- * namespace root.
- */
- static int disconnect(const struct path *path, char *buf, char **name,
-- int flags)
-+ int flags, const char *disconnected)
- {
- int error = 0;
-
-@@ -63,9 +63,14 @@ static int disconnect(const struct path *path, char *buf, char **name,
- error = -EACCES;
- if (**name == '/')
- *name = *name + 1;
-- } else if (**name != '/')
-- /* CONNECT_PATH with missing root */
-- error = prepend(name, *name - buf, "/", 1);
-+ } else {
-+ if (**name != '/')
-+ /* CONNECT_PATH with missing root */
-+ error = prepend(name, *name - buf, "/", 1);
-+ if (!error && disconnected)
-+ error = prepend(name, *name - buf, disconnected,
-+ strlen(disconnected));
-+ }
-
- return error;
- }
-@@ -77,6 +82,7 @@ static int disconnect(const struct path *path, char *buf, char **name,
- * @buflen: length of @buf
- * @name: Returns - pointer for start of path name with in @buf (NOT NULL)
- * @flags: flags controlling path lookup
-+ * @disconnected: string to prefix to disconnected paths
- *
- * Handle path name lookup.
- *
-@@ -85,7 +91,7 @@ static int disconnect(const struct path *path, char *buf, char **name,
- * to a position in @buf
- */
- static int d_namespace_path(const struct path *path, char *buf, int buflen,
-- char **name, int flags)
-+ char **name, int flags, const char *disconnected)
- {
- char *res;
- int error = 0;
-@@ -106,8 +112,8 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
- */
- return prepend(name, *name - buf, "/proc", 5);
- } else
-- return disconnect(path, buf, name, flags);
-- return 0;
-+ return disconnect(path, buf, name, flags,
-+ disconnected);
- }
-
- /* resolve paths relative to chroot?*/
-@@ -153,7 +159,7 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
- }
-
- if (!connected)
-- error = disconnect(path, buf, name, flags);
-+ error = disconnect(path, buf, name, flags, disconnected);
-
- out:
- return error;
-@@ -170,10 +176,12 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
- * Returns: %0 else error on failure
- */
- static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
-- int size, char **name, const char **info)
-+ int size, char **name, const char **info,
-+ const char *disconnected)
- {
- int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
-- int error = d_namespace_path(path, buffer, size - adjust, name, flags);
-+ int error = d_namespace_path(path, buffer, size - adjust, name, flags,
-+ disconnected);
-
- if (!error && (flags & PATH_IS_DIR) && (*name)[1] != '\0')
- /*
-@@ -203,6 +211,7 @@ static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
- * @buffer: buffer that aa_get_name() allocated (NOT NULL)
- * @name: Returns - the generated path name if !error (NOT NULL)
- * @info: Returns - information on why the path lookup failed (MAYBE NULL)
-+ * @disconnected: string to prepend to disconnected paths
- *
- * @name is a pointer to the beginning of the pathname (which usually differs
- * from the beginning of the buffer), or NULL. If there is an error @name
-@@ -216,7 +225,7 @@ static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
- * Returns: %0 else error code if could retrieve name
- */
- int aa_path_name(const struct path *path, int flags, char **buffer,
-- const char **name, const char **info)
-+ const char **name, const char **info, const char *disconnected)
- {
- char *buf, *str = NULL;
- int size = 256;
-@@ -230,7 +239,8 @@ int aa_path_name(const struct path *path, int flags, char **buffer,
- if (!buf)
- return -ENOMEM;
-
-- error = get_name_to_buffer(path, flags, buf, size, &str, info);
-+ error = get_name_to_buffer(path, flags, buf, size, &str, info,
-+ disconnected);
- if (error != -ENAMETOOLONG)
- break;
-
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index 981d570eebba..182bbfeb4b2c 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -569,6 +569,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- profile->xmatch_len = tmp;
- }
-
-+ /* disconnected attachment string is optional */
-+ (void) unpack_str(e, &profile->disconnected, "disconnected");
-+
- /* per profile debug flags (complain, audit) */
- if (!unpack_nameX(e, AA_STRUCT, "flags"))
- goto fail;
---
-2.12.3
-
diff --git a/patches.apparmor/0009-apparmor-make-policy_unpack-able-to-audit-different-.patch b/patches.apparmor/0009-apparmor-make-policy_unpack-able-to-audit-different-.patch
deleted file mode 100644
index c2ec8c0522..0000000000
--- a/patches.apparmor/0009-apparmor-make-policy_unpack-able-to-audit-different-.patch
+++ /dev/null
@@ -1,221 +0,0 @@
-From 483939f63449d291a2d62661d405da17b52e5e08 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Tue, 18 Jul 2017 23:37:18 -0700
-Subject: [PATCH 09/17] apparmor: make policy_unpack able to audit different info messages
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 2410aa96d6b4930ed25fd02c3d173f14b962e0f4
-
-Switch unpack auditing to using the generic name field in the audit
-struct and make it so we can start adding new info messages about
-why an unpack failed.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/audit.h | 4 +--
- security/apparmor/policy_unpack.c | 52 ++++++++++++++++++++++++++++-----------
- 2 files changed, 40 insertions(+), 16 deletions(-)
-
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index c3fe1c5ef3bc..620e81169659 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -127,9 +127,9 @@ struct apparmor_audit_data {
- } fs;
- };
- struct {
-- const char *name;
-- long pos;
-+ struct aa_profile *profile;
- const char *ns;
-+ long pos;
- } iface;
- int signal;
- struct {
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index bda0dce3b582..4ede87c30f8b 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
- audit_log_format(ab, " ns=");
- audit_log_untrustedstring(ab, aad(sa)->iface.ns);
- }
-- if (aad(sa)->iface.name) {
-+ if (aad(sa)->name) {
- audit_log_format(ab, " name=");
-- audit_log_untrustedstring(ab, aad(sa)->iface.name);
-+ audit_log_untrustedstring(ab, aad(sa)->name);
- }
- if (aad(sa)->iface.pos)
- audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
-@@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
- aad(&sa)->iface.pos = e->pos - e->start;
- aad(&sa)->iface.ns = ns_name;
- if (new)
-- aad(&sa)->iface.name = new->base.hname;
-+ aad(&sa)->name = new->base.hname;
- else
-- aad(&sa)->iface.name = name;
-+ aad(&sa)->name = name;
- aad(&sa)->info = info;
- aad(&sa)->error = error;
-
-@@ -583,6 +583,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- {
- struct aa_profile *profile = NULL;
- const char *tmpname, *tmpns = NULL, *name = NULL;
-+ const char *info = "failed to unpack profile";
- size_t ns_len;
- struct rhashtable_params params = { 0 };
- char *key = NULL;
-@@ -604,8 +605,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
- if (tmpns) {
- *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
-- if (!*ns_name)
-+ if (!*ns_name) {
-+ info = "out of memory";
- goto fail;
-+ }
- name = tmpname;
- }
-
-@@ -624,12 +627,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- if (IS_ERR(profile->xmatch)) {
- error = PTR_ERR(profile->xmatch);
- profile->xmatch = NULL;
-+ info = "bad xmatch";
- goto fail;
- }
- /* xmatch_len is not optional if xmatch is set */
- if (profile->xmatch) {
-- if (!unpack_u32(e, &tmp, NULL))
-+ if (!unpack_u32(e, &tmp, NULL)) {
-+ info = "missing xmatch len";
- goto fail;
-+ }
- profile->xmatch_len = tmp;
- }
-
-@@ -637,8 +643,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- (void) unpack_str(e, &profile->disconnected, "disconnected");
-
- /* per profile debug flags (complain, audit) */
-- if (!unpack_nameX(e, AA_STRUCT, "flags"))
-+ if (!unpack_nameX(e, AA_STRUCT, "flags")) {
-+ info = "profile missing flags";
- goto fail;
-+ }
-+ info = "failed to unpack profile flags";
- if (!unpack_u32(e, &tmp, NULL))
- goto fail;
- if (tmp & PACKED_FLAG_HAT)
-@@ -667,6 +676,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- /* set a default value if path_flags field is not present */
- profile->path_flags = PATH_MEDIATE_DELETED;
-
-+ info = "failed to unpack profile capabilities";
- if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
- goto fail;
- if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
-@@ -676,6 +686,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- if (!unpack_u32(e, &tmpcap.cap[0], NULL))
- goto fail;
-
-+ info = "failed to unpack upper profile capabilities";
- if (unpack_nameX(e, AA_STRUCT, "caps64")) {
- /* optional upper half of 64 bit caps */
- if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
-@@ -690,6 +701,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- goto fail;
- }
-
-+ info = "failed to unpack extended profile capabilities";
- if (unpack_nameX(e, AA_STRUCT, "capsx")) {
- /* optional extended caps mediation mask */
- if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
-@@ -700,11 +712,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- goto fail;
- }
-
-- if (!unpack_rlimits(e, profile))
-+ if (!unpack_rlimits(e, profile)) {
-+ info = "failed to unpack profile rlimits";
- goto fail;
-+ }
-
- if (unpack_nameX(e, AA_STRUCT, "policydb")) {
- /* generic policy dfa - optional and may be NULL */
-+ info = "failed to unpack policydb";
- profile->policy.dfa = unpack_dfa(e);
- if (IS_ERR(profile->policy.dfa)) {
- error = PTR_ERR(profile->policy.dfa);
-@@ -734,6 +749,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- if (IS_ERR(profile->file.dfa)) {
- error = PTR_ERR(profile->file.dfa);
- profile->file.dfa = NULL;
-+ info = "failed to unpack profile file rules";
- goto fail;
- } else if (profile->file.dfa) {
- if (!unpack_u32(e, &profile->file.start, "dfa_start"))
-@@ -746,10 +762,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- } else
- profile->file.dfa = aa_get_dfa(nulldfa);
-
-- if (!unpack_trans_table(e, profile))
-+ if (!unpack_trans_table(e, profile)) {
-+ info = "failed to unpack profile transition table";
- goto fail;
-+ }
-
- if (unpack_nameX(e, AA_STRUCT, "data")) {
-+ info = "out of memory";
- profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
- if (!profile->data)
- goto fail;
-@@ -761,8 +780,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- params.hashfn = strhash;
- params.obj_cmpfn = datacmp;
-
-- if (rhashtable_init(profile->data, &params))
-+ if (rhashtable_init(profile->data, &params)) {
-+ info = "failed to init key, value hash table";
- goto fail;
-+ }
-
- while (unpack_strdup(e, &key, NULL)) {
- data = kzalloc(sizeof(*data), GFP_KERNEL);
-@@ -784,12 +805,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- profile->data->p);
- }
-
-- if (!unpack_nameX(e, AA_STRUCTEND, NULL))
-+ if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
-+ info = "failed to unpack end of key, value data table";
- goto fail;
-+ }
- }
-
-- if (!unpack_nameX(e, AA_STRUCTEND, NULL))
-+ if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
-+ info = "failed to unpack end of profile";
- goto fail;
-+ }
-
- return profile;
-
-@@ -798,8 +823,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- name = NULL;
- else if (!name)
- name = "unknown";
-- audit_iface(profile, NULL, name, "failed to unpack profile", e,
-- error);
-+ audit_iface(profile, NULL, name, info, e, error);
- aa_free_profile(profile);
-
- return ERR_PTR(error);
---
-2.14.1
-
diff --git a/patches.apparmor/0010-apparmor-Move-path-lookup-to-using-preallocated-buff.patch b/patches.apparmor/0010-apparmor-Move-path-lookup-to-using-preallocated-buff.patch
deleted file mode 100644
index 075ecf0528..0000000000
--- a/patches.apparmor/0010-apparmor-Move-path-lookup-to-using-preallocated-buff.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 7ead53fe15ab016eeff34fac68c7c90f4bd5c6c1 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Tue, 23 May 2017 03:25:14 -0700
-Subject: [PATCH 10/65] apparmor: Move path lookup to using preallocated
- buffers
-Git-commit: 4227c333f65cddc6c2f048e5b67cfe796b9df9a6
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Dynamically allocating buffers is problematic and is an extra layer
-that is a potntial point of failure and can slow down mediation.
-Change path lookup to use the preallocated per cpu buffers.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 8 +--
- security/apparmor/file.c | 13 ++---
- security/apparmor/include/path.h | 4 +-
- security/apparmor/path.c | 114 ++++++++++++++-------------------------
- 4 files changed, 53 insertions(+), 86 deletions(-)
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index c92fd0e7b33c..ab8f23cdccff 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -357,6 +357,9 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- AA_BUG(!ctx);
-
- profile = aa_get_newest_profile(ctx->profile);
-+
-+ /* buffer freed below, name is pointer into buffer */
-+ get_buffers(buffer);
- /*
- * get the namespace from the replacement profile as replacement
- * can change the namespace
-@@ -364,8 +367,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- ns = profile->ns;
- state = profile->file.start;
-
-- /* buffer freed below, name is pointer into buffer */
-- error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
-+ error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
- &name, &info, profile->disconnected);
- if (error) {
- if (unconfined(profile) ||
-@@ -515,7 +517,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- cleanup:
- aa_put_profile(new_profile);
- aa_put_profile(profile);
-- kfree(buffer);
-+ put_buffers(buffer);
-
- return error;
- }
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index 83d43ac72134..22be62f0fc73 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -285,7 +285,8 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
- int error;
-
- flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
-- error = aa_path_name(path, flags, &buffer, &name, &info,
-+ get_buffers(buffer);
-+ error = aa_path_name(path, flags, buffer, &name, &info,
- profile->disconnected);
- if (error) {
- if (error == -ENOENT && is_deleted(path->dentry)) {
-@@ -304,7 +305,7 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
- }
- error = aa_audit_file(profile, &perms, op, request, name, NULL,
- cond->uid, info, error);
-- kfree(buffer);
-+ put_buffers(buffer);
-
- return error;
- }
-@@ -363,16 +364,17 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
- unsigned int state;
- int error;
-
-+ get_buffers(buffer, buffer2);
- lperms = nullperms;
-
- /* buffer freed below, lname is pointer in buffer */
-- error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
-+ error = aa_path_name(&link, profile->path_flags, buffer, &lname,
- &info, profile->disconnected);
- if (error)
- goto audit;
-
- /* buffer2 freed below, tname is pointer in buffer2 */
-- error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
-+ error = aa_path_name(&target, profile->path_flags, buffer2, &tname,
- &info, profile->disconnected);
- if (error)
- goto audit;
-@@ -432,8 +434,7 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
- audit:
- error = aa_audit_file(profile, &lperms, OP_LINK, request,
- lname, tname, cond.uid, info, error);
-- kfree(buffer);
-- kfree(buffer2);
-+ put_buffers(buffer, buffer2);
-
- return error;
- }
-diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
-index 78e4909dcc6a..05fb3305671e 100644
---- a/security/apparmor/include/path.h
-+++ b/security/apparmor/include/path.h
-@@ -23,10 +23,10 @@ enum path_flags {
- PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */
-
- PATH_DELEGATE_DELETED = 0x08000, /* delegate deleted files */
-- PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
-+ PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
- };
-
--int aa_path_name(const struct path *path, int flags, char **buffer,
-+int aa_path_name(const struct path *path, int flags, char *buffer,
- const char **name, const char **info,
- const char *disconnected);
-
-diff --git a/security/apparmor/path.c b/security/apparmor/path.c
-index 9490f8e89630..9d5de1d05be4 100644
---- a/security/apparmor/path.c
-+++ b/security/apparmor/path.c
-@@ -79,7 +79,6 @@ static int disconnect(const struct path *path, char *buf, char **name,
- * d_namespace_path - lookup a name associated with a given path
- * @path: path to lookup (NOT NULL)
- * @buf: buffer to store path to (NOT NULL)
-- * @buflen: length of @buf
- * @name: Returns - pointer for start of path name with in @buf (NOT NULL)
- * @flags: flags controlling path lookup
- * @disconnected: string to prefix to disconnected paths
-@@ -90,12 +89,14 @@ static int disconnect(const struct path *path, char *buf, char **name,
- * When no error the path name is returned in @name which points to
- * to a position in @buf
- */
--static int d_namespace_path(const struct path *path, char *buf, int buflen,
-- char **name, int flags, const char *disconnected)
-+static int d_namespace_path(const struct path *path, char *buf, char **name,
-+ int flags, const char *disconnected)
- {
- char *res;
- int error = 0;
- int connected = 1;
-+ int isdir = (flags & PATH_IS_DIR) ? 1 : 0;
-+ int buflen = aa_g_path_max - isdir;
-
- if (path->mnt->mnt_flags & MNT_INTERNAL) {
- /* it's not mounted anywhere */
-@@ -110,10 +111,12 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
- /* TODO: convert over to using a per namespace
- * control instead of hard coded /proc
- */
-- return prepend(name, *name - buf, "/proc", 5);
-+ error = prepend(name, *name - buf, "/proc", 5);
-+ goto out;
- } else
-- return disconnect(path, buf, name, flags,
-- disconnected);
-+ error = disconnect(path, buf, name, flags,
-+ disconnected);
-+ goto out;
- }
-
- /* resolve paths relative to chroot?*/
-@@ -132,8 +135,11 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
- * be returned.
- */
- if (!res || IS_ERR(res)) {
-- if (PTR_ERR(res) == -ENAMETOOLONG)
-- return -ENAMETOOLONG;
-+ if (PTR_ERR(res) == -ENAMETOOLONG) {
-+ error = -ENAMETOOLONG;
-+ *name = buf;
-+ goto out;
-+ }
- connected = 0;
- res = dentry_path_raw(path->dentry, buf, buflen);
- if (IS_ERR(res)) {
-@@ -146,6 +152,9 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
-
- *name = res;
-
-+ if (!connected)
-+ error = disconnect(path, buf, name, flags, disconnected);
-+
- /* Handle two cases:
- * 1. A deleted dentry && profile is not allowing mediation of deleted
- * 2. On some filesystems, newly allocated dentries appear to the
-@@ -153,62 +162,27 @@ static int d_namespace_path(const struct path *path, char *buf, int buflen,
- * allocated.
- */
- if (d_unlinked(path->dentry) && d_is_positive(path->dentry) &&
-- !(flags & PATH_MEDIATE_DELETED)) {
-+ !(flags & (PATH_MEDIATE_DELETED | PATH_DELEGATE_DELETED))) {
- error = -ENOENT;
- goto out;
- }
-
-- if (!connected)
-- error = disconnect(path, buf, name, flags, disconnected);
--
- out:
-- return error;
--}
--
--/**
-- * get_name_to_buffer - get the pathname to a buffer ensure dir / is appended
-- * @path: path to get name for (NOT NULL)
-- * @flags: flags controlling path lookup
-- * @buffer: buffer to put name in (NOT NULL)
-- * @size: size of buffer
-- * @name: Returns - contains position of path name in @buffer (NOT NULL)
-- *
-- * Returns: %0 else error on failure
-- */
--static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
-- int size, char **name, const char **info,
-- const char *disconnected)
--{
-- int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
-- int error = d_namespace_path(path, buffer, size - adjust, name, flags,
-- disconnected);
--
-- if (!error && (flags & PATH_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], "/");
--
-- if (info && error) {
-- if (error == -ENOENT)
-- *info = "Failed name lookup - deleted entry";
-- else if (error == -EACCES)
-- *info = "Failed name lookup - disconnected path";
-- else if (error == -ENAMETOOLONG)
-- *info = "Failed name lookup - name too long";
-- else
-- *info = "Failed name lookup";
-- }
-+ /*
-+ * Append "/" to the pathname. The root directory is a special
-+ * case; it already ends in slash.
-+ */
-+ if (!error && isdir && ((*name)[1] != '\0' || (*name)[0] != '/'))
-+ strcpy(&buf[aa_g_path_max - 2], "/");
-
- return error;
- }
-
- /**
-- * aa_path_name - compute the pathname of a file
-+ * aa_path_name - get the pathname to a buffer ensure dir / is appended
- * @path: path the file (NOT NULL)
- * @flags: flags controlling path name generation
-- * @buffer: buffer that aa_get_name() allocated (NOT NULL)
-+ * @buffer: buffer to put name in (NOT NULL)
- * @name: Returns - the generated path name if !error (NOT NULL)
- * @info: Returns - information on why the path lookup failed (MAYBE NULL)
- * @disconnected: string to prepend to disconnected paths
-@@ -224,33 +198,23 @@ static int get_name_to_buffer(const struct path *path, int flags, char *buffer,
- *
- * Returns: %0 else error code if could retrieve name
- */
--int aa_path_name(const struct path *path, int flags, char **buffer,
-+int aa_path_name(const struct path *path, int flags, char *buffer,
- const char **name, const char **info, const char *disconnected)
- {
-- char *buf, *str = NULL;
-- int size = 256;
-- int error;
--
-- *name = NULL;
-- *buffer = NULL;
-- for (;;) {
-- /* freed by caller */
-- buf = kmalloc(size, GFP_KERNEL);
-- if (!buf)
-- return -ENOMEM;
-+ char *str = NULL;
-+ int error = d_namespace_path(path, buffer, &str, flags, disconnected);
-
-- error = get_name_to_buffer(path, flags, buf, size, &str, info,
-- disconnected);
-- if (error != -ENAMETOOLONG)
-- break;
--
-- kfree(buf);
-- size <<= 1;
-- if (size > aa_g_path_max)
-- return -ENAMETOOLONG;
-- *info = NULL;
-+ if (info && error) {
-+ if (error == -ENOENT)
-+ *info = "Failed name lookup - deleted entry";
-+ else if (error == -EACCES)
-+ *info = "Failed name lookup - disconnected path";
-+ else if (error == -ENAMETOOLONG)
-+ *info = "Failed name lookup - name too long";
-+ else
-+ *info = "Failed name lookup";
- }
-- *buffer = buf;
-+
- *name = str;
-
- return error;
---
-2.12.3
-
diff --git a/patches.apparmor/0010-apparmor-add-more-debug-asserts-to-apparmorfs.patch b/patches.apparmor/0010-apparmor-add-more-debug-asserts-to-apparmorfs.patch
deleted file mode 100644
index 6ebde32747..0000000000
--- a/patches.apparmor/0010-apparmor-add-more-debug-asserts-to-apparmorfs.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 55ba3bb63b78e3a5ae74c19507abfa2be6cdb69f Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Tue, 18 Jul 2017 23:41:13 -0700
-Subject: [PATCH 10/17] apparmor: add more debug asserts to apparmorfs
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: cbf2d0e1a9e4876046a628e0e036a7545a3a4c40
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Seth Arnold <seth.arnold@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 8fa6c898c44b..7acea14c850b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -1446,6 +1446,10 @@ void __aafs_profile_migrate_dents(struct aa_profile *old,
- {
- int i;
-
-+ AA_BUG(!old);
-+ AA_BUG(!new);
-+ AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
-+
- for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
- new->dents[i] = old->dents[i];
- if (new->dents[i])
-@@ -1509,6 +1513,9 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- struct dentry *dent = NULL, *dir;
- int error;
-
-+ AA_BUG(!profile);
-+ AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
-+
- if (!parent) {
- struct aa_profile *p;
- p = aa_deref_parent(profile);
-@@ -1734,6 +1741,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns)
-
- if (!ns)
- return;
-+ AA_BUG(!mutex_is_locked(&ns->lock));
-
- list_for_each_entry(child, &ns->base.profiles, base.list)
- __aafs_profile_rmdir(child);
-@@ -1906,6 +1914,10 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
- {
- struct aa_ns *parent, *next;
-
-+ AA_BUG(!root);
-+ AA_BUG(!ns);
-+ AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
-+
- /* is next namespace a child */
- if (!list_empty(&ns->sub_ns)) {
- next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
-@@ -1940,6 +1952,9 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
- static struct aa_profile *__first_profile(struct aa_ns *root,
- struct aa_ns *ns)
- {
-+ AA_BUG(!root);
-+ AA_BUG(ns && !mutex_is_locked(&ns->lock));
-+
- for (; ns; ns = __next_ns(root, ns)) {
- if (!list_empty(&ns->base.profiles))
- return list_first_entry(&ns->base.profiles,
-@@ -1962,6 +1977,8 @@ static struct aa_profile *__next_profile(struct aa_profile *p)
- struct aa_profile *parent;
- struct aa_ns *ns = p->ns;
-
-+ AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
-+
- /* is next profile a child */
- if (!list_empty(&p->base.profiles))
- return list_first_entry(&p->base.profiles, typeof(*p),
---
-2.14.1
-
diff --git a/patches.apparmor/0011-apparmor-move-to-per-loaddata-files-instead-of-repli.patch b/patches.apparmor/0011-apparmor-move-to-per-loaddata-files-instead-of-repli.patch
deleted file mode 100644
index 5afe29229b..0000000000
--- a/patches.apparmor/0011-apparmor-move-to-per-loaddata-files-instead-of-repli.patch
+++ /dev/null
@@ -1,786 +0,0 @@
-From 3ca09e527d11e352a5d562a717ef84bc7089f4fc Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Tue, 9 May 2017 00:08:41 -0700
-Subject: [PATCH 11/65] apparmor: move to per loaddata files, instead of
- replicating in profiles
-Git-commit: 5d5182cae40115c03933989473288e54afb39c7c
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-The loaddata sets cover more than just a single profile and should
-be tracked at the ns level. Move the load data files under the namespace
-and reference the files from the profiles via a symlink.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 294 +++++++++++++++++++++++-------
- security/apparmor/include/apparmorfs.h | 5 +
- security/apparmor/include/policy_ns.h | 3 +
- security/apparmor/include/policy_unpack.h | 68 ++++++-
- security/apparmor/policy.c | 46 ++++-
- security/apparmor/policy_ns.c | 1 +
- security/apparmor/policy_unpack.c | 61 ++++++-
- 7 files changed, 409 insertions(+), 69 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 26ad1a370632..d3dafd4ed144 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -98,14 +98,11 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
- return ERR_PTR(-ESPIPE);
-
- /* freed by caller to simple_write_to_buffer */
-- data = kvmalloc(sizeof(*data) + alloc_size, GFP_KERNEL);
-- if (data == NULL)
-- return ERR_PTR(-ENOMEM);
-- kref_init(&data->count);
-- data->size = copy_size;
-- data->hash = NULL;
-- data->abi = 0;
-+ data = aa_loaddata_alloc(alloc_size);
-+ if (IS_ERR(data))
-+ return data;
-
-+ data->size = copy_size;
- if (copy_from_user(data->data, userbuf, copy_size)) {
- kvfree(data);
- return ERR_PTR(-EFAULT);
-@@ -213,6 +210,11 @@ static const struct file_operations aa_fs_profile_remove = {
- .llseek = default_llseek,
- };
-
-+void __aa_bump_ns_revision(struct aa_ns *ns)
-+{
-+ ns->revision++;
-+}
-+
- /**
- * query_data - queries a policy and writes its data to buf
- * @buf: the resulting data is stored here (NOT NULL)
-@@ -559,68 +561,88 @@ static const struct file_operations aa_fs_ns_name = {
- .release = single_release,
- };
-
--static int rawdata_release(struct inode *inode, struct file *file)
-+
-+/* policy/raw_data/ * file ops */
-+
-+#define SEQ_RAWDATA_FOPS(NAME) \
-+static int seq_rawdata_ ##NAME ##_open(struct inode *inode, struct file *file)\
-+{ \
-+ return seq_rawdata_open(inode, file, seq_rawdata_ ##NAME ##_show); \
-+} \
-+ \
-+static const struct file_operations seq_rawdata_ ##NAME ##_fops = { \
-+ .owner = THIS_MODULE, \
-+ .open = seq_rawdata_ ##NAME ##_open, \
-+ .read = seq_read, \
-+ .llseek = seq_lseek, \
-+ .release = seq_rawdata_release, \
-+} \
-+
-+static int seq_rawdata_open(struct inode *inode, struct file *file,
-+ int (*show)(struct seq_file *, void *))
- {
-- /* TODO: switch to loaddata when profile switched to symlink */
-- aa_put_loaddata(file->private_data);
-+ struct aa_loaddata *data = __aa_get_loaddata(inode->i_private);
-+ int error;
-
-- return 0;
-+ if (!data)
-+ /* lost race this ent is being reaped */
-+ return -ENOENT;
-+
-+ error = single_open(file, show, data);
-+ if (error) {
-+ AA_BUG(file->private_data &&
-+ ((struct seq_file *)file->private_data)->private);
-+ aa_put_loaddata(data);
-+ }
-+
-+ return error;
- }
-
--static int aa_fs_seq_raw_abi_show(struct seq_file *seq, void *v)
-+static int seq_rawdata_release(struct inode *inode, struct file *file)
- {
-- struct aa_proxy *proxy = seq->private;
-- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-+ struct seq_file *seq = (struct seq_file *) file->private_data;
-+
-+ if (seq)
-+ aa_put_loaddata(seq->private);
-
-- if (profile->rawdata->abi)
-- seq_printf(seq, "v%d\n", profile->rawdata->abi);
-+ return single_release(inode, file);
-+}
-
-- aa_put_profile(profile);
-+static int seq_rawdata_abi_show(struct seq_file *seq, void *v)
-+{
-+ struct aa_loaddata *data = seq->private;
-+
-+ seq_printf(seq, "v%d\n", data->abi);
-
- return 0;
- }
-
--static int aa_fs_seq_raw_abi_open(struct inode *inode, struct file *file)
-+static int seq_rawdata_revision_show(struct seq_file *seq, void *v)
- {
-- return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_abi_show);
--}
-+ struct aa_loaddata *data = seq->private;
-
--static const struct file_operations aa_fs_seq_raw_abi_fops = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_raw_abi_open,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = aa_fs_seq_profile_release,
--};
-+ seq_printf(seq, "%ld\n", data->revision);
-
--static int aa_fs_seq_raw_hash_show(struct seq_file *seq, void *v)
-+ return 0;
-+}
-+
-+static int seq_rawdata_hash_show(struct seq_file *seq, void *v)
- {
-- struct aa_proxy *proxy = seq->private;
-- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-+ struct aa_loaddata *data = seq->private;
- unsigned int i, size = aa_hash_size();
-
-- if (profile->rawdata->hash) {
-+ if (data->hash) {
- for (i = 0; i < size; i++)
-- seq_printf(seq, "%.2x", profile->rawdata->hash[i]);
-+ seq_printf(seq, "%.2x", data->hash[i]);
- seq_putc(seq, '\n');
- }
-- aa_put_profile(profile);
-
- return 0;
- }
-
--static int aa_fs_seq_raw_hash_open(struct inode *inode, struct file *file)
--{
-- return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_hash_show);
--}
--
--static const struct file_operations aa_fs_seq_raw_hash_fops = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_raw_hash_open,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = aa_fs_seq_profile_release,
--};
-+SEQ_RAWDATA_FOPS(abi);
-+SEQ_RAWDATA_FOPS(revision);
-+SEQ_RAWDATA_FOPS(hash);
-
- static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
- loff_t *ppos)
-@@ -631,27 +653,120 @@ static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
- rawdata->size);
- }
-
--static int rawdata_open(struct inode *inode, struct file *file)
-+static int rawdata_release(struct inode *inode, struct file *file)
- {
-- struct aa_proxy *proxy = inode->i_private;
-- struct aa_profile *profile;
-+ aa_put_loaddata(file->private_data);
-+
-+ return 0;
-+}
-
-+static int rawdata_open(struct inode *inode, struct file *file)
-+{
- if (!policy_view_capable(NULL))
- return -EACCES;
-- profile = aa_get_profile_rcu(&proxy->profile);
-- file->private_data = aa_get_loaddata(profile->rawdata);
-- aa_put_profile(profile);
-+ file->private_data = __aa_get_loaddata(inode->i_private);
-+ if (!file->private_data)
-+ /* lost race: this entry is being reaped */
-+ return -ENOENT;
-
- return 0;
- }
-
--static const struct file_operations aa_fs_rawdata_fops = {
-+static const struct file_operations rawdata_fops = {
- .open = rawdata_open,
- .read = rawdata_read,
- .llseek = generic_file_llseek,
- .release = rawdata_release,
- };
-
-+static void remove_rawdata_dents(struct aa_loaddata *rawdata)
-+{
-+ int i;
-+
-+ for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) {
-+ if (!IS_ERR_OR_NULL(rawdata->dents[i])) {
-+ /* no refcounts on i_private */
-+ securityfs_remove(rawdata->dents[i]);
-+ rawdata->dents[i] = NULL;
-+ }
-+ }
-+}
-+
-+void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
-+{
-+ AA_BUG(rawdata->ns && !mutex_is_locked(&rawdata->ns->lock));
-+
-+ if (rawdata->ns) {
-+ remove_rawdata_dents(rawdata);
-+ list_del_init(&rawdata->list);
-+ aa_put_ns(rawdata->ns);
-+ rawdata->ns = NULL;
-+ }
-+}
-+
-+int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
-+{
-+ struct dentry *dent, *dir;
-+
-+ AA_BUG(!ns);
-+ AA_BUG(!rawdata);
-+ AA_BUG(!mutex_is_locked(&ns->lock));
-+ AA_BUG(!ns_subdata_dir(ns));
-+
-+ /*
-+ * just use ns revision dir was originally created at. This is
-+ * under ns->lock and if load is successful revision will be
-+ * bumped and is guaranteed to be unique
-+ */
-+ rawdata->name = kasprintf(GFP_KERNEL, "%ld", ns->revision);
-+ if (!rawdata->name)
-+ return -ENOMEM;
-+
-+ dir = securityfs_create_dir(rawdata->name, ns_subdata_dir(ns));
-+ if (IS_ERR(dir))
-+ /* ->name freed when rawdata freed */
-+ return PTR_ERR(dir);
-+ rawdata->dents[AAFS_LOADDATA_DIR] = dir;
-+
-+ dent = securityfs_create_file("abi", S_IFREG | 0444, dir, rawdata,
-+ &seq_rawdata_abi_fops);
-+ if (IS_ERR(dent))
-+ goto fail;
-+ rawdata->dents[AAFS_LOADDATA_ABI] = dent;
-+
-+ dent = securityfs_create_file("revision", S_IFREG | 0444, dir, rawdata,
-+ &seq_rawdata_revision_fops);
-+ if (IS_ERR(dent))
-+ goto fail;
-+ rawdata->dents[AAFS_LOADDATA_REVISION] = dent;
-+
-+ if (aa_g_hash_policy) {
-+ dent = securityfs_create_file("sha1", S_IFREG | 0444, dir,
-+ rawdata, &seq_rawdata_hash_fops);
-+ if (IS_ERR(dent))
-+ goto fail;
-+ rawdata->dents[AAFS_LOADDATA_HASH] = dent;
-+ }
-+
-+ dent = securityfs_create_file("raw_data", S_IFREG | 0444,
-+ dir, rawdata, &rawdata_fops);
-+ if (IS_ERR(dent))
-+ goto fail;
-+ rawdata->dents[AAFS_LOADDATA_DATA] = dent;
-+ d_inode(dent)->i_size = rawdata->size;
-+
-+ rawdata->ns = aa_get_ns(ns);
-+ list_add(&rawdata->list, &ns->rawdata_list);
-+ /* no refcount on inode rawdata */
-+
-+ return 0;
-+
-+fail:
-+ remove_rawdata_dents(rawdata);
-+
-+ return PTR_ERR(dent);
-+}
-+
- /** fns to setup dynamic per profile/namespace files **/
- void __aa_fs_profile_rmdir(struct aa_profile *profile)
- {
-@@ -703,7 +818,41 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name,
- return dent;
- }
-
--/* requires lock be held */
-+static int profile_depth(struct aa_profile *profile)
-+{
-+ int depth = 0;
-+
-+ rcu_read_lock();
-+ for (depth = 0; profile; profile = rcu_access_pointer(profile->parent))
-+ depth++;
-+ rcu_read_unlock();
-+
-+ return depth;
-+}
-+
-+static int gen_symlink_name(char *buffer, size_t bsize, int depth,
-+ const char *dirname, const char *fname)
-+{
-+ int error;
-+
-+ for (; depth > 0; depth--) {
-+ if (bsize < 7)
-+ return -ENAMETOOLONG;
-+ strcpy(buffer, "../../");
-+ buffer += 6;
-+ bsize -= 6;
-+ }
-+
-+ error = snprintf(buffer, bsize, "raw_data/%s/%s", dirname, fname);
-+ if (error >= bsize || error < 0)
-+ return -ENAMETOOLONG;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Requires: @profile->ns->lock held
-+ */
- int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- {
- struct aa_profile *child;
-@@ -766,26 +915,35 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- }
-
- if (profile->rawdata) {
-- dent = create_profile_file(dir, "raw_sha1", profile,
-- &aa_fs_seq_raw_hash_fops);
-+ char target[64];
-+ int depth = profile_depth(profile);
-+
-+ error = gen_symlink_name(target, sizeof(target), depth,
-+ profile->rawdata->name, "sha1");
-+ if (error < 0)
-+ goto fail2;
-+ dent = securityfs_create_symlink("raw_sha1", dir, target, NULL);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_RAW_HASH] = dent;
-
-- dent = create_profile_file(dir, "raw_abi", profile,
-- &aa_fs_seq_raw_abi_fops);
-+ error = gen_symlink_name(target, sizeof(target), depth,
-+ profile->rawdata->name, "abi");
-+ if (error < 0)
-+ goto fail2;
-+ dent = securityfs_create_symlink("raw_abi", dir, target, NULL);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_RAW_ABI] = dent;
-
-- dent = securityfs_create_file("raw_data", S_IFREG | 0444, dir,
-- profile->proxy,
-- &aa_fs_rawdata_fops);
-+ error = gen_symlink_name(target, sizeof(target), depth,
-+ profile->rawdata->name, "raw_data");
-+ if (error < 0)
-+ goto fail2;
-+ dent = securityfs_create_symlink("raw_data", dir, target, NULL);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_RAW_DATA] = dent;
-- d_inode(dent)->i_size = profile->rawdata->size;
-- aa_get_proxy(profile->proxy);
- }
-
- list_for_each_entry(child, &profile->base.profiles, base.list) {
-@@ -805,6 +963,16 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- return error;
- }
-
-+static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
-+{
-+ struct aa_loaddata *ent, *tmp;
-+
-+ AA_BUG(!mutex_is_locked(&ns->lock));
-+
-+ list_for_each_entry_safe(ent, tmp, &ns->rawdata_list, list)
-+ __aa_fs_remove_rawdata(ent);
-+}
-+
- void __aa_fs_ns_rmdir(struct aa_ns *ns)
- {
- struct aa_ns *sub;
-@@ -823,6 +991,8 @@ void __aa_fs_ns_rmdir(struct aa_ns *ns)
- mutex_unlock(&sub->lock);
- }
-
-+ __aa_fs_list_remove_rawdata(ns);
-+
- if (ns_subns_dir(ns)) {
- sub = d_inode(ns_subns_dir(ns))->i_private;
- aa_put_ns(sub);
-diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
-index 120a798b5bb0..0b6d32b3f05e 100644
---- a/security/apparmor/include/apparmorfs.h
-+++ b/security/apparmor/include/apparmorfs.h
-@@ -106,6 +106,7 @@ enum aafs_prof_type {
- #define prof_dir(X) ((X)->dents[AAFS_PROF_DIR])
- #define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS])
-
-+void __aa_bump_ns_revision(struct aa_ns *ns);
- void __aa_fs_profile_rmdir(struct aa_profile *profile);
- void __aa_fs_profile_migrate_dents(struct aa_profile *old,
- struct aa_profile *new);
-@@ -114,4 +115,8 @@ void __aa_fs_ns_rmdir(struct aa_ns *ns);
- int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent,
- const char *name);
-
-+struct aa_loaddata;
-+void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata);
-+int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata);
-+
- #endif /* __AA_APPARMORFS_H */
-diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
-index 89cffddd7e75..d7a07ac96168 100644
---- a/security/apparmor/include/policy_ns.h
-+++ b/security/apparmor/include/policy_ns.h
-@@ -68,6 +68,9 @@ struct aa_ns {
- atomic_t uniq_null;
- long uniq_id;
- int level;
-+ long revision;
-+
-+ struct list_head rawdata_list;
-
- struct dentry *dents[AAFS_NS_SIZEOF];
- };
-diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h
-index 4c1319eebc42..be6cd69ac319 100644
---- a/security/apparmor/include/policy_unpack.h
-+++ b/security/apparmor/include/policy_unpack.h
-@@ -17,6 +17,8 @@
-
- #include <linux/list.h>
- #include <linux/kref.h>
-+#include <linux/dcache.h>
-+#include <linux/workqueue.h>
-
- struct aa_load_ent {
- struct list_head list;
-@@ -36,26 +38,84 @@ struct aa_load_ent *aa_load_ent_alloc(void);
- #define PACKED_MODE_KILL 2
- #define PACKED_MODE_UNCONFINED 3
-
--/* struct aa_loaddata - buffer of policy load data set */
-+struct aa_ns;
-+
-+enum {
-+ AAFS_LOADDATA_ABI = 0,
-+ AAFS_LOADDATA_REVISION,
-+ AAFS_LOADDATA_HASH,
-+ AAFS_LOADDATA_DATA,
-+ AAFS_LOADDATA_DIR, /* must be last actual entry */
-+ AAFS_LOADDATA_NDENTS /* count of entries */
-+};
-+
-+/*
-+ * struct aa_loaddata - buffer of policy raw_data set
-+ *
-+ * there is no loaddata ref for being on ns list, nor a ref from
-+ * d_inode(@dentry) when grab a ref from these, @ns->lock must be held
-+ * && __aa_get_loaddata() needs to be used, and the return value
-+ * checked, if NULL the loaddata is already being reaped and should be
-+ * considered dead.
-+ */
- struct aa_loaddata {
- struct kref count;
-+ struct list_head list;
-+ struct work_struct work;
-+ struct dentry *dents[AAFS_LOADDATA_NDENTS];
-+ struct aa_ns *ns;
-+ char *name;
- size_t size;
-+ long revision; /* the ns policy revision this caused */
- int abi;
- unsigned char *hash;
-+
- char data[];
- };
-
- int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns);
-
-+/**
-+ * __aa_get_loaddata - get a reference count to uncounted data reference
-+ * @data: reference to get a count on
-+ *
-+ * Returns: pointer to reference OR NULL if race is lost and reference is
-+ * being repeated.
-+ * Requires: @data->ns->lock held, and the return code MUST be checked
-+ *
-+ * Use only from inode->i_private and @data->list found references
-+ */
-+static inline struct aa_loaddata *
-+__aa_get_loaddata(struct aa_loaddata *data)
-+{
-+ if (data && kref_get_unless_zero(&(data->count)))
-+ return data;
-+
-+ return NULL;
-+}
-+
-+/**
-+ * aa_get_loaddata - get a reference count from a counted data reference
-+ * @data: reference to get a count on
-+ *
-+ * Returns: point to reference
-+ * Requires: @data to have a valid reference count on it. It is a bug
-+ * if the race to reap can be encountered when it is used.
-+ */
- static inline struct aa_loaddata *
- aa_get_loaddata(struct aa_loaddata *data)
- {
-- if (data)
-- kref_get(&(data->count));
-- return data;
-+ struct aa_loaddata *tmp = __aa_get_loaddata(data);
-+
-+ AA_BUG(data && !tmp);
-+
-+ return tmp;
- }
-
-+void __aa_loaddata_update(struct aa_loaddata *data, long revision);
-+bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r);
- void aa_loaddata_kref(struct kref *kref);
-+struct aa_loaddata *aa_loaddata_alloc(size_t size);
- static inline void aa_put_loaddata(struct aa_loaddata *data)
- {
- if (data)
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index cf9d670dca94..5968914247a4 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -840,10 +840,13 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- const char *ns_name, *info = NULL;
- struct aa_ns *ns = NULL;
- struct aa_load_ent *ent, *tmp;
-+ struct aa_loaddata *rawdata_ent;
- const char *op = OP_PROF_REPL;
- ssize_t count, error;
-+
- LIST_HEAD(lh);
-
-+ aa_get_loaddata(udata);
- /* released below */
- error = aa_unpack(udata, &lh, &ns_name);
- if (error)
-@@ -887,9 +890,24 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- ns = aa_get_ns(view);
-
- mutex_lock(&ns->lock);
-+ /* check for duplicate rawdata blobs: space and file dedup */
-+ list_for_each_entry(rawdata_ent, &ns->rawdata_list, list) {
-+ if (aa_rawdata_eq(rawdata_ent, udata)) {
-+ struct aa_loaddata *tmp;
-+
-+ tmp = __aa_get_loaddata(rawdata_ent);
-+ /* check we didn't fail the race */
-+ if (tmp) {
-+ aa_put_loaddata(udata);
-+ udata = tmp;
-+ break;
-+ }
-+ }
-+ }
- /* setup parent and ns info */
- list_for_each_entry(ent, &lh, list) {
- struct aa_policy *policy;
-+
- ent->new->rawdata = aa_get_loaddata(udata);
- error = __lookup_replace(ns, ent->new->base.hname, noreplace,
- &ent->old, &info);
-@@ -929,6 +947,14 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- }
-
- /* create new fs entries for introspection if needed */
-+ if (!udata->dents[AAFS_LOADDATA_DIR]) {
-+ error = __aa_fs_create_rawdata(ns, udata);
-+ if (error) {
-+ info = "failed to create raw_data dir and files";
-+ ent = NULL;
-+ goto fail_lock;
-+ }
-+ }
- list_for_each_entry(ent, &lh, list) {
- if (ent->old) {
- /* inherit old interface files */
-@@ -955,10 +981,24 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- }
-
- /* Done with checks that may fail - do actual replacement */
-+ __aa_bump_ns_revision(ns);
-+ __aa_loaddata_update(udata, ns->revision);
- list_for_each_entry_safe(ent, tmp, &lh, list) {
- list_del_init(&ent->list);
- op = (!ent->old && !ent->rename) ? OP_PROF_LOAD : OP_PROF_REPL;
-
-+ if (ent->old && ent->old->rawdata == ent->new->rawdata) {
-+ /* dedup actual profile replacement */
-+ audit_policy(profile, op, ns_name, ent->new->base.hname,
-+ "same as current profile, skipping",
-+ error);
-+ goto skip;
-+ }
-+
-+ /*
-+ * TODO: finer dedup based on profile range in data. Load set
-+ * can differ but profile may remain unchanged
-+ */
- audit_policy(profile, op, NULL, ent->new->base.hname,
- NULL, error);
-
-@@ -998,12 +1038,14 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- aa_get_profile(ent->new));
- __list_add_profile(&ns->base.profiles, ent->new);
- }
-+ skip:
- aa_load_ent_free(ent);
- }
- mutex_unlock(&ns->lock);
-
- out:
- aa_put_ns(ns);
-+ aa_put_loaddata(udata);
-
- if (error)
- return error;
-@@ -1013,7 +1055,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- mutex_unlock(&ns->lock);
-
- /* audit cause of failure */
-- op = (!ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
-+ op = (ent && !ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
- fail:
- audit_policy(profile, op, ns_name, ent ? ent->new->base.hname : NULL,
- info, error);
-@@ -1085,6 +1127,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
- /* remove namespace - can only happen if fqname[0] == ':' */
- mutex_lock(&ns->parent->lock);
- __aa_remove_ns(ns);
-+ __aa_bump_ns_revision(ns);
- mutex_unlock(&ns->parent->lock);
- } else {
- /* remove profile */
-@@ -1097,6 +1140,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
- }
- name = profile->base.hname;
- __remove_profile(profile);
-+ __aa_bump_ns_revision(ns);
- mutex_unlock(&ns->lock);
- }
-
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index 93d1826c4b09..c94ec6ef9e35 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -99,6 +99,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
- goto fail_ns;
-
- INIT_LIST_HEAD(&ns->sub_ns);
-+ INIT_LIST_HEAD(&ns->rawdata_list);
- mutex_init(&ns->lock);
-
- /* released by aa_free_ns() */
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index 182bbfeb4b2c..5ea6a7cb0212 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -122,16 +122,73 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
- return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
- }
-
-+void __aa_loaddata_update(struct aa_loaddata *data, long revision)
-+{
-+ AA_BUG(!data);
-+ AA_BUG(!data->ns);
-+ AA_BUG(!data->dents[AAFS_LOADDATA_REVISION]);
-+ AA_BUG(!mutex_is_locked(&data->ns->lock));
-+ AA_BUG(data->revision > revision);
-+
-+ data->revision = revision;
-+ d_inode(data->dents[AAFS_LOADDATA_DIR])->i_mtime =
-+ current_time(d_inode(data->dents[AAFS_LOADDATA_DIR]));
-+ d_inode(data->dents[AAFS_LOADDATA_REVISION])->i_mtime =
-+ current_time(d_inode(data->dents[AAFS_LOADDATA_REVISION]));
-+}
-+
-+bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r)
-+{
-+ if (l->size != r->size)
-+ return false;
-+ if (aa_g_hash_policy && memcmp(l->hash, r->hash, aa_hash_size()) != 0)
-+ return false;
-+ return memcmp(l->data, r->data, r->size) == 0;
-+}
-+
-+/*
-+ * need to take the ns mutex lock which is NOT safe most places that
-+ * put_loaddata is called, so we have to delay freeing it
-+ */
-+static void do_loaddata_free(struct work_struct *work)
-+{
-+ struct aa_loaddata *d = container_of(work, struct aa_loaddata, work);
-+ struct aa_ns *ns = aa_get_ns(d->ns);
-+
-+ if (ns) {
-+ mutex_lock(&ns->lock);
-+ __aa_fs_remove_rawdata(d);
-+ mutex_unlock(&ns->lock);
-+ aa_put_ns(ns);
-+ }
-+
-+ kzfree(d->hash);
-+ kfree(d->name);
-+ kvfree(d);
-+}
-+
- void aa_loaddata_kref(struct kref *kref)
- {
- struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count);
-
- if (d) {
-- kzfree(d->hash);
-- kvfree(d);
-+ INIT_WORK(&d->work, do_loaddata_free);
-+ schedule_work(&d->work);
- }
- }
-
-+struct aa_loaddata *aa_loaddata_alloc(size_t size)
-+{
-+ struct aa_loaddata *d = kvzalloc(sizeof(*d) + size, GFP_KERNEL);
-+
-+ if (d == NULL)
-+ return ERR_PTR(-ENOMEM);
-+ kref_init(&d->count);
-+ INIT_LIST_HEAD(&d->list);
-+
-+ return d;
-+}
-+
- /* test if read will be in packed data bounds */
- static bool inbounds(struct aa_ext *e, size_t size)
- {
---
-2.12.3
-
diff --git a/patches.apparmor/0012-apparmor-move-new_null_profile-to-after-profile-look.patch b/patches.apparmor/0012-apparmor-move-new_null_profile-to-after-profile-look.patch
deleted file mode 100644
index af08f7e818..0000000000
--- a/patches.apparmor/0012-apparmor-move-new_null_profile-to-after-profile-look.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-From 86352938e152537a8e7dc7ab204f518b90eb7e39 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 16 Aug 2017 08:59:57 -0700
-Subject: [PATCH 12/17] apparmor: move new_null_profile to after profile lookup fns()
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: d07881d2edb0ab783846730629ac2faeaafdf4f1
-
-new_null_profile will need to use some of the profile lookup fns()
-so move instead of doing forward fn declarations.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy.c | 158 ++++++++++++++++++++++-----------------------
- 1 file changed, 79 insertions(+), 79 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 244ea4a4a8f0..a81a384a63b1 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -289,85 +289,6 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
- return NULL;
- }
-
--/**
-- * aa_new_null_profile - create or find a null-X learning profile
-- * @parent: profile that caused this profile to be created (NOT NULL)
-- * @hat: true if the null- learning profile is a hat
-- * @base: name to base the null profile off of
-- * @gfp: type of allocation
-- *
-- * Find/Create a null- complain mode profile used in learning mode. The
-- * name of the profile is unique and follows the format of parent//null-XXX.
-- * where XXX is based on the @name or if that fails or is not supplied
-- * a unique number
-- *
-- * 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.
-- *
-- * Returns: new refcounted profile else NULL on failure
-- */
--struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
-- const char *base, gfp_t gfp)
--{
-- struct aa_profile *profile;
-- char *name;
--
-- AA_BUG(!parent);
--
-- if (base) {
-- name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
-- gfp);
-- if (name) {
-- sprintf(name, "%s//null-%s", parent->base.hname, base);
-- goto name;
-- }
-- /* fall through to try shorter uniq */
-- }
--
-- name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
-- if (!name)
-- return NULL;
-- sprintf(name, "%s//null-%x", parent->base.hname,
-- atomic_inc_return(&parent->ns->uniq_null));
--
--name:
-- /* lookup to see if this is a dup creation */
-- profile = aa_find_child(parent, basename(name));
-- if (profile)
-- goto out;
--
-- profile = aa_alloc_profile(name, NULL, gfp);
-- if (!profile)
-- goto fail;
--
-- profile->mode = APPARMOR_COMPLAIN;
-- profile->label.flags |= FLAG_NULL;
-- if (hat)
-- profile->label.flags |= FLAG_HAT;
-- profile->path_flags = parent->path_flags;
--
-- /* released on free_profile */
-- rcu_assign_pointer(profile->parent, aa_get_profile(parent));
-- profile->ns = aa_get_ns(parent->ns);
-- profile->file.dfa = aa_get_dfa(nulldfa);
-- profile->policy.dfa = aa_get_dfa(nulldfa);
--
-- mutex_lock(&profile->ns->lock);
-- __add_profile(&parent->base.profiles, profile);
-- mutex_unlock(&profile->ns->lock);
--
-- /* refcount released by caller */
--out:
-- kfree(name);
--
-- return profile;
--
--fail:
-- aa_free_profile(profile);
-- return NULL;
--}
--
- /* TODO: profile accounting - setup in remove */
-
- /**
-@@ -558,6 +479,85 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
- return profile;
- }
-
-+/**
-+ * aa_new_null_profile - create or find a null-X learning profile
-+ * @parent: profile that caused this profile to be created (NOT NULL)
-+ * @hat: true if the null- learning profile is a hat
-+ * @base: name to base the null profile off of
-+ * @gfp: type of allocation
-+ *
-+ * Find/Create a null- complain mode profile used in learning mode. The
-+ * name of the profile is unique and follows the format of parent//null-XXX.
-+ * where XXX is based on the @name or if that fails or is not supplied
-+ * a unique number
-+ *
-+ * 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.
-+ *
-+ * Returns: new refcounted profile else NULL on failure
-+ */
-+struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
-+ const char *base, gfp_t gfp)
-+{
-+ struct aa_profile *profile;
-+ char *name;
-+
-+ AA_BUG(!parent);
-+
-+ if (base) {
-+ name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base),
-+ gfp);
-+ if (name) {
-+ sprintf(name, "%s//null-%s", parent->base.hname, base);
-+ goto name;
-+ }
-+ /* fall through to try shorter uniq */
-+ }
-+
-+ name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp);
-+ if (!name)
-+ return NULL;
-+ sprintf(name, "%s//null-%x", parent->base.hname,
-+ atomic_inc_return(&parent->ns->uniq_null));
-+
-+name:
-+ /* lookup to see if this is a dup creation */
-+ profile = aa_find_child(parent, basename(name));
-+ if (profile)
-+ goto out;
-+
-+ profile = aa_alloc_profile(name, NULL, gfp);
-+ if (!profile)
-+ goto fail;
-+
-+ profile->mode = APPARMOR_COMPLAIN;
-+ profile->label.flags |= FLAG_NULL;
-+ if (hat)
-+ profile->label.flags |= FLAG_HAT;
-+ profile->path_flags = parent->path_flags;
-+
-+ /* released on free_profile */
-+ rcu_assign_pointer(profile->parent, aa_get_profile(parent));
-+ profile->ns = aa_get_ns(parent->ns);
-+ profile->file.dfa = aa_get_dfa(nulldfa);
-+ profile->policy.dfa = aa_get_dfa(nulldfa);
-+
-+ mutex_lock(&profile->ns->lock);
-+ __add_profile(&parent->base.profiles, profile);
-+ mutex_unlock(&profile->ns->lock);
-+
-+ /* refcount released by caller */
-+out:
-+ kfree(name);
-+
-+ return profile;
-+
-+fail:
-+ aa_free_profile(profile);
-+ return NULL;
-+}
-+
- /**
- * replacement_allowed - test to see if replacement is allowed
- * @profile: profile to test if it can be replaced (MAYBE NULL)
---
-2.14.1
-
diff --git a/patches.apparmor/0012-apparmor-use-macro-template-to-simplify-profile-seq_.patch b/patches.apparmor/0012-apparmor-use-macro-template-to-simplify-profile-seq_.patch
deleted file mode 100644
index 04aaa2aca5..0000000000
--- a/patches.apparmor/0012-apparmor-use-macro-template-to-simplify-profile-seq_.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-From 88bc035bead1b6a6f7356b654591333b6b795d17 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 25 May 2017 04:35:09 -0700
-Subject: [PATCH 12/65] apparmor: use macro template to simplify profile
- seq_files
-Git-commit: 52b97de32236d4cc9b302ae9259e70bb2f1fa2a5
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 97 ++++++++++++++++--------------------------
- 1 file changed, 36 insertions(+), 61 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index d3dafd4ed144..750431b0ec4e 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -391,8 +391,27 @@ const struct file_operations aa_fs_seq_file_ops = {
- .release = single_release,
- };
-
--static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
-- int (*show)(struct seq_file *, void *))
-+/*
-+ * profile based file operations
-+ * policy/profiles/XXXX/profiles/ *
-+ */
-+
-+#define SEQ_PROFILE_FOPS(NAME) \
-+static int seq_profile_ ##NAME ##_open(struct inode *inode, struct file *file)\
-+{ \
-+ return seq_profile_open(inode, file, seq_profile_ ##NAME ##_show); \
-+} \
-+ \
-+static const struct file_operations seq_profile_ ##NAME ##_fops = { \
-+ .owner = THIS_MODULE, \
-+ .open = seq_profile_ ##NAME ##_open, \
-+ .read = seq_read, \
-+ .llseek = seq_lseek, \
-+ .release = seq_profile_release, \
-+} \
-+
-+static int seq_profile_open(struct inode *inode, struct file *file,
-+ int (*show)(struct seq_file *, void *))
- {
- struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
- int error = single_open(file, show, proxy);
-@@ -405,7 +424,7 @@ static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
- return error;
- }
-
--static int aa_fs_seq_profile_release(struct inode *inode, struct file *file)
-+static int seq_profile_release(struct inode *inode, struct file *file)
- {
- struct seq_file *seq = (struct seq_file *) file->private_data;
- if (seq)
-@@ -413,7 +432,7 @@ static int aa_fs_seq_profile_release(struct inode *inode, struct file *file)
- return single_release(inode, file);
- }
-
--static int aa_fs_seq_profname_show(struct seq_file *seq, void *v)
-+static int seq_profile_name_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-@@ -423,20 +442,7 @@ static int aa_fs_seq_profname_show(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_profname_open(struct inode *inode, struct file *file)
--{
-- return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profname_show);
--}
--
--static const struct file_operations aa_fs_profname_fops = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_profname_open,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = aa_fs_seq_profile_release,
--};
--
--static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
-+static int seq_profile_mode_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-@@ -446,20 +452,7 @@ static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_profmode_open(struct inode *inode, struct file *file)
--{
-- return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profmode_show);
--}
--
--static const struct file_operations aa_fs_profmode_fops = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_profmode_open,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = aa_fs_seq_profile_release,
--};
--
--static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
-+static int seq_profile_attach_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-@@ -474,20 +467,7 @@ static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_profattach_open(struct inode *inode, struct file *file)
--{
-- return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profattach_show);
--}
--
--static const struct file_operations aa_fs_profattach_fops = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_profattach_open,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = aa_fs_seq_profile_release,
--};
--
--static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
-+static int seq_profile_hash_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-@@ -503,18 +483,11 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_hash_open(struct inode *inode, struct file *file)
--{
-- return single_open(file, aa_fs_seq_hash_show, inode->i_private);
--}
-+SEQ_PROFILE_FOPS(name);
-+SEQ_PROFILE_FOPS(mode);
-+SEQ_PROFILE_FOPS(attach);
-+SEQ_PROFILE_FOPS(hash);
-
--static const struct file_operations aa_fs_seq_hash_fops = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_hash_open,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = single_release,
--};
-
-
- static int aa_fs_seq_show_ns_level(struct seq_file *seq, void *v)
-@@ -890,25 +863,27 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- goto fail;
- prof_dir(profile) = dir = dent;
-
-- dent = create_profile_file(dir, "name", profile, &aa_fs_profname_fops);
-+ dent = create_profile_file(dir, "name", profile,
-+ &seq_profile_name_fops);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_NAME] = dent;
-
-- dent = create_profile_file(dir, "mode", profile, &aa_fs_profmode_fops);
-+ dent = create_profile_file(dir, "mode", profile,
-+ &seq_profile_mode_fops);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_MODE] = dent;
-
- dent = create_profile_file(dir, "attach", profile,
-- &aa_fs_profattach_fops);
-+ &seq_profile_attach_fops);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_ATTACH] = dent;
-
- if (profile->hash) {
- dent = create_profile_file(dir, "sha1", profile,
-- &aa_fs_seq_hash_fops);
-+ &seq_profile_hash_fops);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_HASH] = dent;
---
-2.12.3
-
diff --git a/patches.apparmor/0013-apparmor-fix-race-condition-in-null-profile-creation.patch b/patches.apparmor/0013-apparmor-fix-race-condition-in-null-profile-creation.patch
deleted file mode 100644
index 2061fe1448..0000000000
--- a/patches.apparmor/0013-apparmor-fix-race-condition-in-null-profile-creation.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 29ec50aa3815bddeee97a224e917a310b677ca15 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 16 Aug 2017 05:40:49 -0700
-Subject: [PATCH 13/17] apparmor: fix race condition in null profile creation
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 290638a52a808d658bd04b746b3ca46886c157e0
-
-There is a race when null- profile is being created between the
-initial lookup/creation of the profile and lock/addition of the
-profile. This could result in multiple version of a profile being
-added to the list which need to be removed/replaced.
-
-Since these are learning profile their is no affect on mediation.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index a81a384a63b1..4243b0c3f0e4 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -500,7 +500,8 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
- struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- const char *base, gfp_t gfp)
- {
-- struct aa_profile *profile;
-+ struct aa_profile *p, *profile;
-+ const char *bname;
- char *name;
-
- AA_BUG(!parent);
-@@ -523,7 +524,8 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
-
- name:
- /* lookup to see if this is a dup creation */
-- profile = aa_find_child(parent, basename(name));
-+ bname = basename(name);
-+ profile = aa_find_child(parent, bname);
- if (profile)
- goto out;
-
-@@ -544,7 +546,13 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- profile->policy.dfa = aa_get_dfa(nulldfa);
-
- mutex_lock(&profile->ns->lock);
-- __add_profile(&parent->base.profiles, profile);
-+ p = __find_child(&parent->base.profiles, bname);
-+ if (p) {
-+ aa_free_profile(profile);
-+ profile = aa_get_profile(p);
-+ } else {
-+ __add_profile(&parent->base.profiles, profile);
-+ }
- mutex_unlock(&profile->ns->lock);
-
- /* refcount released by caller */
---
-2.14.1
-
diff --git a/patches.apparmor/0013-apparmor-use-macro-template-to-simplify-namespace-se.patch b/patches.apparmor/0013-apparmor-use-macro-template-to-simplify-namespace-se.patch
deleted file mode 100644
index 4f82675ed8..0000000000
--- a/patches.apparmor/0013-apparmor-use-macro-template-to-simplify-namespace-se.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 6926a160746d360ad9067b49d252f667930c066c Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 25 May 2017 07:27:35 -0700
-Subject: [PATCH 13/65] apparmor: use macro template to simplify namespace
- seq_files
-Git-commit: 64c8697045f87713f0648e8429fcc3a0c4c61ffd
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 53 +++++++++++++++++++-----------------------
- 1 file changed, 24 insertions(+), 29 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 750431b0ec4e..16680d15d43e 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -488,9 +488,27 @@ SEQ_PROFILE_FOPS(mode);
- SEQ_PROFILE_FOPS(attach);
- SEQ_PROFILE_FOPS(hash);
-
-+/*
-+ * namespace based files
-+ * several root files and
-+ * policy/ *
-+ */
-
-+#define SEQ_NS_FOPS(NAME) \
-+static int seq_ns_ ##NAME ##_open(struct inode *inode, struct file *file) \
-+{ \
-+ return single_open(file, seq_ns_ ##NAME ##_show, inode->i_private); \
-+} \
-+ \
-+static const struct file_operations seq_ns_ ##NAME ##_fops = { \
-+ .owner = THIS_MODULE, \
-+ .open = seq_ns_ ##NAME ##_open, \
-+ .read = seq_read, \
-+ .llseek = seq_lseek, \
-+ .release = single_release, \
-+} \
-
--static int aa_fs_seq_show_ns_level(struct seq_file *seq, void *v)
-+static int seq_ns_level_show(struct seq_file *seq, void *v)
- {
- struct aa_ns *ns = aa_current_profile()->ns;
-
-@@ -499,20 +517,7 @@ static int aa_fs_seq_show_ns_level(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_open_ns_level(struct inode *inode, struct file *file)
--{
-- return single_open(file, aa_fs_seq_show_ns_level, inode->i_private);
--}
--
--static const struct file_operations aa_fs_ns_level = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_open_ns_level,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = single_release,
--};
--
--static int aa_fs_seq_show_ns_name(struct seq_file *seq, void *v)
-+static int seq_ns_name_show(struct seq_file *seq, void *v)
- {
- struct aa_ns *ns = aa_current_profile()->ns;
-
-@@ -521,18 +526,8 @@ static int aa_fs_seq_show_ns_name(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_open_ns_name(struct inode *inode, struct file *file)
--{
-- return single_open(file, aa_fs_seq_show_ns_name, inode->i_private);
--}
--
--static const struct file_operations aa_fs_ns_name = {
-- .owner = THIS_MODULE,
-- .open = aa_fs_seq_open_ns_name,
-- .read = seq_read,
-- .llseek = seq_lseek,
-- .release = single_release,
--};
-+SEQ_NS_FOPS(level);
-+SEQ_NS_FOPS(name);
-
-
- /* policy/raw_data/ * file ops */
-@@ -1363,8 +1358,8 @@ static struct aa_fs_entry aa_fs_entry_features[] = {
-
- static struct aa_fs_entry aa_fs_entry_apparmor[] = {
- AA_FS_FILE_FOPS(".access", 0640, &aa_fs_access),
-- AA_FS_FILE_FOPS(".ns_level", 0666, &aa_fs_ns_level),
-- AA_FS_FILE_FOPS(".ns_name", 0640, &aa_fs_ns_name),
-+ AA_FS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops),
-+ AA_FS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops),
- AA_FS_FILE_FOPS("profiles", 0440, &aa_fs_profiles_fops),
- AA_FS_DIR("features", aa_fs_entry_features),
- { }
---
-2.12.3
-
diff --git a/patches.apparmor/0014-apparmor-add-custom-apparmorfs-that-will-be-used-by-.patch b/patches.apparmor/0014-apparmor-add-custom-apparmorfs-that-will-be-used-by-.patch
deleted file mode 100644
index f0f99bef6d..0000000000
--- a/patches.apparmor/0014-apparmor-add-custom-apparmorfs-that-will-be-used-by-.patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From de1c3c809dd096b96bb0eca649fd5895c304b03f Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 25 May 2017 05:52:56 -0700
-Subject: [PATCH 14/65] apparmor: add custom apparmorfs that will be used by
- policy namespace files
-Git-commit: a481f4d917835cad86701fc0d1e620c74bb5cd5f
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-
-AppArmor policy needs to be able to be resolved based on the policy
-namespace a task is confined by. Add a base apparmorfs filesystem that
-(like nsfs) will exist as a kern mount and be accessed via jump_link
-through a securityfs file.
-
-Setup the base apparmorfs fns and data, but don't use it yet.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
----
- include/uapi/linux/magic.h | 2 +
- security/apparmor/apparmorfs.c | 353 +++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 338 insertions(+), 17 deletions(-)
-
-diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
-index e230af2e6855..a0908f1d2760 100644
---- a/include/uapi/linux/magic.h
-+++ b/include/uapi/linux/magic.h
-@@ -80,6 +80,8 @@
- #define BTRFS_TEST_MAGIC 0x73727279
- #define NSFS_MAGIC 0x6e736673
- #define BPF_FS_MAGIC 0xcafe4a11
-+#define AAFS_MAGIC 0x5a3c69f0
-+
- /* Since UDF 2.01 is ISO 13346 based... */
- #define UDF_SUPER_MAGIC 0x15013346
- #define BALLOON_KVM_MAGIC 0x13661366
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 16680d15d43e..7e4b7f28ee20 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -22,8 +22,9 @@
- #include <linux/namei.h>
- #include <linux/capability.h>
- #include <linux/rcupdate.h>
--#include <uapi/linux/major.h>
- #include <linux/fs.h>
-+#include <uapi/linux/major.h>
-+#include <uapi/linux/magic.h>
-
- #include "include/apparmor.h"
- #include "include/apparmorfs.h"
-@@ -74,6 +75,265 @@ static int mangle_name(const char *name, char *target)
- return t - target;
- }
-
-+
-+/*
-+ * aafs - core fns and data for the policy tree
-+ */
-+
-+#define AAFS_NAME "apparmorfs"
-+static struct vfsmount *aafs_mnt;
-+static int aafs_count;
-+
-+
-+static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
-+{
-+ struct inode *inode = d_inode(dentry);
-+
-+ seq_printf(seq, "%s:[%lu]", AAFS_NAME, inode->i_ino);
-+ return 0;
-+}
-+
-+static void aafs_evict_inode(struct inode *inode)
-+{
-+ truncate_inode_pages_final(&inode->i_data);
-+ clear_inode(inode);
-+ if (S_ISLNK(inode->i_mode))
-+ kfree(inode->i_link);
-+}
-+
-+static const struct super_operations aafs_super_ops = {
-+ .statfs = simple_statfs,
-+ .evict_inode = aafs_evict_inode,
-+ .show_path = aafs_show_path,
-+};
-+
-+static int fill_super(struct super_block *sb, void *data, int silent)
-+{
-+ static struct tree_descr files[] = { {""} };
-+ int error;
-+
-+ error = simple_fill_super(sb, AAFS_MAGIC, files);
-+ if (error)
-+ return error;
-+ sb->s_op = &aafs_super_ops;
-+
-+ return 0;
-+}
-+
-+static struct dentry *aafs_mount(struct file_system_type *fs_type,
-+ int flags, const char *dev_name, void *data)
-+{
-+ return mount_single(fs_type, flags, data, fill_super);
-+}
-+
-+static struct file_system_type aafs_ops = {
-+ .owner = THIS_MODULE,
-+ .name = AAFS_NAME,
-+ .mount = aafs_mount,
-+ .kill_sb = kill_anon_super,
-+};
-+
-+/**
-+ * __aafs_setup_d_inode - basic inode setup for apparmorfs
-+ * @dir: parent directory for the dentry
-+ * @dentry: dentry we are seting the inode up for
-+ * @mode: permissions the file should have
-+ * @data: data to store on inode.i_private, available in open()
-+ * @link: if symlink, symlink target string
-+ * @fops: struct file_operations that should be used
-+ * @iops: struct of inode_operations that should be used
-+ */
-+static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry,
-+ umode_t mode, void *data, char *link,
-+ const struct file_operations *fops,
-+ const struct inode_operations *iops)
-+{
-+ struct inode *inode = new_inode(dir->i_sb);
-+
-+ AA_BUG(!dir);
-+ AA_BUG(!dentry);
-+
-+ if (!inode)
-+ return -ENOMEM;
-+
-+ inode->i_ino = get_next_ino();
-+ inode->i_mode = mode;
-+ inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
-+ inode->i_private = data;
-+ if (S_ISDIR(mode)) {
-+ inode->i_op = iops ? iops : &simple_dir_inode_operations;
-+ inode->i_fop = &simple_dir_operations;
-+ inc_nlink(inode);
-+ inc_nlink(dir);
-+ } else if (S_ISLNK(mode)) {
-+ inode->i_op = iops ? iops : &simple_symlink_inode_operations;
-+ inode->i_link = link;
-+ } else {
-+ inode->i_fop = fops;
-+ }
-+ d_instantiate(dentry, inode);
-+ dget(dentry);
-+
-+ return 0;
-+}
-+
-+/**
-+ * aafs_create - create a dentry in the apparmorfs filesystem
-+ *
-+ * @name: name of dentry to create
-+ * @mode: permissions the file should have
-+ * @parent: parent directory for this dentry
-+ * @data: data to store on inode.i_private, available in open()
-+ * @link: if symlink, symlink target string
-+ * @fops: struct file_operations that should be used for
-+ * @iops: struct of inode_operations that should be used
-+ *
-+ * This is the basic "create a xxx" function for apparmorfs.
-+ *
-+ * Returns a pointer to a dentry if it succeeds, that must be free with
-+ * aafs_remove(). Will return ERR_PTR on failure.
-+ */
-+static struct dentry *aafs_create(const char *name, umode_t mode,
-+ struct dentry *parent, void *data, void *link,
-+ const struct file_operations *fops,
-+ const struct inode_operations *iops)
-+{
-+ struct dentry *dentry;
-+ struct inode *dir;
-+ int error;
-+
-+ AA_BUG(!name);
-+ AA_BUG(!parent);
-+
-+ if (!(mode & S_IFMT))
-+ mode = (mode & S_IALLUGO) | S_IFREG;
-+
-+ error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
-+ if (error)
-+ return ERR_PTR(error);
-+
-+ dir = d_inode(parent);
-+
-+ inode_lock(dir);
-+ dentry = lookup_one_len(name, parent, strlen(name));
-+ if (IS_ERR(dentry))
-+ goto fail_lock;
-+
-+ if (d_really_is_positive(dentry)) {
-+ error = -EEXIST;
-+ goto fail_dentry;
-+ }
-+
-+ error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops);
-+ if (error)
-+ goto fail_dentry;
-+ inode_unlock(dir);
-+
-+ return dentry;
-+
-+fail_dentry:
-+ dput(dentry);
-+
-+fail_lock:
-+ inode_unlock(dir);
-+ simple_release_fs(&aafs_mnt, &aafs_count);
-+
-+ return ERR_PTR(error);
-+}
-+
-+/**
-+ * aafs_create_file - create a file in the apparmorfs filesystem
-+ *
-+ * @name: name of dentry to create
-+ * @mode: permissions the file should have
-+ * @parent: parent directory for this dentry
-+ * @data: data to store on inode.i_private, available in open()
-+ * @fops: struct file_operations that should be used for
-+ *
-+ * see aafs_create
-+ */
-+static struct dentry *aafs_create_file(const char *name, umode_t mode,
-+ struct dentry *parent, void *data,
-+ const struct file_operations *fops)
-+{
-+ return aafs_create(name, mode, parent, data, NULL, fops, NULL);
-+}
-+
-+/**
-+ * aafs_create_dir - create a directory in the apparmorfs filesystem
-+ *
-+ * @name: name of dentry to create
-+ * @parent: parent directory for this dentry
-+ *
-+ * see aafs_create
-+ */
-+static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
-+{
-+ return aafs_create(name, S_IFDIR | 0755, parent, NULL, NULL, NULL,
-+ NULL);
-+}
-+
-+/**
-+ * aafs_create_symlink - create a symlink in the apparmorfs filesystem
-+ * @name: name of dentry to create
-+ * @parent: parent directory for this dentry
-+ * @target: if symlink, symlink target string
-+ * @iops: struct of inode_operations that should be used
-+ *
-+ * If @target parameter is %NULL, then the @iops parameter needs to be
-+ * setup to handle .readlink and .get_link inode_operations.
-+ */
-+static struct dentry *aafs_create_symlink(const char *name,
-+ struct dentry *parent,
-+ const char *target,
-+ const struct inode_operations *iops)
-+{
-+ struct dentry *dent;
-+ char *link = NULL;
-+
-+ if (target) {
-+ link = kstrdup(target, GFP_KERNEL);
-+ if (!link)
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ dent = aafs_create(name, S_IFLNK | 0444, parent, NULL, link, NULL,
-+ iops);
-+ if (IS_ERR(dent))
-+ kfree(link);
-+
-+ return dent;
-+}
-+
-+/**
-+ * aafs_remove - removes a file or directory from the apparmorfs filesystem
-+ *
-+ * @dentry: dentry of the file/directory/symlink to removed.
-+ */
-+static void aafs_remove(struct dentry *dentry)
-+{
-+ struct inode *dir;
-+
-+ if (!dentry || IS_ERR(dentry))
-+ return;
-+
-+ dir = d_inode(dentry->d_parent);
-+ inode_lock(dir);
-+ if (simple_positive(dentry)) {
-+ if (d_is_dir(dentry))
-+ simple_rmdir(dir, dentry);
-+ else
-+ simple_unlink(dir, dentry);
-+ dput(dentry);
-+ }
-+ inode_unlock(dir);
-+ simple_release_fs(&aafs_mnt, &aafs_count);
-+}
-+
-+
-+/*
-+ * aa_fs - policy load/replace/remove
-+ */
-+
- /**
- * aa_simple_write_to_buffer - common routine for getting policy from user
- * @userbuf: user buffer to copy data from (NOT NULL)
-@@ -1369,14 +1629,14 @@ static struct aa_fs_entry aa_fs_entry =
- AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
-
- /**
-- * aafs_create_file - create a file entry in the apparmor securityfs
-+ * entry_create_file - create a file entry in the apparmor securityfs
- * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
- * @parent: the parent dentry in the securityfs
- *
-- * Use aafs_remove_file to remove entries created with this fn.
-+ * Use entry_remove_file to remove entries created with this fn.
- */
--static int __init aafs_create_file(struct aa_fs_entry *fs_file,
-- struct dentry *parent)
-+static int __init entry_create_file(struct aa_fs_entry *fs_file,
-+ struct dentry *parent)
- {
- int error = 0;
-
-@@ -1391,15 +1651,15 @@ static int __init aafs_create_file(struct aa_fs_entry *fs_file,
- return error;
- }
-
--static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir);
-+static void __init entry_remove_dir(struct aa_fs_entry *fs_dir);
- /**
-- * aafs_create_dir - recursively create a directory entry in the securityfs
-+ * entry_create_dir - recursively create a directory entry in the securityfs
- * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
- * @parent: the parent dentry in the securityfs
- *
-- * Use aafs_remove_dir to remove entries created with this fn.
-+ * Use entry_remove_dir to remove entries created with this fn.
- */
--static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
-+static int __init entry_create_dir(struct aa_fs_entry *fs_dir,
- struct dentry *parent)
- {
- struct aa_fs_entry *fs_file;
-@@ -1413,9 +1673,9 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
-
- for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
- if (fs_file->v_type == AA_FS_TYPE_DIR)
-- error = aafs_create_dir(fs_file, fs_dir->dentry);
-+ error = entry_create_dir(fs_file, fs_dir->dentry);
- else
-- error = aafs_create_file(fs_file, fs_dir->dentry);
-+ error = entry_create_file(fs_file, fs_dir->dentry);
- if (error)
- goto failed;
- }
-@@ -1423,7 +1683,7 @@ static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
- return 0;
-
- failed:
-- aafs_remove_dir(fs_dir);
-+ entry_remove_dir(fs_dir);
-
- return error;
- }
-@@ -1442,16 +1702,16 @@ static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
- }
-
- /**
-- * aafs_remove_dir - recursively drop a directory entry from the securityfs
-+ * entry_remove_dir - recursively drop a directory entry from the securityfs
- * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
- */
--static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
-+static void __init entry_remove_dir(struct aa_fs_entry *fs_dir)
- {
- struct aa_fs_entry *fs_file;
-
- for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
- if (fs_file->v_type == AA_FS_TYPE_DIR)
-- aafs_remove_dir(fs_file);
-+ entry_remove_dir(fs_file);
- else
- aafs_remove_file(fs_file);
- }
-@@ -1466,7 +1726,7 @@ static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
- */
- void __init aa_destroy_aafs(void)
- {
-- aafs_remove_dir(&aa_fs_entry);
-+ entry_remove_dir(&aa_fs_entry);
- }
-
-
-@@ -1515,6 +1775,59 @@ static int aa_mk_null_file(struct dentry *parent)
- return error;
- }
-
-+
-+
-+static const char *policy_get_link(struct dentry *dentry,
-+ struct inode *inode,
-+ struct delayed_call *done)
-+{
-+ struct aa_ns *ns;
-+ struct path path;
-+
-+ if (!dentry)
-+ return ERR_PTR(-ECHILD);
-+ ns = aa_get_current_ns();
-+ path.mnt = mntget(aafs_mnt);
-+ path.dentry = dget(ns_dir(ns));
-+ nd_jump_link(&path);
-+ aa_put_ns(ns);
-+
-+ return NULL;
-+}
-+
-+static int ns_get_name(char *buf, size_t size, struct aa_ns *ns,
-+ struct inode *inode)
-+{
-+ int res = snprintf(buf, size, "%s:[%lu]", AAFS_NAME, inode->i_ino);
-+
-+ if (res < 0 || res >= size)
-+ res = -ENOENT;
-+
-+ return res;
-+}
-+
-+static int policy_readlink(struct dentry *dentry, char __user *buffer,
-+ int buflen)
-+{
-+ struct aa_ns *ns;
-+ char name[32];
-+ int res;
-+
-+ ns = aa_get_current_ns();
-+ res = ns_get_name(name, sizeof(name), ns, d_inode(dentry));
-+ if (res >= 0)
-+ res = readlink_copy(buffer, buflen, name);
-+ aa_put_ns(ns);
-+
-+ return res;
-+}
-+
-+static const struct inode_operations policy_link_iops = {
-+ .readlink = policy_readlink,
-+ .get_link = policy_get_link,
-+};
-+
-+
- /**
- * aa_create_aafs - create the apparmor security filesystem
- *
-@@ -1535,8 +1848,14 @@ static int __init aa_create_aafs(void)
- return -EEXIST;
- }
-
-+ /* setup apparmorfs used to virtualize policy/ */
-+ aafs_mnt = kern_mount(&aafs_ops);
-+ if (IS_ERR(aafs_mnt))
-+ panic("can't set apparmorfs up\n");
-+ aafs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
-+
- /* Populate fs tree. */
-- error = aafs_create_dir(&aa_fs_entry, NULL);
-+ error = entry_create_dir(&aa_fs_entry, NULL);
- if (error)
- goto error;
-
---
-2.12.3
-
diff --git a/patches.apparmor/0014-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch b/patches.apparmor/0014-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch
deleted file mode 100644
index df260c8d62..0000000000
--- a/patches.apparmor/0014-apparmor-ensure-unconfined-profiles-have-dfas-initia.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 970d4f158cab54cc90f649fa5ed1a4c5dcec001d Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 16 Aug 2017 05:48:06 -0700
-Subject: [PATCH 14/17] apparmor: ensure unconfined profiles have dfas initialized
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: 15372b97aa7593c6f5bc1afe69f42fd403c40685
-
-Generally unconfined has early bailout tests and does not need the
-dfas initialized, however if an early bailout test is ever missed
-it will result in an oops.
-
-Be defensive and initialize the unconfined profile to have null dfas
-(no permission) so if an early bailout test is missed we fail
-closed (no perms granted) instead of oopsing.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy_ns.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index 351d3bab3a3d..62a3589c62ab 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -112,6 +112,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
- ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
- FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
- ns->unconfined->mode = APPARMOR_UNCONFINED;
-+ ns->unconfined->file.dfa = aa_get_dfa(nulldfa);
-+ ns->unconfined->policy.dfa = aa_get_dfa(nulldfa);
-
- /* ns and ns->unconfined share ns->unconfined refcount */
- ns->unconfined->ns = ns;
---
-2.14.1
-
diff --git a/patches.apparmor/0015-apparmor-fix-incorrect-type-assignment-when-freeing-.patch b/patches.apparmor/0015-apparmor-fix-incorrect-type-assignment-when-freeing-.patch
deleted file mode 100644
index 96286de549..0000000000
--- a/patches.apparmor/0015-apparmor-fix-incorrect-type-assignment-when-freeing-.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 3298c42b313d63d48b5f4e0fd9a942beca66d9d0 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 16 Aug 2017 09:33:48 -0700
-Subject: [PATCH 15/17] apparmor: fix incorrect type assignment when freeing proxies
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: bc4d82fb946e7b471eab2a80e384227c4eb15652
-
-sparse reports
-
-poisoning the proxy->label before freeing the struct is resulting in
-a sparse build warning.
-../security/apparmor/label.c:52:30: warning: incorrect type in assignment (different address spaces)
-../security/apparmor/label.c:52:30: expected struct aa_label [noderef] <asn:4>*label
-../security/apparmor/label.c:52:30: got struct aa_label *<noident>
-
-fix with RCU_INIT_POINTER as this is one of those cases where
-rcu_assign_pointer() is not needed.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/label.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-index 52b4ef14840d..c5b99b954580 100644
---- a/security/apparmor/label.c
-+++ b/security/apparmor/label.c
-@@ -49,7 +49,7 @@ static void free_proxy(struct aa_proxy *proxy)
- /* p->label will not updated any more as p is dead */
- aa_put_label(rcu_dereference_protected(proxy->label, true));
- memset(proxy, 0, sizeof(*proxy));
-- proxy->label = (struct aa_label *) PROXY_POISON;
-+ RCU_INIT_POINTER(proxy->label, (struct aa_label *)PROXY_POISON);
- kfree(proxy);
- }
- }
---
-2.14.1
-
diff --git a/patches.apparmor/0015-apparmor-rename-apparmor-file-fns-and-data-to-indica.patch b/patches.apparmor/0015-apparmor-rename-apparmor-file-fns-and-data-to-indica.patch
deleted file mode 100644
index 542ec88ce5..0000000000
--- a/patches.apparmor/0015-apparmor-rename-apparmor-file-fns-and-data-to-indica.patch
+++ /dev/null
@@ -1,775 +0,0 @@
-From 0966d2dc636cd82765f02cfc14c4b4b9a7d9f28e Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 25 May 2017 06:23:42 -0700
-Subject: [PATCH 15/65] apparmor: rename apparmor file fns and data to indicate
- use
-Git-commit: c97204baf840bf850e14ef4f5f43251239ca43b6
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-prefixes are used for fns/data that are not static to apparmorfs.c
-with the prefixes being
- aafs - special magic apparmorfs for policy namespace data
- aa_sfs - for fns/data that go into securityfs
- aa_fs - for fns/data that may be used in the either of aafs or
- securityfs
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/Makefile | 6 +-
- security/apparmor/apparmorfs.c | 213 ++++++++++++++++++++-------------
- security/apparmor/capability.c | 4 +-
- security/apparmor/include/apparmorfs.h | 58 ++++-----
- security/apparmor/include/capability.h | 2 +-
- security/apparmor/include/resource.h | 2 +-
- security/apparmor/policy.c | 6 +-
- security/apparmor/policy_ns.c | 4 +-
- security/apparmor/resource.c | 4 +-
- 9 files changed, 172 insertions(+), 127 deletions(-)
-
-diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
-index 2ded2f1be98b..b3e7c04b7e7b 100644
---- a/security/apparmor/Makefile
-+++ b/security/apparmor/Makefile
-@@ -20,7 +20,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
- sed $< >>$@ -r -n -e '/CAP_FS_MASK/d' \
- -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/[\2] = "\L\1",/p';\
- echo "};" >> $@ ;\
-- printf '%s' '\#define AA_FS_CAPS_MASK "' >> $@ ;\
-+ printf '%s' '\#define AA_SFS_CAPS_MASK "' >> $@ ;\
- sed $< -r -n -e '/CAP_FS_MASK/d' \
- -e 's/^\#define[ \t]+CAP_([A-Z0-9_]+)[ \t]+([0-9]+)/\L\1/p' | \
- tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
-@@ -46,7 +46,7 @@ cmd_make-caps = echo "static const char *const capability_names[] = {" > $@ ;\
- # #define RLIMIT_FSIZE 1 /* Maximum filesize */
- # #define RLIMIT_STACK 3 /* max stack size */
- # to
--# #define AA_FS_RLIMIT_MASK "fsize stack"
-+# #define AA_SFS_RLIMIT_MASK "fsize stack"
- quiet_cmd_make-rlim = GEN $@
- cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
- > $@ ;\
-@@ -56,7 +56,7 @@ cmd_make-rlim = echo "static const char *const rlim_names[RLIM_NLIMITS] = {" \
- echo "static const int rlim_map[RLIM_NLIMITS] = {" >> $@ ;\
- sed -r -n "s/^\# ?define[ \t]+(RLIMIT_[A-Z0-9_]+).*/\1,/p" $< >> $@ ;\
- echo "};" >> $@ ; \
-- printf '%s' '\#define AA_FS_RLIMIT_MASK "' >> $@ ;\
-+ printf '%s' '\#define AA_SFS_RLIMIT_MASK "' >> $@ ;\
- sed -r -n 's/^\# ?define[ \t]+RLIMIT_([A-Z0-9_]+).*/\L\1/p' $< | \
- tr '\n' ' ' | sed -e 's/ $$/"\n/' >> $@
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 7e4b7f28ee20..35b822c4a079 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -36,6 +36,35 @@
- #include "include/resource.h"
- #include "include/policy_unpack.h"
-
-+/*
-+ * The apparmor filesystem interface used for policy load and introspection
-+ * The interface is split into two main components based on their function
-+ * a securityfs component:
-+ * used for static files that are always available, and which allows
-+ * userspace to specificy the location of the security filesystem.
-+ *
-+ * fns and data are prefixed with
-+ * aa_sfs_
-+ *
-+ * an apparmorfs component:
-+ * used loaded policy content and introspection. It is not part of a
-+ * regular mounted filesystem and is available only through the magic
-+ * policy symlink in the root of the securityfs apparmor/ directory.
-+ * Tasks queries will be magically redirected to the correct portion
-+ * of the policy tree based on their confinement.
-+ *
-+ * fns and data are prefixed with
-+ * aafs_
-+ *
-+ * The aa_fs_ prefix is used to indicate the fn is used by both the
-+ * securityfs and apparmorfs filesystems.
-+ */
-+
-+
-+/*
-+ * support fns
-+ */
-+
- /**
- * aa_mangle_name - mangle a profile name to std profile layout form
- * @name: profile name to mangle (NOT NULL)
-@@ -606,28 +635,28 @@ static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
- return count;
- }
-
--static const struct file_operations aa_fs_access = {
-+static const struct file_operations aa_sfs_access = {
- .write = aa_write_access,
- .read = simple_transaction_read,
- .release = simple_transaction_release,
- .llseek = generic_file_llseek,
- };
-
--static int aa_fs_seq_show(struct seq_file *seq, void *v)
-+static int aa_sfs_seq_show(struct seq_file *seq, void *v)
- {
-- struct aa_fs_entry *fs_file = seq->private;
-+ struct aa_sfs_entry *fs_file = seq->private;
-
- if (!fs_file)
- return 0;
-
- switch (fs_file->v_type) {
-- case AA_FS_TYPE_BOOLEAN:
-+ case AA_SFS_TYPE_BOOLEAN:
- seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
- break;
-- case AA_FS_TYPE_STRING:
-+ case AA_SFS_TYPE_STRING:
- seq_printf(seq, "%s\n", fs_file->v.string);
- break;
-- case AA_FS_TYPE_U64:
-+ case AA_SFS_TYPE_U64:
- seq_printf(seq, "%#08lx\n", fs_file->v.u64);
- break;
- default:
-@@ -638,14 +667,14 @@ static int aa_fs_seq_show(struct seq_file *seq, void *v)
- return 0;
- }
-
--static int aa_fs_seq_open(struct inode *inode, struct file *file)
-+static int aa_sfs_seq_open(struct inode *inode, struct file *file)
- {
-- return single_open(file, aa_fs_seq_show, inode->i_private);
-+ return single_open(file, aa_sfs_seq_show, inode->i_private);
- }
-
--const struct file_operations aa_fs_seq_file_ops = {
-+const struct file_operations aa_sfs_seq_file_ops = {
- .owner = THIS_MODULE,
-- .open = aa_fs_seq_open,
-+ .open = aa_sfs_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-@@ -996,7 +1025,12 @@ int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
- }
-
- /** fns to setup dynamic per profile/namespace files **/
--void __aa_fs_profile_rmdir(struct aa_profile *profile)
-+
-+/**
-+ *
-+ * Requires: @profile->ns->lock held
-+ */
-+void __aafs_profile_rmdir(struct aa_profile *profile)
- {
- struct aa_profile *child;
- int i;
-@@ -1005,7 +1039,7 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile)
- return;
-
- list_for_each_entry(child, &profile->base.profiles, base.list)
-- __aa_fs_profile_rmdir(child);
-+ __aafs_profile_rmdir(child);
-
- for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
- struct aa_proxy *proxy;
-@@ -1019,8 +1053,12 @@ void __aa_fs_profile_rmdir(struct aa_profile *profile)
- }
- }
-
--void __aa_fs_profile_migrate_dents(struct aa_profile *old,
-- struct aa_profile *new)
-+/**
-+ *
-+ * Requires: @old->ns->lock held
-+ */
-+void __aafs_profile_migrate_dents(struct aa_profile *old,
-+ struct aa_profile *new)
- {
- int i;
-
-@@ -1081,7 +1119,7 @@ static int gen_symlink_name(char *buffer, size_t bsize, int depth,
- /*
- * Requires: @profile->ns->lock held
- */
--int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
-+int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- {
- struct aa_profile *child;
- struct dentry *dent = NULL, *dir;
-@@ -1177,7 +1215,7 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- }
-
- list_for_each_entry(child, &profile->base.profiles, base.list) {
-- error = __aa_fs_profile_mkdir(child, prof_child_dir(profile));
-+ error = __aafs_profile_mkdir(child, prof_child_dir(profile));
- if (error)
- goto fail2;
- }
-@@ -1188,7 +1226,7 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- error = PTR_ERR(dent);
-
- fail2:
-- __aa_fs_profile_rmdir(profile);
-+ __aafs_profile_rmdir(profile);
-
- return error;
- }
-@@ -1203,7 +1241,11 @@ static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
- __aa_fs_remove_rawdata(ent);
- }
-
--void __aa_fs_ns_rmdir(struct aa_ns *ns)
-+/**
-+ *
-+ * Requires: @ns->lock held
-+ */
-+void __aafs_ns_rmdir(struct aa_ns *ns)
- {
- struct aa_ns *sub;
- struct aa_profile *child;
-@@ -1213,11 +1255,11 @@ void __aa_fs_ns_rmdir(struct aa_ns *ns)
- return;
-
- list_for_each_entry(child, &ns->base.profiles, base.list)
-- __aa_fs_profile_rmdir(child);
-+ __aafs_profile_rmdir(child);
-
- list_for_each_entry(sub, &ns->sub_ns, base.list) {
- mutex_lock(&sub->lock);
-- __aa_fs_ns_rmdir(sub);
-+ __aafs_ns_rmdir(sub);
- mutex_unlock(&sub->lock);
- }
-
-@@ -1247,7 +1289,7 @@ void __aa_fs_ns_rmdir(struct aa_ns *ns)
- }
-
- /* assumes cleanup in caller */
--static int __aa_fs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
-+static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
- {
- struct dentry *dent;
-
-@@ -1294,7 +1336,10 @@ static int __aa_fs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
- return 0;
- }
-
--int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
-+/*
-+ * Requires: @ns->lock held
-+ */
-+int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
- {
- struct aa_ns *sub;
- struct aa_profile *child;
-@@ -1314,13 +1359,13 @@ int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
- goto fail;
-
- ns_dir(ns) = dir = dent;
-- error = __aa_fs_ns_mkdir_entries(ns, dir);
-+ error = __aafs_ns_mkdir_entries(ns, dir);
- if (error)
- goto fail2;
-
- /* profiles */
- list_for_each_entry(child, &ns->base.profiles, base.list) {
-- error = __aa_fs_profile_mkdir(child, ns_subprofs_dir(ns));
-+ error = __aafs_profile_mkdir(child, ns_subprofs_dir(ns));
- if (error)
- goto fail2;
- }
-@@ -1328,7 +1373,7 @@ int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
- /* subnamespaces */
- list_for_each_entry(sub, &ns->sub_ns, base.list) {
- mutex_lock(&sub->lock);
-- error = __aa_fs_ns_mkdir(sub, ns_subns_dir(ns), NULL);
-+ error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL);
- mutex_unlock(&sub->lock);
- if (error)
- goto fail2;
-@@ -1340,7 +1385,7 @@ int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
- error = PTR_ERR(dent);
-
- fail2:
-- __aa_fs_ns_rmdir(ns);
-+ __aafs_ns_rmdir(ns);
-
- return error;
- }
-@@ -1550,7 +1595,7 @@ static int seq_show_profile(struct seq_file *f, void *p)
- return 0;
- }
-
--static const struct seq_operations aa_fs_profiles_op = {
-+static const struct seq_operations aa_sfs_profiles_op = {
- .start = p_start,
- .next = p_next,
- .stop = p_stop,
-@@ -1562,7 +1607,7 @@ static int profiles_open(struct inode *inode, struct file *file)
- if (!policy_view_capable(NULL))
- return -EACCES;
-
-- return seq_open(file, &aa_fs_profiles_op);
-+ return seq_open(file, &aa_sfs_profiles_op);
- }
-
- static int profiles_release(struct inode *inode, struct file *file)
-@@ -1570,7 +1615,7 @@ static int profiles_release(struct inode *inode, struct file *file)
- return seq_release(inode, file);
- }
-
--static const struct file_operations aa_fs_profiles_fops = {
-+static const struct file_operations aa_sfs_profiles_fops = {
- .open = profiles_open,
- .read = seq_read,
- .llseek = seq_lseek,
-@@ -1579,63 +1624,63 @@ static const struct file_operations aa_fs_profiles_fops = {
-
-
- /** Base file system setup **/
--static struct aa_fs_entry aa_fs_entry_file[] = {
-- AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
-- "link lock"),
-+static struct aa_sfs_entry aa_sfs_entry_file[] = {
-+ AA_SFS_FILE_STRING("mask",
-+ "create read write exec append mmap_exec link lock"),
- { }
- };
-
--static struct aa_fs_entry aa_fs_entry_domain[] = {
-- AA_FS_FILE_BOOLEAN("change_hat", 1),
-- AA_FS_FILE_BOOLEAN("change_hatv", 1),
-- AA_FS_FILE_BOOLEAN("change_onexec", 1),
-- AA_FS_FILE_BOOLEAN("change_profile", 1),
-- AA_FS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
-- AA_FS_FILE_STRING("version", "1.2"),
-+static struct aa_sfs_entry aa_sfs_entry_domain[] = {
-+ AA_SFS_FILE_BOOLEAN("change_hat", 1),
-+ AA_SFS_FILE_BOOLEAN("change_hatv", 1),
-+ AA_SFS_FILE_BOOLEAN("change_onexec", 1),
-+ AA_SFS_FILE_BOOLEAN("change_profile", 1),
-+ AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
-+ AA_SFS_FILE_STRING("version", "1.2"),
- { }
- };
-
--static struct aa_fs_entry aa_fs_entry_versions[] = {
-- AA_FS_FILE_BOOLEAN("v5", 1),
-+static struct aa_sfs_entry aa_sfs_entry_versions[] = {
-+ AA_SFS_FILE_BOOLEAN("v5", 1),
- { }
- };
-
--static struct aa_fs_entry aa_fs_entry_policy[] = {
-- AA_FS_DIR("versions", aa_fs_entry_versions),
-- AA_FS_FILE_BOOLEAN("set_load", 1),
-+static struct aa_sfs_entry aa_sfs_entry_policy[] = {
-+ AA_SFS_DIR("versions", aa_sfs_entry_versions),
-+ AA_SFS_FILE_BOOLEAN("set_load", 1),
- { }
- };
-
--static struct aa_fs_entry aa_fs_entry_features[] = {
-- AA_FS_DIR("policy", aa_fs_entry_policy),
-- AA_FS_DIR("domain", aa_fs_entry_domain),
-- AA_FS_DIR("file", aa_fs_entry_file),
-- AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
-- AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
-- AA_FS_DIR("caps", aa_fs_entry_caps),
-+static struct aa_sfs_entry aa_sfs_entry_features[] = {
-+ AA_SFS_DIR("policy", aa_sfs_entry_policy),
-+ AA_SFS_DIR("domain", aa_sfs_entry_domain),
-+ AA_SFS_DIR("file", aa_sfs_entry_file),
-+ AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
-+ AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
-+ AA_SFS_DIR("caps", aa_sfs_entry_caps),
- { }
- };
-
--static struct aa_fs_entry aa_fs_entry_apparmor[] = {
-- AA_FS_FILE_FOPS(".access", 0640, &aa_fs_access),
-- AA_FS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops),
-- AA_FS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops),
-- AA_FS_FILE_FOPS("profiles", 0440, &aa_fs_profiles_fops),
-- AA_FS_DIR("features", aa_fs_entry_features),
-+static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
-+ AA_SFS_FILE_FOPS(".access", 0640, &aa_sfs_access),
-+ AA_SFS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops),
-+ AA_SFS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops),
-+ AA_SFS_FILE_FOPS("profiles", 0440, &aa_sfs_profiles_fops),
-+ AA_SFS_DIR("features", aa_sfs_entry_features),
- { }
- };
-
--static struct aa_fs_entry aa_fs_entry =
-- AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
-+static struct aa_sfs_entry aa_sfs_entry =
-+ AA_SFS_DIR("apparmor", aa_sfs_entry_apparmor);
-
- /**
- * entry_create_file - create a file entry in the apparmor securityfs
-- * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
-+ * @fs_file: aa_sfs_entry to build an entry for (NOT NULL)
- * @parent: the parent dentry in the securityfs
- *
- * Use entry_remove_file to remove entries created with this fn.
- */
--static int __init entry_create_file(struct aa_fs_entry *fs_file,
-+static int __init entry_create_file(struct aa_sfs_entry *fs_file,
- struct dentry *parent)
- {
- int error = 0;
-@@ -1651,18 +1696,18 @@ static int __init entry_create_file(struct aa_fs_entry *fs_file,
- return error;
- }
-
--static void __init entry_remove_dir(struct aa_fs_entry *fs_dir);
-+static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir);
- /**
- * entry_create_dir - recursively create a directory entry in the securityfs
-- * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
-+ * @fs_dir: aa_sfs_entry (and all child entries) to build (NOT NULL)
- * @parent: the parent dentry in the securityfs
- *
- * Use entry_remove_dir to remove entries created with this fn.
- */
--static int __init entry_create_dir(struct aa_fs_entry *fs_dir,
-- struct dentry *parent)
-+static int __init entry_create_dir(struct aa_sfs_entry *fs_dir,
-+ struct dentry *parent)
- {
-- struct aa_fs_entry *fs_file;
-+ struct aa_sfs_entry *fs_file;
- struct dentry *dir;
- int error;
-
-@@ -1672,7 +1717,7 @@ static int __init entry_create_dir(struct aa_fs_entry *fs_dir,
- fs_dir->dentry = dir;
-
- for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
-- if (fs_file->v_type == AA_FS_TYPE_DIR)
-+ if (fs_file->v_type == AA_SFS_TYPE_DIR)
- error = entry_create_dir(fs_file, fs_dir->dentry);
- else
- error = entry_create_file(fs_file, fs_dir->dentry);
-@@ -1689,10 +1734,10 @@ static int __init entry_create_dir(struct aa_fs_entry *fs_dir,
- }
-
- /**
-- * aafs_remove_file - drop a single file entry in the apparmor securityfs
-- * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
-+ * entry_remove_file - drop a single file entry in the apparmor securityfs
-+ * @fs_file: aa_sfs_entry to detach from the securityfs (NOT NULL)
- */
--static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
-+static void __init entry_remove_file(struct aa_sfs_entry *fs_file)
- {
- if (!fs_file->dentry)
- return;
-@@ -1703,20 +1748,20 @@ static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
-
- /**
- * entry_remove_dir - recursively drop a directory entry from the securityfs
-- * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
-+ * @fs_dir: aa_sfs_entry (and all child entries) to detach (NOT NULL)
- */
--static void __init entry_remove_dir(struct aa_fs_entry *fs_dir)
-+static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir)
- {
-- struct aa_fs_entry *fs_file;
-+ struct aa_sfs_entry *fs_file;
-
- for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
-- if (fs_file->v_type == AA_FS_TYPE_DIR)
-+ if (fs_file->v_type == AA_SFS_TYPE_DIR)
- entry_remove_dir(fs_file);
- else
-- aafs_remove_file(fs_file);
-+ entry_remove_file(fs_file);
- }
-
-- aafs_remove_file(fs_dir);
-+ entry_remove_file(fs_dir);
- }
-
- /**
-@@ -1726,7 +1771,7 @@ static void __init entry_remove_dir(struct aa_fs_entry *fs_dir)
- */
- void __init aa_destroy_aafs(void)
- {
-- entry_remove_dir(&aa_fs_entry);
-+ entry_remove_dir(&aa_sfs_entry);
- }
-
-
-@@ -1843,7 +1888,7 @@ static int __init aa_create_aafs(void)
- if (!apparmor_initialized)
- return 0;
-
-- if (aa_fs_entry.dentry) {
-+ if (aa_sfs_entry.dentry) {
- AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
- return -EEXIST;
- }
-@@ -1855,11 +1900,11 @@ static int __init aa_create_aafs(void)
- aafs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
-
- /* Populate fs tree. */
-- error = entry_create_dir(&aa_fs_entry, NULL);
-+ error = entry_create_dir(&aa_sfs_entry, NULL);
- if (error)
- goto error;
-
-- dent = securityfs_create_file(".load", 0666, aa_fs_entry.dentry,
-+ dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
- NULL, &aa_fs_profile_load);
- if (IS_ERR(dent)) {
- error = PTR_ERR(dent);
-@@ -1867,7 +1912,7 @@ static int __init aa_create_aafs(void)
- }
- ns_subload(root_ns) = dent;
-
-- dent = securityfs_create_file(".replace", 0666, aa_fs_entry.dentry,
-+ dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
- NULL, &aa_fs_profile_replace);
- if (IS_ERR(dent)) {
- error = PTR_ERR(dent);
-@@ -1875,7 +1920,7 @@ static int __init aa_create_aafs(void)
- }
- ns_subreplace(root_ns) = dent;
-
-- dent = securityfs_create_file(".remove", 0666, aa_fs_entry.dentry,
-+ dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
- NULL, &aa_fs_profile_remove);
- if (IS_ERR(dent)) {
- error = PTR_ERR(dent);
-@@ -1884,13 +1929,13 @@ static int __init aa_create_aafs(void)
- ns_subremove(root_ns) = dent;
-
- mutex_lock(&root_ns->lock);
-- error = __aa_fs_ns_mkdir(root_ns, aa_fs_entry.dentry, "policy");
-+ error = __aafs_ns_mkdir(root_ns, aa_sfs_entry.dentry, "policy");
- mutex_unlock(&root_ns->lock);
-
- if (error)
- goto error;
-
-- error = aa_mk_null_file(aa_fs_entry.dentry);
-+ error = aa_mk_null_file(aa_sfs_entry.dentry);
- if (error)
- goto error;
-
-diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
-index ed0a3e6b8022..3bc19843d8df 100644
---- a/security/apparmor/capability.c
-+++ b/security/apparmor/capability.c
-@@ -28,8 +28,8 @@
- */
- #include "capability_names.h"
-
--struct aa_fs_entry aa_fs_entry_caps[] = {
-- AA_FS_FILE_STRING("mask", AA_FS_CAPS_MASK),
-+struct aa_sfs_entry aa_sfs_entry_caps[] = {
-+ AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK),
- { }
- };
-
-diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
-index 0b6d32b3f05e..bcad87740cb6 100644
---- a/security/apparmor/include/apparmorfs.h
-+++ b/security/apparmor/include/apparmorfs.h
-@@ -17,49 +17,49 @@
-
- extern struct path aa_null;
-
--enum aa_fs_type {
-- AA_FS_TYPE_BOOLEAN,
-- AA_FS_TYPE_STRING,
-- AA_FS_TYPE_U64,
-- AA_FS_TYPE_FOPS,
-- AA_FS_TYPE_DIR,
-+enum aa_sfs_type {
-+ AA_SFS_TYPE_BOOLEAN,
-+ AA_SFS_TYPE_STRING,
-+ AA_SFS_TYPE_U64,
-+ AA_SFS_TYPE_FOPS,
-+ AA_SFS_TYPE_DIR,
- };
-
--struct aa_fs_entry;
-+struct aa_sfs_entry;
-
--struct aa_fs_entry {
-+struct aa_sfs_entry {
- const char *name;
- struct dentry *dentry;
- umode_t mode;
-- enum aa_fs_type v_type;
-+ enum aa_sfs_type v_type;
- union {
- bool boolean;
- char *string;
- unsigned long u64;
-- struct aa_fs_entry *files;
-+ struct aa_sfs_entry *files;
- } v;
- const struct file_operations *file_ops;
- };
-
--extern const struct file_operations aa_fs_seq_file_ops;
-+extern const struct file_operations aa_sfs_seq_file_ops;
-
--#define AA_FS_FILE_BOOLEAN(_name, _value) \
-+#define AA_SFS_FILE_BOOLEAN(_name, _value) \
- { .name = (_name), .mode = 0444, \
-- .v_type = AA_FS_TYPE_BOOLEAN, .v.boolean = (_value), \
-- .file_ops = &aa_fs_seq_file_ops }
--#define AA_FS_FILE_STRING(_name, _value) \
-+ .v_type = AA_SFS_TYPE_BOOLEAN, .v.boolean = (_value), \
-+ .file_ops = &aa_sfs_seq_file_ops }
-+#define AA_SFS_FILE_STRING(_name, _value) \
- { .name = (_name), .mode = 0444, \
-- .v_type = AA_FS_TYPE_STRING, .v.string = (_value), \
-- .file_ops = &aa_fs_seq_file_ops }
--#define AA_FS_FILE_U64(_name, _value) \
-+ .v_type = AA_SFS_TYPE_STRING, .v.string = (_value), \
-+ .file_ops = &aa_sfs_seq_file_ops }
-+#define AA_SFS_FILE_U64(_name, _value) \
- { .name = (_name), .mode = 0444, \
-- .v_type = AA_FS_TYPE_U64, .v.u64 = (_value), \
-- .file_ops = &aa_fs_seq_file_ops }
--#define AA_FS_FILE_FOPS(_name, _mode, _fops) \
-- { .name = (_name), .v_type = AA_FS_TYPE_FOPS, \
-+ .v_type = AA_SFS_TYPE_U64, .v.u64 = (_value), \
-+ .file_ops = &aa_sfs_seq_file_ops }
-+#define AA_SFS_FILE_FOPS(_name, _mode, _fops) \
-+ { .name = (_name), .v_type = AA_SFS_TYPE_FOPS, \
- .mode = (_mode), .file_ops = (_fops) }
--#define AA_FS_DIR(_name, _value) \
-- { .name = (_name), .v_type = AA_FS_TYPE_DIR, .v.files = (_value) }
-+#define AA_SFS_DIR(_name, _value) \
-+ { .name = (_name), .v_type = AA_SFS_TYPE_DIR, .v.files = (_value) }
-
- extern void __init aa_destroy_aafs(void);
-
-@@ -107,12 +107,12 @@ enum aafs_prof_type {
- #define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS])
-
- void __aa_bump_ns_revision(struct aa_ns *ns);
--void __aa_fs_profile_rmdir(struct aa_profile *profile);
--void __aa_fs_profile_migrate_dents(struct aa_profile *old,
-+void __aafs_profile_rmdir(struct aa_profile *profile);
-+void __aafs_profile_migrate_dents(struct aa_profile *old,
- struct aa_profile *new);
--int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
--void __aa_fs_ns_rmdir(struct aa_ns *ns);
--int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent,
-+int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
-+void __aafs_ns_rmdir(struct aa_ns *ns);
-+int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent,
- const char *name);
-
- struct aa_loaddata;
-diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
-index fc3fa381d850..1218e95ebe49 100644
---- a/security/apparmor/include/capability.h
-+++ b/security/apparmor/include/capability.h
-@@ -36,7 +36,7 @@ struct aa_caps {
- kernel_cap_t extended;
- };
-
--extern struct aa_fs_entry aa_fs_entry_caps[];
-+extern struct aa_sfs_entry aa_sfs_entry_caps[];
-
- int aa_capable(struct aa_profile *profile, int cap, int audit);
-
-diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
-index d3f4cf027957..f6289f335c4d 100644
---- a/security/apparmor/include/resource.h
-+++ b/security/apparmor/include/resource.h
-@@ -34,7 +34,7 @@ struct aa_rlimit {
- struct rlimit limits[RLIM_NLIMITS];
- };
-
--extern struct aa_fs_entry aa_fs_entry_rlimit[];
-+extern struct aa_sfs_entry aa_sfs_entry_rlimit[];
-
- int aa_map_resource(int resource);
- int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 5968914247a4..a5e8559e4dec 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -160,7 +160,7 @@ static void __remove_profile(struct aa_profile *profile)
- __aa_profile_list_release(&profile->base.profiles);
- /* released by free_profile */
- __aa_update_proxy(profile, profile->ns->unconfined);
-- __aa_fs_profile_rmdir(profile);
-+ __aafs_profile_rmdir(profile);
- __list_remove_profile(profile);
- }
-
-@@ -784,7 +784,7 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
- /* aafs interface uses proxy */
- rcu_assign_pointer(new->proxy->profile,
- aa_get_profile(new));
-- __aa_fs_profile_migrate_dents(old, new);
-+ __aafs_profile_migrate_dents(old, new);
-
- if (list_empty(&new->base.list)) {
- /* new is not on a list already */
-@@ -971,7 +971,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- parent = prof_child_dir(p);
- } else
- parent = ns_subprofs_dir(ent->new->ns);
-- error = __aa_fs_profile_mkdir(ent->new, parent);
-+ error = __aafs_profile_mkdir(ent->new, parent);
- }
-
- if (error) {
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index c94ec6ef9e35..0a8bc4e887ef 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -196,7 +196,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
- if (!ns)
- return NULL;
- mutex_lock(&ns->lock);
-- error = __aa_fs_ns_mkdir(ns, ns_subns_dir(parent), name);
-+ error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name);
- if (error) {
- AA_ERROR("Failed to create interface for ns %s\n",
- ns->base.name);
-@@ -284,7 +284,7 @@ static void destroy_ns(struct aa_ns *ns)
-
- if (ns->parent)
- __aa_update_proxy(ns->unconfined, ns->parent->unconfined);
-- __aa_fs_ns_rmdir(ns);
-+ __aafs_ns_rmdir(ns);
- mutex_unlock(&ns->lock);
- }
-
-diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
-index 86a941afd956..ae66151fdc38 100644
---- a/security/apparmor/resource.c
-+++ b/security/apparmor/resource.c
-@@ -24,8 +24,8 @@
- */
- #include "rlim_names.h"
-
--struct aa_fs_entry aa_fs_entry_rlimit[] = {
-- AA_FS_FILE_STRING("mask", AA_FS_RLIMIT_MASK),
-+struct aa_sfs_entry aa_sfs_entry_rlimit[] = {
-+ AA_SFS_FILE_STRING("mask", AA_SFS_RLIMIT_MASK),
- { }
- };
-
---
-2.12.3
-
diff --git a/patches.apparmor/0016-apparmor-allow-specifying-an-already-created-dir-to-.patch b/patches.apparmor/0016-apparmor-allow-specifying-an-already-created-dir-to-.patch
deleted file mode 100644
index c009d83b5e..0000000000
--- a/patches.apparmor/0016-apparmor-allow-specifying-an-already-created-dir-to-.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-From b30c67c46e1e7c4966bc2a3ffd350767541f3ed1 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 25 May 2017 06:31:46 -0700
-Subject: [PATCH 16/65] apparmor: allow specifying an already created dir to
- create ns entries in
-Git-commit: 98407f0a0d378df27bfea79301a3aba42d7cea1c
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 9 +++++----
- security/apparmor/include/apparmorfs.h | 4 ++--
- security/apparmor/policy_ns.c | 2 +-
- 3 files changed, 8 insertions(+), 7 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 35b822c4a079..a18f14ab7a8b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -1339,11 +1339,12 @@ static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
- /*
- * Requires: @ns->lock held
- */
--int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
-+int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
-+ struct dentry *dent)
- {
- struct aa_ns *sub;
- struct aa_profile *child;
-- struct dentry *dent, *dir;
-+ struct dentry *dir;
- int error;
-
- AA_BUG(!ns);
-@@ -1373,7 +1374,7 @@ int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
- /* subnamespaces */
- list_for_each_entry(sub, &ns->sub_ns, base.list) {
- mutex_lock(&sub->lock);
-- error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL);
-+ error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
- mutex_unlock(&sub->lock);
- if (error)
- goto fail2;
-@@ -1929,7 +1930,7 @@ static int __init aa_create_aafs(void)
- ns_subremove(root_ns) = dent;
-
- mutex_lock(&root_ns->lock);
-- error = __aafs_ns_mkdir(root_ns, aa_sfs_entry.dentry, "policy");
-+ error = __aafs_ns_mkdir(root_ns, aa_sfs_entry.dentry, "policy", NULL);
- mutex_unlock(&root_ns->lock);
-
- if (error)
-diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
-index bcad87740cb6..071a59a1f056 100644
---- a/security/apparmor/include/apparmorfs.h
-+++ b/security/apparmor/include/apparmorfs.h
-@@ -112,8 +112,8 @@ void __aafs_profile_migrate_dents(struct aa_profile *old,
- struct aa_profile *new);
- int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent);
- void __aafs_ns_rmdir(struct aa_ns *ns);
--int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent,
-- const char *name);
-+int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
-+ struct dentry *dent);
-
- struct aa_loaddata;
- void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata);
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index 0a8bc4e887ef..7d7c23705be2 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -196,7 +196,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
- if (!ns)
- return NULL;
- mutex_lock(&ns->lock);
-- error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name);
-+ error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
- if (error) {
- AA_ERROR("Failed to create interface for ns %s\n",
- ns->base.name);
---
-2.12.3
-
diff --git a/patches.apparmor/0016-apparmor-fix-build-failure-on-sparc-caused-by-undecl.patch b/patches.apparmor/0016-apparmor-fix-build-failure-on-sparc-caused-by-undecl.patch
deleted file mode 100644
index fd85d39ec4..0000000000
--- a/patches.apparmor/0016-apparmor-fix-build-failure-on-sparc-caused-by-undecl.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 58c09ef9a59cd58d2900b910c27e50f10b1c2e23 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Wed, 23 Aug 2017 12:10:39 -0700
-Subject: [PATCH 16/17] apparmor: fix build failure on sparc caused by undeclared signals
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: b1545dba092ba543eab1f7b5ed757a4988e267c8
-
- In file included from security/apparmor/ipc.c:23:0:
- security/apparmor/include/sig_names.h:26:3: error: 'SIGSTKFLT' undeclared here (not in a function)
- [SIGSTKFLT] = 16, /* -, 16, - */
- ^
- security/apparmor/include/sig_names.h:26:3: error: array index in initializer not of integer type
- security/apparmor/include/sig_names.h:26:3: note: (near initialization for 'sig_map')
- security/apparmor/include/sig_names.h:51:3: error: 'SIGUNUSED' undeclared here (not in a function)
- [SIGUNUSED] = 34, /* -, 31, - */
- ^
- security/apparmor/include/sig_names.h:51:3: error: array index in initializer not of integer type
- security/apparmor/include/sig_names.h:51:3: note: (near initialization for 'sig_map')
-
-Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Fixes: c6bf1adaecaa ("apparmor: add the ability to mediate signals")
-Signed-off-by: John Johansen <john.johansen@canonical.com>
----
- security/apparmor/include/sig_names.h | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/include/sig_names.h b/security/apparmor/include/sig_names.h
-index 0d4395f231ca..92e62fe95292 100644
---- a/security/apparmor/include/sig_names.h
-+++ b/security/apparmor/include/sig_names.h
-@@ -23,7 +23,9 @@ static const int sig_map[MAXMAPPED_SIG] = {
- [SIGPIPE] = 13,
- [SIGALRM] = 14,
- [SIGTERM] = 15,
-+#ifdef SIGSTKFLT
- [SIGSTKFLT] = 16, /* -, 16, - */
-+#endif
- [SIGCHLD] = 17, /* 20, 17, 18. SIGCHLD -, -, 18 */
- [SIGCONT] = 18, /* 19, 18, 25 */
- [SIGSTOP] = 19, /* 17, 19, 23 */
-@@ -47,7 +49,8 @@ static const int sig_map[MAXMAPPED_SIG] = {
- #if defined(SIGLOST) && SIGPWR != SIGLOST /* sparc */
- [SIGLOST] = 33, /* unused on Linux */
- #endif
--#if defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
-+#if defined(SIGUNUSED) && \
-+ defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS
- [SIGUNUSED] = 34, /* -, 31, - */
- #endif
- };
---
-2.14.1
-
diff --git a/patches.apparmor/0017-apparmor-convert-from-securityfs-to-apparmorfs-for-p.patch b/patches.apparmor/0017-apparmor-convert-from-securityfs-to-apparmorfs-for-p.patch
deleted file mode 100644
index 6e23097466..0000000000
--- a/patches.apparmor/0017-apparmor-convert-from-securityfs-to-apparmorfs-for-p.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From de0b29caff196166ce6b58e700ba5dcb75ff9936 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 25 May 2017 06:35:38 -0700
-Subject: [PATCH 17/65] apparmor: convert from securityfs to apparmorfs for
- policy ns files
-Git-commit: c961ee5f21b202dea60b63eeef945730d92e46a6
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Virtualize the apparmor policy/ directory so that the current
-namespace affects what part of policy is seen. To do this convert to
-using apparmorfs for policy namespace files and setup a magic symlink
-in the securityfs apparmor dir to access those files.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Reviewed-by: Seth Arnold <seth.arnold@canonical.com>
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 63 +++++++++++++++++++++++++-----------------
- 1 file changed, 37 insertions(+), 26 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index a18f14ab7a8b..c847f601371d 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -943,7 +943,7 @@ static void remove_rawdata_dents(struct aa_loaddata *rawdata)
- for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) {
- if (!IS_ERR_OR_NULL(rawdata->dents[i])) {
- /* no refcounts on i_private */
-- securityfs_remove(rawdata->dents[i]);
-+ aafs_remove(rawdata->dents[i]);
- rawdata->dents[i] = NULL;
- }
- }
-@@ -979,33 +979,33 @@ int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
- if (!rawdata->name)
- return -ENOMEM;
-
-- dir = securityfs_create_dir(rawdata->name, ns_subdata_dir(ns));
-+ dir = aafs_create_dir(rawdata->name, ns_subdata_dir(ns));
- if (IS_ERR(dir))
- /* ->name freed when rawdata freed */
- return PTR_ERR(dir);
- rawdata->dents[AAFS_LOADDATA_DIR] = dir;
-
-- dent = securityfs_create_file("abi", S_IFREG | 0444, dir, rawdata,
-+ dent = aafs_create_file("abi", S_IFREG | 0444, dir, rawdata,
- &seq_rawdata_abi_fops);
- if (IS_ERR(dent))
- goto fail;
- rawdata->dents[AAFS_LOADDATA_ABI] = dent;
-
-- dent = securityfs_create_file("revision", S_IFREG | 0444, dir, rawdata,
-+ dent = aafs_create_file("revision", S_IFREG | 0444, dir, rawdata,
- &seq_rawdata_revision_fops);
- if (IS_ERR(dent))
- goto fail;
- rawdata->dents[AAFS_LOADDATA_REVISION] = dent;
-
- if (aa_g_hash_policy) {
-- dent = securityfs_create_file("sha1", S_IFREG | 0444, dir,
-+ dent = aafs_create_file("sha1", S_IFREG | 0444, dir,
- rawdata, &seq_rawdata_hash_fops);
- if (IS_ERR(dent))
- goto fail;
- rawdata->dents[AAFS_LOADDATA_HASH] = dent;
- }
-
-- dent = securityfs_create_file("raw_data", S_IFREG | 0444,
-+ dent = aafs_create_file("raw_data", S_IFREG | 0444,
- dir, rawdata, &rawdata_fops);
- if (IS_ERR(dent))
- goto fail;
-@@ -1047,7 +1047,7 @@ void __aafs_profile_rmdir(struct aa_profile *profile)
- continue;
-
- proxy = d_inode(profile->dents[i])->i_private;
-- securityfs_remove(profile->dents[i]);
-+ aafs_remove(profile->dents[i]);
- aa_put_proxy(proxy);
- profile->dents[i] = NULL;
- }
-@@ -1077,7 +1077,7 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name,
- struct aa_proxy *proxy = aa_get_proxy(profile->proxy);
- struct dentry *dent;
-
-- dent = securityfs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
-+ dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
- if (IS_ERR(dent))
- aa_put_proxy(proxy);
-
-@@ -1130,7 +1130,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- p = aa_deref_parent(profile);
- dent = prof_dir(p);
- /* adding to parent that previously didn't have children */
-- dent = securityfs_create_dir("profiles", dent);
-+ dent = aafs_create_dir("profiles", dent);
- if (IS_ERR(dent))
- goto fail;
- prof_child_dir(p) = parent = dent;
-@@ -1151,7 +1151,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
- }
-
-- dent = securityfs_create_dir(profile->dirname, parent);
-+ dent = aafs_create_dir(profile->dirname, parent);
- if (IS_ERR(dent))
- goto fail;
- prof_dir(profile) = dir = dent;
-@@ -1190,7 +1190,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- profile->rawdata->name, "sha1");
- if (error < 0)
- goto fail2;
-- dent = securityfs_create_symlink("raw_sha1", dir, target, NULL);
-+ dent = aafs_create_symlink("raw_sha1", dir, target, NULL);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_RAW_HASH] = dent;
-@@ -1199,7 +1199,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- profile->rawdata->name, "abi");
- if (error < 0)
- goto fail2;
-- dent = securityfs_create_symlink("raw_abi", dir, target, NULL);
-+ dent = aafs_create_symlink("raw_abi", dir, target, NULL);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_RAW_ABI] = dent;
-@@ -1208,7 +1208,7 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- profile->rawdata->name, "raw_data");
- if (error < 0)
- goto fail2;
-- dent = securityfs_create_symlink("raw_data", dir, target, NULL);
-+ dent = aafs_create_symlink("raw_data", dir, target, NULL);
- if (IS_ERR(dent))
- goto fail;
- profile->dents[AAFS_PROF_RAW_DATA] = dent;
-@@ -1283,7 +1283,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns)
- }
-
- for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
-- securityfs_remove(ns->dents[i]);
-+ aafs_remove(ns->dents[i]);
- ns->dents[i] = NULL;
- }
- }
-@@ -1296,38 +1296,38 @@ static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
- AA_BUG(!ns);
- AA_BUG(!dir);
-
-- dent = securityfs_create_dir("profiles", dir);
-+ dent = aafs_create_dir("profiles", dir);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- ns_subprofs_dir(ns) = dent;
-
-- dent = securityfs_create_dir("raw_data", dir);
-+ dent = aafs_create_dir("raw_data", dir);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- ns_subdata_dir(ns) = dent;
-
-- dent = securityfs_create_file(".load", 0640, dir, ns,
-+ dent = aafs_create_file(".load", 0640, dir, ns,
- &aa_fs_profile_load);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- aa_get_ns(ns);
- ns_subload(ns) = dent;
-
-- dent = securityfs_create_file(".replace", 0640, dir, ns,
-+ dent = aafs_create_file(".replace", 0640, dir, ns,
- &aa_fs_profile_replace);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- aa_get_ns(ns);
- ns_subreplace(ns) = dent;
-
-- dent = securityfs_create_file(".remove", 0640, dir, ns,
-+ dent = aafs_create_file(".remove", 0640, dir, ns,
- &aa_fs_profile_remove);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- aa_get_ns(ns);
- ns_subremove(ns) = dent;
-
-- dent = securityfs_create_dir("namespaces", dir);
-+ dent = aafs_create_dir("namespaces", dir);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- aa_get_ns(ns);
-@@ -1354,11 +1354,13 @@ int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
- if (!name)
- name = ns->base.name;
-
-- /* create ns dir if it doesn't already exist */
-- dent = securityfs_create_dir(name, parent);
-- if (IS_ERR(dent))
-- goto fail;
--
-+ if (!dent) {
-+ /* create ns dir if it doesn't already exist */
-+ dent = aafs_create_dir(name, parent);
-+ if (IS_ERR(dent))
-+ goto fail;
-+ } else
-+ dget(dent);
- ns_dir(ns) = dir = dent;
- error = __aafs_ns_mkdir_entries(ns, dir);
- if (error)
-@@ -1930,12 +1932,21 @@ static int __init aa_create_aafs(void)
- ns_subremove(root_ns) = dent;
-
- mutex_lock(&root_ns->lock);
-- error = __aafs_ns_mkdir(root_ns, aa_sfs_entry.dentry, "policy", NULL);
-+ error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
-+ aafs_mnt->mnt_root);
- mutex_unlock(&root_ns->lock);
-
- if (error)
- goto error;
-
-+ /* magic symlink similar to nsfs redirects based on task policy */
-+ dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
-+ NULL, &policy_link_iops);
-+ if (IS_ERR(dent)) {
-+ error = PTR_ERR(dent);
-+ goto error;
-+ }
-+
- error = aa_mk_null_file(aa_sfs_entry.dentry);
- if (error)
- goto error;
---
-2.12.3
-
diff --git a/patches.apparmor/0017-apparmor-fix-apparmorfs-DAC-access-permissions.patch b/patches.apparmor/0017-apparmor-fix-apparmorfs-DAC-access-permissions.patch
deleted file mode 100644
index ec27c15e0e..0000000000
--- a/patches.apparmor/0017-apparmor-fix-apparmorfs-DAC-access-permissions.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 287b1ee04780e6921eea4e427376c756ab314fab Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 31 Aug 2017 09:54:43 -0700
-Subject: [PATCH 17/17] apparmor: fix apparmorfs DAC access permissions
-References: FATE#323500
-Patch-mainline: v4.14-rc2
-Git-commit: bf81100f63db7ea243d17b9d5008ba3af2fdf6b2
-
-The DAC access permissions for several apparmorfs files are wrong.
-
-.access - needs to be writable by all tasks to perform queries
-the others in the set only provide a read fn so should be read only.
-
-With policy namespace virtualization all apparmor needs to control
-the permission and visibility checks directly which means DAC
-access has to be allowed for all user, group, and other.
-
-BugLink: http://bugs.launchpad.net/bugs/1713103
-Fixes: c97204baf840b ("apparmor: rename apparmor file fns and data to indicate use")
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 125dad5c3fde..518d5928661b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -2215,12 +2215,12 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
- };
-
- static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
-- AA_SFS_FILE_FOPS(".access", 0640, &aa_sfs_access),
-+ AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access),
- AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops),
- AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops),
-- AA_SFS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops),
-- AA_SFS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops),
-- AA_SFS_FILE_FOPS("profiles", 0440, &aa_sfs_profiles_fops),
-+ AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops),
-+ AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops),
-+ AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops),
- AA_SFS_DIR("features", aa_sfs_entry_features),
- { }
- };
---
-2.14.1
-
diff --git a/patches.apparmor/0018-apparmor-move-permissions-into-their-own-file-to-be-.patch b/patches.apparmor/0018-apparmor-move-permissions-into-their-own-file-to-be-.patch
deleted file mode 100644
index 30f4dbdd62..0000000000
--- a/patches.apparmor/0018-apparmor-move-permissions-into-their-own-file-to-be-.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 77116b1422c270acfeeefae235fc5400ed620b60 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 01:57:09 -0700
-Subject: [PATCH 18/65] apparmor: move permissions into their own file to be
- more easily shared
-Git-commit: fc7e0b26b8d26e680bb2f252e9521385e0092e4c
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/file.h | 20 +------------------
- security/apparmor/include/perms.h | 40 ++++++++++++++++++++++++++++++++++++++
- security/apparmor/include/policy.h | 1 +
- security/apparmor/lib.c | 1 +
- 4 files changed, 43 insertions(+), 19 deletions(-)
- create mode 100644 security/apparmor/include/perms.h
-
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-index eba39cb25f02..a75e4872053a 100644
---- a/security/apparmor/include/file.h
-+++ b/security/apparmor/include/file.h
-@@ -17,29 +17,11 @@
-
- #include "domain.h"
- #include "match.h"
-+#include "perms.h"
-
- struct aa_profile;
- struct path;
-
--/*
-- * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
-- * for profile permissions
-- */
--#define AA_MAY_CREATE 0x0010
--#define AA_MAY_DELETE 0x0020
--#define AA_MAY_META_WRITE 0x0040
--#define AA_MAY_META_READ 0x0080
--
--#define AA_MAY_CHMOD 0x0100
--#define AA_MAY_CHOWN 0x0200
--#define AA_MAY_LOCK 0x0400
--#define AA_EXEC_MMAP 0x0800
--
--#define AA_MAY_LINK 0x1000
--#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
--#define AA_MAY_ONEXEC 0x40000000 /* exec allows onexec */
--#define AA_MAY_CHANGE_PROFILE 0x80000000
--#define AA_MAY_CHANGEHAT 0x80000000 /* ctrl auditing only */
-
- #define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
- AA_MAY_CREATE | AA_MAY_DELETE | \
-diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
-new file mode 100644
-index 000000000000..4a65755a2dc0
---- /dev/null
-+++ b/security/apparmor/include/perms.h
-@@ -0,0 +1,40 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor basic permission sets definitions.
-+ *
-+ * Copyright 2017 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_PERM_H
-+#define __AA_PERM_H
-+
-+#include <linux/fs.h>
-+
-+/*
-+ * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
-+ * for profile permissions
-+ */
-+#define AA_MAY_CREATE 0x0010
-+#define AA_MAY_DELETE 0x0020
-+#define AA_MAY_META_WRITE 0x0040
-+#define AA_MAY_META_READ 0x0080
-+
-+#define AA_MAY_CHMOD 0x0100
-+#define AA_MAY_CHOWN 0x0200
-+#define AA_MAY_LOCK 0x0400
-+#define AA_EXEC_MMAP 0x0800
-+
-+#define AA_MAY_LINK 0x1000
-+#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
-+#define AA_MAY_ONEXEC 0x40000000 /* exec allows onexec */
-+#define AA_MAY_CHANGE_PROFILE 0x80000000
-+#define AA_MAY_CHANGEHAT 0x80000000 /* ctrl auditing only */
-+
-+
-+#endif /* __AA_PERM_H */
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
-index dffa01c018c8..0f87f70287ad 100644
---- a/security/apparmor/include/policy.h
-+++ b/security/apparmor/include/policy.h
-@@ -29,6 +29,7 @@
- #include "domain.h"
- #include "file.h"
- #include "lib.h"
-+#include "perms.h"
- #include "resource.h"
-
-
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index 864b2fa45852..90eb14c9e0cf 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -21,6 +21,7 @@
- #include "include/audit.h"
- #include "include/apparmor.h"
- #include "include/lib.h"
-+#include "include/perms.h"
- #include "include/policy.h"
-
- /**
---
-2.12.3
-
diff --git a/patches.apparmor/0019-apparmor-rework-perm-mapping-to-a-slightly-broader-s.patch b/patches.apparmor/0019-apparmor-rework-perm-mapping-to-a-slightly-broader-s.patch
deleted file mode 100644
index 5d0b92966d..0000000000
--- a/patches.apparmor/0019-apparmor-rework-perm-mapping-to-a-slightly-broader-s.patch
+++ /dev/null
@@ -1,311 +0,0 @@
-From ba54ac8ab064ddb8bf082f6c71d28aa8d9b16af4 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 15:07:22 -0700
-Subject: [PATCH 19/65] apparmor: rework perm mapping to a slightly broader set
-Git-commit: e53cfe6c7caa79ccdccce53e600dae522acb1c84
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/file.c | 43 +++++++++---------------
- security/apparmor/include/file.h | 5 +--
- security/apparmor/include/perms.h | 69 ++++++++++++++++++++++++++++-----------
- security/apparmor/lib.c | 59 +++++++++++++++++++++++++++++++++
- security/apparmor/lsm.c | 10 +++---
- 5 files changed, 133 insertions(+), 53 deletions(-)
-
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index 22be62f0fc73..44549db904b3 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -21,6 +21,17 @@
-
- struct file_perms nullperms;
-
-+static u32 map_mask_to_chr_mask(u32 mask)
-+{
-+ u32 m = mask & PERMS_CHRS_MASK;
-+
-+ if (mask & AA_MAY_GETATTR)
-+ m |= MAY_READ;
-+ if (mask & (AA_MAY_SETATTR | AA_MAY_CHMOD | AA_MAY_CHOWN))
-+ m |= MAY_WRITE;
-+
-+ return m;
-+}
-
- /**
- * audit_file_mask - convert mask to permission string
-@@ -31,29 +42,7 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
- {
- char str[10];
-
-- char *m = str;
--
-- if (mask & AA_EXEC_MMAP)
-- *m++ = 'm';
-- if (mask & (MAY_READ | AA_MAY_META_READ))
-- *m++ = 'r';
-- if (mask & (MAY_WRITE | AA_MAY_META_WRITE | AA_MAY_CHMOD |
-- AA_MAY_CHOWN))
-- *m++ = 'w';
-- else if (mask & MAY_APPEND)
-- *m++ = 'a';
-- if (mask & AA_MAY_CREATE)
-- *m++ = 'c';
-- if (mask & AA_MAY_DELETE)
-- *m++ = 'd';
-- if (mask & AA_MAY_LINK)
-- *m++ = 'l';
-- if (mask & AA_MAY_LOCK)
-- *m++ = 'k';
-- if (mask & MAY_EXEC)
-- *m++ = 'x';
-- *m = '\0';
--
-+ aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask));
- audit_log_string(ab, str);
- }
-
-@@ -163,10 +152,10 @@ static u32 map_old_perms(u32 old)
- {
- u32 new = old & 0xf;
- if (old & MAY_READ)
-- new |= AA_MAY_META_READ;
-+ new |= AA_MAY_GETATTR | AA_MAY_OPEN;
- if (old & MAY_WRITE)
-- new |= AA_MAY_META_WRITE | AA_MAY_CREATE | AA_MAY_DELETE |
-- AA_MAY_CHMOD | AA_MAY_CHOWN;
-+ new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
-+ AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
- if (old & 0x10)
- new |= AA_MAY_LINK;
- /* the old mapping lock and link_subset flags where overlaid
-@@ -214,7 +203,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
- perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
- perms.xindex = dfa_other_xindex(dfa, state);
- }
-- perms.allow |= AA_MAY_META_READ;
-+ perms.allow |= AA_MAY_GETATTR;
-
- /* change_profile wasn't determined by ownership in old mapping */
- if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-index a75e4872053a..fb3642a94e3d 100644
---- a/security/apparmor/include/file.h
-+++ b/security/apparmor/include/file.h
-@@ -22,10 +22,11 @@
- struct aa_profile;
- struct path;
-
-+#define mask_mode_t(X) (X & (MAY_EXEC | MAY_WRITE | MAY_READ | MAY_APPEND))
-
- #define AA_AUDIT_FILE_MASK (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND |\
- AA_MAY_CREATE | AA_MAY_DELETE | \
-- AA_MAY_META_READ | AA_MAY_META_WRITE | \
-+ AA_MAY_GETATTR | AA_MAY_SETATTR | \
- AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
- AA_EXEC_MMAP | AA_MAY_LINK)
-
-@@ -37,7 +38,7 @@ struct path;
- * ctx struct will expand in the future so we keep the struct.
- */
- struct aa_file_ctx {
-- u16 allow;
-+ u32 allow;
- };
-
- /**
-diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
-index 4a65755a2dc0..35e365e7aa75 100644
---- a/security/apparmor/include/perms.h
-+++ b/security/apparmor/include/perms.h
-@@ -16,25 +16,56 @@
-
- #include <linux/fs.h>
-
--/*
-- * We use MAY_EXEC, MAY_WRITE, MAY_READ, MAY_APPEND and the following flags
-- * for profile permissions
-- */
--#define AA_MAY_CREATE 0x0010
--#define AA_MAY_DELETE 0x0020
--#define AA_MAY_META_WRITE 0x0040
--#define AA_MAY_META_READ 0x0080
--
--#define AA_MAY_CHMOD 0x0100
--#define AA_MAY_CHOWN 0x0200
--#define AA_MAY_LOCK 0x0400
--#define AA_EXEC_MMAP 0x0800
--
--#define AA_MAY_LINK 0x1000
--#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
--#define AA_MAY_ONEXEC 0x40000000 /* exec allows onexec */
--#define AA_MAY_CHANGE_PROFILE 0x80000000
--#define AA_MAY_CHANGEHAT 0x80000000 /* ctrl auditing only */
-+#define AA_MAY_EXEC MAY_EXEC
-+#define AA_MAY_WRITE MAY_WRITE
-+#define AA_MAY_READ MAY_READ
-+#define AA_MAY_APPEND MAY_APPEND
-+
-+#define AA_MAY_CREATE 0x0010
-+#define AA_MAY_DELETE 0x0020
-+#define AA_MAY_OPEN 0x0040
-+#define AA_MAY_RENAME 0x0080 /* pair */
-+
-+#define AA_MAY_SETATTR 0x0100 /* meta write */
-+#define AA_MAY_GETATTR 0x0200 /* meta read */
-+#define AA_MAY_SETCRED 0x0400 /* security cred/attr */
-+#define AA_MAY_GETCRED 0x0800
-+
-+#define AA_MAY_CHMOD 0x1000 /* pair */
-+#define AA_MAY_CHOWN 0x2000 /* pair */
-+#define AA_MAY_CHGRP 0x4000 /* pair */
-+#define AA_MAY_LOCK 0x8000 /* LINK_SUBSET overlaid */
-+
-+#define AA_EXEC_MMAP 0x00010000
-+#define AA_MAY_MPROT 0x00020000 /* extend conditions */
-+#define AA_MAY_LINK 0x00040000 /* pair */
-+#define AA_MAY_SNAPSHOT 0x00080000 /* pair */
-+
-+#define AA_MAY_DELEGATE
-+#define AA_CONT_MATCH 0x08000000
-+
-+#define AA_MAY_STACK 0x10000000
-+#define AA_MAY_ONEXEC 0x20000000 /* either stack or change_profile */
-+#define AA_MAY_CHANGE_PROFILE 0x40000000
-+#define AA_MAY_CHANGEHAT 0x80000000
-+
-+#define AA_LINK_SUBSET AA_MAY_LOCK /* overlaid */
-+
-+
-+#define PERMS_CHRS_MASK (MAY_READ | MAY_WRITE | AA_MAY_CREATE | \
-+ AA_MAY_DELETE | AA_MAY_LINK | AA_MAY_LOCK | \
-+ AA_MAY_EXEC | AA_EXEC_MMAP | AA_MAY_APPEND)
-+
-+#define PERMS_NAMES_MASK (PERMS_CHRS_MASK | AA_MAY_OPEN | AA_MAY_RENAME | \
-+ AA_MAY_SETATTR | AA_MAY_GETATTR | AA_MAY_SETCRED | \
-+ AA_MAY_GETCRED | AA_MAY_CHMOD | AA_MAY_CHOWN | \
-+ AA_MAY_CHGRP | AA_MAY_MPROT | AA_MAY_SNAPSHOT | \
-+ AA_MAY_STACK | AA_MAY_ONEXEC | \
-+ AA_MAY_CHANGE_PROFILE | AA_MAY_CHANGEHAT)
-+
-+extern const char aa_file_perm_chrs[];
-+extern const char *aa_file_perm_names[];
-
-+void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
-
- #endif /* __AA_PERM_H */
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index 90eb14c9e0cf..90d4631ddafe 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -129,6 +129,65 @@ void aa_info_message(const char *str)
- printk(KERN_INFO "AppArmor: %s\n", str);
- }
-
-+const char aa_file_perm_chrs[] = "xwracd km l ";
-+const char *aa_file_perm_names[] = {
-+ "exec",
-+ "write",
-+ "read",
-+ "append",
-+
-+ "create",
-+ "delete",
-+ "open",
-+ "rename",
-+
-+ "setattr",
-+ "getattr",
-+ "setcred",
-+ "getcred",
-+
-+ "chmod",
-+ "chown",
-+ "chgrp",
-+ "lock",
-+
-+ "mmap",
-+ "mprot",
-+ "link",
-+ "snapshot",
-+
-+ "unknown",
-+ "unknown",
-+ "unknown",
-+ "unknown",
-+
-+ "unknown",
-+ "unknown",
-+ "unknown",
-+ "unknown",
-+
-+ "stack",
-+ "change_onexec",
-+ "change_profile",
-+ "change_hat",
-+};
-+
-+/**
-+ * aa_perm_mask_to_str - convert a perm mask to its short string
-+ * @str: character buffer to store string in (at least 10 characters)
-+ * @mask: permission mask to convert
-+ */
-+void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
-+{
-+ unsigned int i, perm = 1;
-+
-+ for (i = 0; i < 32; perm <<= 1, i++) {
-+ if (mask & perm)
-+ *str++ = chrs[i];
-+ }
-+ *str = '\0';
-+}
-+
- /**
- * aa_policy_init - initialize a policy structure
- * @policy: policy to initialize (NOT NULL)
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 8f3c0f7aca5a..a128f1772135 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -278,7 +278,7 @@ static int apparmor_path_mknod(const struct path *dir, struct dentry *dentry,
-
- static int apparmor_path_truncate(const struct path *path)
- {
-- return common_perm_cond(OP_TRUNC, path, MAY_WRITE | AA_MAY_META_WRITE);
-+ return common_perm_cond(OP_TRUNC, path, MAY_WRITE | AA_MAY_SETATTR);
- }
-
- static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry,
-@@ -323,12 +323,12 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d
- };
-
- error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0,
-- MAY_READ | AA_MAY_META_READ | MAY_WRITE |
-- AA_MAY_META_WRITE | AA_MAY_DELETE,
-+ MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
-+ AA_MAY_SETATTR | AA_MAY_DELETE,
- &cond);
- if (!error)
- error = aa_path_perm(OP_RENAME_DEST, profile, &new_path,
-- 0, MAY_WRITE | AA_MAY_META_WRITE |
-+ 0, MAY_WRITE | AA_MAY_SETATTR |
- AA_MAY_CREATE, &cond);
-
- }
-@@ -347,7 +347,7 @@ static int apparmor_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
-
- static int apparmor_inode_getattr(const struct path *path)
- {
-- return common_perm_cond(OP_GETATTR, path, AA_MAY_META_READ);
-+ return common_perm_cond(OP_GETATTR, path, AA_MAY_GETATTR);
- }
-
- static int apparmor_file_open(struct file *file, const struct cred *cred)
---
-2.12.3
-
diff --git a/patches.apparmor/0020-apparmor-provide-finer-control-over-policy-managemen.patch b/patches.apparmor/0020-apparmor-provide-finer-control-over-policy-managemen.patch
deleted file mode 100644
index 71c8373494..0000000000
--- a/patches.apparmor/0020-apparmor-provide-finer-control-over-policy-managemen.patch
+++ /dev/null
@@ -1,199 +0,0 @@
-From 9926b19ca1fc029c30503cdf0c6afc7da4215534 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 01:45:08 -0700
-Subject: [PATCH 20/65] apparmor: provide finer control over policy management
-Git-commit: 18e99f191a8e66ec8fd06e4820de44bd9faa296a
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 15 +++++++--------
- security/apparmor/include/policy.h | 8 ++++++--
- security/apparmor/policy.c | 35 ++++++++++++++++++++++-------------
- 3 files changed, 35 insertions(+), 23 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index c847f601371d..570d6b58b159 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -400,17 +400,16 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
- return data;
- }
-
--static ssize_t policy_update(int binop, const char __user *buf, size_t size,
-+static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
- loff_t *pos, struct aa_ns *ns)
- {
- ssize_t error;
- struct aa_loaddata *data;
- struct aa_profile *profile = aa_current_profile();
-- const char *op = binop == PROF_ADD ? OP_PROF_LOAD : OP_PROF_REPL;
- /* high level check about policy management - fine grained in
- * below after unpack
- */
-- error = aa_may_manage_policy(profile, ns, op);
-+ error = aa_may_manage_policy(profile, ns, mask);
- if (error)
- return error;
-
-@@ -418,7 +417,7 @@ static ssize_t policy_update(int binop, const char __user *buf, size_t size,
- error = PTR_ERR(data);
- if (!IS_ERR(data)) {
- error = aa_replace_profiles(ns ? ns : profile->ns, profile,
-- binop, data);
-+ mask, data);
- aa_put_loaddata(data);
- }
-
-@@ -430,7 +429,7 @@ static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
- loff_t *pos)
- {
- struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
-- int error = policy_update(PROF_ADD, buf, size, pos, ns);
-+ int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
-
- aa_put_ns(ns);
-
-@@ -447,8 +446,8 @@ static ssize_t profile_replace(struct file *f, const char __user *buf,
- size_t size, loff_t *pos)
- {
- struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
-- int error = policy_update(PROF_REPLACE, buf, size, pos, ns);
--
-+ int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
-+ buf, size, pos, ns);
- aa_put_ns(ns);
-
- return error;
-@@ -472,7 +471,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
- /* high level check about policy management - fine grained in
- * below after unpack
- */
-- error = aa_may_manage_policy(profile, ns, OP_PROF_RM);
-+ error = aa_may_manage_policy(profile, ns, AA_MAY_REMOVE_POLICY);
- if (error)
- goto out;
-
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
-index 0f87f70287ad..97bfbddef7b2 100644
---- a/security/apparmor/include/policy.h
-+++ b/security/apparmor/include/policy.h
-@@ -188,6 +188,10 @@ struct aa_profile {
-
- extern enum profile_mode aa_g_profile_mode;
-
-+#define AA_MAY_LOAD_POLICY AA_MAY_APPEND
-+#define AA_MAY_REPLACE_POLICY AA_MAY_WRITE
-+#define AA_MAY_REMOVE_POLICY AA_MAY_DELETE
-+
- void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new);
-
- void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
-@@ -208,7 +212,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
- struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
-
- ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
-- bool noreplace, struct aa_loaddata *udata);
-+ u32 mask, struct aa_loaddata *udata);
- ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile,
- char *name, size_t size);
- void __aa_profile_list_release(struct list_head *head);
-@@ -323,6 +327,6 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
- bool policy_view_capable(struct aa_ns *ns);
- bool policy_admin_capable(struct aa_ns *ns);
- int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
-- const char *op);
-+ u32 mask);
-
- #endif /* __AA_POLICY_H */
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index a5e8559e4dec..65e98d0491f4 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -690,17 +690,25 @@ bool policy_admin_capable(struct aa_ns *ns)
- *
- * Returns: 0 if the task is allowed to manipulate policy else error
- */
--int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
-- const char *op)
-+int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, u32 mask)
- {
-+ const char *op;
-+
-+ if (mask & AA_MAY_REMOVE_POLICY)
-+ op = OP_PROF_RM;
-+ else if (mask & AA_MAY_REPLACE_POLICY)
-+ op = OP_PROF_REPL;
-+ else
-+ op = OP_PROF_LOAD;
-+
- /* check if loading policy is locked out */
- if (aa_g_lock_policy)
-- return audit_policy(profile, op, NULL, NULL,
-- "policy_locked", -EACCES);
-+ return audit_policy(profile, op, NULL, NULL, "policy_locked",
-+ -EACCES);
-
- if (!policy_admin_capable(ns))
-- return audit_policy(profile, op, NULL, NULL,
-- "not policy admin", -EACCES);
-+ return audit_policy(profile, op, NULL, NULL, "not policy admin",
-+ -EACCES);
-
- /* TODO: add fine grained mediation of policy loads */
- return 0;
-@@ -825,7 +833,7 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
- * aa_replace_profiles - replace profile(s) on the profile list
- * @view: namespace load is viewed from
- * @label: label that is attempting to load/replace policy
-- * @noreplace: true if only doing addition, no replacement allowed
-+ * @mask: permission mask
- * @udata: serialized data stream (NOT NULL)
- *
- * unpack and replace a profile on the profile list and uses of that profile
-@@ -835,17 +843,17 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
- * Returns: size of data consumed else error code on failure.
- */
- ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
-- bool noreplace, struct aa_loaddata *udata)
-+ u32 mask, struct aa_loaddata *udata)
- {
- const char *ns_name, *info = NULL;
- struct aa_ns *ns = NULL;
- struct aa_load_ent *ent, *tmp;
- struct aa_loaddata *rawdata_ent;
-- const char *op = OP_PROF_REPL;
-+ const char *op;
- ssize_t count, error;
--
- LIST_HEAD(lh);
-
-+ op = mask & AA_MAY_REPLACE_POLICY ? OP_PROF_REPL : OP_PROF_LOAD;
- aa_get_loaddata(udata);
- /* released below */
- error = aa_unpack(udata, &lh, &ns_name);
-@@ -909,15 +917,16 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- struct aa_policy *policy;
-
- ent->new->rawdata = aa_get_loaddata(udata);
-- error = __lookup_replace(ns, ent->new->base.hname, noreplace,
-+ error = __lookup_replace(ns, ent->new->base.hname,
-+ !(mask & AA_MAY_REPLACE_POLICY),
- &ent->old, &info);
- if (error)
- goto fail_lock;
-
- if (ent->new->rename) {
- error = __lookup_replace(ns, ent->new->rename,
-- noreplace, &ent->rename,
-- &info);
-+ !(mask & AA_MAY_REPLACE_POLICY),
-+ &ent->rename, &info);
- if (error)
- goto fail_lock;
- }
---
-2.12.3
-
diff --git a/patches.apparmor/0021-apparmor-add-policy-revision-file-interface.patch b/patches.apparmor/0021-apparmor-add-policy-revision-file-interface.patch
deleted file mode 100644
index e85b5c8f36..0000000000
--- a/patches.apparmor/0021-apparmor-add-policy-revision-file-interface.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From 449b4c3612d117118108bc87b3978a966b1cc985 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 16:27:58 -0700
-Subject: [PATCH 21/65] apparmor: add policy revision file interface
-Git-commit: d9bf2c268be6064ae0c9980e4c37fdd262c7effc
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Add a policy revision file to find the current revision of a ns's policy.
-There is a revision file per ns, as well as a virtualized global revision
-file in the base apparmor fs directory. The global revision file when
-opened will provide the revision of the opening task namespace.
-
-The revision file can be waited on via select/poll to detect apparmor
-policy changes from the last read revision of the opened file. This
-means that the revision file must be read after the select/poll other
-wise update data will remain ready for reading.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 113 ++++++++++++++++++++++++++++++++-
- security/apparmor/include/apparmorfs.h | 2 +
- security/apparmor/include/policy_ns.h | 1 +
- security/apparmor/policy_ns.c | 1 +
- 4 files changed, 116 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 570d6b58b159..8c413333726b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -23,6 +23,7 @@
- #include <linux/capability.h>
- #include <linux/rcupdate.h>
- #include <linux/fs.h>
-+#include <linux/poll.h>
- #include <uapi/linux/major.h>
- #include <uapi/linux/magic.h>
-
-@@ -31,6 +32,7 @@
- #include "include/audit.h"
- #include "include/context.h"
- #include "include/crypto.h"
-+#include "include/policy_ns.h"
- #include "include/policy.h"
- #include "include/policy_ns.h"
- #include "include/resource.h"
-@@ -498,11 +500,101 @@ static const struct file_operations aa_fs_profile_remove = {
- .llseek = default_llseek,
- };
-
-+struct aa_revision {
-+ struct aa_ns *ns;
-+ long last_read;
-+};
-+
-+/* revision file hook fn for policy loads */
-+static int ns_revision_release(struct inode *inode, struct file *file)
-+{
-+ struct aa_revision *rev = file->private_data;
-+
-+ if (rev) {
-+ aa_put_ns(rev->ns);
-+ kfree(rev);
-+ }
-+
-+ return 0;
-+}
-+
-+static ssize_t ns_revision_read(struct file *file, char __user *buf,
-+ size_t size, loff_t *ppos)
-+{
-+ struct aa_revision *rev = file->private_data;
-+ char buffer[32];
-+ long last_read;
-+ int avail;
-+
-+ mutex_lock(&rev->ns->lock);
-+ last_read = rev->last_read;
-+ if (last_read == rev->ns->revision) {
-+ mutex_unlock(&rev->ns->lock);
-+ if (file->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ if (wait_event_interruptible(rev->ns->wait,
-+ last_read !=
-+ READ_ONCE(rev->ns->revision)))
-+ return -ERESTARTSYS;
-+ mutex_lock(&rev->ns->lock);
-+ }
-+
-+ avail = sprintf(buffer, "%ld\n", rev->ns->revision);
-+ if (*ppos + size > avail) {
-+ rev->last_read = rev->ns->revision;
-+ *ppos = 0;
-+ }
-+ mutex_unlock(&rev->ns->lock);
-+
-+ return simple_read_from_buffer(buf, size, ppos, buffer, avail);
-+}
-+
-+static int ns_revision_open(struct inode *inode, struct file *file)
-+{
-+ struct aa_revision *rev = kzalloc(sizeof(*rev), GFP_KERNEL);
-+
-+ if (!rev)
-+ return -ENOMEM;
-+
-+ rev->ns = aa_get_ns(inode->i_private);
-+ if (!rev->ns)
-+ rev->ns = aa_get_current_ns();
-+ file->private_data = rev;
-+
-+ return 0;
-+}
-+
-+static unsigned int ns_revision_poll(struct file *file, poll_table *pt)
-+{
-+ struct aa_revision *rev = file->private_data;
-+ unsigned int mask = 0;
-+
-+ if (rev) {
-+ mutex_lock(&rev->ns->lock);
-+ poll_wait(file, &rev->ns->wait, pt);
-+ if (rev->last_read < rev->ns->revision)
-+ mask |= POLLIN | POLLRDNORM;
-+ mutex_unlock(&rev->ns->lock);
-+ }
-+
-+ return mask;
-+}
-+
- void __aa_bump_ns_revision(struct aa_ns *ns)
- {
- ns->revision++;
-+ wake_up_interruptible(&ns->wait);
- }
-
-+static const struct file_operations aa_fs_ns_revision_fops = {
-+ .owner = THIS_MODULE,
-+ .open = ns_revision_open,
-+ .poll = ns_revision_poll,
-+ .read = ns_revision_read,
-+ .llseek = generic_file_llseek,
-+ .release = ns_revision_release,
-+};
-+
- /**
- * query_data - queries a policy and writes its data to buf
- * @buf: the resulting data is stored here (NOT NULL)
-@@ -1280,6 +1372,10 @@ void __aafs_ns_rmdir(struct aa_ns *ns)
- sub = d_inode(ns_subremove(ns))->i_private;
- aa_put_ns(sub);
- }
-+ if (ns_subrevision(ns)) {
-+ sub = d_inode(ns_subrevision(ns))->i_private;
-+ aa_put_ns(sub);
-+ }
-
- for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
- aafs_remove(ns->dents[i]);
-@@ -1305,6 +1401,13 @@ static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
- return PTR_ERR(dent);
- ns_subdata_dir(ns) = dent;
-
-+ dent = aafs_create_file("revision", 0444, dir, ns,
-+ &aa_fs_ns_revision_fops);
-+ if (IS_ERR(dent))
-+ return PTR_ERR(dent);
-+ aa_get_ns(ns);
-+ ns_subrevision(ns) = dent;
-+
- dent = aafs_create_file(".load", 0640, dir, ns,
- &aa_fs_profile_load);
- if (IS_ERR(dent))
-@@ -1930,11 +2033,19 @@ static int __init aa_create_aafs(void)
- }
- ns_subremove(root_ns) = dent;
-
-+ dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
-+ NULL, &aa_fs_ns_revision_fops);
-+ if (IS_ERR(dent)) {
-+ error = PTR_ERR(dent);
-+ goto error;
-+ }
-+ ns_subrevision(root_ns) = dent;
-+
-+ /* policy tree referenced by magic policy symlink */
- mutex_lock(&root_ns->lock);
- error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
- aafs_mnt->mnt_root);
- mutex_unlock(&root_ns->lock);
--
- if (error)
- goto error;
-
-diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
-index 071a59a1f056..bd689114bf93 100644
---- a/security/apparmor/include/apparmorfs.h
-+++ b/security/apparmor/include/apparmorfs.h
-@@ -74,6 +74,7 @@ enum aafs_ns_type {
- AAFS_NS_LOAD,
- AAFS_NS_REPLACE,
- AAFS_NS_REMOVE,
-+ AAFS_NS_REVISION,
- AAFS_NS_COUNT,
- AAFS_NS_MAX_COUNT,
- AAFS_NS_SIZE,
-@@ -102,6 +103,7 @@ enum aafs_prof_type {
- #define ns_subload(X) ((X)->dents[AAFS_NS_LOAD])
- #define ns_subreplace(X) ((X)->dents[AAFS_NS_REPLACE])
- #define ns_subremove(X) ((X)->dents[AAFS_NS_REMOVE])
-+#define ns_subrevision(X) ((X)->dents[AAFS_NS_REVISION])
-
- #define prof_dir(X) ((X)->dents[AAFS_PROF_DIR])
- #define prof_child_dir(X) ((X)->dents[AAFS_PROF_PROFS])
-diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
-index d7a07ac96168..23e7cb770226 100644
---- a/security/apparmor/include/policy_ns.h
-+++ b/security/apparmor/include/policy_ns.h
-@@ -69,6 +69,7 @@ struct aa_ns {
- long uniq_id;
- int level;
- long revision;
-+ wait_queue_head_t wait;
-
- struct list_head rawdata_list;
-
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index 7d7c23705be2..f3418a9e59b1 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -101,6 +101,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
- INIT_LIST_HEAD(&ns->sub_ns);
- INIT_LIST_HEAD(&ns->rawdata_list);
- mutex_init(&ns->lock);
-+ init_waitqueue_head(&ns->wait);
-
- /* released by aa_free_ns() */
- ns->unconfined = aa_alloc_profile("unconfined", GFP_KERNEL);
---
-2.12.3
-
diff --git a/patches.apparmor/0022-apparmor-add-mkdir-rmdir-interface-to-manage-policy-.patch b/patches.apparmor/0022-apparmor-add-mkdir-rmdir-interface-to-manage-policy-.patch
deleted file mode 100644
index d3b7549692..0000000000
--- a/patches.apparmor/0022-apparmor-add-mkdir-rmdir-interface-to-manage-policy-.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From 45f06af64e6d81ed917df095f06baff6b4a80404 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 16:45:48 -0700
-Subject: [PATCH 22/65] apparmor: add mkdir/rmdir interface to manage policy
- namespaces
-Git-commit: 4ae47f33354a96efb4e4231dec0d72a586b3921c
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-When setting up namespaces for containers its easier for them to use
-an fs interface to create the namespace for the containers
-policy. Allow mkdir/rmdir under the policy/namespaces/ dir to be used
-to create and remove namespaces.
-
-BugLink: http://bugs.launchpad.net/bugs/1611078
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 95 +++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 94 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 8c413333726b..7f3049300ce3 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -1322,6 +1322,97 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
- return error;
- }
-
-+static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
-+{
-+ struct aa_ns *ns, *parent;
-+ /* TODO: improve permission check */
-+ struct aa_profile *profile = aa_current_profile();
-+ int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
-+
-+ if (error)
-+ return error;
-+
-+ parent = aa_get_ns(dir->i_private);
-+ AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
-+
-+ /* we have to unlock and then relock to get locking order right
-+ * for pin_fs
-+ */
-+ inode_unlock(dir);
-+ error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
-+ mutex_lock(&parent->lock);
-+ inode_lock_nested(dir, I_MUTEX_PARENT);
-+ if (error)
-+ goto out;
-+
-+ error = __aafs_setup_d_inode(dir, dentry, mode | S_IFDIR, NULL,
-+ NULL, NULL, NULL);
-+ if (error)
-+ goto out_pin;
-+
-+ ns = __aa_find_or_create_ns(parent, READ_ONCE(dentry->d_name.name),
-+ dentry);
-+ if (IS_ERR(ns)) {
-+ error = PTR_ERR(ns);
-+ ns = NULL;
-+ }
-+
-+ aa_put_ns(ns); /* list ref remains */
-+out_pin:
-+ if (error)
-+ simple_release_fs(&aafs_mnt, &aafs_count);
-+out:
-+ mutex_unlock(&parent->lock);
-+ aa_put_ns(parent);
-+
-+ return error;
-+}
-+
-+static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
-+{
-+ struct aa_ns *ns, *parent;
-+ /* TODO: improve permission check */
-+ struct aa_profile *profile = aa_current_profile();
-+ int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
-+
-+ if (error)
-+ return error;
-+
-+ parent = aa_get_ns(dir->i_private);
-+ /* rmdir calls the generic securityfs functions to remove files
-+ * from the apparmor dir. It is up to the apparmor ns locking
-+ * to avoid races.
-+ */
-+ inode_unlock(dir);
-+ inode_unlock(dentry->d_inode);
-+
-+ mutex_lock(&parent->lock);
-+ ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
-+ dentry->d_name.len));
-+ if (!ns) {
-+ error = -ENOENT;
-+ goto out;
-+ }
-+ AA_BUG(ns_dir(ns) != dentry);
-+
-+ __aa_remove_ns(ns);
-+ aa_put_ns(ns);
-+
-+out:
-+ mutex_unlock(&parent->lock);
-+ inode_lock_nested(dir, I_MUTEX_PARENT);
-+ inode_lock(dentry->d_inode);
-+ aa_put_ns(parent);
-+
-+ return error;
-+}
-+
-+static const struct inode_operations ns_dir_inode_operations = {
-+ .lookup = simple_lookup,
-+ .mkdir = ns_mkdir_op,
-+ .rmdir = ns_rmdir_op,
-+};
-+
- static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
- {
- struct aa_loaddata *ent, *tmp;
-@@ -1429,7 +1520,9 @@ static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
- aa_get_ns(ns);
- ns_subremove(ns) = dent;
-
-- dent = aafs_create_dir("namespaces", dir);
-+ /* use create_dentry so we can supply private data */
-+ dent = aafs_create("namespaces", S_IFDIR | 0755, dir, ns, NULL, NULL,
-+ &ns_dir_inode_operations);
- if (IS_ERR(dent))
- return PTR_ERR(dent);
- aa_get_ns(ns);
---
-2.12.3
-
diff --git a/patches.apparmor/0023-apparmor-add-label-data-availability-to-the-feature-.patch b/patches.apparmor/0023-apparmor-add-label-data-availability-to-the-feature-.patch
deleted file mode 100644
index b7e23c673e..0000000000
--- a/patches.apparmor/0023-apparmor-add-label-data-availability-to-the-feature-.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 64aa0a3ce8246414908ab89edf90a432fa4fae30 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 18:49:04 -0700
-Subject: [PATCH 23/65] apparmor: add label data availability to the feature
- set
-Git-commit: a83bd86e833a5842ad033527ea9af589efa6dc84
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-gsettings mediation needs to be able to determine if apparmor supports
-label data queries. A label data query can be done to test for support
-but its failure is indistinguishable from other failures, making it an
-unreliable indicator.
-
-Fix by making support of label data queries available as a flag in the
-apparmorfs features dir tree.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 7f3049300ce3..a447c00a452c 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -1849,6 +1849,15 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
- { }
- };
-
-+static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
-+ AA_SFS_FILE_BOOLEAN("data", 1),
-+ { }
-+};
-+
-+static struct aa_sfs_entry aa_sfs_entry_query[] = {
-+ AA_SFS_DIR("label", aa_sfs_entry_query_label),
-+ { }
-+};
- static struct aa_sfs_entry aa_sfs_entry_features[] = {
- AA_SFS_DIR("policy", aa_sfs_entry_policy),
- AA_SFS_DIR("domain", aa_sfs_entry_domain),
-@@ -1856,6 +1865,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
- AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
- AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
- AA_SFS_DIR("caps", aa_sfs_entry_caps),
-+ AA_SFS_DIR("query", aa_sfs_entry_query),
- { }
- };
-
---
-2.12.3
-
diff --git a/patches.apparmor/0024-apparmor-speed-up-transactional-queries.patch b/patches.apparmor/0024-apparmor-speed-up-transactional-queries.patch
deleted file mode 100644
index 97097118f6..0000000000
--- a/patches.apparmor/0024-apparmor-speed-up-transactional-queries.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From dd33af1c6dda5b2558918f5b6e638a5d58b85f06 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 17:23:23 -0700
-Subject: [PATCH 24/65] apparmor: speed up transactional queries
-Git-commit: 1dea3b41e84c5923173fe654dcb758a5cb4a46e5
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-The simple_transaction interface is slow. It requires 4 syscalls
-(open, write, read, close) per query and shares a single lock for each
-queries.
-
-So replace its use with a compatible in multi_transaction interface.
-It allows for a faster 2 syscall pattern per query. After an initial
-open, an arbitrary number of writes and reads can be issued. Each
-write will reset the query with new data that can be read. Reads do
-not clear the data, and can be issued multiple times, and used with
-seek, until a new write is performed which will reset the data
-available and the seek position.
-
-Note: this keeps the single lock design, if needed moving to a per
-file lock will have to come later.
-
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-Signed-off-by: John Johansen <john.johansen@canonical.com>
----
- security/apparmor/apparmorfs.c | 125 +++++++++++++++++++++++++++++++++++++----
- 1 file changed, 114 insertions(+), 11 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index a447c00a452c..e553de58f801 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -673,6 +673,106 @@ static ssize_t query_data(char *buf, size_t buf_len,
- return out - buf;
- }
-
-+/*
-+ * Transaction based IO.
-+ * The file expects a write which triggers the transaction, and then
-+ * possibly a read(s) which collects the result - which is stored in a
-+ * file-local buffer. Once a new write is performed, a new set of results
-+ * are stored in the file-local buffer.
-+ */
-+struct multi_transaction {
-+ struct kref count;
-+ ssize_t size;
-+ char data[0];
-+};
-+
-+#define MULTI_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct multi_transaction))
-+/* TODO: replace with per file lock */
-+static DEFINE_SPINLOCK(multi_transaction_lock);
-+
-+static void multi_transaction_kref(struct kref *kref)
-+{
-+ struct multi_transaction *t;
-+
-+ t = container_of(kref, struct multi_transaction, count);
-+ free_page((unsigned long) t);
-+}
-+
-+static struct multi_transaction *
-+get_multi_transaction(struct multi_transaction *t)
-+{
-+ if (t)
-+ kref_get(&(t->count));
-+
-+ return t;
-+}
-+
-+static void put_multi_transaction(struct multi_transaction *t)
-+{
-+ if (t)
-+ kref_put(&(t->count), multi_transaction_kref);
-+}
-+
-+/* does not increment @new's count */
-+static void multi_transaction_set(struct file *file,
-+ struct multi_transaction *new, size_t n)
-+{
-+ struct multi_transaction *old;
-+
-+ AA_BUG(n > MULTI_TRANSACTION_LIMIT);
-+
-+ new->size = n;
-+ spin_lock(&multi_transaction_lock);
-+ old = (struct multi_transaction *) file->private_data;
-+ file->private_data = new;
-+ spin_unlock(&multi_transaction_lock);
-+ put_multi_transaction(old);
-+}
-+
-+static struct multi_transaction *multi_transaction_new(struct file *file,
-+ const char __user *buf,
-+ size_t size)
-+{
-+ struct multi_transaction *t;
-+
-+ if (size > MULTI_TRANSACTION_LIMIT - 1)
-+ return ERR_PTR(-EFBIG);
-+
-+ t = (struct multi_transaction *)get_zeroed_page(GFP_KERNEL);
-+ if (!t)
-+ return ERR_PTR(-ENOMEM);
-+ kref_init(&t->count);
-+ if (copy_from_user(t->data, buf, size))
-+ return ERR_PTR(-EFAULT);
-+
-+ return t;
-+}
-+
-+static ssize_t multi_transaction_read(struct file *file, char __user *buf,
-+ size_t size, loff_t *pos)
-+{
-+ struct multi_transaction *t;
-+ ssize_t ret;
-+
-+ spin_lock(&multi_transaction_lock);
-+ t = get_multi_transaction(file->private_data);
-+ spin_unlock(&multi_transaction_lock);
-+ if (!t)
-+ return 0;
-+
-+ ret = simple_read_from_buffer(buf, size, pos, t->data, t->size);
-+ put_multi_transaction(t);
-+
-+ return ret;
-+}
-+
-+static int multi_transaction_release(struct inode *inode, struct file *file)
-+{
-+ put_multi_transaction(file->private_data);
-+
-+ return 0;
-+}
-+
- #define QUERY_CMD_DATA "data\0"
- #define QUERY_CMD_DATA_LEN 5
-
-@@ -700,36 +800,38 @@ static ssize_t query_data(char *buf, size_t buf_len,
- static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
- size_t count, loff_t *ppos)
- {
-- char *buf;
-+ struct multi_transaction *t;
- ssize_t len;
-
- if (*ppos)
- return -ESPIPE;
-
-- buf = simple_transaction_get(file, ubuf, count);
-- if (IS_ERR(buf))
-- return PTR_ERR(buf);
-+ t = multi_transaction_new(file, ubuf, count);
-+ if (IS_ERR(t))
-+ return PTR_ERR(t);
-
- if (count > QUERY_CMD_DATA_LEN &&
-- !memcmp(buf, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
-- len = query_data(buf, SIMPLE_TRANSACTION_LIMIT,
-- buf + QUERY_CMD_DATA_LEN,
-+ !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
-+ len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
-+ t->data + QUERY_CMD_DATA_LEN,
- count - QUERY_CMD_DATA_LEN);
- } else
- len = -EINVAL;
-
-- if (len < 0)
-+ if (len < 0) {
-+ put_multi_transaction(t);
- return len;
-+ }
-
-- simple_transaction_set(file, len);
-+ multi_transaction_set(file, t, len);
-
- return count;
- }
-
- static const struct file_operations aa_sfs_access = {
- .write = aa_write_access,
-- .read = simple_transaction_read,
-- .release = simple_transaction_release,
-+ .read = multi_transaction_read,
-+ .release = multi_transaction_release,
- .llseek = generic_file_llseek,
- };
-
-@@ -1851,6 +1953,7 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
-
- static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
- AA_SFS_FILE_BOOLEAN("data", 1),
-+ AA_SFS_FILE_BOOLEAN("multi_transaction", 1),
- { }
- };
-
---
-2.12.3
-
diff --git a/patches.apparmor/0025-apparmor-add-fn-to-test-if-profile-supports-a-given-.patch b/patches.apparmor/0025-apparmor-add-fn-to-test-if-profile-supports-a-given-.patch
deleted file mode 100644
index 08160316f3..0000000000
--- a/patches.apparmor/0025-apparmor-add-fn-to-test-if-profile-supports-a-given-.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 38f2676cda498dc477a558ff0163b90b0bb7a9fe Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 29 May 2017 11:45:29 -0700
-Subject: [PATCH 25/65] apparmor: add fn to test if profile supports a given
- mediation class
-Git-commit: b5b2557c0aeca35b34c558fd09ad6da67b9f3557
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/policy.h | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
-index 97bfbddef7b2..d93f475bfd8b 100644
---- a/security/apparmor/include/policy.h
-+++ b/security/apparmor/include/policy.h
-@@ -222,6 +222,16 @@ void __aa_profile_list_release(struct list_head *head);
-
- #define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
-
-+#define PROFILE_MEDIATES(P, T) ((P)->policy.start[(T)])
-+/* safe version of POLICY_MEDIATES for full range input */
-+static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
-+ unsigned char class)
-+{
-+ if (profile->policy.dfa)
-+ return aa_dfa_match_len(profile->policy.dfa,
-+ profile->policy.start[0], &class, 1);
-+ return 0;
-+}
-
- /**
- * aa_get_profile - increment refcount on profile @p
---
-2.12.3
-
diff --git a/patches.apparmor/0026-apparmor-add-gerneric-permissions-struct-and-support.patch b/patches.apparmor/0026-apparmor-add-gerneric-permissions-struct-and-support.patch
deleted file mode 100644
index b2ec9f458e..0000000000
--- a/patches.apparmor/0026-apparmor-add-gerneric-permissions-struct-and-support.patch
+++ /dev/null
@@ -1,281 +0,0 @@
-From 9377e727c8045a58dee38ff817029e2a3627363e Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 29 May 2017 12:16:04 -0700
-Subject: [PATCH 26/65] apparmor: add gerneric permissions struct and support
- fns
-Git-commit: aa9aeea8d4c3dfb9297723c4340671ef88e372d3
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/file.c | 30 +++++------
- security/apparmor/include/audit.h | 4 +-
- security/apparmor/include/perms.h | 34 +++++++++++++
- security/apparmor/lib.c | 102 ++++++++++++++++++++++++++++++++++++++
- 4 files changed, 153 insertions(+), 17 deletions(-)
-
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index 44549db904b3..1ee656f66aa4 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -56,15 +56,15 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
- struct common_audit_data *sa = va;
- kuid_t fsuid = current_fsuid();
-
-- if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) {
-+ if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " requested_mask=");
-- audit_file_mask(ab, aad(sa)->fs.request);
-+ audit_file_mask(ab, aad(sa)->request);
- }
-- if (aad(sa)->fs.denied & AA_AUDIT_FILE_MASK) {
-+ if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " denied_mask=");
-- audit_file_mask(ab, aad(sa)->fs.denied);
-+ audit_file_mask(ab, aad(sa)->denied);
- }
-- if (aad(sa)->fs.request & AA_AUDIT_FILE_MASK) {
-+ if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " fsuid=%d",
- from_kuid(&init_user_ns, fsuid));
- audit_log_format(ab, " ouid=%d",
-@@ -100,7 +100,7 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);
-
- sa.u.tsk = NULL;
-- aad(&sa)->fs.request = request;
-+ aad(&sa)->request = request;
- aad(&sa)->name = name;
- aad(&sa)->fs.target = target;
- aad(&sa)->fs.ouid = ouid;
-@@ -115,30 +115,30 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
- mask = 0xffff;
-
- /* mask off perms that are not being force audited */
-- aad(&sa)->fs.request &= mask;
-+ aad(&sa)->request &= mask;
-
-- if (likely(!aad(&sa)->fs.request))
-+ if (likely(!aad(&sa)->request))
- return 0;
- type = AUDIT_APPARMOR_AUDIT;
- } else {
- /* only report permissions that were denied */
-- aad(&sa)->fs.request = aad(&sa)->fs.request & ~perms->allow;
-- AA_BUG(!aad(&sa)->fs.request);
-+ aad(&sa)->request = aad(&sa)->request & ~perms->allow;
-+ AA_BUG(!aad(&sa)->request);
-
-- if (aad(&sa)->fs.request & perms->kill)
-+ if (aad(&sa)->request & perms->kill)
- type = AUDIT_APPARMOR_KILL;
-
- /* quiet known rejects, assumes quiet and kill do not overlap */
-- if ((aad(&sa)->fs.request & perms->quiet) &&
-+ if ((aad(&sa)->request & perms->quiet) &&
- AUDIT_MODE(profile) != AUDIT_NOQUIET &&
- AUDIT_MODE(profile) != AUDIT_ALL)
-- aad(&sa)->fs.request &= ~perms->quiet;
-+ aad(&sa)->request &= ~perms->quiet;
-
-- if (!aad(&sa)->fs.request)
-+ if (!aad(&sa)->request)
- return COMPLAIN_MODE(profile) ? 0 : aad(&sa)->error;
- }
-
-- aad(&sa)->fs.denied = aad(&sa)->fs.request & ~perms->allow;
-+ aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
- return aa_audit(type, profile, &sa, file_audit_cb);
- }
-
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index fdc4774318ba..1aeb8550fb82 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -107,14 +107,14 @@ struct apparmor_audit_data {
- void *profile;
- const char *name;
- const char *info;
-+ u32 request;
-+ u32 denied;
- union {
- /* these entries require a custom callback fn */
- struct {
- struct aa_profile *peer;
- struct {
- const char *target;
-- u32 request;
-- u32 denied;
- kuid_t ouid;
- } fs;
- };
-diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
-index 35e365e7aa75..6ef23212bd66 100644
---- a/security/apparmor/include/perms.h
-+++ b/security/apparmor/include/perms.h
-@@ -66,6 +66,40 @@
- extern const char aa_file_perm_chrs[];
- extern const char *aa_file_perm_names[];
-
-+struct aa_perms {
-+ u32 allow;
-+ u32 audit; /* set only when allow is set */
-+
-+ u32 deny; /* explicit deny, or conflict if allow also set */
-+ u32 quiet; /* set only when ~allow | deny */
-+ u32 kill; /* set only when ~allow | deny */
-+ u32 stop; /* set only when ~allow | deny */
-+
-+ u32 complain; /* accumulates only used when ~allow & ~deny */
-+ u32 cond; /* set only when ~allow and ~deny */
-+
-+ u32 hide; /* set only when ~allow | deny */
-+ u32 prompt; /* accumulates only used when ~allow & ~deny */
-+
-+ /* Reserved:
-+ * u32 subtree; / * set only when allow is set * /
-+ */
-+ u16 xindex;
-+};
-+
-+#define ALL_PERMS_MASK 0xffffffff
-+
-+extern struct aa_perms allperms;
-+
-+struct aa_profile;
-+
- void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask);
-+void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask);
-+void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
-+ u32 chrsmask, const char **names, u32 namesmask);
-+void aa_apply_modes_to_perms(struct aa_profile *profile,
-+ struct aa_perms *perms);
-+void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
-+ struct aa_perms *perms);
-
- #endif /* __AA_PERM_H */
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index 90d4631ddafe..a50913744823 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -24,6 +24,10 @@
- #include "include/perms.h"
- #include "include/policy.h"
-
-+struct aa_perms allperms = { .allow = ALL_PERMS_MASK,
-+ .quiet = ALL_PERMS_MASK,
-+ .hide = ALL_PERMS_MASK };
-+
- /**
- * aa_split_fqname - split a fqname into a profile and namespace name
- * @fqname: a full qualified name in namespace profile format (NOT NULL)
-@@ -188,6 +192,104 @@ void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask)
- *str = '\0';
- }
-
-+void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask)
-+{
-+ const char *fmt = "%s";
-+ unsigned int i, perm = 1;
-+ bool prev = false;
-+
-+ for (i = 0; i < 32; perm <<= 1, i++) {
-+ if (mask & perm) {
-+ audit_log_format(ab, fmt, names[i]);
-+ if (!prev) {
-+ prev = true;
-+ fmt = " %s";
-+ }
-+ }
-+ }
-+}
-+
-+void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
-+ u32 chrsmask, const char **names, u32 namesmask)
-+{
-+ char str[33];
-+
-+ audit_log_format(ab, "\"");
-+ if ((mask & chrsmask) && chrs) {
-+ aa_perm_mask_to_str(str, chrs, mask & chrsmask);
-+ mask &= ~chrsmask;
-+ audit_log_format(ab, "%s", str);
-+ if (mask & namesmask)
-+ audit_log_format(ab, " ");
-+ }
-+ if ((mask & namesmask) && names)
-+ aa_audit_perm_names(ab, names, mask & namesmask);
-+ audit_log_format(ab, "\"");
-+}
-+
-+/**
-+ * aa_apply_modes_to_perms - apply namespace and profile flags to perms
-+ * @profile: that perms where computed from
-+ * @perms: perms to apply mode modifiers to
-+ *
-+ * TODO: split into profile and ns based flags for when accumulating perms
-+ */
-+void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms)
-+{
-+ switch (AUDIT_MODE(profile)) {
-+ case AUDIT_ALL:
-+ perms->audit = ALL_PERMS_MASK;
-+ /* fall through */
-+ case AUDIT_NOQUIET:
-+ perms->quiet = 0;
-+ break;
-+ case AUDIT_QUIET:
-+ perms->audit = 0;
-+ /* fall through */
-+ case AUDIT_QUIET_DENIED:
-+ perms->quiet = ALL_PERMS_MASK;
-+ break;
-+ }
-+
-+ if (KILL_MODE(profile))
-+ perms->kill = ALL_PERMS_MASK;
-+ else if (COMPLAIN_MODE(profile))
-+ perms->complain = ALL_PERMS_MASK;
-+/*
-+ * TODO:
-+ * else if (PROMPT_MODE(profile))
-+ * perms->prompt = ALL_PERMS_MASK;
-+ */
-+}
-+
-+static u32 map_other(u32 x)
-+{
-+ return ((x & 0x3) << 8) | /* SETATTR/GETATTR */
-+ ((x & 0x1c) << 18) | /* ACCEPT/BIND/LISTEN */
-+ ((x & 0x60) << 19); /* SETOPT/GETOPT */
-+}
-+
-+void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
-+ struct aa_perms *perms)
-+{
-+ perms->deny = 0;
-+ perms->kill = perms->stop = 0;
-+ perms->complain = perms->cond = 0;
-+ perms->hide = 0;
-+ perms->prompt = 0;
-+ perms->allow = dfa_user_allow(dfa, state);
-+ perms->audit = dfa_user_audit(dfa, state);
-+ perms->quiet = dfa_user_quiet(dfa, state);
-+
-+ /* for v5 perm mapping in the policydb, the other set is used
-+ * to extend the general perm set
-+ */
-+ perms->allow |= map_other(dfa_other_allow(dfa, state));
-+ perms->audit |= map_other(dfa_other_audit(dfa, state));
-+ perms->quiet |= map_other(dfa_other_quiet(dfa, state));
-+// perms->xindex = dfa_user_xindex(dfa, state);
-+}
-+
- /**
- * aa_policy_init - initialize a policy structure
- * @policy: policy to initialize (NOT NULL)
---
-2.12.3
-
diff --git a/patches.apparmor/0027-apparmor-switch-from-file_perms-to-aa_perms.patch b/patches.apparmor/0027-apparmor-switch-from-file_perms-to-aa_perms.patch
deleted file mode 100644
index b6ec60467c..0000000000
--- a/patches.apparmor/0027-apparmor-switch-from-file_perms-to-aa_perms.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From 66f4781f467e03ad8c2896275ed747798f9ca02c Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Mon, 29 May 2017 12:19:39 -0700
-Subject: [PATCH 27/65] apparmor: switch from file_perms to aa_perms
-Git-commit: 2d679f3cb0eaa6afa0dc97fe6ad3b797e1c1899a
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 18 +++++++++---------
- security/apparmor/file.c | 31 ++++++++++++++-----------------
- security/apparmor/include/file.h | 25 ++++---------------------
- security/apparmor/include/perms.h | 2 +-
- security/apparmor/lib.c | 1 +
- 5 files changed, 29 insertions(+), 48 deletions(-)
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index ab8f23cdccff..a0ba33454b8c 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -93,12 +93,12 @@ static int may_change_ptraced_domain(struct aa_profile *to_profile)
- *
- * Returns: permission set
- */
--static struct file_perms change_profile_perms(struct aa_profile *profile,
-- struct aa_ns *ns,
-- const char *name, u32 request,
-- unsigned int start)
-+static struct aa_perms change_profile_perms(struct aa_profile *profile,
-+ struct aa_ns *ns,
-+ const char *name, u32 request,
-+ unsigned int start)
- {
-- struct file_perms perms;
-+ struct aa_perms perms;
- struct path_cond cond = { };
- unsigned int state;
-
-@@ -342,7 +342,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- struct aa_ns *ns;
- char *buffer = NULL;
- unsigned int state;
-- struct file_perms perms = {};
-+ struct aa_perms perms = {};
- struct path_cond cond = {
- file_inode(bprm->file)->i_uid,
- file_inode(bprm->file)->i_mode
-@@ -400,7 +400,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- /* find exec permissions for name */
- state = aa_str_perms(profile->file.dfa, state, name, &cond, &perms);
- if (ctx->onexec) {
-- struct file_perms cp;
-+ struct aa_perms cp;
- info = "change_profile onexec";
- new_profile = aa_get_newest_profile(ctx->onexec);
- if (!(perms.allow & AA_MAY_ONEXEC))
-@@ -609,7 +609,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- struct aa_profile *profile, *previous_profile, *hat = NULL;
- char *name = NULL;
- int i;
-- struct file_perms perms = {};
-+ struct aa_perms perms = {};
- const char *target = NULL, *info = NULL;
- int error = 0;
-
-@@ -748,7 +748,7 @@ int aa_change_profile(const char *fqname, bool onexec,
- {
- const struct cred *cred;
- struct aa_profile *profile, *target = NULL;
-- struct file_perms perms = {};
-+ struct aa_perms perms = {};
- const char *info = NULL, *op;
- int error = 0;
- u32 request;
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index 1ee656f66aa4..2e128c2aa4dc 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -19,8 +19,6 @@
- #include "include/path.h"
- #include "include/policy.h"
-
--struct file_perms nullperms;
--
- static u32 map_mask_to_chr_mask(u32 mask)
- {
- u32 m = mask & PERMS_CHRS_MASK;
-@@ -92,7 +90,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
- *
- * Returns: %0 or error on failure
- */
--int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
-+int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
- const char *op, u32 request, const char *name,
- const char *target, kuid_t ouid, const char *info, int error)
- {
-@@ -170,7 +168,7 @@ static u32 map_old_perms(u32 old)
- }
-
- /**
-- * compute_perms - convert dfa compressed perms to internal perms
-+ * aa_compute_fperms - convert dfa compressed perms to internal perms
- * @dfa: dfa to compute perms for (NOT NULL)
- * @state: state in dfa
- * @cond: conditions to consider (NOT NULL)
-@@ -180,17 +178,21 @@ static u32 map_old_perms(u32 old)
- *
- * Returns: computed permission set
- */
--static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
-- struct path_cond *cond)
-+struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
-+ struct path_cond *cond)
- {
-- struct file_perms perms;
-+ struct aa_perms perms;
-
- /* FIXME: change over to new dfa format
- * currently file perms are encoded in the dfa, new format
- * splits the permissions from the dfa. This mapping can be
- * done at profile load
- */
-- perms.kill = 0;
-+ perms.deny = 0;
-+ perms.kill = perms.stop = 0;
-+ perms.complain = perms.cond = 0;
-+ perms.hide = 0;
-+ perms.prompt = 0;
-
- if (uid_eq(current_fsuid(), cond->uid)) {
- perms.allow = map_old_perms(dfa_user_allow(dfa, state));
-@@ -226,16 +228,11 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
- */
- unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
- const char *name, struct path_cond *cond,
-- struct file_perms *perms)
-+ struct aa_perms *perms)
- {
- unsigned int state;
-- if (!dfa) {
-- *perms = nullperms;
-- return DFA_NOMATCH;
-- }
--
- state = aa_dfa_match(dfa, start, name);
-- *perms = compute_perms(dfa, state, cond);
-+ *perms = aa_compute_fperms(dfa, state, cond);
-
- return state;
- }
-@@ -269,7 +266,7 @@ int aa_path_perm(const char *op, struct aa_profile *profile,
- struct path_cond *cond)
- {
- char *buffer = NULL;
-- struct file_perms perms = {};
-+ struct aa_perms perms = {};
- const char *name, *info = NULL;
- int error;
-
-@@ -348,7 +345,7 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
- };
- char *buffer = NULL, *buffer2 = NULL;
- const char *lname, *tname = NULL, *info = NULL;
-- struct file_perms lperms, perms;
-+ struct aa_perms lperms, perms;
- u32 request = AA_MAY_LINK;
- unsigned int state;
- int error;
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-index fb3642a94e3d..365ca7ead133 100644
---- a/security/apparmor/include/file.h
-+++ b/security/apparmor/include/file.h
-@@ -90,25 +90,6 @@ struct path_cond {
- umode_t mode;
- };
-
--/* struct file_perms - file permission
-- * @allow: 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 @allow contains MAY_EXEC
-- *
-- * The @audit and @queit mask should be mutually exclusive.
-- */
--struct file_perms {
-- u32 allow;
-- u32 audit;
-- u32 quiet;
-- u32 kill;
-- u16 xindex;
--};
--
--extern struct file_perms nullperms;
--
- #define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
-
- /* FIXME: split perms from dfa and match this to description
-@@ -159,7 +140,7 @@ static inline u16 dfa_map_xindex(u16 mask)
- #define dfa_other_xindex(dfa, state) \
- dfa_map_xindex((ACCEPT_TABLE(dfa)[state] >> 14) & 0x3fff)
-
--int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
-+int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
- const char *op, u32 request, const char *name,
- const char *target, kuid_t ouid, const char *info, int error);
-
-@@ -182,9 +163,11 @@ struct aa_file_rules {
- /* TODO: add delegate table */
- };
-
-+struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
-+ struct path_cond *cond);
- unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
- const char *name, struct path_cond *cond,
-- struct file_perms *perms);
-+ struct aa_perms *perms);
-
- int aa_path_perm(const char *op, struct aa_profile *profile,
- const struct path *path, int flags, u32 request,
-diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
-index 6ef23212bd66..82946fb81f91 100644
---- a/security/apparmor/include/perms.h
-+++ b/security/apparmor/include/perms.h
-@@ -88,7 +88,7 @@ struct aa_perms {
- };
-
- #define ALL_PERMS_MASK 0xffffffff
--
-+extern struct aa_perms nullperms;
- extern struct aa_perms allperms;
-
- struct aa_profile;
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index a50913744823..3e9146e68c4a 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -24,6 +24,7 @@
- #include "include/perms.h"
- #include "include/policy.h"
-
-+struct aa_perms nullperms;
- struct aa_perms allperms = { .allow = ALL_PERMS_MASK,
- .quiet = ALL_PERMS_MASK,
- .hide = ALL_PERMS_MASK };
---
-2.12.3
-
diff --git a/patches.apparmor/0028-apparmor-add-profile-permission-query-ability.patch b/patches.apparmor/0028-apparmor-add-profile-permission-query-ability.patch
deleted file mode 100644
index 551321653e..0000000000
--- a/patches.apparmor/0028-apparmor-add-profile-permission-query-ability.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From 4d5bf455c74738444b82831b32594d291f28733f Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 26 May 2017 18:35:29 -0700
-Subject: [PATCH 28/65] apparmor: add profile permission query ability
-Git-commit: 4f3b3f2d79a42e5094f55eca4f29d8f60f1190bd
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Allow userspace to query a profile about permissions, through the
-transaction interface that is already used to allow userspace to
-query about key,value data.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 103 ++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 102 insertions(+), 1 deletion(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index e553de58f801..105a1da57b8f 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -595,6 +595,40 @@ static const struct file_operations aa_fs_ns_revision_fops = {
- .release = ns_revision_release,
- };
-
-+static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
-+ const char *match_str, size_t match_len)
-+{
-+ struct aa_perms tmp;
-+ struct aa_dfa *dfa;
-+ unsigned int state = 0;
-+
-+ if (unconfined(profile))
-+ return;
-+ if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
-+ dfa = profile->file.dfa;
-+ state = aa_dfa_match_len(dfa, profile->file.start,
-+ match_str + 1, match_len - 1);
-+ tmp = nullperms;
-+ if (state) {
-+ struct path_cond cond = { };
-+
-+ tmp = aa_compute_fperms(dfa, state, &cond);
-+ }
-+ } else if (profile->policy.dfa) {
-+ if (!PROFILE_MEDIATES_SAFE(profile, *match_str))
-+ return; /* no change to current perms */
-+ dfa = profile->policy.dfa;
-+ state = aa_dfa_match_len(dfa, profile->policy.start[0],
-+ match_str, match_len);
-+ if (state)
-+ aa_compute_perms(dfa, state, &tmp);
-+ else
-+ tmp = nullperms;
-+ }
-+ aa_apply_modes_to_perms(profile, &tmp);
-+}
-+
-+
- /**
- * query_data - queries a policy and writes its data to buf
- * @buf: the resulting data is stored here (NOT NULL)
-@@ -673,6 +707,64 @@ static ssize_t query_data(char *buf, size_t buf_len,
- return out - buf;
- }
-
-+/**
-+ * query_label - queries a label and writes permissions to buf
-+ * @buf: the resulting permissions string is stored here (NOT NULL)
-+ * @buf_len: size of buf
-+ * @query: binary query string to match against the dfa
-+ * @query_len: size of query
-+ * @view_only: only compute for querier's view
-+ *
-+ * The buffers pointed to by buf and query may overlap. The query buffer is
-+ * parsed before buf is written to.
-+ *
-+ * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
-+ * the name of the label, in the current namespace, that is to be queried and
-+ * DFA_STRING is a binary string to match against the label(s)'s DFA.
-+ *
-+ * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
-+ * but must *not* be NUL terminated.
-+ *
-+ * Returns: number of characters written to buf or -errno on failure
-+ */
-+static ssize_t query_label(char *buf, size_t buf_len,
-+ char *query, size_t query_len, bool view_only)
-+{
-+ struct aa_profile *profile, *curr;
-+ char *label_name, *match_str;
-+ size_t label_name_len, match_len;
-+ struct aa_perms perms;
-+
-+ if (!query_len)
-+ return -EINVAL;
-+
-+ label_name = query;
-+ label_name_len = strnlen(query, query_len);
-+ if (!label_name_len || label_name_len == query_len)
-+ return -EINVAL;
-+
-+ /**
-+ * The extra byte is to account for the null byte between the
-+ * profile name and dfa string. profile_name_len is greater
-+ * than zero and less than query_len, so a byte can be safely
-+ * added or subtracted.
-+ */
-+ match_str = label_name + label_name_len + 1;
-+ match_len = query_len - label_name_len - 1;
-+
-+ curr = aa_current_profile();
-+ profile = aa_fqlookupn_profile(curr, label_name, label_name_len);
-+ if (!profile)
-+ return -ENOENT;
-+
-+ perms = allperms;
-+ profile_query_cb(profile, &perms, match_str, match_len);
-+
-+ return scnprintf(buf, buf_len,
-+ "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
-+ perms.allow, perms.deny, perms.audit, perms.quiet);
-+}
-+
- /*
- * Transaction based IO.
- * The file expects a write which triggers the transaction, and then
-@@ -773,6 +865,9 @@ static int multi_transaction_release(struct inode *inode, struct file *file)
- return 0;
- }
-
-+#define QUERY_CMD_PROFILE "profile\0"
-+#define QUERY_CMD_PROFILE_LEN 8
-+
- #define QUERY_CMD_DATA "data\0"
- #define QUERY_CMD_DATA_LEN 5
-
-@@ -810,7 +905,12 @@ static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
- if (IS_ERR(t))
- return PTR_ERR(t);
-
-- if (count > QUERY_CMD_DATA_LEN &&
-+ if (count > QUERY_CMD_PROFILE_LEN &&
-+ !memcmp(t->data, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
-+ len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
-+ t->data + QUERY_CMD_PROFILE_LEN,
-+ count - QUERY_CMD_PROFILE_LEN, true);
-+ } else if (count > QUERY_CMD_DATA_LEN &&
- !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
- len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
- t->data + QUERY_CMD_DATA_LEN,
-@@ -1952,6 +2052,7 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = {
- };
-
- static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
-+ AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
- AA_SFS_FILE_BOOLEAN("data", 1),
- AA_SFS_FILE_BOOLEAN("multi_transaction", 1),
- { }
---
-2.12.3
-
diff --git a/patches.apparmor/0029-apparmor-provide-information-about-path-buffer-size-.patch b/patches.apparmor/0029-apparmor-provide-information-about-path-buffer-size-.patch
deleted file mode 100644
index b4a3f3a1a9..0000000000
--- a/patches.apparmor/0029-apparmor-provide-information-about-path-buffer-size-.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From c4838ffabb2d671934b99ace0f09539c292fc57c Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Thu, 30 Mar 2017 05:25:23 -0700
-Subject: [PATCH 29/65] apparmor: provide information about path buffer size at
- boot
-Git-commit: 39d84824eae3b1348408237173c710473e726ca9
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/lsm.c | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index a128f1772135..8ab00c98613f 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -774,11 +774,18 @@ static int param_get_aabool(char *buffer, const struct kernel_param *kp)
-
- static int param_set_aauint(const char *val, const struct kernel_param *kp)
- {
-+ int error;
-+
- if (!apparmor_enabled)
- return -EINVAL;
-- if (apparmor_initialized && !policy_admin_capable(NULL))
-+ /* file is ro but enforce 2nd line check */
-+ if (apparmor_initialized)
- return -EPERM;
-- return param_set_uint(val, kp);
-+
-+ error = param_set_uint(val, kp);
-+ pr_info("AppArmor: buffer size set to %d bytes\n", aa_g_path_max);
-+
-+ return error;
- }
-
- static int param_get_aauint(char *buffer, const struct kernel_param *kp)
---
-2.12.3
-
diff --git a/patches.apparmor/0030-apparmor-cleanup-__find_child.patch b/patches.apparmor/0030-apparmor-cleanup-__find_child.patch
deleted file mode 100644
index 37cce74e87..0000000000
--- a/patches.apparmor/0030-apparmor-cleanup-__find_child.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 00787f48b355f8942498c58edd474820723a4abc Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 2 Jun 2017 13:50:22 -0700
-Subject: [PATCH 30/65] apparmor: cleanup __find_child(
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-Git-commit: ae3b31653691b9c5b572b99596de3dfcc8f05006
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 65e98d0491f4..0a99e5324da0 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -397,33 +397,33 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- /* TODO: profile accounting - setup in remove */
-
- /**
-- * __find_child - find a profile on @head list with a name matching @name
-+ * __strn_find_child - find a profile on @head list using substring of @name
- * @head: list to search (NOT NULL)
- * @name: name of profile (NOT NULL)
-+ * @len: length of @name substring to match
- *
- * Requires: rcu_read_lock be held
- *
- * Returns: unrefcounted profile ptr, or NULL if not found
- */
--static struct aa_profile *__find_child(struct list_head *head, const char *name)
-+static struct aa_profile *__strn_find_child(struct list_head *head,
-+ const char *name, int len)
- {
-- return (struct aa_profile *)__policy_find(head, name);
-+ return (struct aa_profile *)__policy_strn_find(head, name, len);
- }
-
- /**
-- * __strn_find_child - find a profile on @head list using substring of @name
-+ * __find_child - find a profile on @head list with a name matching @name
- * @head: list to search (NOT NULL)
- * @name: name of profile (NOT NULL)
-- * @len: length of @name substring to match
- *
- * Requires: rcu_read_lock be held
- *
- * Returns: unrefcounted profile ptr, or NULL if not found
- */
--static struct aa_profile *__strn_find_child(struct list_head *head,
-- const char *name, int len)
-+static struct aa_profile *__find_child(struct list_head *head, const char *name)
- {
-- return (struct aa_profile *)__policy_strn_find(head, name, len);
-+ return __strn_find_child(head, name, strlen(name));
- }
-
- /**
---
-2.12.3
-
diff --git a/patches.apparmor/0031-apparmor-add-namespace-lookup-fns.patch b/patches.apparmor/0031-apparmor-add-namespace-lookup-fns.patch
deleted file mode 100644
index 350954467d..0000000000
--- a/patches.apparmor/0031-apparmor-add-namespace-lookup-fns.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From fbfdb53589eed33b3b4b61216de21bfdc1f1c5d6 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 2 Jun 2017 17:44:27 -0700
-Subject: [PATCH 31/65] apparmor: add namespace lookup fns()
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-Git-commit: 3664268f19ea07bec55df92fe53ff9ed28968bcc
-
-Currently lookups are restricted to a single ns component in the
-path. However when namespaces are allowed to have separate views, and
-scopes this will not be sufficient, as it will be possible to have
-a multiple component ns path in scope.
-
-Add some ns lookup fns() to allow this and use them.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/policy_ns.h | 13 +++++++++
- security/apparmor/policy.c | 10 ++++---
- security/apparmor/policy_ns.c | 54 +++++++++++++++++++++++++++++++++++
- 3 files changed, 73 insertions(+), 4 deletions(-)
-
-diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
-index 23e7cb770226..2f7e480a34e0 100644
---- a/security/apparmor/include/policy_ns.h
-+++ b/security/apparmor/include/policy_ns.h
-@@ -89,6 +89,8 @@ void aa_free_ns_kref(struct kref *kref);
-
- struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name);
- struct aa_ns *aa_findn_ns(struct aa_ns *root, const char *name, size_t n);
-+struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n);
-+struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n);
- struct aa_ns *__aa_find_or_create_ns(struct aa_ns *parent, const char *name,
- struct dentry *dir);
- struct aa_ns *aa_prepare_ns(struct aa_ns *root, const char *name);
-@@ -148,4 +150,15 @@ static inline struct aa_ns *__aa_find_ns(struct list_head *head,
- return __aa_findn_ns(head, name, strlen(name));
- }
-
-+static inline struct aa_ns *__aa_lookup_ns(struct aa_ns *base,
-+ const char *hname)
-+{
-+ return __aa_lookupn_ns(base, hname, strlen(hname));
-+}
-+
-+static inline struct aa_ns *aa_lookup_ns(struct aa_ns *view, const char *name)
-+{
-+ return aa_lookupn_ns(view, name, strlen(name));
-+}
-+
- #endif /* AA_NAMESPACE_H */
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 0a99e5324da0..d95aae6bf710 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -566,7 +566,7 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
-
- name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
- if (ns_name) {
-- ns = aa_findn_ns(base->ns, ns_name, ns_len);
-+ ns = aa_lookupn_ns(base->ns, ns_name, ns_len);
- if (!ns)
- return NULL;
- } else
-@@ -1108,7 +1108,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
- struct aa_ns *root = NULL, *ns = NULL;
- struct aa_profile *profile = NULL;
- const char *name = fqname, *info = NULL;
-- char *ns_name = NULL;
-+ const char *ns_name = NULL;
- ssize_t error = 0;
-
- if (*fqname == 0) {
-@@ -1120,9 +1120,11 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
- root = view;
-
- if (fqname[0] == ':') {
-- name = aa_split_fqname(fqname, &ns_name);
-+ size_t ns_len;
-+
-+ name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
- /* released below */
-- ns = aa_find_ns(root, ns_name);
-+ ns = aa_lookupn_ns(root, ns_name, ns_len);
- if (!ns) {
- info = "namespace does not exist";
- error = -ENOENT;
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index f3418a9e59b1..c05316809a5e 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -183,6 +183,60 @@ struct aa_ns *aa_find_ns(struct aa_ns *root, const char *name)
- return aa_findn_ns(root, name, strlen(name));
- }
-
-+/**
-+ * __aa_lookupn_ns - lookup the namespace matching @hname
-+ * @base: base list to start looking up profile name from (NOT NULL)
-+ * @hname: hierarchical ns name (NOT NULL)
-+ * @n: length of @hname
-+ *
-+ * Requires: rcu_read_lock be held
-+ *
-+ * Returns: unrefcounted ns pointer or NULL if not found
-+ *
-+ * Do a relative name lookup, recursing through profile tree.
-+ */
-+struct aa_ns *__aa_lookupn_ns(struct aa_ns *view, const char *hname, size_t n)
-+{
-+ struct aa_ns *ns = view;
-+ const char *split;
-+
-+ for (split = strnstr(hname, "//", n); split;
-+ split = strnstr(hname, "//", n)) {
-+ ns = __aa_findn_ns(&ns->sub_ns, hname, split - hname);
-+ if (!ns)
-+ return NULL;
-+
-+ n -= split + 2 - hname;
-+ hname = split + 2;
-+ }
-+
-+ if (n)
-+ return __aa_findn_ns(&ns->sub_ns, hname, n);
-+ return NULL;
-+}
-+
-+/**
-+ * aa_lookupn_ns - look up a policy namespace relative to @view
-+ * @view: namespace to search in (NOT NULL)
-+ * @name: name of namespace to find (NOT NULL)
-+ * @n: length of @name
-+ *
-+ * Returns: a refcounted namespace on the list, or NULL if no namespace
-+ * called @name exists.
-+ *
-+ * refcount released by caller
-+ */
-+struct aa_ns *aa_lookupn_ns(struct aa_ns *view, const char *name, size_t n)
-+{
-+ struct aa_ns *ns = NULL;
-+
-+ rcu_read_lock();
-+ ns = aa_get_ns(__aa_lookupn_ns(view, name, n));
-+ rcu_read_unlock();
-+
-+ return ns;
-+}
-+
- static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
- struct dentry *dir)
- {
---
-2.12.3
-
diff --git a/patches.apparmor/0032-apparmor-fix-policy-load-remove-semantics.patch b/patches.apparmor/0032-apparmor-fix-policy-load-remove-semantics.patch
deleted file mode 100644
index 97fcb83e2e..0000000000
--- a/patches.apparmor/0032-apparmor-fix-policy-load-remove-semantics.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 2d3f8f332ad3a4b2b7a8b468de082ebae4280d45 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Sun, 4 Jun 2017 12:22:22 -0700
-Subject: [PATCH 32/65] apparmor: fix policy load/remove semantics
-Git-commit: 60285eb3e7c8827e00e2f2b54561a8cca07d802f
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-The namespace being passed into the replace/remove profiles fns() is
-not the view, but the namespace specified by the inode from the
-file hook (if present) or the loading tasks ns, if accessing the
-top level virtualized load/replace file interface.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 6 ++----
- security/apparmor/policy.c | 22 +++++++++++-----------
- 2 files changed, 13 insertions(+), 15 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 105a1da57b8f..4f4cd98d2b3b 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -418,8 +418,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
- data = aa_simple_write_to_buffer(buf, size, size, pos);
- error = PTR_ERR(data);
- if (!IS_ERR(data)) {
-- error = aa_replace_profiles(ns ? ns : profile->ns, profile,
-- mask, data);
-+ error = aa_replace_profiles(ns, profile, mask, data);
- aa_put_loaddata(data);
- }
-
-@@ -486,8 +485,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
- error = PTR_ERR(data);
- if (!IS_ERR(data)) {
- data->data[size] = 0;
-- error = aa_remove_profiles(ns ? ns : profile->ns, profile,
-- data->data, size);
-+ error = aa_remove_profiles(ns, profile, data->data, size);
- aa_put_loaddata(data);
- }
- out:
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index d95aae6bf710..29e04638790f 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -831,7 +831,7 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
-
- /**
- * aa_replace_profiles - replace profile(s) on the profile list
-- * @view: namespace load is viewed from
-+ * @policy_ns: namespace load is occurring on
- * @label: label that is attempting to load/replace policy
- * @mask: permission mask
- * @udata: serialized data stream (NOT NULL)
-@@ -842,7 +842,7 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
- *
- * Returns: size of data consumed else error code on failure.
- */
--ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
-+ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- u32 mask, struct aa_loaddata *udata)
- {
- const char *ns_name, *info = NULL;
-@@ -885,7 +885,8 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- count++;
- }
- if (ns_name) {
-- ns = aa_prepare_ns(view, ns_name);
-+ ns = aa_prepare_ns(policy_ns ? policy_ns : profile->ns,
-+ ns_name);
- if (IS_ERR(ns)) {
- op = OP_PROF_LOAD;
- info = "failed to prepare namespace";
-@@ -895,7 +896,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- goto fail;
- }
- } else
-- ns = aa_get_ns(view);
-+ ns = aa_get_ns(policy_ns ? policy_ns : profile->ns);
-
- mutex_lock(&ns->lock);
- /* check for duplicate rawdata blobs: space and file dedup */
-@@ -1090,7 +1091,7 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
-
- /**
- * aa_remove_profiles - remove profile(s) from the system
-- * @view: namespace the remove is being done from
-+ * @policy_ns: namespace the remove is being done from
- * @subj: profile attempting to remove policy
- * @fqname: name of the profile or namespace to remove (NOT NULL)
- * @size: size of the name
-@@ -1102,10 +1103,10 @@ ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
- *
- * Returns: size of data consume else error code if fails
- */
--ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
-+ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_profile *subj,
- char *fqname, size_t size)
- {
-- struct aa_ns *root = NULL, *ns = NULL;
-+ struct aa_ns *ns = NULL;
- struct aa_profile *profile = NULL;
- const char *name = fqname, *info = NULL;
- const char *ns_name = NULL;
-@@ -1117,14 +1118,13 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
- goto fail;
- }
-
-- root = view;
--
- if (fqname[0] == ':') {
- size_t ns_len;
-
- name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
- /* released below */
-- ns = aa_lookupn_ns(root, ns_name, ns_len);
-+ ns = aa_lookupn_ns(policy_ns ? policy_ns : subj->ns, ns_name,
-+ ns_len);
- if (!ns) {
- info = "namespace does not exist";
- error = -ENOENT;
-@@ -1132,7 +1132,7 @@ ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *subj,
- }
- } else
- /* released below */
-- ns = aa_get_ns(root);
-+ ns = aa_get_ns(policy_ns ? policy_ns : subj->ns);
-
- if (!name) {
- /* remove namespace - can only happen if fqname[0] == ':' */
---
-2.12.3
-
diff --git a/patches.apparmor/0033-apparmor-fix-apparmor_query-data.patch b/patches.apparmor/0033-apparmor-fix-apparmor_query-data.patch
deleted file mode 100644
index eec3c302dd..0000000000
--- a/patches.apparmor/0033-apparmor-fix-apparmor_query-data.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 3d7a7d44e402393f4e234c232809514520757a0a Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 02:28:19 -0700
-Subject: [PATCH 33/65] apparmor: fix apparmor_query data
-Git-commit: 5262ef60b1bcc40e17476fda53284621af9b0bab
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-The data being queried isn't always the current profile and a lookup
-relative to the current profile should be done.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 4f4cd98d2b3b..818b70130bae 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -650,7 +650,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
- {
- char *out;
- const char *key;
-- struct aa_profile *profile;
-+ struct aa_profile *profile, *curr;
- struct aa_data *data;
- u32 bytes, blocks;
- __le32 outle32;
-@@ -667,7 +667,10 @@ static ssize_t query_data(char *buf, size_t buf_len,
- if (buf_len < sizeof(bytes) + sizeof(blocks))
- return -EINVAL; /* not enough space */
-
-- profile = aa_current_profile();
-+ curr = aa_current_profile();
-+ profile = aa_fqlookupn_profile(curr, query, strnlen(query, query_len));
-+ if (!profile)
-+ return -ENOENT;
-
- /* We are going to leave space for two numbers. The first is the total
- * number of bytes we are writing after the first number. This is so
-@@ -696,6 +699,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
- blocks++;
- }
- }
-+ aa_put_profile(profile);
-
- outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
- memcpy(buf, &outle32, sizeof(outle32));
---
-2.12.3
-
diff --git a/patches.apparmor/0034-apparmor-fix-display-of-ns-name.patch b/patches.apparmor/0034-apparmor-fix-display-of-ns-name.patch
deleted file mode 100644
index d8131ea726..0000000000
--- a/patches.apparmor/0034-apparmor-fix-display-of-ns-name.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6cd1d682d6e073a5e78fb006a9187febee802738 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 02:11:29 -0700
-Subject: [PATCH 34/65] apparmor: fix display of ns name
-Git-commit: d9f02d9c237aa603d781fe5165ebe383c554376d
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-The ns name being displayed should go through an ns view lookup.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 818b70130bae..b64ea21a42ad 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -1105,7 +1105,7 @@ static int seq_ns_name_show(struct seq_file *seq, void *v)
- {
- struct aa_ns *ns = aa_current_profile()->ns;
-
-- seq_printf(seq, "%s\n", ns->base.name);
-+ seq_printf(seq, "%s\n", aa_ns_name(ns, ns, true));
-
- return 0;
- }
---
-2.12.3
-
diff --git a/patches.apparmor/0035-apparmor-move-bprm_committing_creds-committed_creds-.patch b/patches.apparmor/0035-apparmor-move-bprm_committing_creds-committed_creds-.patch
deleted file mode 100644
index 3a4d4ff16c..0000000000
--- a/patches.apparmor/0035-apparmor-move-bprm_committing_creds-committed_creds-.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From e4a0c89bd117c66393761e3b96a5d03d97f0d0b2 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 05:27:50 -0700
-Subject: [PATCH 35/65] apparmor: move bprm_committing_creds/committed_creds to
- lsm.c
-Git-commit: fe864821d504f33f22b3ce2d5599ae95598db721
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-There is no reason to have the small stubs that don't use domain
-private functions in domain.c, instead move them to lsm.c and make
-them static.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 30 ------------------------------
- security/apparmor/include/domain.h | 2 --
- security/apparmor/lsm.c | 30 ++++++++++++++++++++++++++++++
- 3 files changed, 30 insertions(+), 32 deletions(-)
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index a0ba33454b8c..2b1524c79fb8 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -539,36 +539,6 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)
- return 0;
- }
-
--/**
-- * apparmor_bprm_committing_creds - do task cleanup on committing new creds
-- * @bprm: binprm for the exec (NOT NULL)
-- */
--void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
--{
-- struct aa_profile *profile = __aa_current_profile();
-- struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
--
-- /* bail out if unconfined or not changing profile */
-- if ((new_ctx->profile == profile) ||
-- (unconfined(new_ctx->profile)))
-- return;
--
-- current->pdeath_signal = 0;
--
-- /* reset soft limits and set hard limits for the new profile */
-- __aa_transition_rlimits(profile, new_ctx->profile);
--}
--
--/**
-- * apparmor_bprm_commited_cred - do cleanup after new creds committed
-- * @bprm: binprm for the exec (NOT NULL)
-- */
--void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
--{
-- /* TODO: cleanup signals - ipc mediation */
-- return;
--}
--
- /*
- * Functions for self directed profile change
- */
-diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
-index 30544729878a..6587c4abb7e8 100644
---- a/security/apparmor/include/domain.h
-+++ b/security/apparmor/include/domain.h
-@@ -25,8 +25,6 @@ struct aa_domain {
-
- int apparmor_bprm_set_creds(struct linux_binprm *bprm);
- int apparmor_bprm_secureexec(struct linux_binprm *bprm);
--void 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 *hats[], int count, u64 token, bool permtest);
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 8ab00c98613f..35492008658f 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -575,6 +575,36 @@ static int apparmor_setprocattr(const char *name, void *value,
- goto out;
- }
-
-+/**
-+ * apparmor_bprm_committing_creds - do task cleanup on committing new creds
-+ * @bprm: binprm for the exec (NOT NULL)
-+ */
-+static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
-+{
-+ struct aa_profile *profile = __aa_current_profile();
-+ struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
-+
-+ /* bail out if unconfined or not changing profile */
-+ if ((new_ctx->profile == profile) ||
-+ (unconfined(new_ctx->profile)))
-+ return;
-+
-+ current->pdeath_signal = 0;
-+
-+ /* reset soft limits and set hard limits for the new profile */
-+ __aa_transition_rlimits(profile, new_ctx->profile);
-+}
-+
-+/**
-+ * apparmor_bprm_committed_cred - do cleanup after new creds committed
-+ * @bprm: binprm for the exec (NOT NULL)
-+ */
-+static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
-+{
-+ /* TODO: cleanup signals - ipc mediation */
-+ return;
-+}
-+
- static int apparmor_task_setrlimit(struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim)
- {
---
-2.12.3
-
diff --git a/patches.apparmor/0036-apparmor-convert-to-profile-block-critical-sections.patch b/patches.apparmor/0036-apparmor-convert-to-profile-block-critical-sections.patch
deleted file mode 100644
index 28d24335d8..0000000000
--- a/patches.apparmor/0036-apparmor-convert-to-profile-block-critical-sections.patch
+++ /dev/null
@@ -1,609 +0,0 @@
-From cdb759a09cb1ef90e882cbd93095c5d755de7f92 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 02:08:28 -0700
-Subject: [PATCH 36/65] apparmor: convert to profile block critical sections
-Git-commit: cf797c0e5e312520b0b9f0367039fc0279a07a76
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-There are still a few places where profile replacement fails to update
-and a stale profile is used for mediation. Fix this by moving to
-accessing the current label through a critical section that will
-always ensure mediation is using the current label regardless of
-whether the tasks cred has been updated or not.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 40 +++++++-----
- security/apparmor/context.c | 2 +-
- security/apparmor/domain.c | 5 +-
- security/apparmor/include/context.h | 123 +++++++++++++++++++++++++++++-------
- security/apparmor/lsm.c | 41 ++++++++----
- security/apparmor/policy_unpack.c | 2 +-
- security/apparmor/procattr.c | 3 +-
- security/apparmor/resource.c | 2 +-
- 8 files changed, 162 insertions(+), 56 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index b64ea21a42ad..e2919a0766b0 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -407,7 +407,10 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
- {
- ssize_t error;
- struct aa_loaddata *data;
-- struct aa_profile *profile = aa_current_profile();
-+ struct aa_profile *profile;
-+
-+ profile = begin_current_profile_crit_section();
-+
- /* high level check about policy management - fine grained in
- * below after unpack
- */
-@@ -421,6 +424,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
- error = aa_replace_profiles(ns, profile, mask, data);
- aa_put_loaddata(data);
- }
-+ end_current_profile_crit_section(profile);
-
- return error;
- }
-@@ -468,7 +472,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
- ssize_t error;
- struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
-
-- profile = aa_current_profile();
-+ profile = begin_current_profile_crit_section();
- /* high level check about policy management - fine grained in
- * below after unpack
- */
-@@ -489,6 +493,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
- aa_put_loaddata(data);
- }
- out:
-+ end_current_profile_crit_section(profile);
- aa_put_ns(ns);
- return error;
- }
-@@ -667,8 +672,9 @@ static ssize_t query_data(char *buf, size_t buf_len,
- if (buf_len < sizeof(bytes) + sizeof(blocks))
- return -EINVAL; /* not enough space */
-
-- curr = aa_current_profile();
-+ curr = begin_current_profile_crit_section();
- profile = aa_fqlookupn_profile(curr, query, strnlen(query, query_len));
-+ end_current_profile_crit_section(curr);
- if (!profile)
- return -ENOENT;
-
-@@ -754,8 +760,9 @@ static ssize_t query_label(char *buf, size_t buf_len,
- match_str = label_name + label_name_len + 1;
- match_len = query_len - label_name_len - 1;
-
-- curr = aa_current_profile();
-+ curr = begin_current_profile_crit_section();
- profile = aa_fqlookupn_profile(curr, label_name, label_name_len);
-+ end_current_profile_crit_section(curr);
- if (!profile)
- return -ENOENT;
-
-@@ -1094,18 +1101,22 @@ static const struct file_operations seq_ns_ ##NAME ##_fops = { \
-
- static int seq_ns_level_show(struct seq_file *seq, void *v)
- {
-- struct aa_ns *ns = aa_current_profile()->ns;
-+ struct aa_profile *profile;
-
-- seq_printf(seq, "%d\n", ns->level);
-+ profile = begin_current_profile_crit_section();
-+ seq_printf(seq, "%d\n", profile->ns->level);
-+ end_current_profile_crit_section(profile);
-
- return 0;
- }
-
- static int seq_ns_name_show(struct seq_file *seq, void *v)
- {
-- struct aa_ns *ns = aa_current_profile()->ns;
-+ struct aa_profile *profile;
-
-- seq_printf(seq, "%s\n", aa_ns_name(ns, ns, true));
-+ profile = begin_current_profile_crit_section();
-+ seq_printf(seq, "%s\n", aa_ns_name(profile->ns, profile->ns, true));
-+ end_current_profile_crit_section(profile);
-
- return 0;
- }
-@@ -1530,9 +1541,9 @@ static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
- {
- struct aa_ns *ns, *parent;
- /* TODO: improve permission check */
-- struct aa_profile *profile = aa_current_profile();
-+ struct aa_profile *profile = begin_current_profile_crit_section();
- int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
--
-+ end_current_profile_crit_section(profile);
- if (error)
- return error;
-
-@@ -1576,9 +1587,9 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
- {
- struct aa_ns *ns, *parent;
- /* TODO: improve permission check */
-- struct aa_profile *profile = aa_current_profile();
-+ struct aa_profile *profile = begin_current_profile_crit_section();
- int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
--
-+ end_current_profile_crit_section(profile);
- if (error)
- return error;
-
-@@ -1922,10 +1933,9 @@ static struct aa_profile *next_profile(struct aa_ns *root,
- static void *p_start(struct seq_file *f, loff_t *pos)
- {
- struct aa_profile *profile = NULL;
-- struct aa_ns *root = aa_current_profile()->ns;
-+ struct aa_ns *root = aa_get_current_ns();
- loff_t l = *pos;
-- f->private = aa_get_ns(root);
--
-+ f->private = root;
-
- /* find the first profile */
- mutex_lock(&root->lock);
-diff --git a/security/apparmor/context.c b/security/apparmor/context.c
-index 1fc16b88efbf..410b9f7f68a1 100644
---- a/security/apparmor/context.c
-+++ b/security/apparmor/context.c
-@@ -79,7 +79,7 @@ struct aa_profile *aa_get_task_profile(struct task_struct *task)
- struct aa_profile *p;
-
- rcu_read_lock();
-- p = aa_get_profile(__aa_task_profile(task));
-+ p = aa_get_newest_profile(__aa_task_raw_profile(task));
- rcu_read_unlock();
-
- return p;
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index 2b1524c79fb8..0c02eac33a45 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -594,7 +594,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- /* released below */
- cred = get_current_cred();
- ctx = cred_ctx(cred);
-- profile = aa_get_newest_profile(aa_cred_profile(cred));
-+ profile = aa_get_newest_cred_profile(cred);
- previous_profile = aa_get_newest_profile(ctx->previous);
-
- if (unconfined(profile)) {
-@@ -737,7 +737,7 @@ int aa_change_profile(const char *fqname, bool onexec,
- }
-
- cred = get_current_cred();
-- profile = aa_cred_profile(cred);
-+ profile = aa_get_newest_cred_profile(cred);
-
- /*
- * Fail explicitly requested domain transitions if no_new_privs
-@@ -795,6 +795,7 @@ int aa_change_profile(const char *fqname, bool onexec,
- fqname, GLOBAL_ROOT_UID, info, error);
-
- aa_put_profile(target);
-+ aa_put_profile(profile);
- put_cred(cred);
-
- return error;
-diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
-index 420cfd041218..7665fae7131f 100644
---- a/security/apparmor/include/context.h
-+++ b/security/apparmor/include/context.h
-@@ -56,14 +56,14 @@ struct aa_profile *aa_get_task_profile(struct task_struct *task);
-
-
- /**
-- * aa_cred_profile - obtain cred's profiles
-+ * aa_cred_raw_profile - obtain cred's profiles
- * @cred: cred to obtain profiles from (NOT NULL)
- *
- * Returns: confining profile
- *
- * does NOT increment reference count
- */
--static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
-+static inline struct aa_profile *aa_cred_raw_profile(const struct cred *cred)
- {
- struct aa_task_ctx *ctx = cred_ctx(cred);
-
-@@ -72,16 +72,28 @@ static inline struct aa_profile *aa_cred_profile(const struct cred *cred)
- }
-
- /**
-- * __aa_task_profile - retrieve another task's profile
-+ * aa_get_newest_cred_profile - obtain the newest profile on a cred
-+ * @cred: cred to obtain profile from (NOT NULL)
-+ *
-+ * Returns: newest version of confining profile
-+ */
-+static inline
-+struct aa_profile *aa_get_newest_cred_profile(const struct cred *cred)
-+{
-+ return aa_get_newest_profile(aa_cred_raw_profile(cred));
-+}
-+
-+/**
-+ * __aa_task_raw_profile - retrieve another task's profile
- * @task: task to query (NOT NULL)
- *
- * Returns: @task's profile without incrementing its ref count
- *
- * If @task != current needs to be called in RCU safe critical section
- */
--static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
-+static inline struct aa_profile *__aa_task_raw_profile(struct task_struct *task)
- {
-- return aa_cred_profile(__task_cred(task));
-+ return aa_cred_raw_profile(__task_cred(task));
- }
-
- /**
-@@ -92,50 +104,115 @@ static inline struct aa_profile *__aa_task_profile(struct task_struct *task)
- */
- static inline bool __aa_task_is_confined(struct task_struct *task)
- {
-- return !unconfined(__aa_task_profile(task));
-+ return !unconfined(__aa_task_raw_profile(task));
- }
-
- /**
-- * __aa_current_profile - find the current tasks confining profile
-+ * aa_current_raw_profile - find the current tasks confining profile
- *
- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
- *
- * This fn will not update the tasks cred to the most up to date version
- * of the profile so it is safe to call when inside of locks.
- */
--static inline struct aa_profile *__aa_current_profile(void)
-+static inline struct aa_profile *aa_current_raw_profile(void)
- {
-- return aa_cred_profile(current_cred());
-+ return aa_cred_raw_profile(current_cred());
- }
-
- /**
-- * aa_current_profile - find the current tasks confining profile and do updates
-+ * aa_get_current_profile - get the newest version of the current tasks profile
- *
-- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
-+ * Returns: newest version of confining profile (NOT NULL)
-+ *
-+ * This fn will not update the tasks cred, so it is safe inside of locks
- *
-- * This fn will update the tasks cred structure if the profile has been
-- * replaced. Not safe to call inside locks
-+ * The returned reference must be put with aa_put_profile()
- */
--static inline struct aa_profile *aa_current_profile(void)
-+static inline struct aa_profile *aa_get_current_profile(void)
- {
-- const struct aa_task_ctx *ctx = current_ctx();
-- struct aa_profile *profile;
-+ struct aa_profile *p = aa_current_raw_profile();
-
-- AA_BUG(!ctx || !ctx->profile);
-+ if (profile_is_stale(p))
-+ return aa_get_newest_profile(p);
-+ return aa_get_profile(p);
-+}
-
-- if (profile_is_stale(ctx->profile)) {
-- profile = aa_get_newest_profile(ctx->profile);
-- aa_replace_current_profile(profile);
-+#define __end_current_profile_crit_section(X) \
-+ end_current_profile_crit_section(X)
-+
-+/**
-+ * end_profile_crit_section - put a reference found with begin_current_profile..
-+ * @profile: profile reference to put
-+ *
-+ * Should only be used with a reference obtained with
-+ * begin_current_profile_crit_section and never used in situations where the
-+ * task cred may be updated
-+ */
-+static inline void end_current_profile_crit_section(struct aa_profile *profile)
-+{
-+ if (profile != aa_current_raw_profile())
- aa_put_profile(profile);
-- ctx = current_ctx();
-+}
-+
-+/**
-+ * __begin_current_profile_crit_section - current's confining profile
-+ *
-+ * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
-+ *
-+ * safe to call inside locks
-+ *
-+ * The returned reference must be put with __end_current_profile_crit_section()
-+ * This must NOT be used if the task cred could be updated within the
-+ * critical section between __begin_current_profile_crit_section() ..
-+ * __end_current_profile_crit_section()
-+ */
-+static inline struct aa_profile *__begin_current_profile_crit_section(void)
-+{
-+ struct aa_profile *profile = aa_current_raw_profile();
-+
-+ if (profile_is_stale(profile))
-+ profile = aa_get_newest_profile(profile);
-+
-+ return profile;
-+}
-+
-+/**
-+ * begin_current_profile_crit_section - current's profile and update if needed
-+ *
-+ * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
-+ *
-+ * Not safe to call inside locks
-+ *
-+ * The returned reference must be put with end_current_profile_crit_section()
-+ * This must NOT be used if the task cred could be updated within the
-+ * critical section between begin_current_profile_crit_section() ..
-+ * end_current_profile_crit_section()
-+ */
-+static inline struct aa_profile *begin_current_profile_crit_section(void)
-+{
-+ struct aa_profile *profile = aa_current_raw_profile();
-+
-+ if (profile_is_stale(profile)) {
-+ profile = aa_get_newest_profile(profile);
-+ if (aa_replace_current_profile(profile) == 0)
-+ /* task cred will keep the reference */
-+ aa_put_profile(profile);
- }
-
-- return ctx->profile;
-+ return profile;
- }
-
- static inline struct aa_ns *aa_get_current_ns(void)
- {
-- return aa_get_ns(__aa_current_profile()->ns);
-+ struct aa_profile *profile;
-+ struct aa_ns *ns;
-+
-+ profile = __begin_current_profile_crit_section();
-+ ns = aa_get_ns(profile->ns);
-+ __end_current_profile_crit_section(profile);
-+
-+ return ns;
- }
-
- /**
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 35492008658f..49b780b4c53b 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -120,7 +120,7 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
-
- rcu_read_lock();
- cred = __task_cred(target);
-- profile = aa_cred_profile(cred);
-+ profile = aa_get_newest_cred_profile(cred);
-
- /*
- * cap_capget is stacked ahead of this and will
-@@ -131,6 +131,7 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
- *permitted = cap_intersect(*permitted, profile->caps.allow);
- }
- rcu_read_unlock();
-+ aa_put_profile(profile);
-
- return 0;
- }
-@@ -141,9 +142,11 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
- struct aa_profile *profile;
- int error = 0;
-
-- profile = aa_cred_profile(cred);
-+ profile = aa_get_newest_cred_profile(cred);
- if (!unconfined(profile))
- error = aa_capable(profile, cap, audit);
-+ aa_put_profile(profile);
-+
- return error;
- }
-
-@@ -162,9 +165,10 @@ static int common_perm(const char *op, const struct path *path, u32 mask,
- struct aa_profile *profile;
- int error = 0;
-
-- profile = __aa_current_profile();
-+ profile = __begin_current_profile_crit_section();
- if (!unconfined(profile))
- error = aa_path_perm(op, profile, path, 0, mask, cond);
-+ __end_current_profile_crit_section(profile);
-
- return error;
- }
-@@ -297,9 +301,11 @@ static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_
- if (!path_mediated_fs(old_dentry))
- return 0;
-
-- profile = aa_current_profile();
-+ profile = begin_current_profile_crit_section();
- if (!unconfined(profile))
- error = aa_path_link(profile, old_dentry, new_dir, new_dentry);
-+ end_current_profile_crit_section(profile);
-+
- return error;
- }
-
-@@ -312,7 +318,7 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d
- if (!path_mediated_fs(old_dentry))
- return 0;
-
-- profile = aa_current_profile();
-+ profile = begin_current_profile_crit_section();
- if (!unconfined(profile)) {
- struct path old_path = { .mnt = old_dir->mnt,
- .dentry = old_dentry };
-@@ -332,6 +338,8 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d
- AA_MAY_CREATE, &cond);
-
- }
-+ end_current_profile_crit_section(profile);
-+
- return error;
- }
-
-@@ -369,7 +377,7 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
- return 0;
- }
-
-- profile = aa_cred_profile(cred);
-+ profile = aa_get_newest_cred_profile(cred);
- if (!unconfined(profile)) {
- struct inode *inode = file_inode(file);
- struct path_cond cond = { inode->i_uid, inode->i_mode };
-@@ -379,18 +387,23 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
- /* todo cache full allowed permissions set and state */
- fctx->allow = aa_map_file_to_perms(file);
- }
-+ aa_put_profile(profile);
-
- return error;
- }
-
- static int apparmor_file_alloc_security(struct file *file)
- {
-+ int error = 0;
-+
- /* freed by apparmor_file_free_security */
-+ struct aa_profile *profile = begin_current_profile_crit_section();
- file->f_security = aa_alloc_file_context(GFP_KERNEL);
- if (!file->f_security)
- return -ENOMEM;
-- return 0;
-+ end_current_profile_crit_section(profile);
-
-+ return error;
- }
-
- static void apparmor_file_free_security(struct file *file)
-@@ -403,16 +416,17 @@ static void apparmor_file_free_security(struct file *file)
- static int common_file_perm(const char *op, struct file *file, u32 mask)
- {
- struct aa_file_ctx *fctx = file->f_security;
-- struct aa_profile *profile, *fprofile = aa_cred_profile(file->f_cred);
-+ struct aa_profile *profile, *fprofile;
- int error = 0;
-
-+ fprofile = aa_cred_raw_profile(file->f_cred);
- AA_BUG(!fprofile);
-
- if (!file->f_path.mnt ||
- !path_mediated_fs(file->f_path.dentry))
- return 0;
-
-- profile = __aa_current_profile();
-+ profile = __begin_current_profile_crit_section();
-
- /* revalidate access, if task is unconfined, or the cached cred
- * doesn't match or if the request is for more permissions than
-@@ -424,6 +438,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
- if (!unconfined(profile) && !unconfined(fprofile) &&
- ((fprofile != profile) || (mask & ~fctx->allow)))
- error = aa_file_perm(op, profile, file, mask);
-+ __end_current_profile_crit_section(profile);
-
- return error;
- }
-@@ -568,10 +583,11 @@ static int apparmor_setprocattr(const char *name, void *value,
- return error;
-
- fail:
-- aad(&sa)->profile = aa_current_profile();
-+ aad(&sa)->profile = begin_current_profile_crit_section();
- aad(&sa)->info = name;
- aad(&sa)->error = error = -EINVAL;
- aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
-+ end_current_profile_crit_section(aad(&sa)->profile);
- goto out;
- }
-
-@@ -581,7 +597,7 @@ static int apparmor_setprocattr(const char *name, void *value,
- */
- static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
- {
-- struct aa_profile *profile = __aa_current_profile();
-+ struct aa_profile *profile = aa_current_raw_profile();
- struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
-
- /* bail out if unconfined or not changing profile */
-@@ -608,11 +624,12 @@ static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
- static int apparmor_task_setrlimit(struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim)
- {
-- struct aa_profile *profile = __aa_current_profile();
-+ struct aa_profile *profile = __begin_current_profile_crit_section();
- int error = 0;
-
- if (!unconfined(profile))
- error = aa_task_setrlimit(profile, task, resource, new_rlim);
-+ __end_current_profile_crit_section(profile);
-
- return error;
- }
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index 5ea6a7cb0212..1db4746270ab 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -107,7 +107,7 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
- const char *name, const char *info, struct aa_ext *e,
- int error)
- {
-- struct aa_profile *profile = __aa_current_profile();
-+ struct aa_profile *profile = aa_current_raw_profile();
- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
- if (e)
- aad(&sa)->iface.pos = e->pos - e->start;
-diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
-index 3466a27bca09..41b7b64a906b 100644
---- a/security/apparmor/procattr.c
-+++ b/security/apparmor/procattr.c
-@@ -41,7 +41,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
- const char *mode_str = aa_profile_mode_names[profile->mode];
- const char *ns_name = NULL;
- struct aa_ns *ns = profile->ns;
-- struct aa_ns *current_ns = __aa_current_profile()->ns;
-+ struct aa_ns *current_ns = aa_get_current_ns();
- char *s;
-
- if (!aa_ns_visible(current_ns, ns, true))
-@@ -75,6 +75,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
- else
- sprintf(s, "%s (%s)\n", profile->base.hname, mode_str);
- *string = str;
-+ aa_put_ns(current_ns);
-
- /* NOTE: len does not include \0 of string, not saved as part of file */
- return len;
-diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
-index ae66151fdc38..b26f1dac5106 100644
---- a/security/apparmor/resource.c
-+++ b/security/apparmor/resource.c
-@@ -90,7 +90,7 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
- int error = 0;
-
- rcu_read_lock();
-- task_profile = aa_get_profile(aa_cred_profile(__task_cred(task)));
-+ task_profile = aa_get_newest_cred_profile((__task_cred(task)));
- rcu_read_unlock();
-
- /* TODO: extend resource control to handle other (non current)
---
-2.12.3
-
diff --git a/patches.apparmor/0037-apparmor-share-profile-name-on-replacement.patch b/patches.apparmor/0037-apparmor-share-profile-name-on-replacement.patch
deleted file mode 100644
index b58a22fe90..0000000000
--- a/patches.apparmor/0037-apparmor-share-profile-name-on-replacement.patch
+++ /dev/null
@@ -1,171 +0,0 @@
-From 5b47a7e7a7b67297d6c8dbabe95b12567ebcfe62 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 07:09:05 -0700
-Subject: [PATCH 37/65] apparmor: share profile name on replacement
-Git-commit: a1bd627b46d169268a0ee5960899fb5be960a317
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-The profile names are the same, leverage this.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/lib.h | 32 +++++++++++++++++++++++++++++++-
- security/apparmor/lib.c | 40 ++++++++++++++++++++++++++++++++--------
- security/apparmor/policy.c | 9 +++++++++
- 3 files changed, 72 insertions(+), 9 deletions(-)
-
-diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
-index 89524aade657..593877d38088 100644
---- a/security/apparmor/include/lib.h
-+++ b/security/apparmor/include/lib.h
-@@ -100,6 +100,36 @@ static inline bool path_mediated_fs(struct dentry *dentry)
- return !(dentry->d_sb->s_flags & MS_NOUSER);
- }
-
-+
-+struct counted_str {
-+ struct kref count;
-+ char name[];
-+};
-+
-+#define str_to_counted(str) \
-+ ((struct counted_str *)(str - offsetof(struct counted_str, name)))
-+
-+#define __counted /* atm just a notation */
-+
-+void aa_str_kref(struct kref *kref);
-+char *aa_str_alloc(int size, gfp_t gfp);
-+
-+
-+static inline __counted char *aa_get_str(__counted char *str)
-+{
-+ if (str)
-+ kref_get(&(str_to_counted(str)->count));
-+
-+ return str;
-+}
-+
-+static inline void aa_put_str(__counted char *str)
-+{
-+ if (str)
-+ kref_put(&str_to_counted(str)->count, aa_str_kref);
-+}
-+
-+
- /* struct aa_policy - common part of both namespaces and profiles
- * @name: name of the object
- * @hname - The hierarchical name
-@@ -108,7 +138,7 @@ static inline bool path_mediated_fs(struct dentry *dentry)
- */
- struct aa_policy {
- const char *name;
-- const char *hname;
-+ __counted char *hname;
- struct list_head list;
- struct list_head profiles;
- };
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index 3e9146e68c4a..0ceecdbb4658 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -134,6 +134,24 @@ void aa_info_message(const char *str)
- printk(KERN_INFO "AppArmor: %s\n", str);
- }
-
-+__counted char *aa_str_alloc(int size, gfp_t gfp)
-+{
-+ struct counted_str *str;
-+
-+ str = kmalloc(sizeof(struct counted_str) + size, gfp);
-+ if (!str)
-+ return NULL;
-+
-+ kref_init(&str->count);
-+ return str->name;
-+}
-+
-+void aa_str_kref(struct kref *kref)
-+{
-+ kfree(container_of(kref, struct counted_str, count));
-+}
-+
-+
- const char aa_file_perm_chrs[] = "xwracd km l ";
- const char *aa_file_perm_names[] = {
- "exec",
-@@ -296,6 +314,7 @@ void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
- * @policy: policy to initialize (NOT NULL)
- * @prefix: prefix name if any is required. (MAYBE NULL)
- * @name: name of the policy, init will make a copy of it (NOT NULL)
-+ * @gfp: allocation mode
- *
- * Note: this fn creates a copy of strings passed in
- *
-@@ -304,16 +323,21 @@ void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
- bool aa_policy_init(struct aa_policy *policy, const char *prefix,
- const char *name, gfp_t gfp)
- {
-+ char *hname;
-+
- /* freed by policy_free */
- if (prefix) {
-- policy->hname = kmalloc(strlen(prefix) + strlen(name) + 3,
-- gfp);
-- if (policy->hname)
-- sprintf((char *)policy->hname, "%s//%s", prefix, name);
-- } else
-- policy->hname = kstrdup(name, gfp);
-- if (!policy->hname)
-+ hname = aa_str_alloc(strlen(prefix) + strlen(name) + 3, gfp);
-+ if (hname)
-+ sprintf(hname, "%s//%s", prefix, name);
-+ } else {
-+ hname = aa_str_alloc(strlen(name) + 1, gfp);
-+ if (hname)
-+ strcpy(hname, name);
-+ }
-+ if (!hname)
- return false;
-+ policy->hname = hname;
- /* base.name is a substring of fqname */
- policy->name = basename(policy->hname);
- INIT_LIST_HEAD(&policy->list);
-@@ -332,5 +356,5 @@ void aa_policy_destroy(struct aa_policy *policy)
- AA_BUG(on_list_rcu(&policy->list));
-
- /* don't free name as its a subset of hname */
-- kzfree(policy->hname);
-+ aa_put_str(policy->hname);
- }
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 29e04638790f..af925c07ad4e 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -829,6 +829,14 @@ static int __lookup_replace(struct aa_ns *ns, const char *hname,
- return 0;
- }
-
-+static void share_name(struct aa_profile *old, struct aa_profile *new)
-+{
-+ aa_put_str(new->base.hname);
-+ aa_get_str(old->base.hname);
-+ new->base.hname = old->base.hname;
-+ new->base.name = old->base.name;
-+}
-+
- /**
- * aa_replace_profiles - replace profile(s) on the profile list
- * @policy_ns: namespace load is occurring on
-@@ -1013,6 +1021,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- NULL, error);
-
- if (ent->old) {
-+ share_name(ent->old, ent->new);
- __replace_profile(ent->old, ent->new, 1);
- if (ent->rename) {
- /* aafs interface uses proxy */
---
-2.12.3
-
diff --git a/patches.apparmor/0038-apparmor-refactor-updating-profiles-to-the-newest-pa.patch b/patches.apparmor/0038-apparmor-refactor-updating-profiles-to-the-newest-pa.patch
deleted file mode 100644
index f15b1014af..0000000000
--- a/patches.apparmor/0038-apparmor-refactor-updating-profiles-to-the-newest-pa.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From b438d4cae742c0c10ca33227361d7aba4f5e8823 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 07:16:46 -0700
-Subject: [PATCH 38/65] apparmor: refactor updating profiles to the newest
- parent
-Git-commit: 435222bc1bcc11636f4159fd3ce9e481ab7f2c7c
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy.c | 35 +++++++++++++++++++++++++++++++----
- 1 file changed, 31 insertions(+), 4 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index af925c07ad4e..20613186b1d8 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -837,6 +837,27 @@ static void share_name(struct aa_profile *old, struct aa_profile *new)
- new->base.name = old->base.name;
- }
-
-+/* Update to newest version of parent after previous replacements
-+ * Returns: unrefcount newest version of parent
-+ */
-+static struct aa_profile *update_to_newest_parent(struct aa_profile *new)
-+{
-+ struct aa_profile *parent, *newest;
-+
-+ parent = rcu_dereference_protected(new->parent,
-+ mutex_is_locked(&new->ns->lock));
-+ newest = aa_get_newest_profile(parent);
-+
-+ /* parent replaced in this atomic set? */
-+ if (newest != parent) {
-+ aa_put_profile(parent);
-+ rcu_assign_pointer(new->parent, newest);
-+ } else
-+ aa_put_profile(newest);
-+
-+ return newest;
-+}
-+
- /**
- * aa_replace_profiles - replace profile(s) on the profile list
- * @policy_ns: namespace load is occurring on
-@@ -1052,10 +1073,16 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- __list_add_profile(&newest->base.profiles, ent->new);
- aa_put_profile(newest);
- } else {
-- /* aafs interface uses proxy */
-- rcu_assign_pointer(ent->new->proxy->profile,
-- aa_get_profile(ent->new));
-- __list_add_profile(&ns->base.profiles, ent->new);
-+ struct list_head *lh;
-+
-+ if (rcu_access_pointer(ent->new->parent)) {
-+ struct aa_profile *parent;
-+
-+ parent = update_to_newest_parent(ent->new);
-+ lh = &parent->base.profiles;
-+ } else
-+ lh = &ns->base.profiles;
-+ __list_add_profile(lh, ent->new);
- }
- skip:
- aa_load_ent_free(ent);
---
-2.12.3
-
diff --git a/patches.apparmor/0039-apparmor-cleanup-remove-unused-and-not-fully-impleme.patch b/patches.apparmor/0039-apparmor-cleanup-remove-unused-and-not-fully-impleme.patch
deleted file mode 100644
index 3c473b5f08..0000000000
--- a/patches.apparmor/0039-apparmor-cleanup-remove-unused-and-not-fully-impleme.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From b6b36b260a4ae8c7bb97fb46302d8fd8adff4787 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 07:24:18 -0700
-Subject: [PATCH 39/65] apparmor: cleanup remove unused and not fully
- implemented profile rename
-Git-commit: dca91402e999aa0824c4144ad216bd61dd4fe3ff
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Remove the partially implemented code, until this can be properly
-implemented.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/policy.c | 39 ++-------------------------------------
- 1 file changed, 2 insertions(+), 37 deletions(-)
-
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 20613186b1d8..605cb5949c60 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -995,14 +995,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- }
- }
- list_for_each_entry(ent, &lh, list) {
-- if (ent->old) {
-- /* inherit old interface files */
--
-- /* if (ent->rename)
-- TODO: support rename */
-- /* } else if (ent->rename) {
-- TODO: support rename */
-- } else {
-+ if (!ent->old) {
- struct dentry *parent;
- if (rcu_access_pointer(ent->new->parent)) {
- struct aa_profile *p;
-@@ -1014,7 +1007,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- }
-
- if (error) {
-- info = "failed to create ";
-+ info = "failed to create";
- goto fail_lock;
- }
- }
-@@ -1044,34 +1037,6 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- if (ent->old) {
- share_name(ent->old, ent->new);
- __replace_profile(ent->old, ent->new, 1);
-- if (ent->rename) {
-- /* aafs interface uses proxy */
-- struct aa_proxy *r = ent->new->proxy;
-- rcu_assign_pointer(r->profile,
-- aa_get_profile(ent->new));
-- __replace_profile(ent->rename, ent->new, 0);
-- }
-- } else if (ent->rename) {
-- /* aafs interface uses proxy */
-- rcu_assign_pointer(ent->new->proxy->profile,
-- aa_get_profile(ent->new));
-- __replace_profile(ent->rename, ent->new, 0);
-- } else if (ent->new->parent) {
-- struct aa_profile *parent, *newest;
-- parent = aa_deref_parent(ent->new);
-- newest = aa_get_newest_profile(parent);
--
-- /* parent replaced in this atomic set? */
-- if (newest != parent) {
-- aa_get_profile(newest);
-- rcu_assign_pointer(ent->new->parent, newest);
-- aa_put_profile(parent);
-- }
-- /* aafs interface uses proxy */
-- rcu_assign_pointer(ent->new->proxy->profile,
-- aa_get_profile(ent->new));
-- __list_add_profile(&newest->base.profiles, ent->new);
-- aa_put_profile(newest);
- } else {
- struct list_head *lh;
-
---
-2.12.3
-
diff --git a/patches.apparmor/0040-apparmor-convert-aa_change_XXX-bool-parameters-to-fl.patch b/patches.apparmor/0040-apparmor-convert-aa_change_XXX-bool-parameters-to-fl.patch
deleted file mode 100644
index 25d7e2684d..0000000000
--- a/patches.apparmor/0040-apparmor-convert-aa_change_XXX-bool-parameters-to-fl.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From 09b42b87f18821aabea292c8fcb71f74d878d3b6 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 11:36:48 -0700
-Subject: [PATCH 40/65] apparmor: convert aa_change_XXX bool parameters to
- flags
-Git-commit: df8073c67fd8acb7e79f203ba4c0fa456bb82762
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Instead of passing multiple booleans consolidate on a single flags
-field.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/domain.c | 26 +++++++++++++-------------
- security/apparmor/include/domain.h | 10 +++++++---
- security/apparmor/include/procattr.h | 6 +-----
- security/apparmor/lsm.c | 13 +++++--------
- security/apparmor/procattr.c | 6 +++---
- 5 files changed, 29 insertions(+), 32 deletions(-)
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index 0c02eac33a45..2ec4ae029215 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -563,7 +563,7 @@ static char *new_compound_name(const char *n1, const char *n2)
- * @hats: vector of hat names to try changing into (MAYBE NULL if @count == 0)
- * @count: number of hat names in @hats
- * @token: magic value to validate the hat change
-- * @permtest: true if this is just a permission test
-+ * @flags: flags affecting behavior of the change
- *
- * Change to the first profile specified in @hats that exists, and store
- * the @hat_magic in the current task context. If the count == 0 and the
-@@ -572,7 +572,7 @@ static char *new_compound_name(const char *n1, const char *n2)
- *
- * Returns %0 on success, error otherwise.
- */
--int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
-+int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- {
- const struct cred *cred;
- struct aa_task_ctx *ctx;
-@@ -616,7 +616,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- /* released below */
- hat = aa_find_child(root, hats[i]);
- if (!hat) {
-- if (!COMPLAIN_MODE(root) || permtest) {
-+ if (!COMPLAIN_MODE(root) || (flags & AA_CHANGE_TEST)) {
- if (list_empty(&root->base.profiles))
- error = -ECHILD;
- else
-@@ -663,7 +663,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- goto audit;
- }
-
-- if (!permtest) {
-+ if (!(flags & AA_CHANGE_TEST)) {
- error = aa_set_current_hat(hat, token);
- if (error == -EACCES)
- /* kill task in case of brute force attacks */
-@@ -684,7 +684,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- goto out;
-
- audit:
-- if (!permtest)
-+ if (!(flags & AA_CHANGE_TEST))
- error = aa_audit_file(profile, &perms, OP_CHANGE_HAT,
- AA_MAY_CHANGEHAT, NULL, target,
- GLOBAL_ROOT_UID, info, error);
-@@ -703,7 +703,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- * aa_change_profile - perform a one-way profile transition
- * @fqname: name of profile may include namespace (NOT NULL)
- * @onexec: whether this transition is to take place immediately or at exec
-- * @permtest: true if this is just a permission test
-+ * @flags: flags affecting change behavior
- *
- * Change to new profile @name. Unlike with hats, there is no way
- * to change back. If @name isn't specified the current profile name is
-@@ -713,8 +713,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
- *
- * Returns %0 on success, error otherwise.
- */
--int aa_change_profile(const char *fqname, bool onexec,
-- bool permtest, bool stack)
-+int aa_change_profile(const char *fqname, int flags)
- {
- const struct cred *cred;
- struct aa_profile *profile, *target = NULL;
-@@ -728,7 +727,7 @@ int aa_change_profile(const char *fqname, bool onexec,
- return -EINVAL;
- }
-
-- if (onexec) {
-+ if (flags & AA_CHANGE_ONEXEC) {
- request = AA_MAY_ONEXEC;
- op = OP_CHANGE_ONEXEC;
- } else {
-@@ -755,7 +754,8 @@ int aa_change_profile(const char *fqname, bool onexec,
- if (!target) {
- info = "profile not found";
- error = -ENOENT;
-- if (permtest || !COMPLAIN_MODE(profile))
-+ if ((flags & AA_CHANGE_TEST) ||
-+ !COMPLAIN_MODE(profile))
- goto audit;
- /* released below */
- target = aa_new_null_profile(profile, false, fqname,
-@@ -781,16 +781,16 @@ int aa_change_profile(const char *fqname, bool onexec,
- goto audit;
- }
-
-- if (permtest)
-+ if (flags & AA_CHANGE_TEST)
- goto audit;
-
-- if (onexec)
-+ if (flags & AA_CHANGE_ONEXEC)
- error = aa_set_current_onexec(target);
- else
- error = aa_replace_current_profile(target);
-
- audit:
-- if (!permtest)
-+ if (!(flags & AA_CHANGE_TEST))
- error = aa_audit_file(profile, &perms, op, request, NULL,
- fqname, GLOBAL_ROOT_UID, info, error);
-
-diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h
-index 6587c4abb7e8..255aa40ec1d1 100644
---- a/security/apparmor/include/domain.h
-+++ b/security/apparmor/include/domain.h
-@@ -23,12 +23,16 @@ struct aa_domain {
- char **table;
- };
-
-+#define AA_CHANGE_NOFLAGS 0
-+#define AA_CHANGE_TEST 1
-+#define AA_CHANGE_CHILD 2
-+#define AA_CHANGE_ONEXEC 4
-+
- int apparmor_bprm_set_creds(struct linux_binprm *bprm);
- int apparmor_bprm_secureexec(struct linux_binprm *bprm);
-
- void aa_free_domain_entries(struct aa_domain *domain);
--int aa_change_hat(const char *hats[], int count, u64 token, bool permtest);
--int aa_change_profile(const char *fqname, bool onexec, bool permtest,
-- bool stack);
-+int aa_change_hat(const char *hats[], int count, u64 token, int flags);
-+int aa_change_profile(const char *fqname, int flags);
-
- #endif /* __AA_DOMAIN_H */
-diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
-index 6bd5f33d9533..c0055d727868 100644
---- a/security/apparmor/include/procattr.h
-+++ b/security/apparmor/include/procattr.h
-@@ -15,11 +15,7 @@
- #ifndef __AA_PROCATTR_H
- #define __AA_PROCATTR_H
-
--#define AA_DO_TEST 1
--#define AA_ONEXEC 1
--
- int aa_getprocattr(struct aa_profile *profile, char **string);
--int aa_setprocattr_changehat(char *args, size_t size, int test);
--int aa_setprocattr_changeprofile(char *fqname, bool onexec, int test);
-+int aa_setprocattr_changehat(char *args, size_t size, int flags);
-
- #endif /* __AA_PROCATTR_H */
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 49b780b4c53b..e07dd5a204d7 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -554,22 +554,19 @@ static int apparmor_setprocattr(const char *name, void *value,
- if (strcmp(name, "current") == 0) {
- if (strcmp(command, "changehat") == 0) {
- error = aa_setprocattr_changehat(args, arg_size,
-- !AA_DO_TEST);
-+ AA_CHANGE_NOFLAGS);
- } else if (strcmp(command, "permhat") == 0) {
- error = aa_setprocattr_changehat(args, arg_size,
-- AA_DO_TEST);
-+ AA_CHANGE_TEST);
- } else if (strcmp(command, "changeprofile") == 0) {
-- error = aa_change_profile(args, !AA_ONEXEC,
-- !AA_DO_TEST, false);
-+ error = aa_change_profile(args, AA_CHANGE_NOFLAGS);
- } else if (strcmp(command, "permprofile") == 0) {
-- error = aa_change_profile(args, !AA_ONEXEC, AA_DO_TEST,
-- false);
-+ error = aa_change_profile(args, AA_CHANGE_TEST);
- } else
- goto fail;
- } else if (strcmp(name, "exec") == 0) {
- if (strcmp(command, "exec") == 0)
-- error = aa_change_profile(args, AA_ONEXEC, !AA_DO_TEST,
-- false);
-+ error = aa_change_profile(args, AA_CHANGE_ONEXEC);
- else
- goto fail;
- } else
-diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
-index 41b7b64a906b..2f0cb424927a 100644
---- a/security/apparmor/procattr.c
-+++ b/security/apparmor/procattr.c
-@@ -109,11 +109,11 @@ static char *split_token_from_name(const char *op, char *args, u64 *token)
- * aa_setprocattr_chagnehat - handle procattr interface to change_hat
- * @args: args received from writing to /proc/<pid>/attr/current (NOT NULL)
- * @size: size of the args
-- * @test: true if this is a test of change_hat permissions
-+ * @flags: set of flags governing behavior
- *
- * Returns: %0 or error code if change_hat fails
- */
--int aa_setprocattr_changehat(char *args, size_t size, int test)
-+int aa_setprocattr_changehat(char *args, size_t size, int flags)
- {
- char *hat;
- u64 token;
-@@ -148,5 +148,5 @@ int aa_setprocattr_changehat(char *args, size_t size, int test)
- AA_DEBUG("%s: (pid %d) Magic 0x%llx count %d Hat '%s'\n",
- __func__, current->pid, token, count, "<NULL>");
-
-- return aa_change_hat(hats, count, token, test);
-+ return aa_change_hat(hats, count, token, flags);
- }
---
-2.12.3
-
diff --git a/patches.apparmor/0041-apparmor-cleanup-rename-XXX_file_context-to-XXX_file.patch b/patches.apparmor/0041-apparmor-cleanup-rename-XXX_file_context-to-XXX_file.patch
deleted file mode 100644
index 0b778bc525..0000000000
--- a/patches.apparmor/0041-apparmor-cleanup-rename-XXX_file_context-to-XXX_file.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From aa0d9460b157536a9eab29756d969afb13ba3d7e Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 11:43:45 -0700
-Subject: [PATCH 41/65] apparmor: cleanup rename XXX_file_context() to XXX_file_ctx()
-Git-commit: 2835a13bbdc09d330eafdf5e67eb407c90c01ab7
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/file.h | 17 ++++++++++++-----
- security/apparmor/lsm.c | 10 ++++------
- 2 files changed, 16 insertions(+), 11 deletions(-)
-
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-index 365ca7ead133..19c483850770 100644
---- a/security/apparmor/include/file.h
-+++ b/security/apparmor/include/file.h
-@@ -30,6 +30,8 @@ struct path;
- AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
- AA_EXEC_MMAP | AA_MAY_LINK)
-
-+#define file_ctx(X) ((struct aa_file_ctx *)(X)->f_security)
-+
- /* struct aa_file_ctx - the AppArmor context the file was opened in
- * @perms: the permission the file was opened with
- *
-@@ -42,21 +44,26 @@ struct aa_file_ctx {
- };
-
- /**
-- * aa_alloc_file_context - allocate file_ctx
-+ * aa_alloc_file_ctx - allocate file_ctx
-+ * @label: initial label of task creating the file
- * @gfp: gfp flags for allocation
- *
- * Returns: file_ctx or NULL on failure
- */
--static inline struct aa_file_ctx *aa_alloc_file_context(gfp_t gfp)
-+static inline struct aa_file_ctx *aa_alloc_file_ctx(gfp_t gfp)
- {
-- return kzalloc(sizeof(struct aa_file_ctx), gfp);
-+ struct aa_file_ctx *ctx;
-+
-+ ctx = kzalloc(sizeof(struct aa_file_ctx), gfp);
-+
-+ return ctx;
- }
-
- /**
-- * aa_free_file_context - free a file_ctx
-+ * aa_free_file_ctx - free a file_ctx
- * @ctx: file_ctx to free (MAYBE_NULL)
- */
--static inline void aa_free_file_context(struct aa_file_ctx *ctx)
-+static inline void aa_free_file_ctx(struct aa_file_ctx *ctx)
- {
- if (ctx)
- kzfree(ctx);
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index e07dd5a204d7..3c6fa9753675 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -398,9 +398,9 @@ static int apparmor_file_alloc_security(struct file *file)
-
- /* freed by apparmor_file_free_security */
- struct aa_profile *profile = begin_current_profile_crit_section();
-- file->f_security = aa_alloc_file_context(GFP_KERNEL);
-- if (!file->f_security)
-- return -ENOMEM;
-+ file->f_security = aa_alloc_file_ctx(GFP_KERNEL);
-+ if (!file_ctx(file))
-+ error = -ENOMEM;
- end_current_profile_crit_section(profile);
-
- return error;
-@@ -408,9 +408,7 @@ static int apparmor_file_alloc_security(struct file *file)
-
- static void apparmor_file_free_security(struct file *file)
- {
-- struct aa_file_ctx *ctx = file->f_security;
--
-- aa_free_file_context(ctx);
-+ aa_free_file_ctx(file_ctx(file));
- }
-
- static int common_file_perm(const char *op, struct file *file, u32 mask)
---
-2.12.3
-
diff --git a/patches.apparmor/0042-apparmor-revalidate-files-during-exec.patch b/patches.apparmor/0042-apparmor-revalidate-files-during-exec.patch
deleted file mode 100644
index f9dcc68523..0000000000
--- a/patches.apparmor/0042-apparmor-revalidate-files-during-exec.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From 28ab1952af9ab60e9f7ff450995d15c71c938b14 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 11:58:42 -0700
-Subject: [PATCH 42/65] apparmor: revalidate files during exec
-Git-commit: 192ca6b55a866e838aee98d9cb6a0b5086467c03
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Instead of running file revalidation lazily when read/write are called
-copy selinux and revalidate the file table on exec. This avoids
-extra mediation overhead in read/write and also prevents file handles
-being passed through to a grand child unchecked.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/file.c | 72 +++++++++++++++++++++++++++++++++++++++
- security/apparmor/include/audit.h | 1 +
- security/apparmor/include/file.h | 2 ++
- security/apparmor/lsm.c | 6 ++++
- 4 files changed, 81 insertions(+)
-
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index 2e128c2aa4dc..bf508791cc1f 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -12,8 +12,13 @@
- * License.
- */
-
-+#include <linux/tty.h>
-+#include <linux/fdtable.h>
-+#include <linux/file.h>
-+
- #include "include/apparmor.h"
- #include "include/audit.h"
-+#include "include/context.h"
- #include "include/file.h"
- #include "include/match.h"
- #include "include/path.h"
-@@ -445,3 +450,70 @@ int aa_file_perm(const char *op, struct aa_profile *profile, struct file *file,
- return aa_path_perm(op, profile, &file->f_path, PATH_DELEGATE_DELETED,
- request, &cond);
- }
-+
-+static void revalidate_tty(struct aa_profile *profile)
-+{
-+ struct tty_struct *tty;
-+ int drop_tty = 0;
-+
-+ tty = get_current_tty();
-+ if (!tty)
-+ return;
-+
-+ spin_lock(&tty->files_lock);
-+ if (!list_empty(&tty->tty_files)) {
-+ struct tty_file_private *file_priv;
-+ struct file *file;
-+ /* TODO: Revalidate access to controlling tty. */
-+ file_priv = list_first_entry(&tty->tty_files,
-+ struct tty_file_private, list);
-+ file = file_priv->file;
-+
-+ if (aa_file_perm(OP_INHERIT, profile, file,
-+ MAY_READ | MAY_WRITE))
-+ drop_tty = 1;
-+ }
-+ spin_unlock(&tty->files_lock);
-+ tty_kref_put(tty);
-+
-+ if (drop_tty)
-+ no_tty();
-+}
-+
-+static int match_file(const void *p, struct file *file, unsigned int fd)
-+{
-+ struct aa_profile *profile = (struct aa_profile *)p;
-+
-+ if (aa_file_perm(OP_INHERIT, profile, file,
-+ aa_map_file_to_perms(file)))
-+ return fd + 1;
-+ return 0;
-+}
-+
-+
-+/* based on selinux's flush_unauthorized_files */
-+void aa_inherit_files(const struct cred *cred, struct files_struct *files)
-+{
-+ struct aa_profile *profile = aa_get_newest_cred_profile(cred);
-+ struct file *devnull = NULL;
-+ unsigned int n;
-+
-+ revalidate_tty(profile);
-+
-+ /* Revalidate access to inherited open files. */
-+ n = iterate_fd(files, 0, match_file, profile);
-+ if (!n) /* none found? */
-+ goto out;
-+
-+ devnull = dentry_open(&aa_null, O_RDWR, cred);
-+ if (IS_ERR(devnull))
-+ devnull = NULL;
-+ /* replace all the matching ones with this */
-+ do {
-+ replace_fd(n - 1, devnull, 0);
-+ } while ((n = iterate_fd(files, n, match_file, profile)) != 0);
-+ if (devnull)
-+ fput(devnull);
-+out:
-+ aa_put_profile(profile);
-+}
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index 1aeb8550fb82..d548261dd1b7 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -69,6 +69,7 @@ enum audit_type {
- #define OP_FLOCK "file_lock"
- #define OP_FMMAP "file_mmap"
- #define OP_FMPROT "file_mprotect"
-+#define OP_INHERIT "file_inherit"
-
- #define OP_CREATE "create"
- #define OP_POST_CREATE "post_create"
-diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
-index 19c483850770..df76c208473a 100644
---- a/security/apparmor/include/file.h
-+++ b/security/apparmor/include/file.h
-@@ -186,6 +186,8 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
- int aa_file_perm(const char *op, struct aa_profile *profile, struct file *file,
- u32 request);
-
-+void aa_inherit_files(const struct cred *cred, struct files_struct *files);
-+
- static inline void aa_free_file_rules(struct aa_file_rules *rules)
- {
- aa_put_dfa(rules->dfa);
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 3c6fa9753675..7ba43c18687a 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -417,6 +417,10 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
- struct aa_profile *profile, *fprofile;
- int error = 0;
-
-+ /* don't reaudit files closed during inheritance */
-+ if (file->f_path.dentry == aa_null.dentry)
-+ return -EACCES;
-+
- fprofile = aa_cred_raw_profile(file->f_cred);
- AA_BUG(!fprofile);
-
-@@ -600,6 +604,8 @@ static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
- (unconfined(new_ctx->profile)))
- return;
-
-+ aa_inherit_files(bprm->cred, current->files);
-+
- current->pdeath_signal = 0;
-
- /* reset soft limits and set hard limits for the new profile */
---
-2.12.3
-
diff --git a/patches.apparmor/0043-apparmor-add-the-base-fns-for-domain-labels.patch b/patches.apparmor/0043-apparmor-add-the-base-fns-for-domain-labels.patch
deleted file mode 100644
index 590c09db6e..0000000000
--- a/patches.apparmor/0043-apparmor-add-the-base-fns-for-domain-labels.patch
+++ /dev/null
@@ -1,2597 +0,0 @@
-From 257d4352d5b1220a2a942227cd25228a7210baaa Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 06:19:19 -0700
-Subject: [PATCH 43/65] apparmor: add the base fns() for domain labels
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-Git-commit: f1bd904175e8190ce14aedee37e207ab51fe3b30
-
-Begin moving apparmor to using broader domain labels, that will allow
-run time computation of domain type splitting via "stacking" of
-profiles into a domain label vec.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/label.h | 441 ++++++++
- security/apparmor/label.c | 2120 +++++++++++++++++++++++++++++++++++++
- 2 files changed, 2561 insertions(+)
- create mode 100644 security/apparmor/include/label.h
- create mode 100644 security/apparmor/label.c
-
-diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
-new file mode 100644
-index 000000000000..9a283b722755
---- /dev/null
-+++ b/security/apparmor/include/label.h
-@@ -0,0 +1,441 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor label definitions
-+ *
-+ * Copyright 2017 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_LABEL_H
-+#define __AA_LABEL_H
-+
-+#include <linux/atomic.h>
-+#include <linux/audit.h>
-+#include <linux/rbtree.h>
-+#include <linux/rcupdate.h>
-+
-+#include "apparmor.h"
-+#include "lib.h"
-+
-+struct aa_ns;
-+
-+#define LOCAL_VEC_ENTRIES 8
-+#define DEFINE_VEC(T, V) \
-+ struct aa_ ## T *(_ ## V ## _localtmp)[LOCAL_VEC_ENTRIES]; \
-+ struct aa_ ## T **(V)
-+
-+#define vec_setup(T, V, N, GFP) \
-+({ \
-+ if ((N) <= LOCAL_VEC_ENTRIES) { \
-+ typeof(N) i; \
-+ (V) = (_ ## V ## _localtmp); \
-+ for (i = 0; i < (N); i++) \
-+ (V)[i] = NULL; \
-+ } else \
-+ (V) = kzalloc(sizeof(struct aa_ ## T *) * (N), (GFP)); \
-+ (V) ? 0 : -ENOMEM; \
-+})
-+
-+#define vec_cleanup(T, V, N) \
-+do { \
-+ int i; \
-+ for (i = 0; i < (N); i++) { \
-+ if (!IS_ERR_OR_NULL((V)[i])) \
-+ aa_put_ ## T((V)[i]); \
-+ } \
-+ if ((V) != _ ## V ## _localtmp) \
-+ kfree(V); \
-+} while (0)
-+
-+#define vec_last(VEC, SIZE) ((VEC)[(SIZE) - 1])
-+#define vec_ns(VEC, SIZE) (vec_last((VEC), (SIZE))->ns)
-+#define vec_labelset(VEC, SIZE) (&vec_ns((VEC), (SIZE))->labels)
-+#define cleanup_domain_vec(V, L) cleanup_label_vec((V), (L)->size)
-+
-+struct aa_profile;
-+#define VEC_FLAG_TERMINATE 1
-+int aa_vec_unique(struct aa_profile **vec, int n, int flags);
-+struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
-+ gfp_t gfp);
-+#define aa_sort_and_merge_vec(N, V) \
-+ aa_sort_and_merge_profiles((N), (struct aa_profile **)(V))
-+
-+
-+/* struct aa_labelset - set of labels for a namespace
-+ *
-+ * Labels are reference counted; aa_labelset does not contribute to label
-+ * reference counts. Once a label's last refcount is put it is removed from
-+ * the set.
-+ */
-+struct aa_labelset {
-+ rwlock_t lock;
-+
-+ struct rb_root root;
-+};
-+
-+#define __labelset_for_each(LS, N) \
-+ for ((N) = rb_first(&(LS)->root); (N); (N) = rb_next(N))
-+
-+void aa_labelset_destroy(struct aa_labelset *ls);
-+void aa_labelset_init(struct aa_labelset *ls);
-+
-+
-+enum label_flags {
-+ FLAG_HAT = 1, /* profile is a hat */
-+ FLAG_UNCONFINED = 2, /* label unconfined only if all */
-+ FLAG_NULL = 4, /* profile is null learning profile */
-+ FLAG_IX_ON_NAME_ERROR = 8, /* fallback to ix on name lookup fail */
-+ FLAG_IMMUTIBLE = 0x10, /* don't allow changes/replacement */
-+ FLAG_USER_DEFINED = 0x20, /* user based profile - lower privs */
-+ FLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
-+ FLAG_NS_COUNT = 0x80, /* carries NS ref count */
-+ FLAG_IN_TREE = 0x100, /* label is in tree */
-+ FLAG_PROFILE = 0x200, /* label is a profile */
-+ FLAG_EXPLICIT = 0x400, /* explicit static label */
-+ FLAG_STALE = 0x800, /* replaced/removed */
-+ FLAG_RENAMED = 0x1000, /* label has renaming in it */
-+ FLAG_REVOKED = 0x2000, /* label has revocation in it */
-+
-+ /* These flags must correspond with PATH_flags */
-+ /* TODO: add new path flags */
-+};
-+
-+struct aa_label;
-+struct aa_proxy {
-+ struct kref count;
-+ struct aa_label __rcu *label;
-+};
-+
-+struct label_it {
-+ int i, j;
-+};
-+
-+/* struct aa_label - lazy labeling struct
-+ * @count: ref count of active users
-+ * @node: rbtree position
-+ * @rcu: rcu callback struct
-+ * @proxy: is set to the label that replaced this label
-+ * @hname: text representation of the label (MAYBE_NULL)
-+ * @flags: stale and other flags - values may change under label set lock
-+ * @secid: secid that references this label
-+ * @size: number of entries in @ent[]
-+ * @ent: set of profiles for label, actual size determined by @size
-+ */
-+struct aa_label {
-+ struct kref count;
-+ struct rb_node node;
-+ struct rcu_head rcu;
-+ struct aa_proxy *proxy;
-+ __counted char *hname;
-+ long flags;
-+ u32 secid;
-+ int size;
-+ struct aa_profile *vec[];
-+};
-+
-+#define last_error(E, FN) \
-+do { \
-+ int __subE = (FN); \
-+ if (__subE) \
-+ (E) = __subE; \
-+} while (0)
-+
-+#define label_isprofile(X) ((X)->flags & FLAG_PROFILE)
-+#define label_unconfined(X) ((X)->flags & FLAG_UNCONFINED)
-+#define unconfined(X) label_unconfined(X)
-+#define label_is_stale(X) ((X)->flags & FLAG_STALE)
-+#define __label_make_stale(X) ((X)->flags |= FLAG_STALE)
-+#define labels_ns(X) (vec_ns(&((X)->vec[0]), (X)->size))
-+#define labels_set(X) (&labels_ns(X)->labels)
-+#define labels_profile(X) ((X)->vec[(X)->size - 1])
-+
-+
-+int aa_label_next_confined(struct aa_label *l, int i);
-+
-+/* for each profile in a label */
-+#define label_for_each(I, L, P) \
-+ for ((I).i = 0; ((P) = (L)->vec[(I).i]); ++((I).i))
-+
-+/* assumes break/goto ended label_for_each */
-+#define label_for_each_cont(I, L, P) \
-+ for (++((I).i); ((P) = (L)->vec[(I).i]); ++((I).i))
-+
-+#define next_comb(I, L1, L2) \
-+do { \
-+ (I).j++; \
-+ if ((I).j >= (L2)->size) { \
-+ (I).i++; \
-+ (I).j = 0; \
-+ } \
-+} while (0)
-+
-+
-+/* for each combination of P1 in L1, and P2 in L2 */
-+#define label_for_each_comb(I, L1, L2, P1, P2) \
-+for ((I).i = (I).j = 0; \
-+ ((P1) = (L1)->vec[(I).i]) && ((P2) = (L2)->vec[(I).j]); \
-+ (I) = next_comb(I, L1, L2))
-+
-+#define fn_for_each_comb(L1, L2, P1, P2, FN) \
-+({ \
-+ struct label_it i; \
-+ int __E = 0; \
-+ label_for_each_comb(i, (L1), (L2), (P1), (P2)) { \
-+ last_error(__E, (FN)); \
-+ } \
-+ __E; \
-+})
-+
-+/* for each profile that is enforcing confinement in a label */
-+#define label_for_each_confined(I, L, P) \
-+ for ((I).i = aa_label_next_confined((L), 0); \
-+ ((P) = (L)->vec[(I).i]); \
-+ (I).i = aa_label_next_confined((L), (I).i + 1))
-+
-+#define label_for_each_in_merge(I, A, B, P) \
-+ for ((I).i = (I).j = 0; \
-+ ((P) = aa_label_next_in_merge(&(I), (A), (B))); \
-+ )
-+
-+#define label_for_each_not_in_set(I, SET, SUB, P) \
-+ for ((I).i = (I).j = 0; \
-+ ((P) = __aa_label_next_not_in_set(&(I), (SET), (SUB))); \
-+ )
-+
-+#define next_in_ns(i, NS, L) \
-+({ \
-+ typeof(i) ___i = (i); \
-+ while ((L)->vec[___i] && (L)->vec[___i]->ns != (NS)) \
-+ (___i)++; \
-+ (___i); \
-+})
-+
-+#define label_for_each_in_ns(I, NS, L, P) \
-+ for ((I).i = next_in_ns(0, (NS), (L)); \
-+ ((P) = (L)->vec[(I).i]); \
-+ (I).i = next_in_ns((I).i + 1, (NS), (L)))
-+
-+#define fn_for_each_in_ns(L, P, FN) \
-+({ \
-+ struct label_it __i; \
-+ struct aa_ns *__ns = labels_ns(L); \
-+ int __E = 0; \
-+ label_for_each_in_ns(__i, __ns, (L), (P)) { \
-+ last_error(__E, (FN)); \
-+ } \
-+ __E; \
-+})
-+
-+
-+#define fn_for_each_XXX(L, P, FN, ...) \
-+({ \
-+ struct label_it i; \
-+ int __E = 0; \
-+ label_for_each ## __VA_ARGS__(i, (L), (P)) { \
-+ last_error(__E, (FN)); \
-+ } \
-+ __E; \
-+})
-+
-+#define fn_for_each(L, P, FN) fn_for_each_XXX(L, P, FN)
-+#define fn_for_each_confined(L, P, FN) fn_for_each_XXX(L, P, FN, _confined)
-+
-+#define fn_for_each2_XXX(L1, L2, P, FN, ...) \
-+({ \
-+ struct label_it i; \
-+ int __E = 0; \
-+ label_for_each ## __VA_ARGS__(i, (L1), (L2), (P)) { \
-+ last_error(__E, (FN)); \
-+ } \
-+ __E; \
-+})
-+
-+#define fn_for_each_in_merge(L1, L2, P, FN) \
-+ fn_for_each2_XXX((L1), (L2), P, FN, _in_merge)
-+#define fn_for_each_not_in_set(L1, L2, P, FN) \
-+ fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set)
-+
-+#define LABEL_MEDIATES(L, C) \
-+({ \
-+ struct aa_profile *profile; \
-+ struct label_it i; \
-+ int ret = 0; \
-+ label_for_each(i, (L), profile) { \
-+ if (PROFILE_MEDIATES(profile, (C))) { \
-+ ret = 1; \
-+ break; \
-+ } \
-+ } \
-+ ret; \
-+})
-+
-+
-+void aa_labelset_destroy(struct aa_labelset *ls);
-+void aa_labelset_init(struct aa_labelset *ls);
-+void __aa_labelset_update_subtree(struct aa_ns *ns);
-+
-+void aa_label_free(struct aa_label *label);
-+void aa_label_kref(struct kref *kref);
-+bool aa_label_init(struct aa_label *label, int size);
-+struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp);
-+
-+bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub);
-+struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
-+ struct aa_label *set,
-+ struct aa_label *sub);
-+bool aa_label_remove(struct aa_label *label);
-+struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *l);
-+bool aa_label_replace(struct aa_label *old, struct aa_label *new);
-+bool aa_label_make_newest(struct aa_labelset *ls, struct aa_label *old,
-+ struct aa_label *new);
-+
-+struct aa_label *aa_label_find(struct aa_label *l);
-+
-+struct aa_profile *aa_label_next_in_merge(struct label_it *I,
-+ struct aa_label *a,
-+ struct aa_label *b);
-+struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b);
-+struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
-+ gfp_t gfp);
-+
-+
-+bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp);
-+
-+#define FLAGS_NONE 0
-+#define FLAG_SHOW_MODE 1
-+#define FLAG_VIEW_SUBNS 2
-+#define FLAG_HIDDEN_UNCONFINED 4
-+int aa_label_snxprint(char *str, size_t size, struct aa_ns *view,
-+ struct aa_label *label, int flags);
-+int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
-+ int flags, gfp_t gfp);
-+int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
-+ struct aa_label *label, int flags, gfp_t gfp);
-+void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
-+ struct aa_label *label, int flags, gfp_t gfp);
-+void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
-+ struct aa_label *label, int flags, gfp_t gfp);
-+void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
-+ gfp_t gfp);
-+void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp);
-+void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp);
-+void aa_label_printk(struct aa_label *label, gfp_t gfp);
-+
-+struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
-+ gfp_t gfp, bool create, bool force_stack);
-+
-+
-+struct aa_perms;
-+int aa_label_match(struct aa_profile *profile, struct aa_label *label,
-+ unsigned int state, bool subns, u32 request,
-+ struct aa_perms *perms);
-+
-+
-+/**
-+ * __aa_get_label - get a reference count to uncounted label reference
-+ * @l: reference to get a count on
-+ *
-+ * Returns: pointer to reference OR NULL if race is lost and reference is
-+ * being repeated.
-+ * Requires: lock held, and the return code MUST be checked
-+ */
-+static inline struct aa_label *__aa_get_label(struct aa_label *l)
-+{
-+ if (l && kref_get_unless_zero(&l->count))
-+ return l;
-+
-+ return NULL;
-+}
-+
-+static inline struct aa_label *aa_get_label(struct aa_label *l)
-+{
-+ if (l)
-+ kref_get(&(l->count));
-+
-+ return l;
-+}
-+
-+
-+/**
-+ * aa_get_label_rcu - increment refcount on a label that can be replaced
-+ * @l: pointer to label that can be replaced (NOT NULL)
-+ *
-+ * Returns: pointer to a refcounted label.
-+ * else NULL if no label
-+ */
-+static inline struct aa_label *aa_get_label_rcu(struct aa_label __rcu **l)
-+{
-+ struct aa_label *c;
-+
-+ rcu_read_lock();
-+ do {
-+ c = rcu_dereference(*l);
-+ } while (c && !kref_get_unless_zero(&c->count));
-+ rcu_read_unlock();
-+
-+ return c;
-+}
-+
-+/**
-+ * aa_get_newest_label - find the newest version of @l
-+ * @l: the label to check for newer versions of
-+ *
-+ * Returns: refcounted newest version of @l taking into account
-+ * replacement, renames and removals
-+ * return @l.
-+ */
-+static inline struct aa_label *aa_get_newest_label(struct aa_label *l)
-+{
-+ if (!l)
-+ return NULL;
-+
-+ if (label_is_stale(l)) {
-+ struct aa_label *tmp;
-+
-+ AA_BUG(!l->proxy);
-+ AA_BUG(!l->proxy->label);
-+ /* BUG: only way this can happen is @l ref count and its
-+ * replacement count have gone to 0 and are on their way
-+ * to destruction. ie. we have a refcounting error
-+ */
-+ tmp = aa_get_label_rcu(&l->proxy->label);
-+ AA_BUG(!tmp);
-+
-+ return tmp;
-+ }
-+
-+ return aa_get_label(l);
-+}
-+
-+static inline void aa_put_label(struct aa_label *l)
-+{
-+ if (l)
-+ kref_put(&l->count, aa_label_kref);
-+}
-+
-+
-+struct aa_proxy *aa_alloc_proxy(struct aa_label *l, gfp_t gfp);
-+void aa_proxy_kref(struct kref *kref);
-+
-+static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy)
-+{
-+ if (proxy)
-+ kref_get(&(proxy->count));
-+
-+ return proxy;
-+}
-+
-+static inline void aa_put_proxy(struct aa_proxy *proxy)
-+{
-+ if (proxy)
-+ kref_put(&proxy->count, aa_proxy_kref);
-+}
-+
-+void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new);
-+
-+#endif /* __AA_LABEL_H */
-diff --git a/security/apparmor/label.c b/security/apparmor/label.c
-new file mode 100644
-index 000000000000..e052eaba1cf6
---- /dev/null
-+++ b/security/apparmor/label.c
-@@ -0,0 +1,2120 @@
-+/*
-+ * AppArmor security module
-+ *
-+ * This file contains AppArmor label definitions
-+ *
-+ * Copyright 2017 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 <linux/seq_file.h>
-+#include <linux/sort.h>
-+
-+#include "include/apparmor.h"
-+#include "include/context.h"
-+#include "include/label.h"
-+#include "include/policy.h"
-+#include "include/secid.h"
-+
-+
-+/*
-+ * the aa_label represents the set of profiles confining an object
-+ *
-+ * Labels maintain a reference count to the set of pointers they reference
-+ * Labels are ref counted by
-+ * tasks and object via the security field/security context off the field
-+ * code - will take a ref count on a label if it needs the label
-+ * beyond what is possible with an rcu_read_lock.
-+ * profiles - each profile is a label
-+ * secids - a pinned secid will keep a refcount of the label it is
-+ * referencing
-+ * objects - inode, files, sockets, ...
-+ *
-+ * Labels are not ref counted by the label set, so they maybe removed and
-+ * freed when no longer in use.
-+ *
-+ */
-+
-+#define PROXY_POISON 97
-+#define LABEL_POISON 100
-+
-+static void free_proxy(struct aa_proxy *proxy)
-+{
-+ if (proxy) {
-+ /* p->label will not updated any more as p is dead */
-+ aa_put_label(rcu_dereference_protected(proxy->label, true));
-+ memset(proxy, 0, sizeof(*proxy));
-+ proxy->label = (struct aa_label *) PROXY_POISON;
-+ kfree(proxy);
-+ }
-+}
-+
-+void aa_proxy_kref(struct kref *kref)
-+{
-+ struct aa_proxy *proxy = container_of(kref, struct aa_proxy, count);
-+
-+ free_proxy(proxy);
-+}
-+
-+struct aa_proxy *aa_alloc_proxy(struct aa_label *label, gfp_t gfp)
-+{
-+ struct aa_proxy *new;
-+
-+ new = kzalloc(sizeof(struct aa_proxy), gfp);
-+ if (new) {
-+ kref_init(&new->count);
-+ rcu_assign_pointer(new->label, aa_get_label(label));
-+ }
-+ return new;
-+}
-+
-+/* requires profile list write lock held */
-+void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new)
-+{
-+ struct aa_label *tmp;
-+
-+ AA_BUG(!orig);
-+ AA_BUG(!new);
-+ AA_BUG(!write_is_locked(&labels_set(orig)->lock));
-+
-+ tmp = rcu_dereference_protected(orig->proxy->label,
-+ &labels_ns(orig)->lock);
-+ rcu_assign_pointer(orig->proxy->label, aa_get_label(new));
-+ orig->flags |= FLAG_STALE;
-+ aa_put_label(tmp);
-+}
-+
-+static void __proxy_share(struct aa_label *old, struct aa_label *new)
-+{
-+ struct aa_proxy *proxy = new->proxy;
-+
-+ new->proxy = aa_get_proxy(old->proxy);
-+ __aa_proxy_redirect(old, new);
-+ aa_put_proxy(proxy);
-+}
-+
-+
-+/**
-+ * ns_cmp - compare ns for label set ordering
-+ * @a: ns to compare (NOT NULL)
-+ * @b: ns to compare (NOT NULL)
-+ *
-+ * Returns: <0 if a < b
-+ * ==0 if a == b
-+ * >0 if a > b
-+ */
-+static int ns_cmp(struct aa_ns *a, struct aa_ns *b)
-+{
-+ int res;
-+
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+ AA_BUG(!a->base.hname);
-+ AA_BUG(!b->base.hname);
-+
-+ if (a == b)
-+ return 0;
-+
-+ res = a->level - b->level;
-+ if (res)
-+ return res;
-+
-+ return strcmp(a->base.hname, b->base.hname);
-+}
-+
-+/**
-+ * profile_cmp - profile comparision for set ordering
-+ * @a: profile to compare (NOT NULL)
-+ * @b: profile to compare (NOT NULL)
-+ *
-+ * Returns: <0 if a < b
-+ * ==0 if a == b
-+ * >0 if a > b
-+ */
-+static int profile_cmp(struct aa_profile *a, struct aa_profile *b)
-+{
-+ int res;
-+
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+ AA_BUG(!a->ns);
-+ AA_BUG(!b->ns);
-+ AA_BUG(!a->base.hname);
-+ AA_BUG(!b->base.hname);
-+
-+ if (a == b || a->base.hname == b->base.hname)
-+ return 0;
-+ res = ns_cmp(a->ns, b->ns);
-+ if (res)
-+ return res;
-+
-+ return strcmp(a->base.hname, b->base.hname);
-+}
-+
-+/**
-+ * vec_cmp - label comparision for set ordering
-+ * @a: label to compare (NOT NULL)
-+ * @vec: vector of profiles to compare (NOT NULL)
-+ * @n: length of @vec
-+ *
-+ * Returns: <0 if a < vec
-+ * ==0 if a == vec
-+ * >0 if a > vec
-+ */
-+static int vec_cmp(struct aa_profile **a, int an, struct aa_profile **b, int bn)
-+{
-+ int i;
-+
-+ AA_BUG(!a);
-+ AA_BUG(!*a);
-+ AA_BUG(!b);
-+ AA_BUG(!*b);
-+ AA_BUG(an <= 0);
-+ AA_BUG(bn <= 0);
-+
-+ for (i = 0; i < an && i < bn; i++) {
-+ int res = profile_cmp(a[i], b[i]);
-+
-+ if (res != 0)
-+ return res;
-+ }
-+
-+ return an - bn;
-+}
-+
-+static bool vec_is_stale(struct aa_profile **vec, int n)
-+{
-+ int i;
-+
-+ AA_BUG(!vec);
-+
-+ for (i = 0; i < n; i++) {
-+ if (profile_is_stale(vec[i]))
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static bool vec_unconfined(struct aa_profile **vec, int n)
-+{
-+ int i;
-+
-+ AA_BUG(!vec);
-+
-+ for (i = 0; i < n; i++) {
-+ if (!profile_unconfined(vec[i]))
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static int sort_cmp(const void *a, const void *b)
-+{
-+ return profile_cmp(*(struct aa_profile **)a, *(struct aa_profile **)b);
-+}
-+
-+/*
-+ * assumes vec is sorted
-+ * Assumes @vec has null terminator at vec[n], and will null terminate
-+ * vec[n - dups]
-+ */
-+static inline int unique(struct aa_profile **vec, int n)
-+{
-+ int i, pos, dups = 0;
-+
-+ AA_BUG(n < 1);
-+ AA_BUG(!vec);
-+
-+ pos = 0;
-+ for (i = 1; i < n; i++) {
-+ int res = profile_cmp(vec[pos], vec[i]);
-+
-+ AA_BUG(res > 0, "vec not sorted");
-+ if (res == 0) {
-+ /* drop duplicate */
-+ aa_put_profile(vec[i]);
-+ dups++;
-+ continue;
-+ }
-+ pos++;
-+ if (dups)
-+ vec[pos] = vec[i];
-+ }
-+
-+ AA_BUG(dups < 0);
-+
-+ return dups;
-+}
-+
-+/**
-+ * aa_vec_unique - canonical sort and unique a list of profiles
-+ * @n: number of refcounted profiles in the list (@n > 0)
-+ * @vec: list of profiles to sort and merge
-+ *
-+ * Returns: the number of duplicates eliminated == references put
-+ *
-+ * If @flags & VEC_FLAG_TERMINATE @vec has null terminator at vec[n], and will
-+ * null terminate vec[n - dups]
-+ */
-+int aa_vec_unique(struct aa_profile **vec, int n, int flags)
-+{
-+ int i, dups = 0;
-+
-+ AA_BUG(n < 1);
-+ AA_BUG(!vec);
-+
-+ /* vecs are usually small and inorder, have a fallback for larger */
-+ if (n > 8) {
-+ sort(vec, n, sizeof(struct aa_profile *), sort_cmp, NULL);
-+ dups = unique(vec, n);
-+ goto out;
-+ }
-+
-+ /* insertion sort + unique in one */
-+ for (i = 1; i < n; i++) {
-+ struct aa_profile *tmp = vec[i];
-+ int pos, j;
-+
-+ for (pos = i - 1 - dups; pos >= 0; pos--) {
-+ int res = profile_cmp(vec[pos], tmp);
-+
-+ if (res == 0) {
-+ /* drop duplicate entry */
-+ aa_put_profile(tmp);
-+ dups++;
-+ goto continue_outer;
-+ } else if (res < 0)
-+ break;
-+ }
-+ /* pos is at entry < tmp, or index -1. Set to insert pos */
-+ pos++;
-+
-+ for (j = i - dups; j > pos; j--)
-+ vec[j] = vec[j - 1];
-+ vec[pos] = tmp;
-+continue_outer:
-+ ;
-+ }
-+
-+ AA_BUG(dups < 0);
-+
-+out:
-+ if (flags & VEC_FLAG_TERMINATE)
-+ vec[n - dups] = NULL;
-+
-+ return dups;
-+}
-+
-+
-+static void label_destroy(struct aa_label *label)
-+{
-+ struct aa_label *tmp;
-+
-+ AA_BUG(!label);
-+
-+ if (!label_isprofile(label)) {
-+ struct aa_profile *profile;
-+ struct label_it i;
-+
-+ aa_put_str(label->hname);
-+
-+ label_for_each(i, label, profile) {
-+ aa_put_profile(profile);
-+ label->vec[i.i] = (struct aa_profile *)
-+ (LABEL_POISON + (long) i.i);
-+ }
-+ }
-+
-+ if (rcu_dereference_protected(label->proxy->label, true) == label)
-+ rcu_assign_pointer(label->proxy->label, NULL);
-+
-+ aa_free_secid(label->secid);
-+
-+ tmp = rcu_dereference_protected(label->proxy->label, true);
-+ if (tmp == label)
-+ rcu_assign_pointer(label->proxy->label, NULL);
-+
-+ aa_put_proxy(label->proxy);
-+ label->proxy = (struct aa_proxy *) PROXY_POISON + 1;
-+}
-+
-+void aa_label_free(struct aa_label *label)
-+{
-+ if (!label)
-+ return;
-+
-+ label_destroy(label);
-+ kfree(label);
-+}
-+
-+static void label_free_switch(struct aa_label *label)
-+{
-+ if (label->flags & FLAG_NS_COUNT)
-+ aa_free_ns(labels_ns(label));
-+ else if (label_isprofile(label))
-+ aa_free_profile(labels_profile(label));
-+ else
-+ aa_label_free(label);
-+}
-+
-+static void label_free_rcu(struct rcu_head *head)
-+{
-+ struct aa_label *label = container_of(head, struct aa_label, rcu);
-+
-+ if (label->flags & FLAG_IN_TREE)
-+ (void) aa_label_remove(label);
-+ label_free_switch(label);
-+}
-+
-+void aa_label_kref(struct kref *kref)
-+{
-+ struct aa_label *label = container_of(kref, struct aa_label, count);
-+ struct aa_ns *ns = labels_ns(label);
-+
-+ if (!ns) {
-+ /* never live, no rcu callback needed, just using the fn */
-+ label_free_switch(label);
-+ return;
-+ }
-+ /* TODO: update labels_profile macro so it works here */
-+ AA_BUG(label_isprofile(label) &&
-+ on_list_rcu(&label->vec[0]->base.profiles));
-+ AA_BUG(label_isprofile(label) &&
-+ on_list_rcu(&label->vec[0]->base.list));
-+
-+ /* TODO: if compound label and not stale add to reclaim cache */
-+ call_rcu(&label->rcu, label_free_rcu);
-+}
-+
-+static void label_free_or_put_new(struct aa_label *label, struct aa_label *new)
-+{
-+ if (label != new)
-+ /* need to free directly to break circular ref with proxy */
-+ aa_label_free(new);
-+ else
-+ aa_put_label(new);
-+}
-+
-+bool aa_label_init(struct aa_label *label, int size)
-+{
-+ AA_BUG(!label);
-+ AA_BUG(size < 1);
-+
-+ label->secid = aa_alloc_secid();
-+ if (label->secid == AA_SECID_INVALID)
-+ return false;
-+
-+ label->size = size; /* doesn't include null */
-+ label->vec[size] = NULL; /* null terminate */
-+ kref_init(&label->count);
-+ RB_CLEAR_NODE(&label->node);
-+
-+ return true;
-+}
-+
-+/**
-+ * aa_label_alloc - allocate a label with a profile vector of @size length
-+ * @size: size of profile vector in the label
-+ * @proxy: proxy to use OR null if to allocate a new one
-+ * @gfp: memory allocation type
-+ *
-+ * Returns: new label
-+ * else NULL if failed
-+ */
-+struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp)
-+{
-+ struct aa_label *new;
-+
-+ AA_BUG(size < 1);
-+
-+ /* + 1 for null terminator entry on vec */
-+ new = kzalloc(sizeof(*new) + sizeof(struct aa_profile *) * (size + 1),
-+ gfp);
-+ AA_DEBUG("%s (%p)\n", __func__, new);
-+ if (!new)
-+ goto fail;
-+
-+ if (!aa_label_init(new, size))
-+ goto fail;
-+
-+ if (!proxy) {
-+ proxy = aa_alloc_proxy(new, gfp);
-+ if (!proxy)
-+ goto fail;
-+ } else
-+ aa_get_proxy(proxy);
-+ /* just set new's proxy, don't redirect proxy here if it was passed in*/
-+ new->proxy = proxy;
-+
-+ return new;
-+
-+fail:
-+ kfree(new);
-+
-+ return NULL;
-+}
-+
-+
-+/**
-+ * label_cmp - label comparision for set ordering
-+ * @a: label to compare (NOT NULL)
-+ * @b: label to compare (NOT NULL)
-+ *
-+ * Returns: <0 if a < b
-+ * ==0 if a == b
-+ * >0 if a > b
-+ */
-+static int label_cmp(struct aa_label *a, struct aa_label *b)
-+{
-+ AA_BUG(!b);
-+
-+ if (a == b)
-+ return 0;
-+
-+ return vec_cmp(a->vec, a->size, b->vec, b->size);
-+}
-+
-+/* helper fn for label_for_each_confined */
-+int aa_label_next_confined(struct aa_label *label, int i)
-+{
-+ AA_BUG(!label);
-+ AA_BUG(i < 0);
-+
-+ for (; i < label->size; i++) {
-+ if (!profile_unconfined(label->vec[i]))
-+ return i;
-+ }
-+
-+ return i;
-+}
-+
-+/**
-+ * aa_label_next_not_in_set - return the next profile of @sub not in @set
-+ * @I: label iterator
-+ * @set: label to test against
-+ * @sub: label to if is subset of @set
-+ *
-+ * Returns: profile in @sub that is not in @set, with iterator set pos after
-+ * else NULL if @sub is a subset of @set
-+ */
-+struct aa_profile *__aa_label_next_not_in_set(struct label_it *I,
-+ struct aa_label *set,
-+ struct aa_label *sub)
-+{
-+ AA_BUG(!set);
-+ AA_BUG(!I);
-+ AA_BUG(I->i < 0);
-+ AA_BUG(I->i > set->size);
-+ AA_BUG(!sub);
-+ AA_BUG(I->j < 0);
-+ AA_BUG(I->j > sub->size);
-+
-+ while (I->j < sub->size && I->i < set->size) {
-+ int res = profile_cmp(sub->vec[I->j], set->vec[I->i]);
-+
-+ if (res == 0) {
-+ (I->j)++;
-+ (I->i)++;
-+ } else if (res > 0)
-+ (I->i)++;
-+ else
-+ return sub->vec[(I->j)++];
-+ }
-+
-+ if (I->j < sub->size)
-+ return sub->vec[(I->j)++];
-+
-+ return NULL;
-+}
-+
-+/**
-+ * aa_label_is_subset - test if @sub is a subset of @set
-+ * @set: label to test against
-+ * @sub: label to test if is subset of @set
-+ *
-+ * Returns: true if @sub is subset of @set
-+ * else false
-+ */
-+bool aa_label_is_subset(struct aa_label *set, struct aa_label *sub)
-+{
-+ struct label_it i = { };
-+
-+ AA_BUG(!set);
-+ AA_BUG(!sub);
-+
-+ if (sub == set)
-+ return true;
-+
-+ return __aa_label_next_not_in_set(&i, set, sub) == NULL;
-+}
-+
-+
-+
-+/**
-+ * __label_remove - remove @label from the label set
-+ * @l: label to remove
-+ * @new: label to redirect to
-+ *
-+ * Requires: labels_set(@label)->lock write_lock
-+ * Returns: true if the label was in the tree and removed
-+ */
-+static bool __label_remove(struct aa_label *label, struct aa_label *new)
-+{
-+ struct aa_labelset *ls = labels_set(label);
-+
-+ AA_BUG(!ls);
-+ AA_BUG(!label);
-+ AA_BUG(!write_is_locked(&ls->lock));
-+
-+ if (new)
-+ __aa_proxy_redirect(label, new);
-+
-+ if (!label_is_stale(label))
-+ __label_make_stale(label);
-+
-+ if (label->flags & FLAG_IN_TREE) {
-+ rb_erase(&label->node, &ls->root);
-+ label->flags &= ~FLAG_IN_TREE;
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+/**
-+ * __label_replace - replace @old with @new in label set
-+ * @old: label to remove from label set
-+ * @new: label to replace @old with
-+ *
-+ * Requires: labels_set(@old)->lock write_lock
-+ * valid ref count be held on @new
-+ * Returns: true if @old was in set and replaced by @new
-+ *
-+ * Note: current implementation requires label set be order in such a way
-+ * that @new directly replaces @old position in the set (ie.
-+ * using pointer comparison of the label address would not work)
-+ */
-+static bool __label_replace(struct aa_label *old, struct aa_label *new)
-+{
-+ struct aa_labelset *ls = labels_set(old);
-+
-+ AA_BUG(!ls);
-+ AA_BUG(!old);
-+ AA_BUG(!new);
-+ AA_BUG(!write_is_locked(&ls->lock));
-+ AA_BUG(new->flags & FLAG_IN_TREE);
-+
-+ if (!label_is_stale(old))
-+ __label_make_stale(old);
-+
-+ if (old->flags & FLAG_IN_TREE) {
-+ rb_replace_node(&old->node, &new->node, &ls->root);
-+ old->flags &= ~FLAG_IN_TREE;
-+ new->flags |= FLAG_IN_TREE;
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+/**
-+ * __label_insert - attempt to insert @l into a label set
-+ * @ls: set of labels to insert @l into (NOT NULL)
-+ * @label: new label to insert (NOT NULL)
-+ * @replace: whether insertion should replace existing entry that is not stale
-+ *
-+ * Requires: @ls->lock
-+ * caller to hold a valid ref on l
-+ * if @replace is true l has a preallocated proxy associated
-+ * Returns: @l if successful in inserting @l - with additional refcount
-+ * else ref counted equivalent label that is already in the set,
-+ * the else condition only happens if @replace is false
-+ */
-+static struct aa_label *__label_insert(struct aa_labelset *ls,
-+ struct aa_label *label, bool replace)
-+{
-+ struct rb_node **new, *parent = NULL;
-+
-+ AA_BUG(!ls);
-+ AA_BUG(!label);
-+ AA_BUG(labels_set(label) != ls);
-+ AA_BUG(!write_is_locked(&ls->lock));
-+ AA_BUG(label->flags & FLAG_IN_TREE);
-+
-+ /* Figure out where to put new node */
-+ new = &ls->root.rb_node;
-+ while (*new) {
-+ struct aa_label *this = rb_entry(*new, struct aa_label, node);
-+ int result = label_cmp(label, this);
-+
-+ parent = *new;
-+ if (result == 0) {
-+ /* !__aa_get_label means queued for destruction,
-+ * so replace in place, however the label has
-+ * died before the replacement so do not share
-+ * the proxy
-+ */
-+ if (!replace && !label_is_stale(this)) {
-+ if (__aa_get_label(this))
-+ return this;
-+ } else
-+ __proxy_share(this, label);
-+ AA_BUG(!__label_replace(this, label));
-+ return aa_get_label(label);
-+ } else if (result < 0)
-+ new = &((*new)->rb_left);
-+ else /* (result > 0) */
-+ new = &((*new)->rb_right);
-+ }
-+
-+ /* Add new node and rebalance tree. */
-+ rb_link_node(&label->node, parent, new);
-+ rb_insert_color(&label->node, &ls->root);
-+ label->flags |= FLAG_IN_TREE;
-+
-+ return aa_get_label(label);
-+}
-+
-+/**
-+ * __vec_find - find label that matches @vec in label set
-+ * @vec: vec of profiles to find matching label for (NOT NULL)
-+ * @n: length of @vec
-+ *
-+ * Requires: @vec_labelset(vec) lock held
-+ * caller to hold a valid ref on l
-+ *
-+ * Returns: ref counted @label if matching label is in tree
-+ * ref counted label that is equiv to @l in tree
-+ * else NULL if @vec equiv is not in tree
-+ */
-+static struct aa_label *__vec_find(struct aa_profile **vec, int n)
-+{
-+ struct rb_node *node;
-+
-+ AA_BUG(!vec);
-+ AA_BUG(!*vec);
-+ AA_BUG(n <= 0);
-+
-+ node = vec_labelset(vec, n)->root.rb_node;
-+ while (node) {
-+ struct aa_label *this = rb_entry(node, struct aa_label, node);
-+ int result = vec_cmp(this->vec, this->size, vec, n);
-+
-+ if (result > 0)
-+ node = node->rb_left;
-+ else if (result < 0)
-+ node = node->rb_right;
-+ else
-+ return __aa_get_label(this);
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * __label_find - find label @label in label set
-+ * @label: label to find (NOT NULL)
-+ *
-+ * Requires: labels_set(@label)->lock held
-+ * caller to hold a valid ref on l
-+ *
-+ * Returns: ref counted @label if @label is in tree OR
-+ * ref counted label that is equiv to @label in tree
-+ * else NULL if @label or equiv is not in tree
-+ */
-+static struct aa_label *__label_find(struct aa_label *label)
-+{
-+ AA_BUG(!label);
-+
-+ return __vec_find(label->vec, label->size);
-+}
-+
-+
-+/**
-+ * aa_label_remove - remove a label from the labelset
-+ * @label: label to remove
-+ *
-+ * Returns: true if @label was removed from the tree
-+ * else @label was not in tree so it could not be removed
-+ */
-+bool aa_label_remove(struct aa_label *label)
-+{
-+ struct aa_labelset *ls = labels_set(label);
-+ unsigned long flags;
-+ bool res;
-+
-+ AA_BUG(!ls);
-+
-+ write_lock_irqsave(&ls->lock, flags);
-+ res = __label_remove(label, ns_unconfined(labels_ns(label)));
-+ write_unlock_irqrestore(&ls->lock, flags);
-+
-+ return res;
-+}
-+
-+/**
-+ * aa_label_replace - replace a label @old with a new version @new
-+ * @old: label to replace
-+ * @new: label replacing @old
-+ *
-+ * Returns: true if @old was in tree and replaced
-+ * else @old was not in tree, and @new was not inserted
-+ */
-+bool aa_label_replace(struct aa_label *old, struct aa_label *new)
-+{
-+ unsigned long flags;
-+ bool res;
-+
-+ if (name_is_shared(old, new) && labels_ns(old) == labels_ns(new)) {
-+ write_lock_irqsave(&labels_set(old)->lock, flags);
-+ if (old->proxy != new->proxy)
-+ __proxy_share(old, new);
-+ else
-+ __aa_proxy_redirect(old, new);
-+ res = __label_replace(old, new);
-+ write_unlock_irqrestore(&labels_set(old)->lock, flags);
-+ } else {
-+ struct aa_label *l;
-+ struct aa_labelset *ls = labels_set(old);
-+
-+ write_lock_irqsave(&ls->lock, flags);
-+ res = __label_remove(old, new);
-+ if (labels_ns(old) != labels_ns(new)) {
-+ write_unlock_irqrestore(&ls->lock, flags);
-+ ls = labels_set(new);
-+ write_lock_irqsave(&ls->lock, flags);
-+ }
-+ l = __label_insert(ls, new, true);
-+ res = (l == new);
-+ write_unlock_irqrestore(&ls->lock, flags);
-+ aa_put_label(l);
-+ }
-+
-+ return res;
-+}
-+
-+/**
-+ * vec_find - find label @l in label set
-+ * @vec: array of profiles to find equiv label for (NOT NULL)
-+ * @n: length of @vec
-+ *
-+ * Returns: refcounted label if @vec equiv is in tree
-+ * else NULL if @vec equiv is not in tree
-+ */
-+static struct aa_label *vec_find(struct aa_profile **vec, int n)
-+{
-+ struct aa_labelset *ls;
-+ struct aa_label *label;
-+ unsigned long flags;
-+
-+ AA_BUG(!vec);
-+ AA_BUG(!*vec);
-+ AA_BUG(n <= 0);
-+
-+ ls = vec_labelset(vec, n);
-+ read_lock_irqsave(&ls->lock, flags);
-+ label = __vec_find(vec, n);
-+ read_unlock_irqrestore(&ls->lock, flags);
-+
-+ return label;
-+}
-+
-+/* requires sort and merge done first */
-+static struct aa_label *vec_create_and_insert_label(struct aa_profile **vec,
-+ int len, gfp_t gfp)
-+{
-+ struct aa_label *label = NULL;
-+ struct aa_labelset *ls;
-+ unsigned long flags;
-+ struct aa_label *new;
-+ int i;
-+
-+ AA_BUG(!vec);
-+
-+ if (len == 1)
-+ return aa_get_label(&vec[0]->label);
-+
-+ ls = labels_set(&vec[len - 1]->label);
-+
-+ /* TODO: enable when read side is lockless
-+ * check if label exists before taking locks
-+ */
-+ new = aa_label_alloc(len, NULL, gfp);
-+ if (!new)
-+ return NULL;
-+
-+ for (i = 0; i < len; i++)
-+ new->vec[i] = aa_get_profile(vec[i]);
-+
-+ write_lock_irqsave(&ls->lock, flags);
-+ label = __label_insert(ls, new, false);
-+ write_unlock_irqrestore(&ls->lock, flags);
-+ label_free_or_put_new(label, new);
-+
-+ return label;
-+}
-+
-+struct aa_label *aa_vec_find_or_create_label(struct aa_profile **vec, int len,
-+ gfp_t gfp)
-+{
-+ struct aa_label *label = vec_find(vec, len);
-+
-+ if (label)
-+ return label;
-+
-+ return vec_create_and_insert_label(vec, len, gfp);
-+}
-+
-+/**
-+ * aa_label_find - find label @label in label set
-+ * @label: label to find (NOT NULL)
-+ *
-+ * Requires: caller to hold a valid ref on l
-+ *
-+ * Returns: refcounted @label if @label is in tree
-+ * refcounted label that is equiv to @label in tree
-+ * else NULL if @label or equiv is not in tree
-+ */
-+struct aa_label *aa_label_find(struct aa_label *label)
-+{
-+ AA_BUG(!label);
-+
-+ return vec_find(label->vec, label->size);
-+}
-+
-+
-+/**
-+ * aa_label_insert - insert label @label into @ls or return existing label
-+ * @ls - labelset to insert @label into
-+ * @label - label to insert
-+ *
-+ * Requires: caller to hold a valid ref on @label
-+ *
-+ * Returns: ref counted @label if successful in inserting @label
-+ * else ref counted equivalent label that is already in the set
-+ */
-+struct aa_label *aa_label_insert(struct aa_labelset *ls, struct aa_label *label)
-+{
-+ struct aa_label *l;
-+ unsigned long flags;
-+
-+ AA_BUG(!ls);
-+ AA_BUG(!label);
-+
-+ /* check if label exists before taking lock */
-+ if (!label_is_stale(label)) {
-+ read_lock_irqsave(&ls->lock, flags);
-+ l = __label_find(label);
-+ read_unlock_irqrestore(&ls->lock, flags);
-+ if (l)
-+ return l;
-+ }
-+
-+ write_lock_irqsave(&ls->lock, flags);
-+ l = __label_insert(ls, label, false);
-+ write_unlock_irqrestore(&ls->lock, flags);
-+
-+ return l;
-+}
-+
-+
-+/**
-+ * aa_label_next_in_merge - find the next profile when merging @a and @b
-+ * @I: label iterator
-+ * @a: label to merge
-+ * @b: label to merge
-+ *
-+ * Returns: next profile
-+ * else null if no more profiles
-+ */
-+struct aa_profile *aa_label_next_in_merge(struct label_it *I,
-+ struct aa_label *a,
-+ struct aa_label *b)
-+{
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+ AA_BUG(!I);
-+ AA_BUG(I->i < 0);
-+ AA_BUG(I->i > a->size);
-+ AA_BUG(I->j < 0);
-+ AA_BUG(I->j > b->size);
-+
-+ if (I->i < a->size) {
-+ if (I->j < b->size) {
-+ int res = profile_cmp(a->vec[I->i], b->vec[I->j]);
-+
-+ if (res > 0)
-+ return b->vec[(I->j)++];
-+ if (res == 0)
-+ (I->j)++;
-+ }
-+
-+ return a->vec[(I->i)++];
-+ }
-+
-+ if (I->j < b->size)
-+ return b->vec[(I->j)++];
-+
-+ return NULL;
-+}
-+
-+/**
-+ * label_merge_cmp - cmp of @a merging with @b against @z for set ordering
-+ * @a: label to merge then compare (NOT NULL)
-+ * @b: label to merge then compare (NOT NULL)
-+ * @z: label to compare merge against (NOT NULL)
-+ *
-+ * Assumes: using the most recent versions of @a, @b, and @z
-+ *
-+ * Returns: <0 if a < b
-+ * ==0 if a == b
-+ * >0 if a > b
-+ */
-+static int label_merge_cmp(struct aa_label *a, struct aa_label *b,
-+ struct aa_label *z)
-+{
-+ struct aa_profile *p = NULL;
-+ struct label_it i = { };
-+ int k;
-+
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+ AA_BUG(!z);
-+
-+ for (k = 0;
-+ k < z->size && (p = aa_label_next_in_merge(&i, a, b));
-+ k++) {
-+ int res = profile_cmp(p, z->vec[k]);
-+
-+ if (res != 0)
-+ return res;
-+ }
-+
-+ if (p)
-+ return 1;
-+ else if (k < z->size)
-+ return -1;
-+ return 0;
-+}
-+
-+/**
-+ * label_merge_insert - create a new label by merging @a and @b
-+ * @new: preallocated label to merge into (NOT NULL)
-+ * @a: label to merge with @b (NOT NULL)
-+ * @b: label to merge with @a (NOT NULL)
-+ *
-+ * Requires: preallocated proxy
-+ *
-+ * Returns: ref counted label either @new if merge is unique
-+ * @a if @b is a subset of @a
-+ * @b if @a is a subset of @b
-+ *
-+ * NOTE: will not use @new if the merge results in @new == @a or @b
-+ *
-+ * Must be used within labelset write lock to avoid racing with
-+ * setting labels stale.
-+ */
-+static struct aa_label *label_merge_insert(struct aa_label *new,
-+ struct aa_label *a,
-+ struct aa_label *b)
-+{
-+ struct aa_label *label;
-+ struct aa_labelset *ls;
-+ struct aa_profile *next;
-+ struct label_it i;
-+ unsigned long flags;
-+ int k = 0, invcount = 0;
-+ bool stale = false;
-+
-+ AA_BUG(!a);
-+ AA_BUG(a->size < 0);
-+ AA_BUG(!b);
-+ AA_BUG(b->size < 0);
-+ AA_BUG(!new);
-+ AA_BUG(new->size < a->size + b->size);
-+
-+ label_for_each_in_merge(i, a, b, next) {
-+ AA_BUG(!next);
-+ if (profile_is_stale(next)) {
-+ new->vec[k] = aa_get_newest_profile(next);
-+ AA_BUG(!new->vec[k]->label.proxy);
-+ AA_BUG(!new->vec[k]->label.proxy->label);
-+ if (next->label.proxy != new->vec[k]->label.proxy)
-+ invcount++;
-+ k++;
-+ stale = true;
-+ } else
-+ new->vec[k++] = aa_get_profile(next);
-+ }
-+ /* set to actual size which is <= allocated len */
-+ new->size = k;
-+ new->vec[k] = NULL;
-+
-+ if (invcount) {
-+ new->size -= aa_vec_unique(&new->vec[0], new->size,
-+ VEC_FLAG_TERMINATE);
-+ /* TODO: deal with reference labels */
-+ if (new->size == 1) {
-+ label = aa_get_label(&new->vec[0]->label);
-+ return label;
-+ }
-+ } else if (!stale) {
-+ /*
-+ * merge could be same as a || b, note: it is not possible
-+ * for new->size == a->size == b->size unless a == b
-+ */
-+ if (k == a->size)
-+ return aa_get_label(a);
-+ else if (k == b->size)
-+ return aa_get_label(b);
-+ }
-+ if (vec_unconfined(new->vec, new->size))
-+ new->flags |= FLAG_UNCONFINED;
-+ ls = labels_set(new);
-+ write_lock_irqsave(&ls->lock, flags);
-+ label = __label_insert(labels_set(new), new, false);
-+ write_unlock_irqrestore(&ls->lock, flags);
-+
-+ return label;
-+}
-+
-+/**
-+ * labelset_of_merge - find which labelset a merged label should be inserted
-+ * @a: label to merge and insert
-+ * @b: label to merge and insert
-+ *
-+ * Returns: labelset that the merged label should be inserted into
-+ */
-+static struct aa_labelset *labelset_of_merge(struct aa_label *a,
-+ struct aa_label *b)
-+{
-+ struct aa_ns *nsa = labels_ns(a);
-+ struct aa_ns *nsb = labels_ns(b);
-+
-+ if (ns_cmp(nsa, nsb) <= 0)
-+ return &nsa->labels;
-+ return &nsb->labels;
-+}
-+
-+/**
-+ * __label_find_merge - find label that is equiv to merge of @a and @b
-+ * @ls: set of labels to search (NOT NULL)
-+ * @a: label to merge with @b (NOT NULL)
-+ * @b: label to merge with @a (NOT NULL)
-+ *
-+ * Requires: ls->lock read_lock held
-+ *
-+ * Returns: ref counted label that is equiv to merge of @a and @b
-+ * else NULL if merge of @a and @b is not in set
-+ */
-+static struct aa_label *__label_find_merge(struct aa_labelset *ls,
-+ struct aa_label *a,
-+ struct aa_label *b)
-+{
-+ struct rb_node *node;
-+
-+ AA_BUG(!ls);
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+
-+ if (a == b)
-+ return __label_find(a);
-+
-+ node = ls->root.rb_node;
-+ while (node) {
-+ struct aa_label *this = container_of(node, struct aa_label,
-+ node);
-+ int result = label_merge_cmp(a, b, this);
-+
-+ if (result < 0)
-+ node = node->rb_left;
-+ else if (result > 0)
-+ node = node->rb_right;
-+ else
-+ return __aa_get_label(this);
-+ }
-+
-+ return NULL;
-+}
-+
-+
-+/**
-+ * aa_label_find_merge - find label that is equiv to merge of @a and @b
-+ * @a: label to merge with @b (NOT NULL)
-+ * @b: label to merge with @a (NOT NULL)
-+ *
-+ * Requires: labels be fully constructed with a valid ns
-+ *
-+ * Returns: ref counted label that is equiv to merge of @a and @b
-+ * else NULL if merge of @a and @b is not in set
-+ */
-+struct aa_label *aa_label_find_merge(struct aa_label *a, struct aa_label *b)
-+{
-+ struct aa_labelset *ls;
-+ struct aa_label *label, *ar = NULL, *br = NULL;
-+ unsigned long flags;
-+
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+
-+ if (label_is_stale(a))
-+ a = ar = aa_get_newest_label(a);
-+ if (label_is_stale(b))
-+ b = br = aa_get_newest_label(b);
-+ ls = labelset_of_merge(a, b);
-+ read_lock_irqsave(&ls->lock, flags);
-+ label = __label_find_merge(ls, a, b);
-+ read_unlock_irqrestore(&ls->lock, flags);
-+ aa_put_label(ar);
-+ aa_put_label(br);
-+
-+ return label;
-+}
-+
-+/**
-+ * aa_label_merge - attempt to insert new merged label of @a and @b
-+ * @ls: set of labels to insert label into (NOT NULL)
-+ * @a: label to merge with @b (NOT NULL)
-+ * @b: label to merge with @a (NOT NULL)
-+ * @gfp: memory allocation type
-+ *
-+ * Requires: caller to hold valid refs on @a and @b
-+ * labels be fully constructed with a valid ns
-+ *
-+ * Returns: ref counted new label if successful in inserting merge of a & b
-+ * else ref counted equivalent label that is already in the set.
-+ * else NULL if could not create label (-ENOMEM)
-+ */
-+struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
-+ gfp_t gfp)
-+{
-+ struct aa_label *label = NULL;
-+
-+ AA_BUG(!a);
-+ AA_BUG(!b);
-+
-+ if (a == b)
-+ return aa_get_newest_label(a);
-+
-+ /* TODO: enable when read side is lockless
-+ * check if label exists before taking locks
-+ if (!label_is_stale(a) && !label_is_stale(b))
-+ label = aa_label_find_merge(a, b);
-+ */
-+
-+ if (!label) {
-+ struct aa_label *new;
-+
-+ a = aa_get_newest_label(a);
-+ b = aa_get_newest_label(b);
-+
-+ /* could use label_merge_len(a, b), but requires double
-+ * comparison for small savings
-+ */
-+ new = aa_label_alloc(a->size + b->size, NULL, gfp);
-+ if (!new)
-+ goto out;
-+
-+ label = label_merge_insert(new, a, b);
-+ label_free_or_put_new(label, new);
-+out:
-+ aa_put_label(a);
-+ aa_put_label(b);
-+ }
-+
-+ return label;
-+}
-+
-+static inline bool label_is_visible(struct aa_profile *profile,
-+ struct aa_label *label)
-+{
-+ return aa_ns_visible(profile->ns, labels_ns(label), true);
-+}
-+
-+/* match a profile and its associated ns component if needed
-+ * Assumes visibility test has already been done.
-+ * If a subns profile is not to be matched should be prescreened with
-+ * visibility test.
-+ */
-+static inline unsigned int match_component(struct aa_profile *profile,
-+ struct aa_profile *tp,
-+ unsigned int state)
-+{
-+ const char *ns_name;
-+
-+ if (profile->ns == tp->ns)
-+ return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
-+
-+ /* try matching with namespace name and then profile */
-+ ns_name = aa_ns_name(profile->ns, tp->ns, true);
-+ state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
-+ state = aa_dfa_match(profile->policy.dfa, state, ns_name);
-+ state = aa_dfa_match_len(profile->policy.dfa, state, ":", 1);
-+ return aa_dfa_match(profile->policy.dfa, state, tp->base.hname);
-+}
-+
-+/**
-+ * label_compound_match - find perms for full compound label
-+ * @profile: profile to find perms for
-+ * @label: label to check access permissions for
-+ * @start: state to start match in
-+ * @subns: whether to do permission checks on components in a subns
-+ * @request: permissions to request
-+ * @perms: perms struct to set
-+ *
-+ * Returns: 0 on success else ERROR
-+ *
-+ * For the label A//&B//&C this does the perm match for A//&B//&C
-+ * @perms should be preinitialized with allperms OR a previous permission
-+ * check to be stacked.
-+ */
-+static int label_compound_match(struct aa_profile *profile,
-+ struct aa_label *label,
-+ unsigned int state, bool subns, u32 request,
-+ struct aa_perms *perms)
-+{
-+ struct aa_profile *tp;
-+ struct label_it i;
-+
-+ /* find first subcomponent that is visible */
-+ label_for_each(i, label, tp) {
-+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
-+ continue;
-+ state = match_component(profile, tp, state);
-+ if (!state)
-+ goto fail;
-+ goto next;
-+ }
-+
-+ /* no component visible */
-+ *perms = allperms;
-+ return 0;
-+
-+next:
-+ label_for_each_cont(i, label, tp) {
-+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
-+ continue;
-+ state = aa_dfa_match(profile->policy.dfa, state, "//&");
-+ state = match_component(profile, tp, state);
-+ if (!state)
-+ goto fail;
-+ }
-+ aa_compute_perms(profile->policy.dfa, state, perms);
-+ aa_apply_modes_to_perms(profile, perms);
-+ if ((perms->allow & request) != request)
-+ return -EACCES;
-+
-+ return 0;
-+
-+fail:
-+ *perms = nullperms;
-+ return state;
-+}
-+
-+/**
-+ * label_components_match - find perms for all subcomponents of a label
-+ * @profile: profile to find perms for
-+ * @label: label to check access permissions for
-+ * @start: state to start match in
-+ * @subns: whether to do permission checks on components in a subns
-+ * @request: permissions to request
-+ * @perms: an initialized perms struct to add accumulation to
-+ *
-+ * Returns: 0 on success else ERROR
-+ *
-+ * For the label A//&B//&C this does the perm match for each of A and B and C
-+ * @perms should be preinitialized with allperms OR a previous permission
-+ * check to be stacked.
-+ */
-+static int label_components_match(struct aa_profile *profile,
-+ struct aa_label *label, unsigned int start,
-+ bool subns, u32 request,
-+ struct aa_perms *perms)
-+{
-+ struct aa_profile *tp;
-+ struct label_it i;
-+ struct aa_perms tmp;
-+ unsigned int state = 0;
-+
-+ /* find first subcomponent to test */
-+ label_for_each(i, label, tp) {
-+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
-+ continue;
-+ state = match_component(profile, tp, start);
-+ if (!state)
-+ goto fail;
-+ goto next;
-+ }
-+
-+ /* no subcomponents visible - no change in perms */
-+ return 0;
-+
-+next:
-+ aa_compute_perms(profile->policy.dfa, state, &tmp);
-+ aa_apply_modes_to_perms(profile, &tmp);
-+ aa_perms_accum(perms, &tmp);
-+ label_for_each_cont(i, label, tp) {
-+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
-+ continue;
-+ state = match_component(profile, tp, start);
-+ if (!state)
-+ goto fail;
-+ aa_compute_perms(profile->policy.dfa, state, &tmp);
-+ aa_apply_modes_to_perms(profile, &tmp);
-+ aa_perms_accum(perms, &tmp);
-+ }
-+
-+ if ((perms->allow & request) != request)
-+ return -EACCES;
-+
-+ return 0;
-+
-+fail:
-+ *perms = nullperms;
-+ return -EACCES;
-+}
-+
-+/**
-+ * aa_label_match - do a multi-component label match
-+ * @profile: profile to match against (NOT NULL)
-+ * @label: label to match (NOT NULL)
-+ * @state: state to start in
-+ * @subns: whether to match subns components
-+ * @request: permission request
-+ * @perms: Returns computed perms (NOT NULL)
-+ *
-+ * Returns: the state the match finished in, may be the none matching state
-+ */
-+int aa_label_match(struct aa_profile *profile, struct aa_label *label,
-+ unsigned int state, bool subns, u32 request,
-+ struct aa_perms *perms)
-+{
-+ int error = label_compound_match(profile, label, state, subns, request,
-+ perms);
-+ if (!error)
-+ return error;
-+
-+ *perms = allperms;
-+ return label_components_match(profile, label, state, subns, request,
-+ perms);
-+}
-+
-+
-+/**
-+ * aa_update_label_name - update a label to have a stored name
-+ * @ns: ns being viewed from (NOT NULL)
-+ * @label: label to update (NOT NULL)
-+ * @gfp: type of memory allocation
-+ *
-+ * Requires: labels_set(label) not locked in caller
-+ *
-+ * note: only updates the label name if it does not have a name already
-+ * and if it is in the labelset
-+ */
-+bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp)
-+{
-+ struct aa_labelset *ls;
-+ unsigned long flags;
-+ char __counted *name;
-+ bool res = false;
-+
-+ AA_BUG(!ns);
-+ AA_BUG(!label);
-+
-+ if (label->hname || labels_ns(label) != ns)
-+ return res;
-+
-+ if (aa_label_acntsxprint(&name, ns, label, FLAGS_NONE, gfp) == -1)
-+ return res;
-+
-+ ls = labels_set(label);
-+ write_lock_irqsave(&ls->lock, flags);
-+ if (!label->hname && label->flags & FLAG_IN_TREE) {
-+ label->hname = name;
-+ res = true;
-+ } else
-+ aa_put_str(name);
-+ write_unlock_irqrestore(&ls->lock, flags);
-+
-+ return res;
-+}
-+
-+/*
-+ * cached label name is present and visible
-+ * @label->hname only exists if label is namespace hierachical
-+ */
-+static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label)
-+{
-+ if (label->hname && labels_ns(label) == ns)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* helper macro for snprint routines */
-+#define update_for_len(total, len, size, str) \
-+do { \
-+ AA_BUG(len < 0); \
-+ total += len; \
-+ len = min(len, size); \
-+ size -= len; \
-+ str += len; \
-+} while (0)
-+
-+/**
-+ * aa_profile_snxprint - print a profile name to a buffer
-+ * @str: buffer to write to. (MAY BE NULL if @size == 0)
-+ * @size: size of buffer
-+ * @view: namespace profile is being viewed from
-+ * @profile: profile to view (NOT NULL)
-+ * @flags: whether to include the mode string
-+ * @prev_ns: last ns printed when used in compound print
-+ *
-+ * Returns: size of name written or would be written if larger than
-+ * available buffer
-+ *
-+ * Note: will not print anything if the profile is not visible
-+ */
-+static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view,
-+ struct aa_profile *profile, int flags,
-+ struct aa_ns **prev_ns)
-+{
-+ const char *ns_name = NULL;
-+
-+ AA_BUG(!str && size != 0);
-+ AA_BUG(!profile);
-+
-+ if (!view)
-+ view = profiles_ns(profile);
-+
-+ if (view != profile->ns &&
-+ (!prev_ns || (prev_ns && *prev_ns != profile->ns))) {
-+ if (prev_ns)
-+ *prev_ns = profile->ns;
-+ ns_name = aa_ns_name(view, profile->ns,
-+ flags & FLAG_VIEW_SUBNS);
-+ if (ns_name == aa_hidden_ns_name) {
-+ if (flags & FLAG_HIDDEN_UNCONFINED)
-+ return snprintf(str, size, "%s", "unconfined");
-+ return snprintf(str, size, "%s", ns_name);
-+ }
-+ }
-+
-+ if ((flags & FLAG_SHOW_MODE) && profile != profile->ns->unconfined) {
-+ const char *modestr = aa_profile_mode_names[profile->mode];
-+
-+ if (ns_name)
-+ return snprintf(str, size, ":%s:%s (%s)", ns_name,
-+ profile->base.hname, modestr);
-+ return snprintf(str, size, "%s (%s)", profile->base.hname,
-+ modestr);
-+ }
-+
-+ if (ns_name)
-+ return snprintf(str, size, ":%s:%s", ns_name,
-+ profile->base.hname);
-+ return snprintf(str, size, "%s", profile->base.hname);
-+}
-+
-+static const char *label_modename(struct aa_ns *ns, struct aa_label *label,
-+ int flags)
-+{
-+ struct aa_profile *profile;
-+ struct label_it i;
-+ int mode = -1, count = 0;
-+
-+ label_for_each(i, label, profile) {
-+ if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
-+ if (profile->mode == APPARMOR_UNCONFINED)
-+ /* special case unconfined so stacks with
-+ * unconfined don't report as mixed. ie.
-+ * profile_foo//&:ns1:unconfined (mixed)
-+ */
-+ continue;
-+ count++;
-+ if (mode == -1)
-+ mode = profile->mode;
-+ else if (mode != profile->mode)
-+ return "mixed";
-+ }
-+ }
-+
-+ if (count == 0)
-+ return "-";
-+ if (mode == -1)
-+ /* everything was unconfined */
-+ mode = APPARMOR_UNCONFINED;
-+
-+ return aa_profile_mode_names[mode];
-+}
-+
-+/* if any visible label is not unconfined the display_mode returns true */
-+static inline bool display_mode(struct aa_ns *ns, struct aa_label *label,
-+ int flags)
-+{
-+ if ((flags & FLAG_SHOW_MODE)) {
-+ struct aa_profile *profile;
-+ struct label_it i;
-+
-+ label_for_each(i, label, profile) {
-+ if (aa_ns_visible(ns, profile->ns,
-+ flags & FLAG_VIEW_SUBNS) &&
-+ profile != profile->ns->unconfined)
-+ return true;
-+ }
-+ /* only ns->unconfined in set of profiles in ns */
-+ return false;
-+ }
-+
-+ return false;
-+}
-+
-+/**
-+ * aa_label_snxprint - print a label name to a string buffer
-+ * @str: buffer to write to. (MAY BE NULL if @size == 0)
-+ * @size: size of buffer
-+ * @ns: namespace profile is being viewed from
-+ * @label: label to view (NOT NULL)
-+ * @flags: whether to include the mode string
-+ *
-+ * Returns: size of name written or would be written if larger than
-+ * available buffer
-+ *
-+ * Note: labels do not have to be strictly hierarchical to the ns as
-+ * objects may be shared across different namespaces and thus
-+ * pickup labeling from each ns. If a particular part of the
-+ * label is not visible it will just be excluded. And if none
-+ * of the label is visible "---" will be used.
-+ */
-+int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns,
-+ struct aa_label *label, int flags)
-+{
-+ struct aa_profile *profile;
-+ struct aa_ns *prev_ns = NULL;
-+ struct label_it i;
-+ int count = 0, total = 0;
-+ size_t len;
-+
-+ AA_BUG(!str && size != 0);
-+ AA_BUG(!label);
-+
-+ if (!ns)
-+ ns = labels_ns(label);
-+
-+ label_for_each(i, label, profile) {
-+ if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) {
-+ if (count > 0) {
-+ len = snprintf(str, size, "//&");
-+ update_for_len(total, len, size, str);
-+ }
-+ len = aa_profile_snxprint(str, size, ns, profile,
-+ flags & FLAG_VIEW_SUBNS,
-+ &prev_ns);
-+ update_for_len(total, len, size, str);
-+ count++;
-+ }
-+ }
-+
-+ if (count == 0) {
-+ if (flags & FLAG_HIDDEN_UNCONFINED)
-+ return snprintf(str, size, "%s", "unconfined");
-+ return snprintf(str, size, "%s", aa_hidden_ns_name);
-+ }
-+
-+ /* count == 1 && ... is for backwards compat where the mode
-+ * is not displayed for 'unconfined' in the current ns
-+ */
-+ if (display_mode(ns, label, flags)) {
-+ len = snprintf(str, size, " (%s)",
-+ label_modename(ns, label, flags));
-+ update_for_len(total, len, size, str);
-+ }
-+
-+ return total;
-+}
-+#undef update_for_len
-+
-+/**
-+ * aa_label_asxprint - allocate a string buffer and print label into it
-+ * @strp: Returns - the allocated buffer with the label name. (NOT NULL)
-+ * @ns: namespace profile is being viewed from
-+ * @label: label to view (NOT NULL)
-+ * @flags: flags controlling what label info is printed
-+ * @gfp: kernel memory allocation type
-+ *
-+ * Returns: size of name written or would be written if larger than
-+ * available buffer
-+ */
-+int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
-+ int flags, gfp_t gfp)
-+{
-+ int size;
-+
-+ AA_BUG(!strp);
-+ AA_BUG(!label);
-+
-+ size = aa_label_snxprint(NULL, 0, ns, label, flags);
-+ if (size < 0)
-+ return size;
-+
-+ *strp = kmalloc(size + 1, gfp);
-+ if (!*strp)
-+ return -ENOMEM;
-+ return aa_label_snxprint(*strp, size + 1, ns, label, flags);
-+}
-+
-+/**
-+ * aa_label_acntsxprint - allocate a __counted string buffer and print label
-+ * @strp: buffer to write to. (MAY BE NULL if @size == 0)
-+ * @ns: namespace profile is being viewed from
-+ * @label: label to view (NOT NULL)
-+ * @flags: flags controlling what label info is printed
-+ * @gfp: kernel memory allocation type
-+ *
-+ * Returns: size of name written or would be written if larger than
-+ * available buffer
-+ */
-+int aa_label_acntsxprint(char __counted **strp, struct aa_ns *ns,
-+ struct aa_label *label, int flags, gfp_t gfp)
-+{
-+ int size;
-+
-+ AA_BUG(!strp);
-+ AA_BUG(!label);
-+
-+ size = aa_label_snxprint(NULL, 0, ns, label, flags);
-+ if (size < 0)
-+ return size;
-+
-+ *strp = aa_str_alloc(size + 1, gfp);
-+ if (!*strp)
-+ return -ENOMEM;
-+ return aa_label_snxprint(*strp, size + 1, ns, label, flags);
-+}
-+
-+
-+void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns,
-+ struct aa_label *label, int flags, gfp_t gfp)
-+{
-+ const char *str;
-+ char *name = NULL;
-+ int len;
-+
-+ AA_BUG(!ab);
-+ AA_BUG(!label);
-+
-+ if (!ns)
-+ ns = labels_ns(label);
-+
-+ if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) {
-+ len = aa_label_asxprint(&name, ns, label, flags, gfp);
-+ if (len == -1) {
-+ AA_DEBUG("label print error");
-+ return;
-+ }
-+ str = name;
-+ } else {
-+ str = (char *) label->hname;
-+ len = strlen(str);
-+ }
-+ if (audit_string_contains_control(str, len))
-+ audit_log_n_hex(ab, str, len);
-+ else
-+ audit_log_n_string(ab, str, len);
-+
-+ kfree(name);
-+}
-+
-+void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns,
-+ struct aa_label *label, int flags, gfp_t gfp)
-+{
-+ AA_BUG(!f);
-+ AA_BUG(!label);
-+
-+ if (!ns)
-+ ns = labels_ns(label);
-+
-+ if (!use_label_hname(ns, label)) {
-+ char *str;
-+ int len;
-+
-+ len = aa_label_asxprint(&str, ns, label, flags, gfp);
-+ if (len == -1) {
-+ AA_DEBUG("label print error");
-+ return;
-+ }
-+ seq_printf(f, "%s", str);
-+ kfree(str);
-+ } else if (display_mode(ns, label, flags))
-+ seq_printf(f, "%s (%s)", label->hname,
-+ label_modename(ns, label, flags));
-+ else
-+ seq_printf(f, "%s", label->hname);
-+}
-+
-+void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags,
-+ gfp_t gfp)
-+{
-+ AA_BUG(!label);
-+
-+ if (!ns)
-+ ns = labels_ns(label);
-+
-+ if (!use_label_hname(ns, label)) {
-+ char *str;
-+ int len;
-+
-+ len = aa_label_asxprint(&str, ns, label, flags, gfp);
-+ if (len == -1) {
-+ AA_DEBUG("label print error");
-+ return;
-+ }
-+ pr_info("%s", str);
-+ kfree(str);
-+ } else if (display_mode(ns, label, flags))
-+ pr_info("%s (%s)", label->hname,
-+ label_modename(ns, label, flags));
-+ else
-+ pr_info("%s", label->hname);
-+}
-+
-+void aa_label_audit(struct audit_buffer *ab, struct aa_label *label, gfp_t gfp)
-+{
-+ struct aa_ns *ns = aa_get_current_ns();
-+
-+ aa_label_xaudit(ab, ns, label, FLAG_VIEW_SUBNS, gfp);
-+ aa_put_ns(ns);
-+}
-+
-+void aa_label_seq_print(struct seq_file *f, struct aa_label *label, gfp_t gfp)
-+{
-+ struct aa_ns *ns = aa_get_current_ns();
-+
-+ aa_label_seq_xprint(f, ns, label, FLAG_VIEW_SUBNS, gfp);
-+ aa_put_ns(ns);
-+}
-+
-+void aa_label_printk(struct aa_label *label, gfp_t gfp)
-+{
-+ struct aa_ns *ns = aa_get_current_ns();
-+
-+ aa_label_xprintk(ns, label, FLAG_VIEW_SUBNS, gfp);
-+ aa_put_ns(ns);
-+}
-+
-+static int label_count_str_entries(const char *str)
-+{
-+ const char *split;
-+ int count = 1;
-+
-+ AA_BUG(!str);
-+
-+ for (split = strstr(str, "//&"); split; split = strstr(str, "//&")) {
-+ count++;
-+ str = split + 3;
-+ }
-+
-+ return count;
-+}
-+
-+/*
-+ * ensure stacks with components like
-+ * :ns:A//&B
-+ * have :ns: applied to both 'A' and 'B' by making the lookup relative
-+ * to the base if the lookup specifies an ns, else making the stacked lookup
-+ * relative to the last embedded ns in the string.
-+ */
-+static struct aa_profile *fqlookupn_profile(struct aa_label *base,
-+ struct aa_label *currentbase,
-+ const char *str, size_t n)
-+{
-+ const char *first = skipn_spaces(str, n);
-+
-+ if (first && *first == ':')
-+ return aa_fqlookupn_profile(base, str, n);
-+
-+ return aa_fqlookupn_profile(currentbase, str, n);
-+}
-+
-+/**
-+ * aa_label_parse - parse, validate and convert a text string to a label
-+ * @base: base label to use for lookups (NOT NULL)
-+ * @str: null terminated text string (NOT NULL)
-+ * @gfp: allocation type
-+ * @create: true if should create compound labels if they don't exist
-+ * @force_stack: true if should stack even if no leading &
-+ *
-+ * Returns: the matching refcounted label if present
-+ * else ERRPTR
-+ */
-+struct aa_label *aa_label_parse(struct aa_label *base, const char *str,
-+ gfp_t gfp, bool create, bool force_stack)
-+{
-+ DEFINE_VEC(profile, vec);
-+ struct aa_label *label, *currbase = base;
-+ int i, len, stack = 0, error;
-+ char *split;
-+
-+ AA_BUG(!base);
-+ AA_BUG(!str);
-+
-+ str = skip_spaces(str);
-+ len = label_count_str_entries(str);
-+ if (*str == '&' || force_stack) {
-+ /* stack on top of base */
-+ stack = base->size;
-+ len += stack;
-+ if (*str == '&')
-+ str++;
-+ }
-+ error = vec_setup(profile, vec, len, gfp);
-+ if (error)
-+ return ERR_PTR(error);
-+
-+ for (i = 0; i < stack; i++)
-+ vec[i] = aa_get_profile(base->vec[i]);
-+
-+ for (split = strstr(str, "//&"), i = stack; split && i < len; i++) {
-+ vec[i] = fqlookupn_profile(base, currbase, str, split - str);
-+ if (!vec[i])
-+ goto fail;
-+ /*
-+ * if component specified a new ns it becomes the new base
-+ * so that subsequent lookups are relative to it
-+ */
-+ if (vec[i]->ns != labels_ns(currbase))
-+ currbase = &vec[i]->label;
-+ str = split + 3;
-+ split = strstr(str, "//&");
-+ }
-+ /* last element doesn't have a split */
-+ if (i < len) {
-+ vec[i] = fqlookupn_profile(base, currbase, str, strlen(str));
-+ if (!vec[i])
-+ goto fail;
-+ }
-+ if (len == 1)
-+ /* no need to free vec as len < LOCAL_VEC_ENTRIES */
-+ return &vec[0]->label;
-+
-+ len -= aa_vec_unique(vec, len, VEC_FLAG_TERMINATE);
-+ /* TODO: deal with reference labels */
-+ if (len == 1) {
-+ label = aa_get_label(&vec[0]->label);
-+ goto out;
-+ }
-+
-+ if (create)
-+ label = aa_vec_find_or_create_label(vec, len, gfp);
-+ else
-+ label = vec_find(vec, len);
-+ if (!label)
-+ goto fail;
-+
-+out:
-+ /* use adjusted len from after vec_unique, not original */
-+ vec_cleanup(profile, vec, len);
-+ return label;
-+
-+fail:
-+ label = ERR_PTR(-ENOENT);
-+ goto out;
-+}
-+
-+
-+/**
-+ * aa_labelset_destroy - remove all labels from the label set
-+ * @ls: label set to cleanup (NOT NULL)
-+ *
-+ * Labels that are removed from the set may still exist beyond the set
-+ * being destroyed depending on their reference counting
-+ */
-+void aa_labelset_destroy(struct aa_labelset *ls)
-+{
-+ struct rb_node *node;
-+ unsigned long flags;
-+
-+ AA_BUG(!ls);
-+
-+ write_lock_irqsave(&ls->lock, flags);
-+ for (node = rb_first(&ls->root); node; node = rb_first(&ls->root)) {
-+ struct aa_label *this = rb_entry(node, struct aa_label, node);
-+
-+ if (labels_ns(this) != root_ns)
-+ __label_remove(this,
-+ ns_unconfined(labels_ns(this)->parent));
-+ else
-+ __label_remove(this, NULL);
-+ }
-+ write_unlock_irqrestore(&ls->lock, flags);
-+}
-+
-+/*
-+ * @ls: labelset to init (NOT NULL)
-+ */
-+void aa_labelset_init(struct aa_labelset *ls)
-+{
-+ AA_BUG(!ls);
-+
-+ rwlock_init(&ls->lock);
-+ ls->root = RB_ROOT;
-+}
-+
-+static struct aa_label *labelset_next_stale(struct aa_labelset *ls)
-+{
-+ struct aa_label *label;
-+ struct rb_node *node;
-+ unsigned long flags;
-+
-+ AA_BUG(!ls);
-+
-+ read_lock_irqsave(&ls->lock, flags);
-+
-+ __labelset_for_each(ls, node) {
-+ label = rb_entry(node, struct aa_label, node);
-+ if ((label_is_stale(label) ||
-+ vec_is_stale(label->vec, label->size)) &&
-+ __aa_get_label(label))
-+ goto out;
-+
-+ }
-+ label = NULL;
-+
-+out:
-+ read_unlock_irqrestore(&ls->lock, flags);
-+
-+ return label;
-+}
-+
-+/**
-+ * __label_update - insert updated version of @label into labelset
-+ * @label - the label to update/repace
-+ *
-+ * Returns: new label that is up to date
-+ * else NULL on failure
-+ *
-+ * Requires: @ns lock be held
-+ *
-+ * Note: worst case is the stale @label does not get updated and has
-+ * to be updated at a later time.
-+ */
-+static struct aa_label *__label_update(struct aa_label *label)
-+{
-+ struct aa_label *new, *tmp;
-+ struct aa_labelset *ls;
-+ unsigned long flags;
-+ int i, invcount = 0;
-+
-+ AA_BUG(!label);
-+ AA_BUG(!mutex_is_locked(&labels_ns(label)->lock));
-+
-+ new = aa_label_alloc(label->size, label->proxy, GFP_KERNEL);
-+ if (!new)
-+ return NULL;
-+
-+ /*
-+ * while holding the ns_lock will stop profile replacement, removal,
-+ * and label updates, label merging and removal can be occurring
-+ */
-+ ls = labels_set(label);
-+ write_lock_irqsave(&ls->lock, flags);
-+ for (i = 0; i < label->size; i++) {
-+ AA_BUG(!label->vec[i]);
-+ new->vec[i] = aa_get_newest_profile(label->vec[i]);
-+ AA_BUG(!new->vec[i]);
-+ AA_BUG(!new->vec[i]->label.proxy);
-+ AA_BUG(!new->vec[i]->label.proxy->label);
-+ if (new->vec[i]->label.proxy != label->vec[i]->label.proxy)
-+ invcount++;
-+ }
-+
-+ /* updated stale label by being removed/renamed from labelset */
-+ if (invcount) {
-+ new->size -= aa_vec_unique(&new->vec[0], new->size,
-+ VEC_FLAG_TERMINATE);
-+ /* TODO: deal with reference labels */
-+ if (new->size == 1) {
-+ tmp = aa_get_label(&new->vec[0]->label);
-+ AA_BUG(tmp == label);
-+ goto remove;
-+ }
-+ if (labels_set(label) != labels_set(new)) {
-+ write_unlock_irqrestore(&ls->lock, flags);
-+ tmp = aa_label_insert(labels_set(new), new);
-+ write_lock_irqsave(&ls->lock, flags);
-+ goto remove;
-+ }
-+ } else
-+ AA_BUG(labels_ns(label) != labels_ns(new));
-+
-+ tmp = __label_insert(labels_set(label), new, true);
-+remove:
-+ /* ensure label is removed, and redirected correctly */
-+ __label_remove(label, tmp);
-+ write_unlock_irqrestore(&ls->lock, flags);
-+ label_free_or_put_new(tmp, new);
-+
-+ return tmp;
-+}
-+
-+/**
-+ * __labelset_update - update labels in @ns
-+ * @ns: namespace to update labels in (NOT NULL)
-+ *
-+ * Requires: @ns lock be held
-+ *
-+ * Walk the labelset ensuring that all labels are up to date and valid
-+ * Any label that has a stale component is marked stale and replaced and
-+ * by an updated version.
-+ *
-+ * If failures happen due to memory pressures then stale labels will
-+ * be left in place until the next pass.
-+ */
-+static void __labelset_update(struct aa_ns *ns)
-+{
-+ struct aa_label *label;
-+
-+ AA_BUG(!ns);
-+ AA_BUG(!mutex_is_locked(&ns->lock));
-+
-+ do {
-+ label = labelset_next_stale(&ns->labels);
-+ if (label) {
-+ struct aa_label *l = __label_update(label);
-+
-+ aa_put_label(l);
-+ aa_put_label(label);
-+ }
-+ } while (label);
-+}
-+
-+/**
-+ * __aa_labelset_udate_subtree - update all labels with a stale component
-+ * @ns: ns to start update at (NOT NULL)
-+ *
-+ * Requires: @ns lock be held
-+ *
-+ * Invalidates labels based on @p in @ns and any children namespaces.
-+ */
-+void __aa_labelset_update_subtree(struct aa_ns *ns)
-+{
-+ struct aa_ns *child;
-+
-+ AA_BUG(!ns);
-+ AA_BUG(!mutex_is_locked(&ns->lock));
-+
-+ __labelset_update(ns);
-+
-+ list_for_each_entry(child, &ns->sub_ns, base.list) {
-+ mutex_lock(&child->lock);
-+ __aa_labelset_update_subtree(child);
-+ mutex_unlock(&child->lock);
-+ }
-+}
---
-2.12.3
-
diff --git a/patches.apparmor/0044-apparmor-switch-from-profiles-to-using-labels-on-con.patch b/patches.apparmor/0044-apparmor-switch-from-profiles-to-using-labels-on-con.patch
deleted file mode 100644
index 0bc217d0ce..0000000000
--- a/patches.apparmor/0044-apparmor-switch-from-profiles-to-using-labels-on-con.patch
+++ /dev/null
@@ -1,2908 +0,0 @@
-From b8091427b679f9536316bca6a61ba747226b7ada Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 08:14:28 -0700
-Subject: [PATCH 44/65] apparmor: switch from profiles to using labels on
- contexts
-Git-commit: 637f688dc3dc304a89f441d76f49a0e35bc49c08
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Begin the actual switch to using domain labels by storing them on
-the context and converting the label to a singular profile where
-possible.
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/Makefile | 2 +-
- security/apparmor/apparmorfs.c | 128 +++++++++++----------
- security/apparmor/audit.c | 27 +++--
- security/apparmor/context.c | 87 +++++++-------
- security/apparmor/domain.c | 77 +++++++------
- security/apparmor/file.c | 18 +--
- security/apparmor/include/apparmor.h | 5 +-
- security/apparmor/include/audit.h | 9 +-
- security/apparmor/include/context.h | 158 +++++++++++++-------------
- security/apparmor/include/perms.h | 12 +-
- security/apparmor/include/policy.h | 110 ++++++------------
- security/apparmor/include/policy_ns.h | 4 +
- security/apparmor/ipc.c | 29 +++--
- security/apparmor/lib.c | 163 ++++++++++++++++++++++++++
- security/apparmor/lsm.c | 134 ++++++++++++----------
- security/apparmor/policy.c | 208 +++++++++++++++-------------------
- security/apparmor/policy_ns.c | 20 +++-
- security/apparmor/policy_unpack.c | 12 +-
- security/apparmor/procattr.c | 4 +-
- security/apparmor/resource.c | 8 +-
- 20 files changed, 686 insertions(+), 529 deletions(-)
-
-diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
-index b3e7c04b7e7b..a16b195274de 100644
---- a/security/apparmor/Makefile
-+++ b/security/apparmor/Makefile
-@@ -4,7 +4,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
-
- apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \
- path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
-- resource.o secid.o file.o policy_ns.o
-+ resource.o secid.o file.o policy_ns.o label.o
- apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
-
- clean-files := capability_names.h rlim_names.h
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index e2919a0766b0..976af6da45c3 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -405,26 +405,26 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
- static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
- loff_t *pos, struct aa_ns *ns)
- {
-- ssize_t error;
- struct aa_loaddata *data;
-- struct aa_profile *profile;
-+ struct aa_label *label;
-+ ssize_t error;
-
-- profile = begin_current_profile_crit_section();
-+ label = begin_current_label_crit_section();
-
- /* high level check about policy management - fine grained in
- * below after unpack
- */
-- error = aa_may_manage_policy(profile, ns, mask);
-+ error = aa_may_manage_policy(label, ns, mask);
- if (error)
- return error;
-
- data = aa_simple_write_to_buffer(buf, size, size, pos);
- error = PTR_ERR(data);
- if (!IS_ERR(data)) {
-- error = aa_replace_profiles(ns, profile, mask, data);
-+ error = aa_replace_profiles(ns, label, mask, data);
- aa_put_loaddata(data);
- }
-- end_current_profile_crit_section(profile);
-+ end_current_label_crit_section(label);
-
- return error;
- }
-@@ -468,15 +468,15 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
- size_t size, loff_t *pos)
- {
- struct aa_loaddata *data;
-- struct aa_profile *profile;
-+ struct aa_label *label;
- ssize_t error;
- struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
-
-- profile = begin_current_profile_crit_section();
-+ label = begin_current_label_crit_section();
- /* high level check about policy management - fine grained in
- * below after unpack
- */
-- error = aa_may_manage_policy(profile, ns, AA_MAY_REMOVE_POLICY);
-+ error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
- if (error)
- goto out;
-
-@@ -489,11 +489,11 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
- error = PTR_ERR(data);
- if (!IS_ERR(data)) {
- data->data[size] = 0;
-- error = aa_remove_profiles(ns, profile, data->data, size);
-+ error = aa_remove_profiles(ns, label, data->data, size);
- aa_put_loaddata(data);
- }
- out:
-- end_current_profile_crit_section(profile);
-+ end_current_label_crit_section(label);
- aa_put_ns(ns);
- return error;
- }
-@@ -605,7 +605,7 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
- struct aa_dfa *dfa;
- unsigned int state = 0;
-
-- if (unconfined(profile))
-+ if (profile_unconfined(profile))
- return;
- if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
- dfa = profile->file.dfa;
-@@ -655,7 +655,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
- {
- char *out;
- const char *key;
-- struct aa_profile *profile, *curr;
-+ struct aa_label *label, *curr;
- struct aa_data *data;
- u32 bytes, blocks;
- __le32 outle32;
-@@ -672,11 +672,11 @@ static ssize_t query_data(char *buf, size_t buf_len,
- if (buf_len < sizeof(bytes) + sizeof(blocks))
- return -EINVAL; /* not enough space */
-
-- curr = begin_current_profile_crit_section();
-- profile = aa_fqlookupn_profile(curr, query, strnlen(query, query_len));
-- end_current_profile_crit_section(curr);
-- if (!profile)
-- return -ENOENT;
-+ curr = begin_current_label_crit_section();
-+ label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
-+ end_current_label_crit_section(curr);
-+ if (IS_ERR(label))
-+ return PTR_ERR(label);
-
- /* We are going to leave space for two numbers. The first is the total
- * number of bytes we are writing after the first number. This is so
-@@ -690,13 +690,16 @@ static ssize_t query_data(char *buf, size_t buf_len,
- out = buf + sizeof(bytes) + sizeof(blocks);
-
- blocks = 0;
-- if (profile->data) {
-- data = rhashtable_lookup_fast(profile->data, &key,
-- profile->data->p);
-+ if (labels_profile(label)->data) {
-+ data = rhashtable_lookup_fast(labels_profile(label)->data, &key,
-+ labels_profile(label)->data->p);
-
- if (data) {
-- if (out + sizeof(outle32) + data->size > buf + buf_len)
-+ if (out + sizeof(outle32) + data->size >
-+ buf + buf_len) {
-+ aa_put_label(label);
- return -EINVAL; /* not enough space */
-+ }
- outle32 = __cpu_to_le32(data->size);
- memcpy(out, &outle32, sizeof(outle32));
- out += sizeof(outle32);
-@@ -705,7 +708,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
- blocks++;
- }
- }
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
- memcpy(buf, &outle32, sizeof(outle32));
-@@ -738,7 +741,7 @@ static ssize_t query_data(char *buf, size_t buf_len,
- static ssize_t query_label(char *buf, size_t buf_len,
- char *query, size_t query_len, bool view_only)
- {
-- struct aa_profile *profile, *curr;
-+ struct aa_label *label, *curr;
- char *label_name, *match_str;
- size_t label_name_len, match_len;
- struct aa_perms perms;
-@@ -760,14 +763,14 @@ static ssize_t query_label(char *buf, size_t buf_len,
- match_str = label_name + label_name_len + 1;
- match_len = query_len - label_name_len - 1;
-
-- curr = begin_current_profile_crit_section();
-- profile = aa_fqlookupn_profile(curr, label_name, label_name_len);
-- end_current_profile_crit_section(curr);
-- if (!profile)
-- return -ENOENT;
-+ curr = begin_current_label_crit_section();
-+ label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
-+ end_current_label_crit_section(curr);
-+ if (IS_ERR(label))
-+ return PTR_ERR(label);
-
- perms = allperms;
-- profile_query_cb(profile, &perms, match_str, match_len);
-+ profile_query_cb(labels_profile(label), &perms, match_str, match_len);
-
- return scnprintf(buf, buf_len,
- "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
-@@ -1026,9 +1029,10 @@ static int seq_profile_release(struct inode *inode, struct file *file)
- static int seq_profile_name_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
-- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-+ struct aa_label *label = aa_get_label_rcu(&proxy->label);
-+ struct aa_profile *profile = labels_profile(label);
- seq_printf(seq, "%s\n", profile->base.name);
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- return 0;
- }
-@@ -1036,9 +1040,10 @@ static int seq_profile_name_show(struct seq_file *seq, void *v)
- static int seq_profile_mode_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
-- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-+ struct aa_label *label = aa_get_label_rcu(&proxy->label);
-+ struct aa_profile *profile = labels_profile(label);
- seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- return 0;
- }
-@@ -1046,14 +1051,15 @@ static int seq_profile_mode_show(struct seq_file *seq, void *v)
- static int seq_profile_attach_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
-- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-+ struct aa_label *label = aa_get_label_rcu(&proxy->label);
-+ struct aa_profile *profile = labels_profile(label);
- if (profile->attach)
- seq_printf(seq, "%s\n", profile->attach);
- else if (profile->xmatch)
- seq_puts(seq, "<unknown>\n");
- else
- seq_printf(seq, "%s\n", profile->base.name);
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- return 0;
- }
-@@ -1061,7 +1067,8 @@ static int seq_profile_attach_show(struct seq_file *seq, void *v)
- static int seq_profile_hash_show(struct seq_file *seq, void *v)
- {
- struct aa_proxy *proxy = seq->private;
-- struct aa_profile *profile = aa_get_profile_rcu(&proxy->profile);
-+ struct aa_label *label = aa_get_label_rcu(&proxy->label);
-+ struct aa_profile *profile = labels_profile(label);
- unsigned int i, size = aa_hash_size();
-
- if (profile->hash) {
-@@ -1069,7 +1076,7 @@ static int seq_profile_hash_show(struct seq_file *seq, void *v)
- seq_printf(seq, "%.2x", profile->hash[i]);
- seq_putc(seq, '\n');
- }
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- return 0;
- }
-@@ -1101,22 +1108,22 @@ static const struct file_operations seq_ns_ ##NAME ##_fops = { \
-
- static int seq_ns_level_show(struct seq_file *seq, void *v)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label;
-
-- profile = begin_current_profile_crit_section();
-- seq_printf(seq, "%d\n", profile->ns->level);
-- end_current_profile_crit_section(profile);
-+ label = begin_current_label_crit_section();
-+ seq_printf(seq, "%d\n", labels_ns(label)->level);
-+ end_current_label_crit_section(label);
-
- return 0;
- }
-
- static int seq_ns_name_show(struct seq_file *seq, void *v)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label = begin_current_label_crit_section();
-
-- profile = begin_current_profile_crit_section();
-- seq_printf(seq, "%s\n", aa_ns_name(profile->ns, profile->ns, true));
-- end_current_profile_crit_section(profile);
-+ seq_printf(seq, "%s\n", aa_ns_name(labels_ns(label),
-+ labels_ns(label), true));
-+ end_current_label_crit_section(label);
-
- return 0;
- }
-@@ -1380,7 +1387,7 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name,
- struct aa_profile *profile,
- const struct file_operations *fops)
- {
-- struct aa_proxy *proxy = aa_get_proxy(profile->proxy);
-+ struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
- struct dentry *dent;
-
- dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
-@@ -1541,9 +1548,12 @@ static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
- {
- struct aa_ns *ns, *parent;
- /* TODO: improve permission check */
-- struct aa_profile *profile = begin_current_profile_crit_section();
-- int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
-- end_current_profile_crit_section(profile);
-+ struct aa_label *label;
-+ int error;
-+
-+ label = begin_current_label_crit_section();
-+ error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
-+ end_current_label_crit_section(label);
- if (error)
- return error;
-
-@@ -1587,13 +1597,16 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
- {
- struct aa_ns *ns, *parent;
- /* TODO: improve permission check */
-- struct aa_profile *profile = begin_current_profile_crit_section();
-- int error = aa_may_manage_policy(profile, NULL, AA_MAY_LOAD_POLICY);
-- end_current_profile_crit_section(profile);
-+ struct aa_label *label;
-+ int error;
-+
-+ label = begin_current_label_crit_section();
-+ error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
-+ end_current_label_crit_section(label);
- if (error)
- return error;
-
-- parent = aa_get_ns(dir->i_private);
-+ parent = aa_get_ns(dir->i_private);
- /* rmdir calls the generic securityfs functions to remove files
- * from the apparmor dir. It is up to the apparmor ns locking
- * to avoid races.
-@@ -1999,10 +2012,9 @@ static int seq_show_profile(struct seq_file *f, void *p)
- struct aa_profile *profile = (struct aa_profile *)p;
- struct aa_ns *root = f->private;
-
-- if (profile->ns != root)
-- seq_printf(f, ":%s://", aa_ns_name(root, profile->ns, true));
-- seq_printf(f, "%s (%s)\n", profile->base.hname,
-- aa_profile_mode_names[profile->mode]);
-+ aa_label_seq_xprint(f, root, &profile->label,
-+ FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
-+ seq_putc(f, '\n');
-
- return 0;
- }
-diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
-index 87f40fa8c431..8f9ecac7f8de 100644
---- a/security/apparmor/audit.c
-+++ b/security/apparmor/audit.c
-@@ -77,14 +77,24 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
- audit_log_format(ab, " error=%d", aad(sa)->error);
- }
-
-- if (aad(sa)->profile) {
-- struct aa_profile *profile = aad(sa)->profile;
-- if (profile->ns != root_ns) {
-- audit_log_format(ab, " namespace=");
-- audit_log_untrustedstring(ab, profile->ns->base.hname);
-+ if (aad(sa)->label) {
-+ struct aa_label *label = aad(sa)->label;
-+
-+ if (label_isprofile(label)) {
-+ struct aa_profile *profile = labels_profile(label);
-+
-+ if (profile->ns != root_ns) {
-+ audit_log_format(ab, " namespace=");
-+ audit_log_untrustedstring(ab,
-+ profile->ns->base.hname);
-+ }
-+ audit_log_format(ab, " profile=");
-+ audit_log_untrustedstring(ab, profile->base.hname);
-+ } else {
-+ audit_log_format(ab, " label=");
-+ aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS,
-+ GFP_ATOMIC);
- }
-- audit_log_format(ab, " profile=");
-- audit_log_untrustedstring(ab, profile->base.hname);
- }
-
- if (aad(sa)->name) {
-@@ -139,8 +149,7 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
- if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
- type = AUDIT_APPARMOR_KILL;
-
-- if (!unconfined(profile))
-- aad(sa)->profile = profile;
-+ aad(sa)->label = &profile->label;
-
- aa_audit_msg(type, sa, cb);
-
-diff --git a/security/apparmor/context.c b/security/apparmor/context.c
-index 410b9f7f68a1..c95f1ac6190b 100644
---- a/security/apparmor/context.c
-+++ b/security/apparmor/context.c
-@@ -14,9 +14,9 @@
- *
- *
- * AppArmor sets confinement on every task, via the the aa_task_ctx and
-- * the aa_task_ctx.profile, both of which are required and are not allowed
-+ * the aa_task_ctx.label, both of which are required and are not allowed
- * to be NULL. The aa_task_ctx is not reference counted and is unique
-- * to each cred (which is reference count). The profile pointed to by
-+ * to each cred (which is reference count). The label pointed to by
- * the task_ctx is reference counted.
- *
- * TODO
-@@ -47,9 +47,9 @@ struct aa_task_ctx *aa_alloc_task_context(gfp_t flags)
- void aa_free_task_context(struct aa_task_ctx *ctx)
- {
- if (ctx) {
-- aa_put_profile(ctx->profile);
-- aa_put_profile(ctx->previous);
-- aa_put_profile(ctx->onexec);
-+ aa_put_label(ctx->label);
-+ aa_put_label(ctx->previous);
-+ aa_put_label(ctx->onexec);
-
- kzfree(ctx);
- }
-@@ -63,41 +63,41 @@ void aa_free_task_context(struct aa_task_ctx *ctx)
- void aa_dup_task_context(struct aa_task_ctx *new, const struct aa_task_ctx *old)
- {
- *new = *old;
-- aa_get_profile(new->profile);
-- aa_get_profile(new->previous);
-- aa_get_profile(new->onexec);
-+ aa_get_label(new->label);
-+ aa_get_label(new->previous);
-+ aa_get_label(new->onexec);
- }
-
- /**
-- * aa_get_task_profile - Get another task's profile
-+ * aa_get_task_label - Get another task's label
- * @task: task to query (NOT NULL)
- *
-- * Returns: counted reference to @task's profile
-+ * Returns: counted reference to @task's label
- */
--struct aa_profile *aa_get_task_profile(struct task_struct *task)
-+struct aa_label *aa_get_task_label(struct task_struct *task)
- {
-- struct aa_profile *p;
-+ struct aa_label *p;
-
- rcu_read_lock();
-- p = aa_get_newest_profile(__aa_task_raw_profile(task));
-+ p = aa_get_newest_label(__aa_task_raw_label(task));
- rcu_read_unlock();
-
- return p;
- }
-
- /**
-- * aa_replace_current_profile - replace the current tasks profiles
-- * @profile: new profile (NOT NULL)
-+ * aa_replace_current_label - replace the current tasks label
-+ * @label: new label (NOT NULL)
- *
- * Returns: 0 or error on failure
- */
--int aa_replace_current_profile(struct aa_profile *profile)
-+int aa_replace_current_label(struct aa_label *label)
- {
- struct aa_task_ctx *ctx = current_ctx();
- struct cred *new;
-- AA_BUG(!profile);
-+ AA_BUG(!label);
-
-- if (ctx->profile == profile)
-+ if (ctx->label == label)
- return 0;
-
- if (current_cred() != current_real_cred())
-@@ -108,8 +108,8 @@ int aa_replace_current_profile(struct aa_profile *profile)
- return -ENOMEM;
-
- ctx = cred_ctx(new);
-- if (unconfined(profile) || (ctx->profile->ns != profile->ns))
-- /* if switching to unconfined or a different profile namespace
-+ if (unconfined(label) || (labels_ns(ctx->label) != labels_ns(label)))
-+ /* if switching to unconfined or a different label namespace
- * clear out context state
- */
- aa_clear_task_ctx_trans(ctx);
-@@ -120,9 +120,9 @@ int aa_replace_current_profile(struct aa_profile *profile)
- * keeping @profile valid, so make sure to get its reference before
- * dropping the reference on ctx->profile
- */
-- aa_get_profile(profile);
-- aa_put_profile(ctx->profile);
-- ctx->profile = profile;
-+ aa_get_label(label);
-+ aa_put_label(ctx->label);
-+ ctx->label = label;
-
- commit_creds(new);
- return 0;
-@@ -130,11 +130,11 @@ int aa_replace_current_profile(struct aa_profile *profile)
-
- /**
- * aa_set_current_onexec - set the tasks change_profile to happen onexec
-- * @profile: system profile to set at exec (MAYBE NULL to clear value)
-- *
-+ * @label: system label to set at exec (MAYBE NULL to clear value)
-+ * @stack: whether stacking should be done
- * Returns: 0 or error on failure
- */
--int aa_set_current_onexec(struct aa_profile *profile)
-+int aa_set_current_onexec(struct aa_label *label, bool stack)
- {
- struct aa_task_ctx *ctx;
- struct cred *new = prepare_creds();
-@@ -142,9 +142,10 @@ int aa_set_current_onexec(struct aa_profile *profile)
- return -ENOMEM;
-
- ctx = cred_ctx(new);
-- aa_get_profile(profile);
-- aa_put_profile(ctx->onexec);
-- ctx->onexec = profile;
-+ aa_get_label(label);
-+ aa_clear_task_ctx_trans(ctx);
-+ ctx->onexec = label;
-+ ctx->token = stack;
-
- commit_creds(new);
- return 0;
-@@ -152,7 +153,7 @@ int aa_set_current_onexec(struct aa_profile *profile)
-
- /**
- * aa_set_current_hat - set the current tasks hat
-- * @profile: profile to set as the current hat (NOT NULL)
-+ * @label: label to set as the current hat (NOT NULL)
- * @token: token value that must be specified to change from the hat
- *
- * Do switch of tasks hat. If the task is currently in a hat
-@@ -160,29 +161,29 @@ int aa_set_current_onexec(struct aa_profile *profile)
- *
- * Returns: 0 or error on failure
- */
--int aa_set_current_hat(struct aa_profile *profile, u64 token)
-+int aa_set_current_hat(struct aa_label *label, u64 token)
- {
- struct aa_task_ctx *ctx;
- struct cred *new = prepare_creds();
- if (!new)
- return -ENOMEM;
-- AA_BUG(!profile);
-+ AA_BUG(!label);
-
- ctx = cred_ctx(new);
- if (!ctx->previous) {
- /* transfer refcount */
-- ctx->previous = ctx->profile;
-+ ctx->previous = ctx->label;
- ctx->token = token;
- } else if (ctx->token == token) {
-- aa_put_profile(ctx->profile);
-+ aa_put_label(ctx->label);
- } else {
- /* previous_profile && ctx->token != token */
- abort_creds(new);
- return -EACCES;
- }
-- ctx->profile = aa_get_newest_profile(profile);
-+ ctx->label = aa_get_newest_label(label);
- /* clear exec on switching context */
-- aa_put_profile(ctx->onexec);
-+ aa_put_label(ctx->onexec);
- ctx->onexec = NULL;
-
- commit_creds(new);
-@@ -190,15 +191,15 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)
- }
-
- /**
-- * aa_restore_previous_profile - exit from hat context restoring the profile
-+ * aa_restore_previous_label - exit from hat context restoring previous label
- * @token: the token that must be matched to exit hat context
- *
-- * Attempt to return out of a hat to the previous profile. The token
-+ * Attempt to return out of a hat to the previous label. The token
- * must match the stored token value.
- *
- * Returns: 0 or error of failure
- */
--int aa_restore_previous_profile(u64 token)
-+int aa_restore_previous_label(u64 token)
- {
- struct aa_task_ctx *ctx;
- struct cred *new = prepare_creds();
-@@ -210,15 +211,15 @@ int aa_restore_previous_profile(u64 token)
- abort_creds(new);
- return -EACCES;
- }
-- /* ignore restores when there is no saved profile */
-+ /* ignore restores when there is no saved label */
- if (!ctx->previous) {
- abort_creds(new);
- return 0;
- }
-
-- aa_put_profile(ctx->profile);
-- ctx->profile = aa_get_newest_profile(ctx->previous);
-- AA_BUG(!ctx->profile);
-+ aa_put_label(ctx->label);
-+ ctx->label = aa_get_newest_label(ctx->previous);
-+ AA_BUG(!ctx->label);
- /* clear exec && prev information when restoring to previous context */
- aa_clear_task_ctx_trans(ctx);
-
-diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
-index 2ec4ae029215..8d6797c849fe 100644
---- a/security/apparmor/domain.c
-+++ b/security/apparmor/domain.c
-@@ -61,24 +61,25 @@ void aa_free_domain_entries(struct aa_domain *domain)
- static int may_change_ptraced_domain(struct aa_profile *to_profile)
- {
- struct task_struct *tracer;
-- struct aa_profile *tracerp = NULL;
-+ struct aa_label *tracerl = NULL;
- int error = 0;
-
- rcu_read_lock();
- tracer = ptrace_parent(current);
- if (tracer)
- /* released below */
-- tracerp = aa_get_task_profile(tracer);
-+ tracerl = aa_get_task_label(tracer);
-
- /* not ptraced */
-- if (!tracer || unconfined(tracerp))
-+ if (!tracer || unconfined(tracerl))
- goto out;
-
-- error = aa_may_ptrace(tracerp, to_profile, PTRACE_MODE_ATTACH);
-+ error = aa_may_ptrace(labels_profile(tracerl), to_profile,
-+ PTRACE_MODE_ATTACH);
-
- out:
- rcu_read_unlock();
-- aa_put_profile(tracerp);
-+ aa_put_label(tracerl);
-
- return error;
- }
-@@ -102,7 +103,7 @@ static struct aa_perms change_profile_perms(struct aa_profile *profile,
- struct path_cond cond = { };
- unsigned int state;
-
-- if (unconfined(profile)) {
-+ if (profile_unconfined(profile)) {
- perms.allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
- perms.audit = perms.quiet = perms.kill = 0;
- return perms;
-@@ -144,7 +145,7 @@ static struct aa_profile *__attach_match(const char *name,
- struct aa_profile *profile, *candidate = NULL;
-
- list_for_each_entry_rcu(profile, head, base.list) {
-- if (profile->flags & PFLAG_NULL)
-+ if (profile->label.flags & FLAG_NULL)
- continue;
- if (profile->xmatch && profile->xmatch_len > len) {
- unsigned int state = aa_dfa_match(profile->xmatch,
-@@ -338,6 +339,7 @@ static struct aa_profile *x_to_profile(struct aa_profile *profile,
- int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- {
- struct aa_task_ctx *ctx;
-+ struct aa_label *label;
- struct aa_profile *profile, *new_profile = NULL;
- struct aa_ns *ns;
- char *buffer = NULL;
-@@ -356,7 +358,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- ctx = cred_ctx(bprm->cred);
- AA_BUG(!ctx);
-
-- profile = aa_get_newest_profile(ctx->profile);
-+ label = aa_get_newest_label(ctx->label);
-+ profile = labels_profile(label);
-
- /* buffer freed below, name is pointer into buffer */
- get_buffers(buffer);
-@@ -370,8 +373,8 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
- &name, &info, profile->disconnected);
- if (error) {
-- if (unconfined(profile) ||
-- (profile->flags & PFLAG_IX_ON_NAME_ERROR))
-+ if (profile_unconfined(profile) ||
-+ (profile->label.flags & FLAG_IX_ON_NAME_ERROR))
- error = 0;
- name = bprm->filename;
- goto audit;
-@@ -380,11 +383,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- /* Test for onexec first as onexec directives override other
- * x transitions.
- */
-- if (unconfined(profile)) {
-+ if (profile_unconfined(profile)) {
- /* unconfined task */
- if (ctx->onexec)
- /* change_profile on exec already been granted */
-- new_profile = aa_get_profile(ctx->onexec);
-+ new_profile = labels_profile(aa_get_label(ctx->onexec));
- else
- new_profile = find_attach(ns, &ns->base.profiles, name);
- if (!new_profile)
-@@ -402,7 +405,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- if (ctx->onexec) {
- struct aa_perms cp;
- info = "change_profile onexec";
-- new_profile = aa_get_newest_profile(ctx->onexec);
-+ new_profile = labels_profile(aa_get_newest_label(ctx->onexec));
- if (!(perms.allow & AA_MAY_ONEXEC))
- goto audit;
-
-@@ -411,9 +414,9 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- * exec\0change_profile
- */
- state = aa_dfa_null_transition(profile->file.dfa, state);
-- cp = change_profile_perms(profile, ctx->onexec->ns,
-- ctx->onexec->base.name,
-- AA_MAY_ONEXEC, state);
-+ cp = change_profile_perms(profile, labels_ns(ctx->onexec),
-+ labels_profile(ctx->onexec)->base.name,
-+ AA_MAY_ONEXEC, state);
-
- if (!(cp.allow & AA_MAY_ONEXEC))
- goto audit;
-@@ -501,9 +504,9 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
- bprm->per_clear |= PER_CLEAR_ON_SETID;
-
- x_clear:
-- aa_put_profile(ctx->profile);
-+ aa_put_label(ctx->label);
- /* transfer new profile reference will be released when ctx is freed */
-- ctx->profile = new_profile;
-+ ctx->label = &new_profile->label;
- new_profile = NULL;
-
- /* clear out all temporary/transitional state from the context */
-@@ -516,7 +519,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
-
- cleanup:
- aa_put_profile(new_profile);
-- aa_put_profile(profile);
-+ aa_put_label(label);
- put_buffers(buffer);
-
- return error;
-@@ -576,7 +579,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- {
- const struct cred *cred;
- struct aa_task_ctx *ctx;
-- struct aa_profile *profile, *previous_profile, *hat = NULL;
-+ struct aa_label *label, *previous_label;
-+ struct aa_profile *profile, *hat = NULL;
- char *name = NULL;
- int i;
- struct aa_perms perms = {};
-@@ -594,10 +598,11 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- /* released below */
- cred = get_current_cred();
- ctx = cred_ctx(cred);
-- profile = aa_get_newest_cred_profile(cred);
-- previous_profile = aa_get_newest_profile(ctx->previous);
-+ label = aa_get_newest_cred_label(cred);
-+ previous_label = aa_get_newest_label(ctx->previous);
-+ profile = labels_profile(label);
-
-- if (unconfined(profile)) {
-+ if (unconfined(label)) {
- info = "unconfined";
- error = -EPERM;
- goto audit;
-@@ -664,7 +669,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- }
-
- if (!(flags & AA_CHANGE_TEST)) {
-- error = aa_set_current_hat(hat, token);
-+ error = aa_set_current_hat(&hat->label, token);
- if (error == -EACCES)
- /* kill task in case of brute force attacks */
- perms.kill = AA_MAY_CHANGEHAT;
-@@ -672,12 +677,12 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- /* reset error for learning of new hats */
- error = -ENOENT;
- }
-- } else if (previous_profile) {
-+ } else if (previous_label) {
- /* Return to saved profile. Kill task if restore fails
- * to avoid brute force attacks
- */
-- target = previous_profile->base.hname;
-- error = aa_restore_previous_profile(token);
-+ target = previous_label->hname;
-+ error = aa_restore_previous_label(token);
- perms.kill = AA_MAY_CHANGEHAT;
- } else
- /* ignore restores when there is no saved profile */
-@@ -692,8 +697,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- out:
- aa_put_profile(hat);
- kfree(name);
-- aa_put_profile(profile);
-- aa_put_profile(previous_profile);
-+ aa_put_label(label);
-+ aa_put_label(previous_label);
- put_cred(cred);
-
- return error;
-@@ -716,6 +721,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
- int aa_change_profile(const char *fqname, int flags)
- {
- const struct cred *cred;
-+ struct aa_label *label;
- struct aa_profile *profile, *target = NULL;
- struct aa_perms perms = {};
- const char *info = NULL, *op;
-@@ -736,7 +742,8 @@ int aa_change_profile(const char *fqname, int flags)
- }
-
- cred = get_current_cred();
-- profile = aa_get_newest_cred_profile(cred);
-+ label = aa_get_newest_cred_label(cred);
-+ profile = labels_profile(label);
-
- /*
- * Fail explicitly requested domain transitions if no_new_privs
-@@ -745,12 +752,12 @@ int aa_change_profile(const char *fqname, int flags)
- * no_new_privs is set because this aways results in a reduction
- * of permissions.
- */
-- if (task_no_new_privs(current) && !unconfined(profile)) {
-+ if (task_no_new_privs(current) && !profile_unconfined(profile)) {
- put_cred(cred);
- return -EPERM;
- }
-
-- target = aa_fqlookupn_profile(profile, fqname, strlen(fqname));
-+ target = aa_fqlookupn_profile(label, fqname, strlen(fqname));
- if (!target) {
- info = "profile not found";
- error = -ENOENT;
-@@ -785,9 +792,9 @@ int aa_change_profile(const char *fqname, int flags)
- goto audit;
-
- if (flags & AA_CHANGE_ONEXEC)
-- error = aa_set_current_onexec(target);
-+ error = aa_set_current_onexec(&target->label, 0);
- else
-- error = aa_replace_current_profile(target);
-+ error = aa_replace_current_label(&target->label);
-
- audit:
- if (!(flags & AA_CHANGE_TEST))
-@@ -795,7 +802,7 @@ int aa_change_profile(const char *fqname, int flags)
- fqname, GLOBAL_ROOT_UID, info, error);
-
- aa_put_profile(target);
-- aa_put_profile(profile);
-+ aa_put_label(label);
- put_cred(cred);
-
- return error;
-diff --git a/security/apparmor/file.c b/security/apparmor/file.c
-index bf508791cc1f..5289c8db832b 100644
---- a/security/apparmor/file.c
-+++ b/security/apparmor/file.c
-@@ -451,7 +451,7 @@ int aa_file_perm(const char *op, struct aa_profile *profile, struct file *file,
- request, &cond);
- }
-
--static void revalidate_tty(struct aa_profile *profile)
-+static void revalidate_tty(struct aa_label *label)
- {
- struct tty_struct *tty;
- int drop_tty = 0;
-@@ -469,7 +469,7 @@ static void revalidate_tty(struct aa_profile *profile)
- struct tty_file_private, list);
- file = file_priv->file;
-
-- if (aa_file_perm(OP_INHERIT, profile, file,
-+ if (aa_file_perm(OP_INHERIT, labels_profile(label), file,
- MAY_READ | MAY_WRITE))
- drop_tty = 1;
- }
-@@ -482,9 +482,9 @@ static void revalidate_tty(struct aa_profile *profile)
-
- static int match_file(const void *p, struct file *file, unsigned int fd)
- {
-- struct aa_profile *profile = (struct aa_profile *)p;
-+ struct aa_label *label = (struct aa_label *)p;
-
-- if (aa_file_perm(OP_INHERIT, profile, file,
-+ if (aa_file_perm(OP_INHERIT, labels_profile(label), file,
- aa_map_file_to_perms(file)))
- return fd + 1;
- return 0;
-@@ -494,14 +494,14 @@ static int match_file(const void *p, struct file *file, unsigned int fd)
- /* based on selinux's flush_unauthorized_files */
- void aa_inherit_files(const struct cred *cred, struct files_struct *files)
- {
-- struct aa_profile *profile = aa_get_newest_cred_profile(cred);
-+ struct aa_label *label = aa_get_newest_cred_label(cred);
- struct file *devnull = NULL;
- unsigned int n;
-
-- revalidate_tty(profile);
-+ revalidate_tty(label);
-
- /* Revalidate access to inherited open files. */
-- n = iterate_fd(files, 0, match_file, profile);
-+ n = iterate_fd(files, 0, match_file, label);
- if (!n) /* none found? */
- goto out;
-
-@@ -511,9 +511,9 @@ void aa_inherit_files(const struct cred *cred, struct files_struct *files)
- /* replace all the matching ones with this */
- do {
- replace_fd(n - 1, devnull, 0);
-- } while ((n = iterate_fd(files, n, match_file, profile)) != 0);
-+ } while ((n = iterate_fd(files, n, match_file, label)) != 0);
- if (devnull)
- fput(devnull);
- out:
-- aa_put_profile(profile);
-+ aa_put_label(label);
- }
-diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
-index 1750cc0721c1..c4a900488e76 100644
---- a/security/apparmor/include/apparmor.h
-+++ b/security/apparmor/include/apparmor.h
-@@ -4,7 +4,7 @@
- * This file contains AppArmor basic global
- *
- * Copyright (C) 1998-2008 Novell/SUSE
-- * Copyright 2009-2010 Canonical Ltd.
-+ * Copyright 2009-2017 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
-@@ -27,8 +27,9 @@
- #define AA_CLASS_NET 4
- #define AA_CLASS_RLIMITS 5
- #define AA_CLASS_DOMAIN 6
-+#define AA_CLASS_LABEL 16
-
--#define AA_CLASS_LAST AA_CLASS_DOMAIN
-+#define AA_CLASS_LAST AA_CLASS_LABEL
-
- /* Control parameters settable through module/boot flags */
- extern enum audit_mode aa_g_audit;
-diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
-index d548261dd1b7..20fa6c77db05 100644
---- a/security/apparmor/include/audit.h
-+++ b/security/apparmor/include/audit.h
-@@ -22,8 +22,7 @@
- #include <linux/slab.h>
-
- #include "file.h"
--
--struct aa_profile;
-+#include "label.h"
-
- extern const char *const audit_mode_names[];
- #define AUDIT_MAX_INDEX 5
-@@ -103,9 +102,9 @@ enum audit_type {
-
- struct apparmor_audit_data {
- int error;
-- const char *op;
- int type;
-- void *profile;
-+ const char *op;
-+ struct aa_label *label;
- const char *name;
- const char *info;
- u32 request;
-@@ -113,7 +112,7 @@ struct apparmor_audit_data {
- union {
- /* these entries require a custom callback fn */
- struct {
-- struct aa_profile *peer;
-+ struct aa_label *peer;
- struct {
- const char *target;
- kuid_t ouid;
-diff --git a/security/apparmor/include/context.h b/security/apparmor/include/context.h
-index 7665fae7131f..6ae07e9aaa17 100644
---- a/security/apparmor/include/context.h
-+++ b/security/apparmor/include/context.h
-@@ -19,7 +19,7 @@
- #include <linux/slab.h>
- #include <linux/sched.h>
-
--#include "policy.h"
-+#include "label.h"
- #include "policy_ns.h"
-
- #define cred_ctx(X) ((X)->security)
-@@ -27,20 +27,20 @@
-
- /**
- * struct aa_task_ctx - primary label for confined tasks
-- * @profile: the current profile (NOT NULL)
-- * @exec: profile to transition to on next exec (MAYBE NULL)
-- * @previous: profile the task may return to (MAYBE NULL)
-- * @token: magic value the task must know for returning to @previous_profile
-+ * @label: the current label (NOT NULL)
-+ * @exec: label to transition to on next exec (MAYBE NULL)
-+ * @previous: label the task may return to (MAYBE NULL)
-+ * @token: magic value the task must know for returning to @previous
- *
-- * Contains the task's current profile (which could change due to
-+ * Contains the task's current label (which could change due to
- * change_hat). Plus the hat_magic needed during change_hat.
- *
- * TODO: make so a task can be confined by a stack of contexts
- */
- struct aa_task_ctx {
-- struct aa_profile *profile;
-- struct aa_profile *onexec;
-- struct aa_profile *previous;
-+ struct aa_label *label;
-+ struct aa_label *onexec;
-+ struct aa_label *previous;
- u64 token;
- };
-
-@@ -48,52 +48,51 @@ struct aa_task_ctx *aa_alloc_task_context(gfp_t flags);
- void aa_free_task_context(struct aa_task_ctx *ctx);
- void aa_dup_task_context(struct aa_task_ctx *new,
- const struct aa_task_ctx *old);
--int aa_replace_current_profile(struct aa_profile *profile);
--int aa_set_current_onexec(struct aa_profile *profile);
--int aa_set_current_hat(struct aa_profile *profile, u64 token);
--int aa_restore_previous_profile(u64 cookie);
--struct aa_profile *aa_get_task_profile(struct task_struct *task);
-+int aa_replace_current_label(struct aa_label *label);
-+int aa_set_current_onexec(struct aa_label *label, bool stack);
-+int aa_set_current_hat(struct aa_label *label, u64 token);
-+int aa_restore_previous_label(u64 cookie);
-+struct aa_label *aa_get_task_label(struct task_struct *task);
-
-
- /**
-- * aa_cred_raw_profile - obtain cred's profiles
-- * @cred: cred to obtain profiles from (NOT NULL)
-+ * aa_cred_raw_label - obtain cred's label
-+ * @cred: cred to obtain label from (NOT NULL)
- *
-- * Returns: confining profile
-+ * Returns: confining label
- *
- * does NOT increment reference count
- */
--static inline struct aa_profile *aa_cred_raw_profile(const struct cred *cred)
-+static inline struct aa_label *aa_cred_raw_label(const struct cred *cred)
- {
- struct aa_task_ctx *ctx = cred_ctx(cred);
-
-- AA_BUG(!ctx || !ctx->profile);
-- return ctx->profile;
-+ AA_BUG(!ctx || !ctx->label);
-+ return ctx->label;
- }
-
- /**
-- * aa_get_newest_cred_profile - obtain the newest profile on a cred
-- * @cred: cred to obtain profile from (NOT NULL)
-+ * aa_get_newest_cred_label - obtain the newest label on a cred
-+ * @cred: cred to obtain label from (NOT NULL)
- *
-- * Returns: newest version of confining profile
-+ * Returns: newest version of confining label
- */
--static inline
--struct aa_profile *aa_get_newest_cred_profile(const struct cred *cred)
-+static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred)
- {
-- return aa_get_newest_profile(aa_cred_raw_profile(cred));
-+ return aa_get_newest_label(aa_cred_raw_label(cred));
- }
-
- /**
-- * __aa_task_raw_profile - retrieve another task's profile
-+ * __aa_task_raw_label - retrieve another task's label
- * @task: task to query (NOT NULL)
- *
-- * Returns: @task's profile without incrementing its ref count
-+ * Returns: @task's label without incrementing its ref count
- *
- * If @task != current needs to be called in RCU safe critical section
- */
--static inline struct aa_profile *__aa_task_raw_profile(struct task_struct *task)
-+static inline struct aa_label *__aa_task_raw_label(struct task_struct *task)
- {
-- return aa_cred_raw_profile(__task_cred(task));
-+ return aa_cred_raw_label(__task_cred(task));
- }
-
- /**
-@@ -104,113 +103,112 @@ static inline struct aa_profile *__aa_task_raw_profile(struct task_struct *task)
- */
- static inline bool __aa_task_is_confined(struct task_struct *task)
- {
-- return !unconfined(__aa_task_raw_profile(task));
-+ return !unconfined(__aa_task_raw_label(task));
- }
-
- /**
-- * aa_current_raw_profile - find the current tasks confining profile
-+ * aa_current_raw_label - find the current tasks confining label
- *
-- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
-+ * Returns: up to date confining label or the ns unconfined label (NOT NULL)
- *
- * This fn will not update the tasks cred to the most up to date version
-- * of the profile so it is safe to call when inside of locks.
-+ * of the label so it is safe to call when inside of locks.
- */
--static inline struct aa_profile *aa_current_raw_profile(void)
-+static inline struct aa_label *aa_current_raw_label(void)
- {
-- return aa_cred_raw_profile(current_cred());
-+ return aa_cred_raw_label(current_cred());
- }
-
- /**
-- * aa_get_current_profile - get the newest version of the current tasks profile
-+ * aa_get_current_label - get the newest version of the current tasks label
- *
-- * Returns: newest version of confining profile (NOT NULL)
-+ * Returns: newest version of confining label (NOT NULL)
- *
- * This fn will not update the tasks cred, so it is safe inside of locks
- *
-- * The returned reference must be put with aa_put_profile()
-+ * The returned reference must be put with aa_put_label()
- */
--static inline struct aa_profile *aa_get_current_profile(void)
-+static inline struct aa_label *aa_get_current_label(void)
- {
-- struct aa_profile *p = aa_current_raw_profile();
-+ struct aa_label *l = aa_current_raw_label();
-
-- if (profile_is_stale(p))
-- return aa_get_newest_profile(p);
-- return aa_get_profile(p);
-+ if (label_is_stale(l))
-+ return aa_get_newest_label(l);
-+ return aa_get_label(l);
- }
-
--#define __end_current_profile_crit_section(X) \
-- end_current_profile_crit_section(X)
-+#define __end_current_label_crit_section(X) end_current_label_crit_section(X)
-
- /**
-- * end_profile_crit_section - put a reference found with begin_current_profile..
-- * @profile: profile reference to put
-+ * end_label_crit_section - put a reference found with begin_current_label..
-+ * @label: label reference to put
- *
- * Should only be used with a reference obtained with
-- * begin_current_profile_crit_section and never used in situations where the
-+ * begin_current_label_crit_section and never used in situations where the
- * task cred may be updated
- */
--static inline void end_current_profile_crit_section(struct aa_profile *profile)
-+static inline void end_current_label_crit_section(struct aa_label *label)
- {
-- if (profile != aa_current_raw_profile())
-- aa_put_profile(profile);
-+ if (label != aa_current_raw_label())
-+ aa_put_label(label);
- }
-
- /**
-- * __begin_current_profile_crit_section - current's confining profile
-+ * __begin_current_label_crit_section - current's confining label
- *
-- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
-+ * Returns: up to date confining label or the ns unconfined label (NOT NULL)
- *
- * safe to call inside locks
- *
-- * The returned reference must be put with __end_current_profile_crit_section()
-+ * The returned reference must be put with __end_current_label_crit_section()
- * This must NOT be used if the task cred could be updated within the
-- * critical section between __begin_current_profile_crit_section() ..
-- * __end_current_profile_crit_section()
-+ * critical section between __begin_current_label_crit_section() ..
-+ * __end_current_label_crit_section()
- */
--static inline struct aa_profile *__begin_current_profile_crit_section(void)
-+static inline struct aa_label *__begin_current_label_crit_section(void)
- {
-- struct aa_profile *profile = aa_current_raw_profile();
-+ struct aa_label *label = aa_current_raw_label();
-
-- if (profile_is_stale(profile))
-- profile = aa_get_newest_profile(profile);
-+ if (label_is_stale(label))
-+ label = aa_get_newest_label(label);
-
-- return profile;
-+ return label;
- }
-
- /**
-- * begin_current_profile_crit_section - current's profile and update if needed
-+ * begin_current_label_crit_section - current's confining label and update it
- *
-- * Returns: up to date confining profile or the ns unconfined profile (NOT NULL)
-+ * Returns: up to date confining label or the ns unconfined label (NOT NULL)
- *
- * Not safe to call inside locks
- *
-- * The returned reference must be put with end_current_profile_crit_section()
-+ * The returned reference must be put with end_current_label_crit_section()
- * This must NOT be used if the task cred could be updated within the
-- * critical section between begin_current_profile_crit_section() ..
-- * end_current_profile_crit_section()
-+ * critical section between begin_current_label_crit_section() ..
-+ * end_current_label_crit_section()
- */
--static inline struct aa_profile *begin_current_profile_crit_section(void)
-+static inline struct aa_label *begin_current_label_crit_section(void)
- {
-- struct aa_profile *profile = aa_current_raw_profile();
-+ struct aa_label *label = aa_current_raw_label();
-
-- if (profile_is_stale(profile)) {
-- profile = aa_get_newest_profile(profile);
-- if (aa_replace_current_profile(profile) == 0)
-+ if (label_is_stale(label)) {
-+ label = aa_get_newest_label(label);
-+ if (aa_replace_current_label(label) == 0)
- /* task cred will keep the reference */
-- aa_put_profile(profile);
-+ aa_put_label(label);
- }
-
-- return profile;
-+ return label;
- }
-
- static inline struct aa_ns *aa_get_current_ns(void)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label;
- struct aa_ns *ns;
-
-- profile = __begin_current_profile_crit_section();
-- ns = aa_get_ns(profile->ns);
-- __end_current_profile_crit_section(profile);
-+ label = __begin_current_label_crit_section();
-+ ns = aa_get_ns(labels_ns(label));
-+ __end_current_label_crit_section(label);
-
- return ns;
- }
-@@ -221,8 +219,8 @@ static inline struct aa_ns *aa_get_current_ns(void)
- */
- static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx)
- {
-- aa_put_profile(ctx->previous);
-- aa_put_profile(ctx->onexec);
-+ aa_put_label(ctx->previous);
-+ aa_put_label(ctx->onexec);
- ctx->previous = NULL;
- ctx->onexec = NULL;
- ctx->token = 0;
-diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
-index 82946fb81f91..0c5c2b00be02 100644
---- a/security/apparmor/include/perms.h
-+++ b/security/apparmor/include/perms.h
-@@ -15,6 +15,7 @@
- #define __AA_PERM_H
-
- #include <linux/fs.h>
-+#include "label.h"
-
- #define AA_MAY_EXEC MAY_EXEC
- #define AA_MAY_WRITE MAY_WRITE
-@@ -101,5 +102,14 @@ void aa_apply_modes_to_perms(struct aa_profile *profile,
- struct aa_perms *perms);
- void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
- struct aa_perms *perms);
--
-+void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend);
-+void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend);
-+void aa_profile_match_label(struct aa_profile *profile, struct aa_label *label,
-+ int type, u32 request, struct aa_perms *perms);
-+int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
-+ u32 request, int type, u32 *deny,
-+ struct common_audit_data *sa);
-+int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
-+ u32 request, struct common_audit_data *sa,
-+ void (*cb)(struct audit_buffer *, void *));
- #endif /* __AA_PERM_H */
-diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
-index d93f475bfd8b..17fe41a9cac3 100644
---- a/security/apparmor/include/policy.h
-+++ b/security/apparmor/include/policy.h
-@@ -29,6 +29,7 @@
- #include "domain.h"
- #include "file.h"
- #include "lib.h"
-+#include "label.h"
- #include "perms.h"
- #include "resource.h"
-
-@@ -48,9 +49,9 @@ extern const char *const aa_profile_mode_names[];
-
- #define KILL_MODE(_profile) PROFILE_MODE((_profile), APPARMOR_KILL)
-
--#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
-+#define PROFILE_IS_HAT(_profile) ((_profile)->label.flags & FLAG_HAT)
-
--#define profile_is_stale(_profile) ((_profile)->flags & PFLAG_STALE)
-+#define profile_is_stale(_profile) (label_is_stale(&(_profile)->label))
-
- #define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
-
-@@ -67,22 +68,6 @@ enum profile_mode {
- APPARMOR_UNCONFINED, /* profile set to unconfined */
- };
-
--enum profile_flags {
-- PFLAG_HAT = 1, /* profile is a hat */
-- 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 - lower privs */
-- PFLAG_NO_LIST_REF = 0x40, /* list doesn't keep profile ref */
-- PFLAG_OLD_NULL_TRANS = 0x100, /* use // as the null transition */
-- PFLAG_STALE = 0x200, /* profile replaced/removed */
-- PFLAG_NS_COUNT = 0x400, /* carries NS ref count */
--
-- /* These flags must correspond with PATH_flags */
-- PFLAG_MEDIATE_DELETED = 0x10000, /* mediate instead delegate deleted */
--};
--
--struct aa_profile;
-
- /* struct aa_policydb - match engine for a policy
- * dfa: dfa pattern match
-@@ -95,11 +80,6 @@ struct aa_policydb {
-
- };
-
--struct aa_proxy {
-- struct kref count;
-- struct aa_profile __rcu *profile;
--};
--
- /* struct aa_data - generic data structure
- * key: name for retrieving this data
- * size: size of data in bytes
-@@ -116,18 +96,15 @@ struct aa_data {
-
- /* struct aa_profile - basic confinement data
- * @base - base components of the profile (name, refcount, lists, lock ...)
-- * @count: reference count of the obj
-- * @rcu: rcu head used when removing from @list
-+ * @label - label this profile is an extension of
- * @parent: parent of profile
- * @ns: namespace the profile is in
-- * @proxy: is set to the profile that replaced this profile
- * @rename: optional profile name that this profile renamed
- * @attach: human readable attachment string
- * @xmatch: optional extended matching for unconfined executables names
- * @xmatch_len: xmatch prefix len, used to determine xmatch priority
- * @audit: the auditing mode of the profile
- * @mode: the enforcement mode of the profile
-- * @flags: flags controlling profile behavior
- * @path_flags: flags controlling path generation behavior
- * @disconnected: what to prepend if attach_disconnected is specified
- * @size: the memory consumed by this profiles rules
-@@ -145,8 +122,6 @@ struct aa_data {
- * used to determine profile attachment against unconfined tasks. All other
- * attachments are determined by profile X transition rules.
- *
-- * The @proxy struct is write protected by the profile lock.
-- *
- * Profiles have a hierarchy where hats and children profiles keep
- * a reference to their parent.
- *
-@@ -156,12 +131,9 @@ struct aa_data {
- */
- struct aa_profile {
- struct aa_policy base;
-- struct kref count;
-- struct rcu_head rcu;
- struct aa_profile __rcu *parent;
-
- struct aa_ns *ns;
-- struct aa_proxy *proxy;
- const char *rename;
-
- const char *attach;
-@@ -169,7 +141,6 @@ struct aa_profile {
- int xmatch_len;
- enum audit_mode audit;
- long mode;
-- long flags;
- u32 path_flags;
- const char *disconnected;
- int size;
-@@ -184,6 +155,7 @@ struct aa_profile {
- char *dirname;
- struct dentry *dents[AAFS_PROF_SIZEOF];
- struct rhashtable *data;
-+ struct aa_label label;
- };
-
- extern enum profile_mode aa_g_profile_mode;
-@@ -192,13 +164,15 @@ extern enum profile_mode aa_g_profile_mode;
- #define AA_MAY_REPLACE_POLICY AA_MAY_WRITE
- #define AA_MAY_REMOVE_POLICY AA_MAY_DELETE
-
--void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new);
-+#define profiles_ns(P) ((P)->ns)
-+#define name_is_shared(A, B) ((A)->hname && (A)->hname == (B)->hname)
-
- void aa_add_profile(struct aa_policy *common, struct aa_profile *profile);
-
-
- void aa_free_proxy_kref(struct kref *kref);
--struct aa_profile *aa_alloc_profile(const char *name, gfp_t gfp);
-+struct aa_profile *aa_alloc_profile(const char *name, struct aa_proxy *proxy,
-+ gfp_t gfp);
- struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- const char *base, gfp_t gfp);
- void aa_free_profile(struct aa_profile *profile);
-@@ -207,20 +181,33 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name);
- struct aa_profile *aa_lookupn_profile(struct aa_ns *ns, const char *hname,
- size_t n);
- struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *name);
--struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
-+struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
- const char *fqname, size_t n);
- struct aa_profile *aa_match_profile(struct aa_ns *ns, const char *name);
-
--ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_profile *profile,
-+ssize_t aa_replace_profiles(struct aa_ns *view, struct aa_label *label,
- u32 mask, struct aa_loaddata *udata);
--ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_profile *profile,
-- char *name, size_t size);
-+ssize_t aa_remove_profiles(struct aa_ns *view, struct aa_label *label,
-+ char *name, size_t size);
- void __aa_profile_list_release(struct list_head *head);
-
- #define PROF_ADD 1
- #define PROF_REPLACE 0
-
--#define unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
-+#define profile_unconfined(X) ((X)->mode == APPARMOR_UNCONFINED)
-+
-+/**
-+ * aa_get_newest_profile - simple wrapper fn to wrap the label version
-+ * @p: profile (NOT NULL)
-+ *
-+ * Returns refcount to newest version of the profile (maybe @p)
-+ *
-+ * Requires: @p must be held with a valid refcount
-+ */
-+static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
-+{
-+ return labels_profile(aa_get_newest_label(&p->label));
-+}
-
- #define PROFILE_MEDIATES(P, T) ((P)->policy.start[(T)])
- /* safe version of POLICY_MEDIATES for full range input */
-@@ -243,7 +230,7 @@ static inline unsigned int PROFILE_MEDIATES_SAFE(struct aa_profile *profile,
- static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
- {
- if (p)
-- kref_get(&(p->count));
-+ kref_get(&(p->label.count));
-
- return p;
- }
-@@ -257,7 +244,7 @@ static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
- */
- static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
- {
-- if (p && kref_get_unless_zero(&p->count))
-+ if (p && kref_get_unless_zero(&p->label.count))
- return p;
-
- return NULL;
-@@ -277,53 +264,20 @@ static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
- rcu_read_lock();
- do {
- c = rcu_dereference(*p);
-- } while (c && !kref_get_unless_zero(&c->count));
-+ } while (c && !kref_get_unless_zero(&c->label.count));
- rcu_read_unlock();
-
- return c;
- }
-
- /**
-- * aa_get_newest_profile - find the newest version of @profile
-- * @profile: the profile to check for newer versions of
-- *
-- * Returns: refcounted newest version of @profile taking into account
-- * replacement, renames and removals
-- * return @profile.
-- */
--static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
--{
-- if (!p)
-- return NULL;
--
-- if (profile_is_stale(p))
-- return aa_get_profile_rcu(&p->proxy->profile);
--
-- return aa_get_profile(p);
--}
--
--/**
- * aa_put_profile - decrement refcount on profile @p
- * @p: profile (MAYBE NULL)
- */
- static inline void aa_put_profile(struct aa_profile *p)
- {
- if (p)
-- kref_put(&p->count, aa_free_profile_kref);
--}
--
--static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *p)
--{
-- if (p)
-- kref_get(&(p->count));
--
-- return p;
--}
--
--static inline void aa_put_proxy(struct aa_proxy *p)
--{
-- if (p)
-- kref_put(&p->count, aa_free_proxy_kref);
-+ kref_put(&p->label.count, aa_label_kref);
- }
-
- static inline int AUDIT_MODE(struct aa_profile *profile)
-@@ -336,7 +290,7 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
-
- bool policy_view_capable(struct aa_ns *ns);
- bool policy_admin_capable(struct aa_ns *ns);
--int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns,
-+int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns,
- u32 mask);
-
- #endif /* __AA_POLICY_H */
-diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h
-index 2f7e480a34e0..9605f18624e2 100644
---- a/security/apparmor/include/policy_ns.h
-+++ b/security/apparmor/include/policy_ns.h
-@@ -19,6 +19,7 @@
-
- #include "apparmor.h"
- #include "apparmorfs.h"
-+#include "label.h"
- #include "policy.h"
-
-
-@@ -71,6 +72,7 @@ struct aa_ns {
- long revision;
- wait_queue_head_t wait;
-
-+ struct aa_labelset labels;
- struct list_head rawdata_list;
-
- struct dentry *dents[AAFS_NS_SIZEOF];
-@@ -80,6 +82,8 @@ extern struct aa_ns *root_ns;
-
- extern const char *aa_hidden_ns_name;
-
-+#define ns_unconfined(NS) (&(NS)->unconfined->label)
-+
- bool aa_ns_visible(struct aa_ns *curr, struct aa_ns *view, bool subns);
- const char *aa_ns_name(struct aa_ns *parent, struct aa_ns *child, bool subns);
- void aa_free_ns(struct aa_ns *ns);
-diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
-index edac790923c3..fa68cd42bd15 100644
---- a/security/apparmor/ipc.c
-+++ b/security/apparmor/ipc.c
-@@ -22,11 +22,12 @@
- #include "include/ipc.h"
-
- /* call back to audit ptrace fields */
--static void audit_cb(struct audit_buffer *ab, void *va)
-+static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
- {
- struct common_audit_data *sa = va;
- audit_log_format(ab, " peer=");
-- audit_log_untrustedstring(ab, aad(sa)->peer->base.hname);
-+ aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
-+ FLAGS_NONE, GFP_ATOMIC);
- }
-
- /**
-@@ -42,10 +43,10 @@ static int aa_audit_ptrace(struct aa_profile *profile,
- {
- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
-
-- aad(&sa)->peer = target;
-+ aad(&sa)->peer = &target->label;
- aad(&sa)->error = error;
-
-- return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
-+ return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_ptrace_cb);
- }
-
- /**
-@@ -64,7 +65,7 @@ int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee,
- * Test mode for PTRACE_MODE_READ || PTRACE_MODE_ATTACH
- */
-
-- if (unconfined(tracer) || tracer == tracee)
-+ if (profile_unconfined(tracer) || tracer == tracee)
- return 0;
- /* log this capability request */
- return aa_capable(tracer, CAP_SYS_PTRACE, 1);
-@@ -90,18 +91,22 @@ int aa_ptrace(struct task_struct *tracer, struct task_struct *tracee,
- * - tracer profile has CAP_SYS_PTRACE
- */
-
-- struct aa_profile *tracer_p = aa_get_task_profile(tracer);
-+ struct aa_label *tracer_l = aa_get_task_label(tracer);
- int error = 0;
-
-- if (!unconfined(tracer_p)) {
-- struct aa_profile *tracee_p = aa_get_task_profile(tracee);
-+ if (!unconfined(tracer_l)) {
-+ struct aa_label *tracee_l = aa_get_task_label(tracee);
-
-- error = aa_may_ptrace(tracer_p, tracee_p, mode);
-- error = aa_audit_ptrace(tracer_p, tracee_p, error);
-+ error = aa_may_ptrace(labels_profile(tracer_l),
-+ labels_profile(tracee_l),
-+ mode);
-+ error = aa_audit_ptrace(labels_profile(tracer_l),
-+ labels_profile(tracee_l),
-+ error);
-
-- aa_put_profile(tracee_p);
-+ aa_put_label(tracee_l);
- }
-- aa_put_profile(tracer_p);
-+ aa_put_label(tracer_l);
-
- return error;
- }
-diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
-index 0ceecdbb4658..08ca26bcca77 100644
---- a/security/apparmor/lib.c
-+++ b/security/apparmor/lib.c
-@@ -247,6 +247,32 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
- }
-
- /**
-+ * aa_audit_perms_cb - generic callback fn for auditing perms
-+ * @ab: audit buffer (NOT NULL)
-+ * @va: audit struct to audit values of (NOT NULL)
-+ */
-+static void aa_audit_perms_cb(struct audit_buffer *ab, void *va)
-+{
-+ struct common_audit_data *sa = va;
-+
-+ if (aad(sa)->request) {
-+ audit_log_format(ab, " requested_mask=");
-+ aa_audit_perm_mask(ab, aad(sa)->request, aa_file_perm_chrs,
-+ PERMS_CHRS_MASK, aa_file_perm_names,
-+ PERMS_NAMES_MASK);
-+ }
-+ if (aad(sa)->denied) {
-+ audit_log_format(ab, "denied_mask=");
-+ aa_audit_perm_mask(ab, aad(sa)->denied, aa_file_perm_chrs,
-+ PERMS_CHRS_MASK, aa_file_perm_names,
-+ PERMS_NAMES_MASK);
-+ }
-+ audit_log_format(ab, " peer=");
-+ aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
-+ FLAGS_NONE, GFP_ATOMIC);
-+}
-+
-+/**
- * aa_apply_modes_to_perms - apply namespace and profile flags to perms
- * @profile: that perms where computed from
- * @perms: perms to apply mode modifiers to
-@@ -310,6 +336,143 @@ void aa_compute_perms(struct aa_dfa *dfa, unsigned int state,
- }
-
- /**
-+ * aa_perms_accum_raw - accumulate perms with out masking off overlapping perms
-+ * @accum - perms struct to accumulate into
-+ * @addend - perms struct to add to @accum
-+ */
-+void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend)
-+{
-+ accum->deny |= addend->deny;
-+ accum->allow &= addend->allow & ~addend->deny;
-+ accum->audit |= addend->audit & addend->allow;
-+ accum->quiet &= addend->quiet & ~addend->allow;
-+ accum->kill |= addend->kill & ~addend->allow;
-+ accum->stop |= addend->stop & ~addend->allow;
-+ accum->complain |= addend->complain & ~addend->allow & ~addend->deny;
-+ accum->cond |= addend->cond & ~addend->allow & ~addend->deny;
-+ accum->hide &= addend->hide & ~addend->allow;
-+ accum->prompt |= addend->prompt & ~addend->allow & ~addend->deny;
-+}
-+
-+/**
-+ * aa_perms_accum - accumulate perms, masking off overlapping perms
-+ * @accum - perms struct to accumulate into
-+ * @addend - perms struct to add to @accum
-+ */
-+void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend)
-+{
-+ accum->deny |= addend->deny;
-+ accum->allow &= addend->allow & ~accum->deny;
-+ accum->audit |= addend->audit & accum->allow;
-+ accum->quiet &= addend->quiet & ~accum->allow;
-+ accum->kill |= addend->kill & ~accum->allow;
-+ accum->stop |= addend->stop & ~accum->allow;
-+ accum->complain |= addend->complain & ~accum->allow & ~accum->deny;
-+ accum->cond |= addend->cond & ~accum->allow & ~accum->deny;
-+ accum->hide &= addend->hide & ~accum->allow;
-+ accum->prompt |= addend->prompt & ~accum->allow & ~accum->deny;
-+}
-+
-+void aa_profile_match_label(struct aa_profile *profile, struct aa_label *label,
-+ int type, u32 request, struct aa_perms *perms)
-+{
-+ /* TODO: doesn't yet handle extended types */
-+ unsigned int state;
-+
-+ state = aa_dfa_next(profile->policy.dfa,
-+ profile->policy.start[AA_CLASS_LABEL],
-+ type);
-+ aa_label_match(profile, label, state, false, request, perms);
-+}
-+
-+
-+/* currently unused */
-+int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
-+ u32 request, int type, u32 *deny,
-+ struct common_audit_data *sa)
-+{
-+ struct aa_perms perms;
-+
-+ aad(sa)->label = &profile->label;
-+ aad(sa)->peer = &target->label;
-+ aad(sa)->request = request;
-+
-+ aa_profile_match_label(profile, &target->label, type, request, &perms);
-+ aa_apply_modes_to_perms(profile, &perms);
-+ *deny |= request & perms.deny;
-+ return aa_check_perms(profile, &perms, request, sa, aa_audit_perms_cb);
-+}
-+
-+/**
-+ * aa_check_perms - do audit mode selection based on perms set
-+ * @profile: profile being checked
-+ * @perms: perms computed for the request
-+ * @request: requested perms
-+ * @deny: Returns: explicit deny set
-+ * @sa: initialized audit structure (MAY BE NULL if not auditing)
-+ * @cb: callback fn for tpye specific fields (MAY BE NULL)
-+ *
-+ * Returns: 0 if permission else error code
-+ *
-+ * Note: profile audit modes need to be set before calling by setting the
-+ * perm masks appropriately.
-+ *
-+ * If not auditing then complain mode is not enabled and the
-+ * error code will indicate whether there was an explicit deny
-+ * with a positive value.
-+ */
-+int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
-+ u32 request, struct common_audit_data *sa,
-+ void (*cb)(struct audit_buffer *, void *))
-+{
-+ int type, error;
-+ bool stop = false;
-+ u32 denied = request & (~perms->allow | perms->deny);
-+
-+ if (likely(!denied)) {
-+ /* mask off perms that are not being force audited */
-+ request &= perms->audit;
-+ if (!request || !sa)
-+ return 0;
-+
-+ type = AUDIT_APPARMOR_AUDIT;
-+ error = 0;
-+ } else {
-+ error = -EACCES;
-+
-+ if (denied & perms->kill)
-+ type = AUDIT_APPARMOR_KILL;
-+ else if (denied == (denied & perms->complain))
-+ type = AUDIT_APPARMOR_ALLOWED;
-+ else
-+ type = AUDIT_APPARMOR_DENIED;
-+
-+ if (denied & perms->stop)
-+ stop = true;
-+ if (denied == (denied & perms->hide))
-+ error = -ENOENT;
-+
-+ denied &= ~perms->quiet;
-+ if (!sa || !denied)
-+ return error;
-+ }
-+
-+ if (sa) {
-+ aad(sa)->label = &profile->label;
-+ aad(sa)->request = request;
-+ aad(sa)->denied = denied;
-+ aad(sa)->error = error;
-+ aa_audit_msg(type, sa, cb);
-+ }
-+
-+ if (type == AUDIT_APPARMOR_ALLOWED)
-+ error = 0;
-+
-+ return error;
-+}
-+
-+
-+/**
- * aa_policy_init - initialize a policy structure
- * @policy: policy to initialize (NOT NULL)
- * @prefix: prefix name if any is required. (MAYBE NULL)
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 7ba43c18687a..3ba08530c92e 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -34,6 +34,7 @@
- #include "include/file.h"
- #include "include/ipc.h"
- #include "include/path.h"
-+#include "include/label.h"
- #include "include/policy.h"
- #include "include/policy_ns.h"
- #include "include/procattr.h"
-@@ -49,7 +50,7 @@ DEFINE_PER_CPU(struct aa_buffers, aa_buffers);
- */
-
- /*
-- * free the associated aa_task_ctx and put its profiles
-+ * free the associated aa_task_ctx and put its labels
- */
- static void apparmor_cred_free(struct cred *cred)
- {
-@@ -115,23 +116,24 @@ static int apparmor_ptrace_traceme(struct task_struct *parent)
- static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
- kernel_cap_t *inheritable, kernel_cap_t *permitted)
- {
-+ struct aa_label *label;
- struct aa_profile *profile;
- const struct cred *cred;
-
- rcu_read_lock();
- cred = __task_cred(target);
-- profile = aa_get_newest_cred_profile(cred);
--
-+ label = aa_get_newest_cred_label(cred);
-+ profile = labels_profile(label);
- /*
- * cap_capget is stacked ahead of this and will
- * initialize effective and permitted.
- */
-- if (!unconfined(profile) && !COMPLAIN_MODE(profile)) {
-+ if (!profile_unconfined(profile) && !COMPLAIN_MODE(profile)) {
- *effective = cap_intersect(*effective, profile->caps.allow);
- *permitted = cap_intersect(*permitted, profile->caps.allow);
- }
- rcu_read_unlock();
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- return 0;
- }
-@@ -139,13 +141,13 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
- static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
- int cap, int audit)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label;
- int error = 0;
-
-- profile = aa_get_newest_cred_profile(cred);
-- if (!unconfined(profile))
-- error = aa_capable(profile, cap, audit);
-- aa_put_profile(profile);
-+ label = aa_get_newest_cred_label(cred);
-+ if (!unconfined(label))
-+ error = aa_capable(labels_profile(label), cap, audit);
-+ aa_put_label(label);
-
- return error;
- }
-@@ -162,13 +164,14 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
- static int common_perm(const char *op, const struct path *path, u32 mask,
- struct path_cond *cond)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label;
- int error = 0;
-
-- profile = __begin_current_profile_crit_section();
-- if (!unconfined(profile))
-- error = aa_path_perm(op, profile, path, 0, mask, cond);
-- __end_current_profile_crit_section(profile);
-+ label = __begin_current_label_crit_section();
-+ if (!unconfined(label))
-+ error = aa_path_perm(op, labels_profile(label), path, 0, mask,
-+ cond);
-+ __end_current_label_crit_section(label);
-
- return error;
- }
-@@ -295,16 +298,17 @@ static int apparmor_path_symlink(const struct path *dir, struct dentry *dentry,
- static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_dir,
- struct dentry *new_dentry)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label;
- int error = 0;
-
- if (!path_mediated_fs(old_dentry))
- return 0;
-
-- profile = begin_current_profile_crit_section();
-- if (!unconfined(profile))
-- error = aa_path_link(profile, old_dentry, new_dir, new_dentry);
-- end_current_profile_crit_section(profile);
-+ label = begin_current_label_crit_section();
-+ if (!unconfined(label))
-+ error = aa_path_link(labels_profile(label), old_dentry, new_dir,
-+ new_dentry);
-+ end_current_label_crit_section(label);
-
- return error;
- }
-@@ -312,14 +316,14 @@ static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_
- static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_dentry,
- const struct path *new_dir, struct dentry *new_dentry)
- {
-- struct aa_profile *profile;
-+ struct aa_label *label;
- int error = 0;
-
- if (!path_mediated_fs(old_dentry))
- return 0;
-
-- profile = begin_current_profile_crit_section();
-- if (!unconfined(profile)) {
-+ label = begin_current_label_crit_section();
-+ if (!unconfined(label)) {
- struct path old_path = { .mnt = old_dir->mnt,
- .dentry = old_dentry };
- struct path new_path = { .mnt = new_dir->mnt,
-@@ -328,17 +332,20 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d
- d_backing_inode(old_dentry)->i_mode
- };
-
-- error = aa_path_perm(OP_RENAME_SRC, profile, &old_path, 0,
-+ error = aa_path_perm(OP_RENAME_SRC, labels_profile(label),
-+ &old_path, 0,
- MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
- AA_MAY_SETATTR | AA_MAY_DELETE,
- &cond);
- if (!error)
-- error = aa_path_perm(OP_RENAME_DEST, profile, &new_path,
-+ error = aa_path_perm(OP_RENAME_DEST,
-+ labels_profile(label),
-+ &new_path,
- 0, MAY_WRITE | AA_MAY_SETATTR |
- AA_MAY_CREATE, &cond);
-
- }
-- end_current_profile_crit_section(profile);
-+ end_current_label_crit_section(label);
-
- return error;
- }
-@@ -360,8 +367,8 @@ static int apparmor_inode_getattr(const struct path *path)
-
- static int apparmor_file_open(struct file *file, const struct cred *cred)
- {
-- struct aa_file_ctx *fctx = file->f_security;
-- struct aa_profile *profile;
-+ struct aa_file_ctx *fctx = file_ctx(file);
-+ struct aa_label *label;
- int error = 0;
-
- if (!path_mediated_fs(file->f_path.dentry))
-@@ -377,17 +384,18 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)
- return 0;
- }
-
-- profile = aa_get_newest_cred_profile(cred);
-- if (!unconfined(profile)) {
-+ label = aa_get_newest_cred_label(cred);
-+ if (!unconfined(label)) {
- struct inode *inode = file_inode(file);
- struct path_cond cond = { inode->i_uid, inode->i_mode };
-
-- error = aa_path_perm(OP_OPEN, profile, &file->f_path, 0,
-+ error = aa_path_perm(OP_OPEN, labels_profile(label),
-+ &file->f_path, 0,
- aa_map_file_to_perms(file), &cond);
- /* todo cache full allowed permissions set and state */
- fctx->allow = aa_map_file_to_perms(file);
- }
-- aa_put_profile(profile);
-+ aa_put_label(label);
-
- return error;
- }
-@@ -397,11 +405,11 @@ static int apparmor_file_alloc_security(struct file *file)
- int error = 0;
-
- /* freed by apparmor_file_free_security */
-- struct aa_profile *profile = begin_current_profile_crit_section();
-+ struct aa_label *label = begin_current_label_crit_section();
- file->f_security = aa_alloc_file_ctx(GFP_KERNEL);
- if (!file_ctx(file))
- error = -ENOMEM;
-- end_current_profile_crit_section(profile);
-+ end_current_label_crit_section(label);
-
- return error;
- }
-@@ -414,21 +422,21 @@ static void apparmor_file_free_security(struct file *file)
- static int common_file_perm(const char *op, struct file *file, u32 mask)
- {
- struct aa_file_ctx *fctx = file->f_security;
-- struct aa_profile *profile, *fprofile;
-+ struct aa_label *label, *flabel;
- int error = 0;
-
- /* don't reaudit files closed during inheritance */
- if (file->f_path.dentry == aa_null.dentry)
- return -EACCES;
-
-- fprofile = aa_cred_raw_profile(file->f_cred);
-- AA_BUG(!fprofile);
-+ flabel = aa_cred_raw_label(file->f_cred);
-+ AA_BUG(!flabel);
-
- if (!file->f_path.mnt ||
- !path_mediated_fs(file->f_path.dentry))
- return 0;
-
-- profile = __begin_current_profile_crit_section();
-+ label = __begin_current_label_crit_section();
-
- /* revalidate access, if task is unconfined, or the cached cred
- * doesn't match or if the request is for more permissions than
-@@ -437,10 +445,10 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
- * Note: the test for !unconfined(fprofile) is to handle file
- * delegation from unconfined tasks
- */
-- if (!unconfined(profile) && !unconfined(fprofile) &&
-- ((fprofile != profile) || (mask & ~fctx->allow)))
-- error = aa_file_perm(op, profile, file, mask);
-- __end_current_profile_crit_section(profile);
-+ if (!unconfined(label) && !unconfined(flabel) &&
-+ ((flabel != label) || (mask & ~fctx->allow)))
-+ error = aa_file_perm(op, labels_profile(label), file, mask);
-+ __end_current_label_crit_section(label);
-
- return error;
- }
-@@ -465,7 +473,7 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot,
- {
- int mask = 0;
-
-- if (!file || !file->f_security)
-+ if (!file || !file_ctx(file))
- return 0;
-
- if (prot & PROT_READ)
-@@ -502,21 +510,21 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
- /* released below */
- const struct cred *cred = get_task_cred(task);
- struct aa_task_ctx *ctx = cred_ctx(cred);
-- struct aa_profile *profile = NULL;
-+ struct aa_label *label = NULL;
-
- if (strcmp(name, "current") == 0)
-- profile = aa_get_newest_profile(ctx->profile);
-+ label = aa_get_newest_label(ctx->label);
- else if (strcmp(name, "prev") == 0 && ctx->previous)
-- profile = aa_get_newest_profile(ctx->previous);
-+ label = aa_get_newest_label(ctx->previous);
- else if (strcmp(name, "exec") == 0 && ctx->onexec)
-- profile = aa_get_newest_profile(ctx->onexec);
-+ label = aa_get_newest_label(ctx->onexec);
- else
- error = -EINVAL;
-
-- if (profile)
-- error = aa_getprocattr(profile, value);
-+ if (label)
-+ error = aa_getprocattr(labels_profile(label), value);
-
-- aa_put_profile(profile);
-+ aa_put_label(label);
- put_cred(cred);
-
- return error;
-@@ -582,11 +590,11 @@ static int apparmor_setprocattr(const char *name, void *value,
- return error;
-
- fail:
-- aad(&sa)->profile = begin_current_profile_crit_section();
-+ aad(&sa)->label = begin_current_label_crit_section();
- aad(&sa)->info = name;
- aad(&sa)->error = error = -EINVAL;
- aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
-- end_current_profile_crit_section(aad(&sa)->profile);
-+ end_current_label_crit_section(aad(&sa)->label);
- goto out;
- }
-
-@@ -596,20 +604,21 @@ static int apparmor_setprocattr(const char *name, void *value,
- */
- static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
- {
-- struct aa_profile *profile = aa_current_raw_profile();
-+ struct aa_label *label = aa_current_raw_label();
- struct aa_task_ctx *new_ctx = cred_ctx(bprm->cred);
-
- /* bail out if unconfined or not changing profile */
-- if ((new_ctx->profile == profile) ||
-- (unconfined(new_ctx->profile)))
-+ if ((new_ctx->label->proxy == label->proxy) ||
-+ (unconfined(new_ctx->label)))
- return;
-
- aa_inherit_files(bprm->cred, current->files);
-
- current->pdeath_signal = 0;
-
-- /* reset soft limits and set hard limits for the new profile */
-- __aa_transition_rlimits(profile, new_ctx->profile);
-+ /* reset soft limits and set hard limits for the new label */
-+ __aa_transition_rlimits(labels_profile(label),
-+ labels_profile(new_ctx->label));
- }
-
- /**
-@@ -625,12 +634,13 @@ static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
- static int apparmor_task_setrlimit(struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim)
- {
-- struct aa_profile *profile = __begin_current_profile_crit_section();
-+ struct aa_label *label = __begin_current_label_crit_section();
- int error = 0;
-
-- if (!unconfined(profile))
-- error = aa_task_setrlimit(profile, task, resource, new_rlim);
-- __end_current_profile_crit_section(profile);
-+ if (!unconfined(label))
-+ error = aa_task_setrlimit(labels_profile(label), task,
-+ resource, new_rlim);
-+ __end_current_label_crit_section(label);
-
- return error;
- }
-@@ -924,7 +934,7 @@ static int __init set_init_ctx(void)
- if (!ctx)
- return -ENOMEM;
-
-- ctx->profile = aa_get_profile(root_ns->unconfined);
-+ ctx->label = aa_get_label(ns_unconfined(root_ns));
- cred_ctx(cred) = ctx;
-
- return 0;
-diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
-index 605cb5949c60..244ea4a4a8f0 100644
---- a/security/apparmor/policy.c
-+++ b/security/apparmor/policy.c
-@@ -101,20 +101,9 @@ const char *const aa_profile_mode_names[] = {
- "unconfined",
- };
-
--/* requires profile list write lock held */
--void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new)
--{
-- struct aa_profile *tmp;
--
-- tmp = rcu_dereference_protected(orig->proxy->profile,
-- mutex_is_locked(&orig->ns->lock));
-- rcu_assign_pointer(orig->proxy->profile, aa_get_profile(new));
-- orig->flags |= PFLAG_STALE;
-- aa_put_profile(tmp);
--}
-
- /**
-- * __list_add_profile - add a profile to a list
-+ * __add_profile - add a profiles to list and label tree
- * @list: list to add it to (NOT NULL)
- * @profile: the profile to add (NOT NULL)
- *
-@@ -122,12 +111,21 @@ void __aa_update_proxy(struct aa_profile *orig, struct aa_profile *new)
- *
- * Requires: namespace lock be held, or list not be shared
- */
--static void __list_add_profile(struct list_head *list,
-- struct aa_profile *profile)
-+static void __add_profile(struct list_head *list, struct aa_profile *profile)
- {
-+ struct aa_label *l;
-+
-+ AA_BUG(!list);
-+ AA_BUG(!profile);
-+ AA_BUG(!profile->ns);
-+ AA_BUG(!mutex_is_locked(&profile->ns->lock));
-+
- list_add_rcu(&profile->base.list, list);
- /* get list reference */
- aa_get_profile(profile);
-+ l = aa_label_insert(&profile->ns->labels, &profile->label);
-+ AA_BUG(l != &profile->label);
-+ aa_put_label(l);
- }
-
- /**
-@@ -144,6 +142,10 @@ static void __list_add_profile(struct list_head *list,
- */
- static void __list_remove_profile(struct aa_profile *profile)
- {
-+ AA_BUG(!profile);
-+ AA_BUG(!profile->ns);
-+ AA_BUG(!mutex_is_locked(&profile->ns->lock));
-+
- list_del_rcu(&profile->base.list);
- aa_put_profile(profile);
- }
-@@ -156,10 +158,14 @@ static void __list_remove_profile(struct aa_profile *profile)
- */
- static void __remove_profile(struct aa_profile *profile)
- {
-+ AA_BUG(!profile);
-+ AA_BUG(!profile->ns);
-+ AA_BUG(!mutex_is_locked(&profile->ns->lock));
-+
- /* release any children lists first */
- __aa_profile_list_release(&profile->base.profiles);
- /* released by free_profile */
-- __aa_update_proxy(profile, profile->ns->unconfined);
-+ aa_label_remove(&profile->label);
- __aafs_profile_rmdir(profile);
- __list_remove_profile(profile);
- }
-@@ -177,24 +183,6 @@ void __aa_profile_list_release(struct list_head *head)
- __remove_profile(profile);
- }
-
--
--static void free_proxy(struct aa_proxy *p)
--{
-- if (p) {
-- /* r->profile will not be updated any more as r is dead */
-- aa_put_profile(rcu_dereference_protected(p->profile, true));
-- kzfree(p);
-- }
--}
--
--
--void aa_free_proxy_kref(struct kref *kref)
--{
-- struct aa_proxy *p = container_of(kref, struct aa_proxy, count);
--
-- free_proxy(p);
--}
--
- /**
- * aa_free_data - free a data blob
- * @ptr: data to free
-@@ -242,7 +230,6 @@ void aa_free_profile(struct aa_profile *profile)
- kzfree(profile->dirname);
- aa_put_dfa(profile->xmatch);
- aa_put_dfa(profile->policy.dfa);
-- aa_put_proxy(profile->proxy);
-
- if (profile->data) {
- rht = profile->data;
-@@ -253,30 +240,8 @@ void aa_free_profile(struct aa_profile *profile)
-
- kzfree(profile->hash);
- aa_put_loaddata(profile->rawdata);
-- kzfree(profile);
--}
-
--/**
-- * aa_free_profile_rcu - free aa_profile by rcu (called by aa_free_profile_kref)
-- * @head: rcu_head callback for freeing of a profile (NOT NULL)
-- */
--static void aa_free_profile_rcu(struct rcu_head *head)
--{
-- struct aa_profile *p = container_of(head, struct aa_profile, rcu);
-- if (p->flags & PFLAG_NS_COUNT)
-- aa_free_ns(p->ns);
-- else
-- aa_free_profile(p);
--}
--
--/**
-- * aa_free_profile_kref - free aa_profile by kref (called by aa_put_profile)
-- * @kr: kref callback for freeing of a profile (NOT NULL)
-- */
--void aa_free_profile_kref(struct kref *kref)
--{
-- struct aa_profile *p = container_of(kref, struct aa_profile, count);
-- call_rcu(&p->rcu, aa_free_profile_rcu);
-+ kzfree(profile);
- }
-
- /**
-@@ -286,30 +251,40 @@ void aa_free_profile_kref(struct kref *kref)
- *
- * Returns: refcount profile or NULL on failure
- */
--struct aa_profile *aa_alloc_profile(const char *hname, gfp_t gfp)
-+struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy,
-+ gfp_t gfp)
- {
- struct aa_profile *profile;
-
- /* freed by free_profile - usually through aa_put_profile */
-- profile = kzalloc(sizeof(*profile), gfp);
-+ profile = kzalloc(sizeof(*profile) + sizeof(struct aa_profile *) * 2,
-+ gfp);
- if (!profile)
- return NULL;
-
-- profile->proxy = kzalloc(sizeof(struct aa_proxy), gfp);
-- if (!profile->proxy)
-- goto fail;
-- kref_init(&profile->proxy->count);
--
- if (!aa_policy_init(&profile->base, NULL, hname, gfp))
- goto fail;
-- kref_init(&profile->count);
-+ if (!aa_label_init(&profile->label, 1))
-+ goto fail;
-+
-+ /* update being set needed by fs interface */
-+ if (!proxy) {
-+ proxy = aa_alloc_proxy(&profile->label, gfp);
-+ if (!proxy)
-+ goto fail;
-+ } else
-+ aa_get_proxy(proxy);
-+ profile->label.proxy = proxy;
-+
-+ profile->label.hname = profile->base.hname;
-+ profile->label.flags |= FLAG_PROFILE;
-+ profile->label.vec[0] = profile;
-
- /* refcount released by caller */
- return profile;
-
- fail:
-- kzfree(profile->proxy);
-- kzfree(profile);
-+ aa_free_profile(profile);
-
- return NULL;
- }
-@@ -362,14 +337,14 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- if (profile)
- goto out;
-
-- profile = aa_alloc_profile(name, gfp);
-+ profile = aa_alloc_profile(name, NULL, gfp);
- if (!profile)
- goto fail;
-
- profile->mode = APPARMOR_COMPLAIN;
-- profile->flags |= PFLAG_NULL;
-+ profile->label.flags |= FLAG_NULL;
- if (hat)
-- profile->flags |= PFLAG_HAT;
-+ profile->label.flags |= FLAG_HAT;
- profile->path_flags = parent->path_flags;
-
- /* released on free_profile */
-@@ -379,7 +354,7 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- profile->policy.dfa = aa_get_dfa(nulldfa);
-
- mutex_lock(&profile->ns->lock);
-- __list_add_profile(&parent->base.profiles, profile);
-+ __add_profile(&parent->base.profiles, profile);
- mutex_unlock(&profile->ns->lock);
-
- /* refcount released by caller */
-@@ -389,7 +364,6 @@ struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat,
- return profile;
-
- fail:
-- kfree(name);
- aa_free_profile(profile);
- return NULL;
- }
-@@ -556,7 +530,7 @@ struct aa_profile *aa_lookup_profile(struct aa_ns *ns, const char *hname)
- return aa_lookupn_profile(ns, hname, strlen(hname));
- }
-
--struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
-+struct aa_profile *aa_fqlookupn_profile(struct aa_label *base,
- const char *fqname, size_t n)
- {
- struct aa_profile *profile;
-@@ -566,11 +540,11 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_profile *base,
-
- name = aa_splitn_fqname(fqname, n, &ns_name, &ns_len);
- if (ns_name) {
-- ns = aa_lookupn_ns(base->ns, ns_name, ns_len);
-+ ns = aa_lookupn_ns(labels_ns(base), ns_name, ns_len);
- if (!ns)
- return NULL;
- } else
-- ns = aa_get_ns(base->ns);
-+ ns = aa_get_ns(labels_ns(base));
-
- if (name)
- profile = aa_lookupn_profile(ns, name, n - (name - fqname));
-@@ -596,7 +570,7 @@ static int replacement_allowed(struct aa_profile *profile, int noreplace,
- const char **info)
- {
- if (profile) {
-- if (profile->flags & PFLAG_IMMUTABLE) {
-+ if (profile->label.flags & FLAG_IMMUTIBLE) {
- *info = "cannot replace immutible profile";
- return -EPERM;
- } else if (noreplace) {
-@@ -619,29 +593,31 @@ static void audit_cb(struct audit_buffer *ab, void *va)
- }
-
- /**
-- * aa_audit_policy - Do auditing of policy changes
-- * @profile: profile to check if it can manage policy
-+ * audit_policy - Do auditing of policy changes
-+ * @label: label to check if it can manage policy
- * @op: policy operation being performed
-- * @gfp: memory allocation flags
-- * @nsname: name of the ns being manipulated (MAY BE NULL)
-+ * @ns_name: name of namespace being manipulated
- * @name: name of profile being manipulated (NOT NULL)
- * @info: any extra information to be audited (MAYBE NULL)
- * @error: error code
- *
- * Returns: the error to be returned after audit is done
- */
--static int audit_policy(struct aa_profile *profile, const char *op,
-- const char *nsname, const char *name,
-+static int audit_policy(struct aa_label *label, const char *op,
-+ const char *ns_name, const char *name,
- const char *info, int error)
- {
- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op);
-
-- aad(&sa)->iface.ns = nsname;
-+ aad(&sa)->iface.ns = ns_name;
- aad(&sa)->name = name;
- aad(&sa)->info = info;
- aad(&sa)->error = error;
-+ aad(&sa)->label = label;
-
-- return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
-+ aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, audit_cb);
-+
-+ return error;
- }
-
- /**
-@@ -685,12 +661,12 @@ bool policy_admin_capable(struct aa_ns *ns)
-
- /**
- * aa_may_manage_policy - can the current task manage policy
-- * @profile: profile to check if it can manage policy
-+ * @label: label to check if it can manage policy
- * @op: the policy manipulation operation being done
- *
- * Returns: 0 if the task is allowed to manipulate policy else error
- */
--int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, u32 mask)
-+int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask)
- {
- const char *op;
-
-@@ -703,11 +679,11 @@ int aa_may_manage_policy(struct aa_profile *profile, struct aa_ns *ns, u32 mask)
-
- /* check if loading policy is locked out */
- if (aa_g_lock_policy)
-- return audit_policy(profile, op, NULL, NULL, "policy_locked",
-+ return audit_policy(label, op, NULL, NULL, "policy_locked",
- -EACCES);
-
- if (!policy_admin_capable(ns))
-- return audit_policy(profile, op, NULL, NULL, "not policy admin",
-+ return audit_policy(label, op, NULL, NULL, "not policy admin",
- -EACCES);
-
- /* TODO: add fine grained mediation of policy loads */
-@@ -750,8 +726,7 @@ static struct aa_profile *__list_lookup_parent(struct list_head *lh,
- *
- * Requires: namespace list lock be held, or list not be shared
- */
--static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
-- bool share_proxy)
-+static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
- {
- struct aa_profile *child, *tmp;
-
-@@ -766,7 +741,7 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
- p = __find_child(&new->base.profiles, child->base.name);
- if (p) {
- /* @p replaces @child */
-- __replace_profile(child, p, share_proxy);
-+ __replace_profile(child, p);
- continue;
- }
-
-@@ -784,14 +759,8 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new,
- struct aa_profile *parent = aa_deref_parent(old);
- rcu_assign_pointer(new->parent, aa_get_profile(parent));
- }
-- __aa_update_proxy(old, new);
-- if (share_proxy) {
-- aa_put_proxy(new->proxy);
-- new->proxy = aa_get_proxy(old->proxy);
-- } else if (!rcu_access_pointer(new->proxy->profile))
-- /* aafs interface uses proxy */
-- rcu_assign_pointer(new->proxy->profile,
-- aa_get_profile(new));
-+ aa_label_replace(&old->label, &new->label);
-+ /* migrate dents must come after label replacement b/c update */
- __aafs_profile_migrate_dents(old, new);
-
- if (list_empty(&new->base.list)) {
-@@ -835,6 +804,7 @@ static void share_name(struct aa_profile *old, struct aa_profile *new)
- aa_get_str(old->base.hname);
- new->base.hname = old->base.hname;
- new->base.name = old->base.name;
-+ new->label.hname = old->label.hname;
- }
-
- /* Update to newest version of parent after previous replacements
-@@ -871,7 +841,7 @@ static struct aa_profile *update_to_newest_parent(struct aa_profile *new)
- *
- * Returns: size of data consumed else error code on failure.
- */
--ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
-+ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label,
- u32 mask, struct aa_loaddata *udata)
- {
- const char *ns_name, *info = NULL;
-@@ -914,7 +884,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- count++;
- }
- if (ns_name) {
-- ns = aa_prepare_ns(policy_ns ? policy_ns : profile->ns,
-+ ns = aa_prepare_ns(policy_ns ? policy_ns : labels_ns(label),
- ns_name);
- if (IS_ERR(ns)) {
- op = OP_PROF_LOAD;
-@@ -925,7 +895,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- goto fail;
- }
- } else
-- ns = aa_get_ns(policy_ns ? policy_ns : profile->ns);
-+ ns = aa_get_ns(policy_ns ? policy_ns : labels_ns(label));
-
- mutex_lock(&ns->lock);
- /* check for duplicate rawdata blobs: space and file dedup */
-@@ -955,8 +925,8 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
-
- if (ent->new->rename) {
- error = __lookup_replace(ns, ent->new->rename,
-- !(mask & AA_MAY_REPLACE_POLICY),
-- &ent->rename, &info);
-+ !(mask & AA_MAY_REPLACE_POLICY),
-+ &ent->rename, &info);
- if (error)
- goto fail_lock;
- }
-@@ -1021,7 +991,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
-
- if (ent->old && ent->old->rawdata == ent->new->rawdata) {
- /* dedup actual profile replacement */
-- audit_policy(profile, op, ns_name, ent->new->base.hname,
-+ audit_policy(label, op, ns_name, ent->new->base.hname,
- "same as current profile, skipping",
- error);
- goto skip;
-@@ -1031,12 +1001,12 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- * TODO: finer dedup based on profile range in data. Load set
- * can differ but profile may remain unchanged
- */
-- audit_policy(profile, op, NULL, ent->new->base.hname,
-- NULL, error);
-+ audit_policy(label, op, ns_name, ent->new->base.hname, NULL,
-+ error);
-
- if (ent->old) {
- share_name(ent->old, ent->new);
-- __replace_profile(ent->old, ent->new, 1);
-+ __replace_profile(ent->old, ent->new);
- } else {
- struct list_head *lh;
-
-@@ -1047,11 +1017,12 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- lh = &parent->base.profiles;
- } else
- lh = &ns->base.profiles;
-- __list_add_profile(lh, ent->new);
-+ __add_profile(lh, ent->new);
- }
- skip:
- aa_load_ent_free(ent);
- }
-+ __aa_labelset_update_subtree(ns);
- mutex_unlock(&ns->lock);
-
- out:
-@@ -1068,8 +1039,8 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- /* audit cause of failure */
- op = (ent && !ent->old) ? OP_PROF_LOAD : OP_PROF_REPL;
- fail:
-- audit_policy(profile, op, ns_name, ent ? ent->new->base.hname : NULL,
-- info, error);
-+ audit_policy(label, op, ns_name, ent ? ent->new->base.hname : NULL,
-+ info, error);
- /* audit status that rest of profiles in the atomic set failed too */
- info = "valid profile in failed atomic policy load";
- list_for_each_entry(tmp, &lh, list) {
-@@ -1079,8 +1050,8 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- continue;
- }
- op = (!tmp->old) ? OP_PROF_LOAD : OP_PROF_REPL;
-- audit_policy(profile, op, ns_name,
-- tmp->new->base.hname, info, error);
-+ audit_policy(label, op, ns_name, tmp->new->base.hname, info,
-+ error);
- }
- list_for_each_entry_safe(ent, tmp, &lh, list) {
- list_del_init(&ent->list);
-@@ -1093,7 +1064,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- /**
- * aa_remove_profiles - remove profile(s) from the system
- * @policy_ns: namespace the remove is being done from
-- * @subj: profile attempting to remove policy
-+ * @subj: label attempting to remove policy
- * @fqname: name of the profile or namespace to remove (NOT NULL)
- * @size: size of the name
- *
-@@ -1104,7 +1075,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_profile *profile,
- *
- * Returns: size of data consume else error code if fails
- */
--ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_profile *subj,
-+ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj,
- char *fqname, size_t size)
- {
- struct aa_ns *ns = NULL;
-@@ -1124,8 +1095,8 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_profile *subj,
-
- name = aa_splitn_fqname(fqname, size, &ns_name, &ns_len);
- /* released below */
-- ns = aa_lookupn_ns(policy_ns ? policy_ns : subj->ns, ns_name,
-- ns_len);
-+ ns = aa_lookupn_ns(policy_ns ? policy_ns : labels_ns(subj),
-+ ns_name, ns_len);
- if (!ns) {
- info = "namespace does not exist";
- error = -ENOENT;
-@@ -1133,7 +1104,7 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_profile *subj,
- }
- } else
- /* released below */
-- ns = aa_get_ns(policy_ns ? policy_ns : subj->ns);
-+ ns = aa_get_ns(policy_ns ? policy_ns : labels_ns(subj));
-
- if (!name) {
- /* remove namespace - can only happen if fqname[0] == ':' */
-@@ -1152,6 +1123,7 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_profile *subj,
- }
- name = profile->base.hname;
- __remove_profile(profile);
-+ __aa_labelset_update_subtree(ns);
- __aa_bump_ns_revision(ns);
- mutex_unlock(&ns->lock);
- }
-diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
-index c05316809a5e..351d3bab3a3d 100644
---- a/security/apparmor/policy_ns.c
-+++ b/security/apparmor/policy_ns.c
-@@ -23,6 +23,7 @@
- #include "include/apparmor.h"
- #include "include/context.h"
- #include "include/policy_ns.h"
-+#include "include/label.h"
- #include "include/policy.h"
-
- /* root profile namespace */
-@@ -104,12 +105,12 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
- init_waitqueue_head(&ns->wait);
-
- /* released by aa_free_ns() */
-- ns->unconfined = aa_alloc_profile("unconfined", GFP_KERNEL);
-+ ns->unconfined = aa_alloc_profile("unconfined", NULL, GFP_KERNEL);
- if (!ns->unconfined)
- goto fail_unconfined;
-
-- ns->unconfined->flags = PFLAG_IX_ON_NAME_ERROR |
-- PFLAG_IMMUTABLE | PFLAG_NS_COUNT;
-+ ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR |
-+ FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED;
- ns->unconfined->mode = APPARMOR_UNCONFINED;
-
- /* ns and ns->unconfined share ns->unconfined refcount */
-@@ -117,6 +118,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
-
- atomic_set(&ns->uniq_null, 0);
-
-+ aa_labelset_init(&ns->labels);
-+
- return ns;
-
- fail_unconfined:
-@@ -139,6 +142,7 @@ void aa_free_ns(struct aa_ns *ns)
- return;
-
- aa_policy_destroy(&ns->base);
-+ aa_labelset_destroy(&ns->labels);
- aa_put_ns(ns->parent);
-
- ns->unconfined->ns = NULL;
-@@ -337,8 +341,14 @@ static void destroy_ns(struct aa_ns *ns)
- /* release all sub namespaces */
- __ns_list_release(&ns->sub_ns);
-
-- if (ns->parent)
-- __aa_update_proxy(ns->unconfined, ns->parent->unconfined);
-+ if (ns->parent) {
-+ unsigned long flags;
-+
-+ write_lock_irqsave(&ns->labels.lock, flags);
-+ __aa_proxy_redirect(ns_unconfined(ns),
-+ ns_unconfined(ns->parent));
-+ write_unlock_irqrestore(&ns->labels.lock, flags);
-+ }
- __aafs_ns_rmdir(ns);
- mutex_unlock(&ns->lock);
- }
-diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
-index 1db4746270ab..c010f8b56e1f 100644
---- a/security/apparmor/policy_unpack.c
-+++ b/security/apparmor/policy_unpack.c
-@@ -26,6 +26,7 @@
- #include "include/context.h"
- #include "include/crypto.h"
- #include "include/match.h"
-+#include "include/path.h"
- #include "include/policy.h"
- #include "include/policy_unpack.h"
-
-@@ -107,7 +108,7 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
- const char *name, const char *info, struct aa_ext *e,
- int error)
- {
-- struct aa_profile *profile = aa_current_raw_profile();
-+ struct aa_profile *profile = labels_profile(aa_current_raw_label());
- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
- if (e)
- aad(&sa)->iface.pos = e->pos - e->start;
-@@ -602,7 +603,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- name = tmpname;
- }
-
-- profile = aa_alloc_profile(name, GFP_KERNEL);
-+ profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
- if (!profile)
- return ERR_PTR(-ENOMEM);
-
-@@ -635,7 +636,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
- if (!unpack_u32(e, &tmp, NULL))
- goto fail;
- if (tmp & PACKED_FLAG_HAT)
-- profile->flags |= PFLAG_HAT;
-+ profile->label.flags |= FLAG_HAT;
- if (!unpack_u32(e, &tmp, NULL))
- goto fail;
- if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG))
-@@ -654,10 +655,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
-
- /* path_flags is optional */
- if (unpack_u32(e, &profile->path_flags, "path_flags"))
-- profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED;
-+ profile->path_flags |= profile->label.flags &
-+ PATH_MEDIATE_DELETED;
- else
- /* set a default value if path_flags field is not present */
-- profile->path_flags = PFLAG_MEDIATE_DELETED;
-+ profile->path_flags = PATH_MEDIATE_DELETED;
-
- if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
- goto fail;
-diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
-index 2f0cb424927a..dce970d1f46b 100644
---- a/security/apparmor/procattr.c
-+++ b/security/apparmor/procattr.c
-@@ -55,7 +55,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
- ns_len += 4;
-
- /* unconfined profiles don't have a mode string appended */
-- if (!unconfined(profile))
-+ if (!profile_unconfined(profile))
- mode_len = strlen(mode_str) + 3; /* + 3 for _() */
-
- name_len = strlen(profile->base.hname);
-@@ -69,7 +69,7 @@ int aa_getprocattr(struct aa_profile *profile, char **string)
- sprintf(s, ":%s://", ns_name);
- s += ns_len;
- }
-- if (unconfined(profile))
-+ if (profile_unconfined(profile))
- /* mode string not being appended */
- sprintf(s, "%s\n", profile->base.hname);
- else
-diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
-index b26f1dac5106..ab8e104c1970 100644
---- a/security/apparmor/resource.c
-+++ b/security/apparmor/resource.c
-@@ -86,11 +86,11 @@ int aa_map_resource(int resource)
- int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim)
- {
-- struct aa_profile *task_profile;
-+ struct aa_label *task_label;
- int error = 0;
-
- rcu_read_lock();
-- task_profile = aa_get_newest_cred_profile((__task_cred(task)));
-+ task_label = aa_get_newest_cred_label((__task_cred(task)));
- rcu_read_unlock();
-
- /* TODO: extend resource control to handle other (non current)
-@@ -99,13 +99,13 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
- * the same profile or that the task setting the resource of another
- * task has CAP_SYS_RESOURCE.
- */
-- if ((profile != task_profile &&
-+ if ((profile != labels_profile(task_label) &&
- aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
- (profile->rlimits.mask & (1 << resource) &&
- new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
- error = -EACCES;
-
-- aa_put_profile(task_profile);
-+ aa_put_label(task_label);
-
- return audit_resource(profile, resource, new_rlim->rlim_max, error);
- }
---
-2.12.3
-
diff --git a/patches.apparmor/0045-apparmor-switch-getprocattr-to-using-label_print-fns.patch b/patches.apparmor/0045-apparmor-switch-getprocattr-to-using-label_print-fns.patch
deleted file mode 100644
index 47b764d0a3..0000000000
--- a/patches.apparmor/0045-apparmor-switch-getprocattr-to-using-label_print-fns.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-From d9ae8bd017650ae43ef2c633694a36b8ea8186a7 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 12:47:17 -0700
-Subject: [PATCH 45/65] apparmor: switch getprocattr to using label_print fns(
-Git-commit: 76a1d263aba3c97db7a2ba673059e0f17d983efb
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/procattr.h | 2 +-
- security/apparmor/lsm.c | 2 +-
- security/apparmor/procattr.c | 60 +++++++++++++++---------------------
- 3 files changed, 27 insertions(+), 37 deletions(-)
-
-diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h
-index c0055d727868..c8fd99c9357d 100644
---- a/security/apparmor/include/procattr.h
-+++ b/security/apparmor/include/procattr.h
-@@ -15,7 +15,7 @@
- #ifndef __AA_PROCATTR_H
- #define __AA_PROCATTR_H
-
--int aa_getprocattr(struct aa_profile *profile, char **string);
-+int aa_getprocattr(struct aa_label *label, char **string);
- int aa_setprocattr_changehat(char *args, size_t size, int flags);
-
- #endif /* __AA_PROCATTR_H */
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index 3ba08530c92e..f7f82ce00d73 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -522,7 +522,7 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,
- error = -EINVAL;
-
- if (label)
-- error = aa_getprocattr(labels_profile(label), value);
-+ error = aa_getprocattr(label, value);
-
- aa_put_label(label);
- put_cred(cred);
-diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c
-index dce970d1f46b..d81617379d63 100644
---- a/security/apparmor/procattr.c
-+++ b/security/apparmor/procattr.c
-@@ -34,51 +34,41 @@
- *
- * Returns: size of string placed in @string else error code on failure
- */
--int aa_getprocattr(struct aa_profile *profile, char **string)
-+int aa_getprocattr(struct aa_label *label, char **string)
- {
-- char *str;
-- int len = 0, mode_len = 0, ns_len = 0, name_len;
-- const char *mode_str = aa_profile_mode_names[profile->mode];
-- const char *ns_name = NULL;
-- struct aa_ns *ns = profile->ns;
-+ struct aa_ns *ns = labels_ns(label);
- struct aa_ns *current_ns = aa_get_current_ns();
-- char *s;
-+ int len;
-
-- if (!aa_ns_visible(current_ns, ns, true))
-+ if (!aa_ns_visible(current_ns, ns, true)) {
-+ aa_put_ns(current_ns);
- return -EACCES;
-+ }
-
-- ns_name = aa_ns_name(current_ns, ns, true);
-- ns_len = strlen(ns_name);
--
-- /* if the visible ns_name is > 0 increase size for : :// seperator */
-- if (ns_len)
-- ns_len += 4;
--
-- /* unconfined profiles don't have a mode string appended */
-- if (!profile_unconfined(profile))
-- mode_len = strlen(mode_str) + 3; /* + 3 for _() */
-+ len = aa_label_snxprint(NULL, 0, current_ns, label,
-+ FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
-+ FLAG_HIDDEN_UNCONFINED);
-+ AA_BUG(len < 0);
-
-- name_len = strlen(profile->base.hname);
-- len = mode_len + ns_len + name_len + 1; /* + 1 for \n */
-- s = str = kmalloc(len + 1, GFP_KERNEL); /* + 1 \0 */
-- if (!str)
-+ *string = kmalloc(len + 2, GFP_KERNEL);
-+ if (!*string) {
-+ aa_put_ns(current_ns);
- return -ENOMEM;
-+ }
-
-- if (ns_len) {
-- /* skip over prefix current_ns->base.hname and separating // */
-- sprintf(s, ":%s://", ns_name);
-- s += ns_len;
-+ len = aa_label_snxprint(*string, len + 2, current_ns, label,
-+ FLAG_SHOW_MODE | FLAG_VIEW_SUBNS |
-+ FLAG_HIDDEN_UNCONFINED);
-+ if (len < 0) {
-+ aa_put_ns(current_ns);
-+ return len;
- }
-- if (profile_unconfined(profile))
-- /* mode string not being appended */
-- sprintf(s, "%s\n", profile->base.hname);
-- else
-- sprintf(s, "%s (%s)\n", profile->base.hname, mode_str);
-- *string = str;
-- aa_put_ns(current_ns);
-
-- /* NOTE: len does not include \0 of string, not saved as part of file */
-- return len;
-+ (*string)[len] = '\n';
-+ (*string)[len + 1] = 0;
-+
-+ aa_put_ns(current_ns);
-+ return len + 1;
- }
-
- /**
---
-2.12.3
-
diff --git a/patches.apparmor/0046-apparmor-update-query-interface-to-support-label-que.patch b/patches.apparmor/0046-apparmor-update-query-interface-to-support-label-que.patch
deleted file mode 100644
index f4961a1d0c..0000000000
--- a/patches.apparmor/0046-apparmor-update-query-interface-to-support-label-que.patch
+++ /dev/null
@@ -1,133 +0,0 @@
-From 6feb97ea1cabb9d24fc2ff57be1c5e3901b54d0f Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 13:55:38 -0700
-Subject: [PATCH 46/65] apparmor: update query interface to support label
- queries
-Git-commit: 317d9a054e1c6d5f18b02b99ce09911942f8e603
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/apparmorfs.c | 46 +++++++++++++++++++++++++++++++++++-------
- 1 file changed, 39 insertions(+), 7 deletions(-)
-
-diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
-index 976af6da45c3..d24100f8fd98 100644
---- a/security/apparmor/apparmorfs.c
-+++ b/security/apparmor/apparmorfs.c
-@@ -33,6 +33,7 @@
- #include "include/context.h"
- #include "include/crypto.h"
- #include "include/policy_ns.h"
-+#include "include/label.h"
- #include "include/policy.h"
- #include "include/policy_ns.h"
- #include "include/resource.h"
-@@ -629,6 +630,7 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
- tmp = nullperms;
- }
- aa_apply_modes_to_perms(profile, &tmp);
-+ aa_perms_accum_raw(perms, &tmp);
- }
-
-
-@@ -655,7 +657,9 @@ static ssize_t query_data(char *buf, size_t buf_len,
- {
- char *out;
- const char *key;
-+ struct label_it i;
- struct aa_label *label, *curr;
-+ struct aa_profile *profile;
- struct aa_data *data;
- u32 bytes, blocks;
- __le32 outle32;
-@@ -690,13 +694,16 @@ static ssize_t query_data(char *buf, size_t buf_len,
- out = buf + sizeof(bytes) + sizeof(blocks);
-
- blocks = 0;
-- if (labels_profile(label)->data) {
-- data = rhashtable_lookup_fast(labels_profile(label)->data, &key,
-- labels_profile(label)->data->p);
-+ label_for_each_confined(i, label, profile) {
-+ if (!profile->data)
-+ continue;
-+
-+ data = rhashtable_lookup_fast(profile->data, &key,
-+ profile->data->p);
-
- if (data) {
-- if (out + sizeof(outle32) + data->size >
-- buf + buf_len) {
-+ if (out + sizeof(outle32) + data->size > buf +
-+ buf_len) {
- aa_put_label(label);
- return -EINVAL; /* not enough space */
- }
-@@ -741,10 +748,12 @@ static ssize_t query_data(char *buf, size_t buf_len,
- static ssize_t query_label(char *buf, size_t buf_len,
- char *query, size_t query_len, bool view_only)
- {
-+ struct aa_profile *profile;
- struct aa_label *label, *curr;
- char *label_name, *match_str;
- size_t label_name_len, match_len;
- struct aa_perms perms;
-+ struct label_it i;
-
- if (!query_len)
- return -EINVAL;
-@@ -770,7 +779,16 @@ static ssize_t query_label(char *buf, size_t buf_len,
- return PTR_ERR(label);
-
- perms = allperms;
-- profile_query_cb(labels_profile(label), &perms, match_str, match_len);
-+ if (view_only) {
-+ label_for_each_in_ns(i, labels_ns(label), label, profile) {
-+ profile_query_cb(profile, &perms, match_str, match_len);
-+ }
-+ } else {
-+ label_for_each(i, label, profile) {
-+ profile_query_cb(profile, &perms, match_str, match_len);
-+ }
-+ }
-+ aa_put_label(label);
-
- return scnprintf(buf, buf_len,
- "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
-@@ -877,9 +895,12 @@ static int multi_transaction_release(struct inode *inode, struct file *file)
- return 0;
- }
-
-+#define QUERY_CMD_LABEL "label\0"
-+#define QUERY_CMD_LABEL_LEN 6
- #define QUERY_CMD_PROFILE "profile\0"
- #define QUERY_CMD_PROFILE_LEN 8
--
-+#define QUERY_CMD_LABELALL "labelall\0"
-+#define QUERY_CMD_LABELALL_LEN 9
- #define QUERY_CMD_DATA "data\0"
- #define QUERY_CMD_DATA_LEN 5
-
-@@ -922,6 +943,17 @@ static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
- len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
- t->data + QUERY_CMD_PROFILE_LEN,
- count - QUERY_CMD_PROFILE_LEN, true);
-+ } else if (count > QUERY_CMD_LABEL_LEN &&
-+ !memcmp(t->data, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
-+ len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
-+ t->data + QUERY_CMD_LABEL_LEN,
-+ count - QUERY_CMD_LABEL_LEN, true);
-+ } else if (count > QUERY_CMD_LABELALL_LEN &&
-+ !memcmp(t->data, QUERY_CMD_LABELALL,
-+ QUERY_CMD_LABELALL_LEN)) {
-+ len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
-+ t->data + QUERY_CMD_LABELALL_LEN,
-+ count - QUERY_CMD_LABELALL_LEN, false);
- } else if (count > QUERY_CMD_DATA_LEN &&
- !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
- len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
---
-2.12.3
-
diff --git a/patches.apparmor/0047-apparmor-move-capability-checks-to-using-labels.patch b/patches.apparmor/0047-apparmor-move-capability-checks-to-using-labels.patch
deleted file mode 100644
index c5ae5beeea..0000000000
--- a/patches.apparmor/0047-apparmor-move-capability-checks-to-using-labels.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From a5ebc252a7894a6f0fabd7f3a96422a2ef6d0f72 Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 14:07:02 -0700
-Subject: [PATCH 47/65] apparmor: move capability checks to using labels
-Git-commit: c70c86c421427fd8487867de66c4104b15abd772
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/capability.c | 57 ++++++++++++++++++++++------------
- security/apparmor/include/capability.h | 6 ++--
- security/apparmor/ipc.c | 2 +-
- security/apparmor/lsm.c | 20 ++++++++----
- security/apparmor/resource.c | 2 +-
- 5 files changed, 58 insertions(+), 29 deletions(-)
-
-diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
-index 3bc19843d8df..67e347192a55 100644
---- a/security/apparmor/capability.c
-+++ b/security/apparmor/capability.c
-@@ -48,15 +48,16 @@ static DEFINE_PER_CPU(struct audit_cache, audit_cache);
- static void audit_cb(struct audit_buffer *ab, void *va)
- {
- struct common_audit_data *sa = va;
-+
- audit_log_format(ab, " capname=");
- audit_log_untrustedstring(ab, capability_names[sa->u.cap]);
- }
-
- /**
- * audit_caps - audit a capability
-+ * @sa: audit data
- * @profile: profile being tested for confinement (NOT NULL)
- * @cap: capability tested
-- @audit: whether an audit record should be generated
- * @error: error code returned by test
- *
- * Do auditing of capability and handle, audit/complain/kill modes switching
-@@ -64,16 +65,13 @@ static void audit_cb(struct audit_buffer *ab, void *va)
- *
- * Returns: 0 or sa->error on success, error code on failure
- */
--static int audit_caps(struct aa_profile *profile, int cap, int audit,
-- int error)
-+static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
-+ int cap, int error)
- {
- struct audit_cache *ent;
- int type = AUDIT_APPARMOR_AUTO;
-- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
-- sa.u.cap = cap;
-- aad(&sa)->error = error;
-- if (audit == SECURITY_CAP_NOAUDIT)
-- aad(&sa)->info = "optional: no audit";
-+
-+ aad(sa)->error = error;
-
- if (likely(!error)) {
- /* test if auditing is being forced */
-@@ -105,24 +103,44 @@ static int audit_caps(struct aa_profile *profile, int cap, int audit,
- }
- put_cpu_var(audit_cache);
-
-- return aa_audit(type, profile, &sa, audit_cb);
-+ return aa_audit(type, profile, sa, audit_cb);
- }
-
- /**
- * profile_capable - test if profile allows use of capability @cap
- * @profile: profile being enforced (NOT NULL, NOT unconfined)
- * @cap: capability to test if allowed
-+ * @audit: whether an audit record should be generated
-+ * @sa: audit data (MAY BE NULL indicating no auditing)
- *
- * Returns: 0 if allowed else -EPERM
- */
--static int profile_capable(struct aa_profile *profile, int cap)
-+static int profile_capable(struct aa_profile *profile, int cap, int audit,
-+ struct common_audit_data *sa)
- {
-- return cap_raised(profile->caps.allow, cap) ? 0 : -EPERM;
-+ int error;
-+
-+ if (cap_raised(profile->caps.allow, cap) &&
-+ !cap_raised(profile->caps.denied, cap))
-+ error = 0;
-+ else
-+ error = -EPERM;
-+
-+ if (audit == SECURITY_CAP_NOAUDIT) {
-+ if (!COMPLAIN_MODE(profile))
-+ return error;
-+ /* audit the cap request in complain mode but note that it
-+ * should be optional.
-+ */
-+ aad(sa)->info = "optional: no audit";
-+ }
-+
-+ return audit_caps(sa, profile, cap, error);
- }
-
- /**
- * aa_capable - test permission to use capability
-- * @profile: profile being tested against (NOT NULL)
-+ * @label: label being tested for capability (NOT NULL)
- * @cap: capability to be tested
- * @audit: whether an audit record should be generated
- *
-@@ -130,14 +148,15 @@ static int profile_capable(struct aa_profile *profile, int cap)
- *
- * Returns: 0 on success, or else an error code.
- */
--int aa_capable(struct aa_profile *profile, int cap, int audit)
-+int aa_capable(struct aa_label *label, int cap, int audit)
- {
-- int error = profile_capable(profile, cap);
-+ struct aa_profile *profile;
-+ int error = 0;
-+ DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
-
-- if (audit == SECURITY_CAP_NOAUDIT) {
-- if (!COMPLAIN_MODE(profile))
-- return error;
-- }
-+ sa.u.cap = cap;
-+ error = fn_for_each_confined(label, profile,
-+ profile_capable(profile, cap, audit, &sa));
-
-- return audit_caps(profile, cap, audit, error);
-+ return error;
- }
-diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
-index 1218e95ebe49..e0304e2aeb7f 100644
---- a/security/apparmor/include/capability.h
-+++ b/security/apparmor/include/capability.h
-@@ -19,11 +19,12 @@
-
- #include "apparmorfs.h"
-
--struct aa_profile;
-+struct aa_label;
-
- /* aa_caps - confinement data for capabilities
- * @allowed: capabilities mask
- * @audit: caps that are to be audited
-+ * @denied: caps that are explicitly denied
- * @quiet: caps that should not be audited
- * @kill: caps that when requested will result in the task being killed
- * @extended: caps that are subject finer grained mediation
-@@ -31,6 +32,7 @@ struct aa_profile;
- struct aa_caps {
- kernel_cap_t allow;
- kernel_cap_t audit;
-+ kernel_cap_t denied;
- kernel_cap_t quiet;
- kernel_cap_t kill;
- kernel_cap_t extended;
-@@ -38,7 +40,7 @@ struct aa_caps {
-
- extern struct aa_sfs_entry aa_sfs_entry_caps[];
-
--int aa_capable(struct aa_profile *profile, int cap, int audit);
-+int aa_capable(struct aa_label *label, int cap, int audit);
-
- static inline void aa_free_cap_rules(struct aa_caps *caps)
- {
-diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
-index fa68cd42bd15..7678d94c4002 100644
---- a/security/apparmor/ipc.c
-+++ b/security/apparmor/ipc.c
-@@ -68,7 +68,7 @@ int aa_may_ptrace(struct aa_profile *tracer, struct aa_profile *tracee,
- if (profile_unconfined(tracer) || tracer == tracee)
- return 0;
- /* log this capability request */
-- return aa_capable(tracer, CAP_SYS_PTRACE, 1);
-+ return aa_capable(&tracer->label, CAP_SYS_PTRACE, 1);
- }
-
- /**
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index f7f82ce00d73..bcfdcdb3eae2 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -117,20 +117,28 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
- kernel_cap_t *inheritable, kernel_cap_t *permitted)
- {
- struct aa_label *label;
-- struct aa_profile *profile;
- const struct cred *cred;
-
- rcu_read_lock();
- cred = __task_cred(target);
- label = aa_get_newest_cred_label(cred);
-- profile = labels_profile(label);
-+
- /*
- * cap_capget is stacked ahead of this and will
- * initialize effective and permitted.
- */
-- if (!profile_unconfined(profile) && !COMPLAIN_MODE(profile)) {
-- *effective = cap_intersect(*effective, profile->caps.allow);
-- *permitted = cap_intersect(*permitted, profile->caps.allow);
-+ if (!unconfined(label)) {
-+ struct aa_profile *profile;
-+ struct label_it i;
-+
-+ label_for_each_confined(i, label, profile) {
-+ if (COMPLAIN_MODE(profile))
-+ continue;
-+ *effective = cap_intersect(*effective,
-+ profile->caps.allow);
-+ *permitted = cap_intersect(*permitted,
-+ profile->caps.allow);
-+ }
- }
- rcu_read_unlock();
- aa_put_label(label);
-@@ -146,7 +154,7 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
-
- label = aa_get_newest_cred_label(cred);
- if (!unconfined(label))
-- error = aa_capable(labels_profile(label), cap, audit);
-+ error = aa_capable(label, cap, audit);
- aa_put_label(label);
-
- return error;
-diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
-index ab8e104c1970..2474ee0b3467 100644
---- a/security/apparmor/resource.c
-+++ b/security/apparmor/resource.c
-@@ -100,7 +100,7 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
- * task has CAP_SYS_RESOURCE.
- */
- if ((profile != labels_profile(task_label) &&
-- aa_capable(profile, CAP_SYS_RESOURCE, 1)) ||
-+ aa_capable(&profile->label, CAP_SYS_RESOURCE, 1)) ||
- (profile->rlimits.mask & (1 << resource) &&
- new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
- error = -EACCES;
---
-2.12.3
-
diff --git a/patches.apparmor/0048-apparmor-move-resource-checks-to-using-labels.patch b/patches.apparmor/0048-apparmor-move-resource-checks-to-using-labels.patch
deleted file mode 100644
index 5fe9690b8f..0000000000
--- a/patches.apparmor/0048-apparmor-move-resource-checks-to-using-labels.patch
+++ /dev/null
@@ -1,247 +0,0 @@
-From b8f8ac1fb23f86967c3f7ffcb3569b6b449006ee Mon Sep 17 00:00:00 2001
-From: John Johansen <john.johansen@canonical.com>
-Date: Fri, 9 Jun 2017 14:15:20 -0700
-Subject: [PATCH 48/65] apparmor: move resource checks to using labels
-Git-commit: 86b92cb782b38d71ee344af20fcbe5106dd19dbe
-Patch-mainline: v4.13-rc1
-References: FATE#323500
-
-Signed-off-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
----
- security/apparmor/include/resource.h | 4 +-
- security/apparmor/lsm.c | 6 +-
- security/apparmor/resource.c | 112 ++++++++++++++++++++++++-----------
- 3 files changed, 80 insertions(+), 42 deletions(-)
-
-diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
-index f6289f335c4d..76f1586c9adb 100644
---- a/security/apparmor/include/resource.h
-+++ b/security/apparmor/include/resource.h
-@@ -37,10 +37,10 @@ struct aa_rlimit {
- extern struct aa_sfs_entry aa_sfs_entry_rlimit[];
-
- int aa_map_resource(int resource);
--int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *,
-+int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim);
-
--void __aa_transition_rlimits(struct aa_profile *old, struct aa_profile *new);
-+void __aa_transition_rlimits(struct aa_label *old, struct aa_label *new);
-
- static inline void aa_free_rlimit_rules(struct aa_rlimit *rlims)
- {
-diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index bcfdcdb3eae2..c3e98f74268f 100644
---- a/security/apparmor/lsm.c
-+++ b/security/apparmor/lsm.c
-@@ -625,8 +625,7 @@ static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
- current->pdeath_signal = 0;
-
- /* reset soft limits and set hard limits for the new label */
-- __aa_transition_rlimits(labels_profile(label),
-- labels_profile(new_ctx->label));
-+ __aa_transition_rlimits(label, new_ctx->label);
- }
-
- /**
-@@ -646,8 +645,7 @@ static int apparmor_task_setrlimit(struct task_struct *task,
- int error = 0;
-
- if (!unconfined(label))
-- error = aa_task_setrlimit(labels_profile(label), task,
-- resource, new_rlim);
-+ error = aa_task_setrlimit(label, task, resource, new_rlim);
- __end_current_label_crit_section(label);
-
- return error;
-diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
-index 2474ee0b3467..d8bc842594ed 100644
---- a/security/apparmor/resource.c
-+++ b/security/apparmor/resource.c
-@@ -13,6 +13,7 @@
- */
-
- #include <linux/audit.h>
-+#include <linux/security.h>
-
- #include "include/audit.h"
- #include "include/context.h"
-@@ -36,6 +37,11 @@ static void audit_cb(struct audit_buffer *ab, void *va)
-
- audit_log_format(ab, " rlimit=%s value=%lu",
- rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max);
-+ if (aad(sa)->peer) {
-+ audit_log_format(ab, " peer=");
-+ aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
-+ FLAGS_NONE, GFP_ATOMIC);
-+ }
- }
-
- /**
-@@ -48,13 +54,17 @@ static void audit_cb(struct audit_buffer *ab, void *va)
- * Returns: 0 or sa->error else other error code on failure
- */
- static int audit_resource(struct aa_profile *profile, unsigned int resource,
-- unsigned long value, int error)
-+ unsigned long value, struct aa_label *peer,
-+ const char *info, int error)
- {
- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SETRLIMIT);
-
- aad(&sa)->rlim.rlim = resource;
- aad(&sa)->rlim.max = value;
-+ aad(&sa)->peer = peer;
-+ aad(&sa)->info = info;
- aad(&sa)->error = error;
-+
- return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
- }
-
-@@ -72,9 +82,21 @@ int aa_map_resource(int resource)
- return rlim_map[resource];
- }
-
-+static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
-+ struct rlimit *new_rlim)
-+{
-+ int e = 0;
-+
-+ if (profile->rlimits.mask & (1 << resource) && new_rlim->rlim_max >
-+ profile->rlimits.limits[resource].rlim_max)
-+ e = -EACCES;
-+ return audit_resource(profile, resource, new_rlim->rlim_max, NULL, NULL,
-+ e);
-+}
-+
- /**
- * aa_task_setrlimit - test permission to set an rlimit
-- * @profile - profile confining the task (NOT NULL)
-+ * @label - label confining the task (NOT NULL)
- * @task - task the resource is being set on
- * @resource - the resource being set
- * @new_rlim - the new resource limit (NOT NULL)
-@@ -83,14 +105,15 @@ int aa_map_resource(int resource)
- *
- * Returns: 0 or error code if setting resource failed
- */
--int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
-+int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
- unsigned int resource, struct rlimit *new_rlim)
- {
-- struct aa_label *task_label;
-+ struct aa_profile *profile;
-+ struct aa_label *peer;
- int error = 0;
-
- rcu_read_lock();
-- task_label = aa_get_newest_cred_label((__task_cred(task)));
-+ peer = aa_get_newest_cred_label(__task_cred(task));
- rcu_read_unlock();
-
- /* TODO: extend resource control to handle other (non current)
-@@ -99,53 +122,70 @@ int aa_task_setrlimit(struct aa_profile *profile, struct task_struct *task,
- * the same profile or that the task setting the resource of another
- * task has CAP_SYS_RESOURCE.
- */
-- if ((profile != labels_profile(task_label) &&
-- aa_capable(&profile->label, CAP_SYS_RESOURCE, 1)) ||
-- (profile->rlimits.mask & (1 << resource) &&
-- new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max))
-- error = -EACCES;
-
-- aa_put_label(task_label);
--
-- return audit_resource(profile, resource, new_rlim->rlim_max, error);
-+ if (label != peer &&
-+ !aa_capable(label, CAP_SYS_RESOURCE, SECURITY_CAP_NOAUDIT))
-+ error = fn_for_each(label, profile,
-+ audit_resource(profile, resource,
-+ new_rlim->rlim_max, peer,
-+ "cap_sys_resoure", -EACCES));
-+ else
-+ error = fn_for_each_confined(label, profile,
-+ profile_setrlimit(profile, resource, new_rlim));
-+ aa_put_label(peer);
-+
-+ return error;
- }
-
- /**
- * __aa_transition_rlimits - apply new profile rlimits
-- * @old: old profile on task (NOT NULL)
-- * @new: new profile with rlimits to apply (NOT NULL)