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

« back to all changes in this revision

Viewing changes to kernel-patches/for-mainline/fix-change_hat-replacement.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/main.c
2
 
===================================================================
3
 
--- a/security/apparmor/main.c
4
 
+++ b/security/apparmor/main.c
5
 
@@ -1048,6 +1048,14 @@ static inline int do_change_hat(const ch
6
 
        if (sub) {
7
 
                /* change hat */
8
 
                aa_change_profile(cxt, sub, hat_magic);
9
 
+               /*
10
 
+                * aa_change_profile switches profile lists but we don't
11
 
+                * want this for change_hat.  Switch back to the parents
12
 
+                * list.
13
 
+                * FIXME: update to a full profile change mechanism
14
 
+                * to get rid of this special casing
15
 
+                */
16
 
+               list_move(&cxt->list, &sub->parent->task_contexts);
17
 
        } else {
18
 
                struct aa_profile *profile = cxt->profile;
19
 
 
20
 
@@ -1078,6 +1086,14 @@ static inline int do_change_hat(const ch
21
 
                 * In learning mode, this allows us to learn about new hats.
22
 
                 */
23
 
                aa_change_profile(cxt, cxt->profile->null_profile, hat_magic);
24
 
+               /*
25
 
+                * aa_change_profile switches profile lists but we don't
26
 
+                * want this for change_hat.  Switch back to the parents
27
 
+                * list.
28
 
+                * FIXME: update to a full profile change mechanism
29
 
+                * to get rid of this special casing
30
 
+                */
31
 
+               list_move(&cxt->list, &cxt->profile->parent->task_contexts);
32
 
        }
33
 
 
34
 
        return error;
35
 
@@ -1157,6 +1173,11 @@ repeat:
36
 
                        if (!hat_name) {
37
 
                                /* Return from subprofile back to parent. */
38
 
                                aa_change_profile(cxt, cxt->profile->parent, 0);
39
 
+                               /*
40
 
+                                * switching lists is not needed here because
41
 
+                                * aa_change_profile list move will leave the
42
 
+                                * cxt on the correct list
43
 
+                                */
44
 
                        } else {
45
 
                                /*
46
 
                                 * Change to another (sibling) profile, and
47
 
Index: b/security/apparmor/module_interface.c
48
 
===================================================================
49
 
--- a/security/apparmor/module_interface.c
50
 
+++ b/security/apparmor/module_interface.c
51
 
@@ -57,6 +57,14 @@ static inline void task_replace(struct a
52
 
                        hat = aa_dup_profile(new_profile->null_profile);
53
 
 
54
 
                aa_change_profile(cxt, hat, cxt->hat_magic);
55
 
+               /*
56
 
+                * aa_change_profile switches profile lists but we don't
57
 
+                * want this for change_hat.  Switch back to the parents
58
 
+                * list.
59
 
+                * FIXME: update to a full profile change mechanism
60
 
+                * to get rid of this special casing
61
 
+                */
62
 
+               list_move(&cxt->list, &hat->parent->task_contexts);
63
 
                aa_put_profile(hat);
64
 
        } else
65
 
                aa_change_profile(cxt, new_profile, cxt->hat_magic);
66
 
@@ -451,7 +459,14 @@ ssize_t aa_file_prof_replace(void *udata
67
 
        write_lock(&profile_list_lock);
68
 
        old_profile = __aa_find_profile(new_profile->name, &profile_list);
69
 
        if (old_profile) {
70
 
-               lock_profile(old_profile);
71
 
+               /*
72
 
+                * new_profile needs to be locked in the case that there
73
 
+                * are multiple tasks on old_profiles list, this avoids
74
 
+                * a race between an already replaced task changing its
75
 
+                * profile (updating the list) and replacement updating
76
 
+                * the list
77
 
+                */
78
 
+               lock_both_profiles(old_profile, new_profile);
79
 
                old_profile->isstale = 1;
80
 
                while (!list_empty(&old_profile->task_contexts)) {
81
 
                        struct aa_task_context *cxt =
82
 
@@ -461,7 +476,7 @@ ssize_t aa_file_prof_replace(void *udata
83
 
                        task_replace(cxt, new_profile);
84
 
                        task_unlock(cxt->task);
85
 
                }
86
 
-               unlock_profile(old_profile);
87
 
+               unlock_both_profiles(old_profile, new_profile);
88
 
 
89
 
                list_del_init(&old_profile->list);
90
 
                aa_put_profile(old_profile);