summaryrefslogtreecommitdiffstats
path: root/security/apparmor/lib.c
diff options
context:
space:
mode:
authorJohn Johansen2017-06-09 16:09:05 +0200
committerJohn Johansen2017-06-11 02:11:35 +0200
commita1bd627b46d169268a0ee5960899fb5be960a317 (patch)
treeddcc330c5ddc6efb5e18f1943a55ce4e11884743 /security/apparmor/lib.c
parentapparmor: convert to profile block critical sections (diff)
downloadkernel-qcow2-linux-a1bd627b46d169268a0ee5960899fb5be960a317.tar.gz
kernel-qcow2-linux-a1bd627b46d169268a0ee5960899fb5be960a317.tar.xz
kernel-qcow2-linux-a1bd627b46d169268a0ee5960899fb5be960a317.zip
apparmor: share profile name on replacement
The profile names are the same, leverage this. Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/lib.c')
-rw-r--r--security/apparmor/lib.c40
1 files changed, 32 insertions, 8 deletions
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);
}