Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+10 -35
+4 -8
security/apparmor/include/policy.h
··· 80 80 * @name: name of the object 81 81 * @hname - The hierarchical name 82 82 * @list: list policy object is on 83 - * @rcu: rcu head used when removing from @list 84 83 * @profiles: head of the profiles list contained in the object 85 84 */ 86 85 struct aa_policy { ··· 87 88 char *hname; 88 89 struct list_head list; 89 90 struct list_head profiles; 90 - struct rcu_head rcu; 91 91 }; 92 92 93 93 /* struct aa_ns_acct - accounting of profiles in namespace ··· 155 157 /* struct aa_profile - basic confinement data 156 158 * @base - base components of the profile (name, refcount, lists, lock ...) 157 159 * @count: reference count of the obj 160 + * @rcu: rcu head used when removing from @list 158 161 * @parent: parent of profile 159 162 * @ns: namespace the profile is in 160 163 * @replacedby: is set to the profile that replaced this profile ··· 189 190 struct aa_profile { 190 191 struct aa_policy base; 191 192 struct kref count; 193 + struct rcu_head rcu; 192 194 struct aa_profile __rcu *parent; 193 195 194 196 struct aa_namespace *ns; ··· 317 317 */ 318 318 static inline void aa_put_profile(struct aa_profile *p) 319 319 { 320 - if (p) { 321 - if (p->flags & PFLAG_NS_COUNT) 322 - kref_put(&p->count, aa_free_namespace_kref); 323 - else 324 - kref_put(&p->count, aa_free_profile_kref); 325 - } 320 + if (p) 321 + kref_put(&p->count, aa_free_profile_kref); 326 322 } 327 323 328 324 static inline struct aa_replacedby *aa_get_replacedby(struct aa_replacedby *p)
+6 -27
security/apparmor/policy.c
··· 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 - */ 337 - static 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 - */ 349 - void 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 332 * __aa_find_namespace - find a namespace on a list by @name 357 333 * @head: list to search for namespace on (NOT NULL) 358 334 * @name: name of namespace to look for (NOT NULL) ··· 608 632 */ 609 633 static void aa_free_profile_rcu(struct rcu_head *head) 610 634 { 611 - struct aa_profile *p = container_of(head, struct aa_profile, base.rcu); 612 - free_profile(p); 635 + struct aa_profile *p = container_of(head, struct aa_profile, rcu); 636 + if (p->flags & PFLAG_NS_COUNT) 637 + free_namespace(p->ns); 638 + else 639 + free_profile(p); 613 640 } 614 641 615 642 /** ··· 622 643 void aa_free_profile_kref(struct kref *kref) 623 644 { 624 645 struct aa_profile *p = container_of(kref, struct aa_profile, count); 625 - call_rcu(&p->base.rcu, aa_free_profile_rcu); 646 + call_rcu(&p->rcu, aa_free_profile_rcu); 626 647 } 627 648 628 649 /**