~ubuntu-branches/ubuntu/wily/apparmor/wily

« back to all changes in this revision

Viewing changes to kernel-patches/for-mainline/remove-iterators.diff

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-04-27 10:38:07 UTC
  • mfrom: (5.1.118 natty)
  • Revision ID: james.westby@ubuntu.com-20110427103807-ym3rhwys6o84ith0
Tags: 2.6.1-2
debian/copyright: clarify for some full organization names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Index: b/security/apparmor/apparmor.h
2
 
===================================================================
3
 
--- a/security/apparmor/apparmor.h
4
 
+++ b/security/apparmor/apparmor.h
5
 
@@ -128,6 +128,9 @@ struct aa_profile {
6
 
 extern struct list_head profile_list;
7
 
 extern rwlock_t profile_list_lock;
8
 
 
9
 
+extern struct list_head task_context_list;
10
 
+extern rwlock_t task_context_list_lock;
11
 
+
12
 
 /**
13
 
  * struct aa_task_context - primary label for confined tasks
14
 
  * @profile: the current profile
15
 
@@ -147,8 +150,6 @@ struct aa_task_context {
16
 
        kernel_cap_t caps_logged;
17
 
 };
18
 
 
19
 
-typedef int (*aa_iter) (struct aa_task_context *, void *);
20
 
-
21
 
 static inline struct aa_task_context *aa_task_context(struct task_struct *task)
22
 
 {
23
 
        return (struct aa_task_context *)task->security;
24
 
@@ -236,7 +237,6 @@ extern int aa_fork(struct task_struct *t
25
 
 extern int aa_register(struct linux_binprm *bprm);
26
 
 extern void aa_release(struct task_struct *task);
27
 
 extern int aa_change_hat(const char *id, u32 hat_magic);
28
 
-extern int aa_associate_filp(struct file *filp);
29
 
 extern struct aa_profile *__aa_find_profile(const char *name,
30
 
                                            struct list_head *list);
31
 
 
32
 
@@ -244,8 +244,6 @@ extern struct aa_profile *__aa_find_prof
33
 
 extern void aa_profilelist_release(void);
34
 
 extern void aa_task_context_list_add(struct aa_task_context *);
35
 
 extern void aa_task_context_list_remove(struct aa_task_context *);
36
 
-extern void aa_task_context_list_iterate(aa_iter, void *);
37
 
-extern void aa_task_context_list_iterateremove(aa_iter, void *);
38
 
 extern void aa_task_context_list_release(void);
39
 
 
40
 
 /* module_interface.c */
41
 
Index: b/security/apparmor/list.c
42
 
===================================================================
43
 
--- a/security/apparmor/list.c
44
 
+++ b/security/apparmor/list.c
45
 
@@ -18,8 +18,8 @@ LIST_HEAD(profile_list);
46
 
 rwlock_t profile_list_lock = RW_LOCK_UNLOCKED;
47
 
 
48
 
 /* list of all task_contexts and lock */
49
 
-static LIST_HEAD(task_context_list);
50
 
-static rwlock_t task_context_list_lock = RW_LOCK_UNLOCKED;
51
 
+LIST_HEAD(task_context_list);
52
 
+rwlock_t task_context_list_lock = RW_LOCK_UNLOCKED;
53
 
 
54
 
 /**
55
 
  * __aa_find_profile  -  look up a profile on the profile list
56
 
@@ -93,29 +93,6 @@ void aa_task_context_list_remove(struct 
57
 
 }
58
 
 
59
 
 /**
60
 
- * aa_task_context_list_iterate - apply @func over the task_context_list
61
 
- * @func: method to be called for each element
62
 
- * @cookie: user passed data
63
 
- *
64
 
- * Iterate over aa_task_context list applying @func, stop when @func returns
65
 
- * non zero
66
 
- */
67
 
-void aa_task_context_list_iterate(aa_iter func, void *cookie)
68
 
-{
69
 
-       struct aa_task_context *node;
70
 
-       int ret = 0;
71
 
-       unsigned long flags;
72
 
-
73
 
-       read_lock_irqsave(&task_context_list_lock, flags);
74
 
-       list_for_each_entry(node, &task_context_list, list) {
75
 
-               ret = (*func) (node, cookie);
76
 
-               if (ret != 0)
77
 
-                       break;
78
 
-       }
79
 
-       read_unlock_irqrestore(&task_context_list_lock, flags);
80
 
-}
81
 
-
82
 
-/**
83
 
  * aa_task_context_list_release - Remove all aa_task_contexts from
84
 
  *                               task_context_list
85
 
  */
86
 
Index: b/security/apparmor/lsm.c
87
 
===================================================================
88
 
--- a/security/apparmor/lsm.c
89
 
+++ b/security/apparmor/lsm.c
90
 
@@ -747,27 +747,9 @@ createfs_out:
91
 
 
92
 
 }
93
 
 
94
 
-static int apparmor_exit_removeall_iter(struct aa_task_context *cxt,
95
 
-                                       void *cookie)
96
 
-{
97
 
-       /* spin_lock(&cxt_lock) held here */
98
 
-
99
 
-       if (cxt->profile) {
100
 
-               AA_DEBUG("%s: Dropping profiles %s(%d) "
101
 
-                        "profile %s(%p) active %s(%p)\n",
102
 
-                        __FUNCTION__,
103
 
-                        cxt->task->comm, cxt->task->pid,
104
 
-                        cxt->profile->parent->name,
105
 
-                        cxt->profile->parent,
106
 
-                        cxt->profile->name, cxt->profile);
107
 
-               aa_switch_to_profile(cxt, NULL, 0);
108
 
-       }
109
 
-
110
 
-       return 0;
111
 
-}
112
 
-
113
 
 static void __exit apparmor_exit(void)
114
 
 {
115
 
+       struct aa_task_context *cxt;
116
 
        unsigned long flags;
117
 
 
118
 
        /* Remove profiles from the global profile list.
119
 
@@ -782,8 +764,17 @@ static void __exit apparmor_exit(void)
120
 
         * reattached
121
 
         */
122
 
 
123
 
+       /*
124
 
+        * FIXME: We have a lock inversion here (cp. aa_file_prof_repl,
125
 
+        * aa_file_prof_remove).
126
 
+        */
127
 
        spin_lock_irqsave(&cxt_lock, flags);
128
 
-       aa_task_context_list_iterate(apparmor_exit_removeall_iter, NULL);
129
 
+       read_lock(&task_context_list_lock);
130
 
+       list_for_each_entry(cxt, &task_context_list, list) {
131
 
+               if (cxt->profile)
132
 
+                       aa_switch_to_profile(cxt, NULL, 0);
133
 
+       }
134
 
+       read_unlock(&task_context_list_lock);
135
 
        spin_unlock_irqrestore(&cxt_lock, flags);
136
 
 
137
 
        /* Free up list of profile aa_task_context */
138
 
Index: b/security/apparmor/module_interface.c
139
 
===================================================================
140
 
--- a/security/apparmor/module_interface.c
141
 
+++ b/security/apparmor/module_interface.c
142
 
@@ -19,11 +19,6 @@
143
 
 
144
 
 const int aa_code_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 };
145
 
 
146
 
-struct aa_taskreplace_data {
147
 
-       struct aa_profile *old_profile;
148
 
-       struct aa_profile *new_profile;
149
 
-};
150
 
-
151
 
 /**
152
 
  * free_aa_profile_rcu - rcu callback for free profiles
153
 
  * @head: rcu_head struct of the profile whose reference is being put.
154
 
@@ -37,49 +32,6 @@ static void free_aa_profile_rcu(struct r
155
 
        free_aa_profile(p);
156
 
 }
157
 
 
158
 
-/**
159
 
- * task_remove - remove profile from a task's aa_task_context
160
 
- * @cxt: task's aa_task_context
161
 
- *
162
 
- * remove the profile from a task's aa_task_context, switching the task
163
 
- * to an unconfined state.
164
 
- */
165
 
-static inline void task_remove(struct aa_task_context *cxt)
166
 
-{
167
 
-       /* spin_lock(&cxt_lock) held here */
168
 
-       AA_DEBUG("%s: removing profile from task %s(%d) profile %s active %s\n",
169
 
-                __FUNCTION__,
170
 
-                cxt->task->comm,
171
 
-                cxt->task->pid,
172
 
-                cxt->profile->parent->name,
173
 
-                cxt->profile->name);
174
 
-
175
 
-       aa_switch_to_profile(cxt, NULL, 0);
176
 
-}
177
 
-
178
 
-/** taskremove_iter - Iterator to unconfine aa_task_contexts which match cookie
179
 
- * @cxt: aa_task_context to consider for profile removal
180
 
- * @cookie: pointer to the oldprofile which is being removed
181
 
- *
182
 
- * If the aa_task_context's profile matches old_profile,  then call
183
 
- * task_remove() to remove the profile leaving the task (aa_task_context) unconfined.
184
 
- */
185
 
-static int taskremove_iter(struct aa_task_context *cxt, void *cookie)
186
 
-{
187
 
-       struct aa_profile *old_profile = (struct aa_profile *)cookie;
188
 
-       unsigned long flags;
189
 
-
190
 
-       spin_lock_irqsave(&cxt_lock, flags);
191
 
-
192
 
-       if (cxt->profile && cxt->profile->parent == old_profile) {
193
 
-               task_remove(cxt);
194
 
-       }
195
 
-
196
 
-       spin_unlock_irqrestore(&cxt_lock, flags);
197
 
-
198
 
-       return 0;
199
 
-}
200
 
-
201
 
 /** task_replace - replace aa_task_context's current profile with a new profile
202
 
  * @cxt: aa_task_context to replace the profile on
203
 
  * @new: new profile
204
 
@@ -99,9 +51,6 @@ static inline void task_replace(struct a
205
 
                 cxt->profile->parent->name, cxt->profile->parent,
206
 
                 cxt->profile->name, cxt->profile);
207
 
 
208
 
-       if (!cxt->profile)
209
 
-               return;
210
 
-
211
 
        if (cxt->profile != cxt->profile->parent) {
212
 
                struct aa_profile *nactive;
213
 
 
214
 
@@ -118,29 +67,6 @@ static inline void task_replace(struct a
215
 
                aa_switch_to_profile(cxt, new, cxt->hat_magic);
216
 
 }
217
 
 
218
 
-/** taskreplace_iter - Iterator to replace a aa_task_context's profile
219
 
- * @cxt: aa_task_context to consider for profile replacement
220
 
- * @cookie: pointer to the old profile which is being replaced.
221
 
- *
222
 
- * If the aa_task_context's profile matches old_profile call
223
 
- * task_replace() to replace with the aa_task_context's profile with
224
 
- * the new profile.
225
 
- */
226
 
-static int taskreplace_iter(struct aa_task_context *cxt, void *cookie)
227
 
-{
228
 
-       struct aa_taskreplace_data *data = (struct aa_taskreplace_data *)cookie;
229
 
-       unsigned long flags;
230
 
-
231
 
-       spin_lock_irqsave(&cxt_lock, flags);
232
 
-
233
 
-       if (cxt->profile && cxt->profile->parent == data->old_profile)
234
 
-               task_replace(cxt, data->new_profile);
235
 
-
236
 
-       spin_unlock_irqrestore(&cxt_lock, flags);
237
 
-
238
 
-       return 0;
239
 
-}
240
 
-
241
 
 static inline int aa_inbounds(struct aa_ext *e, size_t size)
242
 
 {
243
 
        return (e->pos + size <= e->end);
244
 
@@ -518,7 +444,7 @@ ssize_t aa_file_prof_add(void *data, siz
245
 
  */
246
 
 ssize_t aa_file_prof_repl(void *udata, size_t size)
247
 
 {
248
 
-       struct aa_taskreplace_data data;
249
 
+       struct aa_profile *old_profile, *new_profile;
250
 
        struct aa_ext e = {
251
 
                .start = udata,
252
 
                .end = udata + size,
253
 
@@ -526,28 +452,40 @@ ssize_t aa_file_prof_repl(void *udata, s
254
 
        };
255
 
        ssize_t error;
256
 
 
257
 
-       data.new_profile = aa_activate_top_profile(&e, &error);
258
 
-       if (!data.new_profile)
259
 
+       new_profile = aa_activate_top_profile(&e, &error);
260
 
+       if (!new_profile)
261
 
                return error;
262
 
 
263
 
        write_lock(&profile_list_lock);
264
 
-       data.old_profile = __aa_find_profile(data.new_profile->name,
265
 
-                                            &profile_list);
266
 
-       if (data.old_profile) {
267
 
-               list_del_init(&data.old_profile->list);
268
 
-
269
 
-               lock_profile(data.old_profile);
270
 
-               data.old_profile->isstale = 1;
271
 
-               unlock_profile(data.old_profile);
272
 
+       old_profile = __aa_find_profile(new_profile->name, &profile_list);
273
 
+       if (old_profile) {
274
 
+               struct aa_task_context *cxt;
275
 
+               unsigned long flags;
276
 
+
277
 
+               list_del_init(&old_profile->list);
278
 
+
279
 
+               lock_profile(old_profile);
280
 
+               old_profile->isstale = 1;
281
 
+               unlock_profile(old_profile);
282
 
 
283
 
                /*
284
 
                 * Find all tasks using the old profile and replace the old
285
 
                 * profile with the new.
286
 
                 */
287
 
-               aa_task_context_list_iterate(taskreplace_iter, &data);
288
 
-               aa_put_profile(data.old_profile);
289
 
+               read_lock_irqsave(&task_context_list_lock, flags);
290
 
+               list_for_each_entry(cxt, &task_context_list, list) {
291
 
+                       spin_lock_irqsave(&cxt_lock, flags);
292
 
+
293
 
+                       if (cxt->profile &&
294
 
+                           cxt->profile->parent == old_profile)
295
 
+                               task_replace(cxt, new_profile);
296
 
+
297
 
+                       spin_unlock_irqrestore(&cxt_lock, flags);
298
 
+               }
299
 
+               read_unlock_irqrestore(&task_context_list_lock, flags);
300
 
+               aa_put_profile(old_profile);
301
 
        }
302
 
-       list_add(&data.new_profile->list, &profile_list);
303
 
+       list_add(&new_profile->list, &profile_list);
304
 
        write_unlock(&profile_list_lock);
305
 
 
306
 
        return size;
307
 
@@ -564,6 +502,8 @@ ssize_t aa_file_prof_repl(void *udata, s
308
 
 ssize_t aa_file_prof_remove(const char *name, size_t size)
309
 
 {
310
 
        struct aa_profile *profile;
311
 
+       struct aa_task_context *cxt;
312
 
+       unsigned long flags;
313
 
 
314
 
        write_lock(&profile_list_lock);
315
 
        profile = __aa_find_profile(name, &profile_list);
316
 
@@ -578,7 +518,16 @@ ssize_t aa_file_prof_remove(const char *
317
 
        profile->isstale = 1;
318
 
        unlock_profile(profile);
319
 
 
320
 
-       aa_task_context_list_iterate(taskremove_iter, profile);
321
 
+       read_lock_irqsave(&task_context_list_lock, flags);
322
 
+       list_for_each_entry(cxt, &task_context_list, list) {
323
 
+               if (cxt->profile && cxt->profile->parent == profile) {
324
 
+                       spin_lock(&cxt_lock);
325
 
+                       aa_switch_to_profile(cxt, NULL, 0);
326
 
+                       spin_unlock(&cxt_lock);
327
 
+               }
328
 
+       }
329
 
+       read_unlock_irqrestore(&task_context_list_lock, flags);
330
 
+
331
 
        aa_put_profile(profile);
332
 
        write_unlock(&profile_list_lock);
333