aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2013-07-11 00:10:43 -0400
committerJohn Johansen <john.johansen@canonical.com>2013-08-14 14:42:06 -0400
commit742058b0f3a2ed32e2a7349aff97989dc4e32452 (patch)
tree25cc9f3f65e0b7889d5509396f6727d29a47ff57 /security
parentfa2ac468db510c653499a47c1ec3deb045bf4763 (diff)
apparmor: rework namespace free path
namespaces now completely use the unconfined profile to track the refcount and rcu freeing cycle. So rework the code to simplify (track everything through the profile path right up to the end), and move the rcu_head from policy base to profile as the namespace no longer needs it. Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Seth Arnold <seth.arnold@canonical.com>
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/include/policy.h12
-rw-r--r--security/apparmor/policy.c33
2 files changed, 10 insertions, 35 deletions
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 1ddd5e5728b8..4eafdd88f44e 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -80,7 +80,6 @@ struct aa_profile;
80 * @name: name of the object 80 * @name: name of the object
81 * @hname - The hierarchical name 81 * @hname - The hierarchical name
82 * @list: list policy object is on 82 * @list: list policy object is on
83 * @rcu: rcu head used when removing from @list
84 * @profiles: head of the profiles list contained in the object 83 * @profiles: head of the profiles list contained in the object
85 */ 84 */
86struct aa_policy { 85struct aa_policy {
@@ -88,7 +87,6 @@ struct aa_policy {
88 char *hname; 87 char *hname;
89 struct list_head list; 88 struct list_head list;
90 struct list_head profiles; 89 struct list_head profiles;
91 struct rcu_head rcu;
92}; 90};
93 91
94/* struct aa_ns_acct - accounting of profiles in namespace 92/* struct aa_ns_acct - accounting of profiles in namespace
@@ -157,6 +155,7 @@ struct aa_replacedby {
157/* struct aa_profile - basic confinement data 155/* struct aa_profile - basic confinement data
158 * @base - base components of the profile (name, refcount, lists, lock ...) 156 * @base - base components of the profile (name, refcount, lists, lock ...)
159 * @count: reference count of the obj 157 * @count: reference count of the obj
158 * @rcu: rcu head used when removing from @list
160 * @parent: parent of profile 159 * @parent: parent of profile
161 * @ns: namespace the profile is in 160 * @ns: namespace the profile is in
162 * @replacedby: is set to the profile that replaced this profile 161 * @replacedby: is set to the profile that replaced this profile
@@ -190,6 +189,7 @@ struct aa_replacedby {
190struct aa_profile { 189struct aa_profile {
191 struct aa_policy base; 190 struct aa_policy base;
192 struct kref count; 191 struct kref count;
192 struct rcu_head rcu;
193 struct aa_profile __rcu *parent; 193 struct aa_profile __rcu *parent;
194 194
195 struct aa_namespace *ns; 195 struct aa_namespace *ns;
@@ -317,12 +317,8 @@ static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
317 */ 317 */
318static inline void aa_put_profile(struct aa_profile *p) 318static inline void aa_put_profile(struct aa_profile *p)
319{ 319{
320 if (p) { 320 if (p)
321 if (p->flags & PFLAG_NS_COUNT) 321 kref_put(&p->count, aa_free_profile_kref);
322 kref_put(&p->count, aa_free_namespace_kref);
323 else
324 kref_put(&p->count, aa_free_profile_kref);
325 }
326} 322}
327 323
328static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p) 324static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index 0ceee967434c..aee2e71827cd 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -329,30 +329,6 @@ static void free_namespace(struct aa_namespace *ns)
329} 329}
330 330
331/** 331/**
332 * aa_free_namespace_rcu - free aa_namespace by rcu
333 * @head: rcu_head callback for freeing of a profile (NOT NULL)
334 *
335 * rcu_head is to the unconfined profile associated with the namespace
336 */
337static void aa_free_namespace_rcu(struct rcu_head *head)
338{
339 struct aa_profile *p = container_of(head, struct aa_profile, base.rcu);
340 free_namespace(p->ns);
341}
342
343/**
344 * aa_free_namespace_kref - free aa_namespace by kref (see aa_put_namespace)
345 * @kr: kref callback for freeing of a namespace (NOT NULL)
346 *
347 * kref is to the unconfined profile associated with the namespace
348 */
349void aa_free_namespace_kref(struct kref *kref)
350{
351 struct aa_profile *p = container_of(kref, struct aa_profile, count);
352 call_rcu(&p->base.rcu, aa_free_namespace_rcu);
353}
354
355/**
356 * __aa_find_namespace - find a namespace on a list by @name 332 * __aa_find_namespace - find a namespace on a list by @name
357 * @head: list to search for namespace on (NOT NULL) 333 * @head: list to search for namespace on (NOT NULL)
358 * @name: name of namespace to look for (NOT NULL) 334 * @name: name of namespace to look for (NOT NULL)
@@ -632,8 +608,11 @@ static void free_profile(struct aa_profile *profile)
632 */ 608 */
633static void aa_free_profile_rcu(struct rcu_head *head) 609static void aa_free_profile_rcu(struct rcu_head *head)
634{ 610{
635 struct aa_profile *p = container_of(head, struct aa_profile, base.rcu); 611 struct aa_profile *p = container_of(head, struct aa_profile, rcu);
636 free_profile(p); 612 if (p->flags & PFLAG_NS_COUNT)
613 free_namespace(p->ns);
614 else
615 free_profile(p);
637} 616}
638 617
639/** 618/**
@@ -643,7 +622,7 @@ static void aa_free_profile_rcu(struct rcu_head *head)
643void aa_free_profile_kref(struct kref *kref) 622void aa_free_profile_kref(struct kref *kref)
644{ 623{
645 struct aa_profile *p = container_of(kref, struct aa_profile, count); 624 struct aa_profile *p = container_of(kref, struct aa_profile, count);
646 call_rcu(&p->base.rcu, aa_free_profile_rcu); 625 call_rcu(&p->rcu, aa_free_profile_rcu);
647} 626}
648 627
649/** 628/**