aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/include
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2013-07-11 00:06:43 -0400
committerJohn Johansen <john.johansen@canonical.com>2013-08-14 14:42:06 -0400
commit01e2b670aa898a39259bc85c78e3d74820f4d3b6 (patch)
treecd78cea5f92788c213f2eb8ef287535ac1bb3327 /security/apparmor/include
parentdd51c84857630e77c139afe4d9bba65fc051dc3f (diff)
apparmor: convert profile lists to RCU based locking
Signed-off-by: John Johansen <john.johansen@canonical.com>
Diffstat (limited to 'security/apparmor/include')
-rw-r--r--security/apparmor/include/apparmor.h6
-rw-r--r--security/apparmor/include/policy.h45
2 files changed, 48 insertions, 3 deletions
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 1ba2ca56a6ef..8fb1488a3cd4 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -78,6 +78,12 @@ static inline void *kvzalloc(size_t size)
78 return __aa_kvmalloc(size, __GFP_ZERO); 78 return __aa_kvmalloc(size, __GFP_ZERO);
79} 79}
80 80
81/* returns 0 if kref not incremented */
82static inline int kref_get_not0(struct kref *kref)
83{
84 return atomic_inc_not_zero(&kref->refcount);
85}
86
81/** 87/**
82 * aa_strneq - compare null terminated @str to a non null terminated substring 88 * aa_strneq - compare null terminated @str to a non null terminated substring
83 * @str: a null terminated string 89 * @str: a null terminated string
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index b25491a3046a..82487a853353 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -42,6 +42,8 @@ extern const char *const profile_mode_names[];
42 42
43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT) 43#define PROFILE_IS_HAT(_profile) ((_profile)->flags & PFLAG_HAT)
44 44
45#define on_list_rcu(X) (!list_empty(X) && (X)->prev != LIST_POISON2)
46
45/* 47/*
46 * FIXME: currently need a clean way to replace and remove profiles as a 48 * FIXME: currently need a clean way to replace and remove profiles as a
47 * set. It should be done at the namespace level. 49 * set. It should be done at the namespace level.
@@ -75,6 +77,7 @@ struct aa_profile;
75 * @hname - The hierarchical name 77 * @hname - The hierarchical name
76 * @count: reference count of the obj 78 * @count: reference count of the obj
77 * @list: list policy object is on 79 * @list: list policy object is on
80 * @rcu: rcu head used when removing from @list
78 * @profiles: head of the profiles list contained in the object 81 * @profiles: head of the profiles list contained in the object
79 */ 82 */
80struct aa_policy { 83struct aa_policy {
@@ -83,6 +86,7 @@ struct aa_policy {
83 struct kref count; 86 struct kref count;
84 struct list_head list; 87 struct list_head list;
85 struct list_head profiles; 88 struct list_head profiles;
89 struct rcu_head rcu;
86}; 90};
87 91
88/* struct aa_ns_acct - accounting of profiles in namespace 92/* struct aa_ns_acct - accounting of profiles in namespace
@@ -124,7 +128,7 @@ struct aa_ns_acct {
124struct aa_namespace { 128struct aa_namespace {
125 struct aa_policy base; 129 struct aa_policy base;
126 struct aa_namespace *parent; 130 struct aa_namespace *parent;
127 rwlock_t lock; 131 struct mutex lock;
128 struct aa_ns_acct acct; 132 struct aa_ns_acct acct;
129 struct aa_profile *unconfined; 133 struct aa_profile *unconfined;
130 struct list_head sub_ns; 134 struct list_head sub_ns;
@@ -166,7 +170,7 @@ struct aa_policydb {
166 * attachments are determined by profile X transition rules. 170 * attachments are determined by profile X transition rules.
167 * 171 *
168 * The @replacedby field is write protected by the profile lock. Reads 172 * The @replacedby field is write protected by the profile lock. Reads
169 * are assumed to be atomic, and are done without locking. 173 * are assumed to be atomic.
170 * 174 *
171 * Profiles have a hierarchy where hats and children profiles keep 175 * Profiles have a hierarchy where hats and children profiles keep
172 * a reference to their parent. 176 * a reference to their parent.
@@ -177,7 +181,7 @@ struct aa_policydb {
177 */ 181 */
178struct aa_profile { 182struct aa_profile {
179 struct aa_policy base; 183 struct aa_policy base;
180 struct aa_profile *parent; 184 struct aa_profile __rcu *parent;
181 185
182 struct aa_namespace *ns; 186 struct aa_namespace *ns;
183 struct aa_profile *replacedby; 187 struct aa_profile *replacedby;
@@ -296,6 +300,41 @@ static inline struct aa_profile *aa_get_profile(struct aa_profile *p)
296} 300}
297 301
298/** 302/**
303 * aa_get_profile_not0 - increment refcount on profile @p found via lookup
304 * @p: profile (MAYBE NULL)
305 *
306 * Returns: pointer to @p if @p is NULL will return NULL
307 * Requires: @p must be held with valid refcount when called
308 */
309static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p)
310{
311 if (p && kref_get_not0(&p->base.count))
312 return p;
313
314 return NULL;
315}
316
317/**
318 * aa_get_profile_rcu - increment a refcount profile that can be replaced
319 * @p: pointer to profile that can be replaced (NOT NULL)
320 *
321 * Returns: pointer to a refcounted profile.
322 * else NULL if no profile
323 */
324static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p)
325{
326 struct aa_profile *c;
327
328 rcu_read_lock();
329 do {
330 c = rcu_dereference(*p);
331 } while (c && !kref_get_not0(&c->base.count));
332 rcu_read_unlock();
333
334 return c;
335}
336
337/**
299 * aa_put_profile - decrement refcount on profile @p 338 * aa_put_profile - decrement refcount on profile @p
300 * @p: profile (MAYBE NULL) 339 * @p: profile (MAYBE NULL)
301 */ 340 */