summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--security/apparmor/apparmorfs.c34
-rw-r--r--security/apparmor/include/apparmorfs.h1
-rw-r--r--security/apparmor/include/policy.h2
-rw-r--r--security/apparmor/policy_unpack.c3
4 files changed, 40 insertions, 0 deletions
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 0fdd08c6ea59..d6329aa7aa98 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -290,6 +290,34 @@ static const struct file_operations aa_fs_profmode_fops = {
 	.release	= aa_fs_seq_profile_release,
 };
 
+static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
+{
+	struct aa_replacedby *r = seq->private;
+	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
+	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);
+
+	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,
+};
+
 /** fns to setup dynamic per profile/namespace files **/
 void __aa_fs_profile_rmdir(struct aa_profile *profile)
 {
@@ -385,6 +413,12 @@ int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
 		goto fail;
 	profile->dents[AAFS_PROF_MODE] = dent;
 
+	dent = create_profile_file(dir, "attach", profile,
+				   &aa_fs_profattach_fops);
+	if (IS_ERR(dent))
+		goto fail;
+	profile->dents[AAFS_PROF_ATTACH] = dent;
+
 	list_for_each_entry(child, &profile->base.profiles, base.list) {
 		error = __aa_fs_profile_mkdir(child, prof_child_dir(profile));
 		if (error)
diff --git a/security/apparmor/include/apparmorfs.h b/security/apparmor/include/apparmorfs.h
index 2494e112f2bf..f91712cf1b30 100644
--- a/security/apparmor/include/apparmorfs.h
+++ b/security/apparmor/include/apparmorfs.h
@@ -81,6 +81,7 @@ enum aafs_prof_type {
 	AAFS_PROF_PROFS,
 	AAFS_PROF_NAME,
 	AAFS_PROF_MODE,
+	AAFS_PROF_ATTACH,
 	AAFS_PROF_SIZEOF,
 };
 
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 5c72231d1c42..59b36372ae40 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -165,6 +165,7 @@ struct aa_replacedby {
  * @ns: namespace the profile is in
  * @replacedby: 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
@@ -204,6 +205,7 @@ struct aa_profile {
 	struct aa_replacedby *replacedby;
 	const char *rename;
 
+	const char *attach;
 	struct aa_dfa *xmatch;
 	int xmatch_len;
 	enum audit_mode audit;
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index cac0aa075787..bdaef2e1b2a0 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -492,6 +492,9 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
 	/* profile renaming is optional */
 	(void) unpack_str(e, &profile->rename, "rename");
 
+	/* attachment string is optional */
+	(void) unpack_str(e, &profile->attach, "attach");
+
 	/* xmatch is optional and may be NULL */
 	profile->xmatch = unpack_dfa(e);
 	if (IS_ERR(profile->xmatch)) {