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

« back to all changes in this revision

Viewing changes to kernel-patches/for-mainline/rcu-stale-forward-ptr-2.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: linux-2.6-apparmor/security/apparmor/apparmor.h
2
 
===================================================================
3
 
--- linux-2.6-apparmor.orig/security/apparmor/apparmor.h
4
 
+++ linux-2.6-apparmor/security/apparmor/apparmor.h
5
 
@@ -257,6 +257,7 @@ extern ssize_t aa_file_prof_replace(void
6
 
 extern ssize_t aa_file_prof_remove(const char *, size_t);
7
 
 extern void free_aa_profile(struct aa_profile *profile);
8
 
 extern void free_aa_profile_kref(struct kref *kref);
9
 
+extern void aa_unconfine_tasks(struct aa_profile *profile);
10
 
 
11
 
 /* procattr.c */
12
 
 extern int aa_getprocattr(struct aa_profile *profile, char **string,
13
 
Index: linux-2.6-apparmor/security/apparmor/lsm.c
14
 
===================================================================
15
 
--- linux-2.6-apparmor.orig/security/apparmor/lsm.c
16
 
+++ linux-2.6-apparmor/security/apparmor/lsm.c
17
 
@@ -807,7 +807,7 @@ static void __exit apparmor_exit(void)
18
 
                /* Remove the profile from each task context it is on. */
19
 
                lock_profile(profile);
20
 
                profile->isstale = ERR_PTR(-ENOENT);
21
 
-               remove_tasks_on_context_list(profile);
22
 
+               aa_unconfine_tasks(profile);
23
 
                unlock_profile(profile);
24
 
 
25
 
                /* Release the profile itself. */
26
 
Index: linux-2.6-apparmor/security/apparmor/module_interface.c
27
 
===================================================================
28
 
--- linux-2.6-apparmor.orig/security/apparmor/module_interface.c
29
 
+++ linux-2.6-apparmor/security/apparmor/module_interface.c
30
 
@@ -444,7 +444,9 @@ ssize_t aa_file_prof_replace(void *udata
31
 
        write_lock(&profile_list_lock);
32
 
        old_profile = __aa_find_profile(new_profile->name, &profile_list);
33
 
        if (old_profile) {
34
 
-               old_profile->isstale = aa_dup_profile(new_profile);
35
 
+               lock_profile(old_profile);
36
 
+               old_profile->isstale = new_profile;
37
 
+               unlock_profile(old_profile);
38
 
                list_del_init(&old_profile->list);
39
 
        }
40
 
        aa_dup_profile(new_profile);
41
 
@@ -471,20 +473,14 @@ ssize_t aa_file_prof_replace(void *udata
42
 
        do {
43
 
                new_cxt = aa_alloc_task_context(GFP_KERNEL | __GFP_NOFAIL);
44
 
 
45
 
-               /*
46
 
-                * new_profile needs to be locked in the case that there
47
 
-                * are multiple tasks on old_profile->list, this avoids
48
 
-                * a race between an already replaced task changing its
49
 
-                * profile (updating the list) and replacement updating
50
 
-                * the list
51
 
-                */
52
 
        repeat:
53
 
                lock_both_profiles(old_profile, new_profile);
54
 
                if (new_profile->isstale) {
55
 
                        struct aa_profile *profile;
56
 
+
57
 
                        if (IS_ERR(new_profile->isstale)) {
58
 
                                /* new_profile was removed so become removal */
59
 
-                               remove_tasks_on_context_list(old_profile);
60
 
+                               aa_unconfine_tasks(old_profile);
61
 
                                unlock_both_profiles(old_profile, new_profile);
62
 
                                break;
63
 
                        }
64
 
@@ -531,14 +527,17 @@ ssize_t aa_file_prof_remove(const char *
65
 
                write_unlock(&profile_list_lock);
66
 
                return -ENOENT;
67
 
        }
68
 
-       profile->isstale = ERR_PTR(-ENOENT);
69
 
-       list_del_init(&profile->list);
70
 
-       write_unlock(&profile_list_lock);
71
 
 
72
 
+       /* Remove the profile from each task context it is on. */
73
 
        lock_profile(profile);
74
 
-       remove_tasks_on_context_list(profile);
75
 
+       profile->isstale = ERR_PTR(-ENOENT);
76
 
+       aa_unconfine_tasks(profile);
77
 
        unlock_profile(profile);
78
 
+
79
 
+       /* Release the profile itself. */
80
 
+       list_del_init(&profile->list);
81
 
        aa_put_profile(profile);
82
 
+       write_unlock(&profile_list_lock);
83
 
 
84
 
        return size;
85
 
 }
86
 
@@ -581,8 +580,6 @@ void free_aa_profile(struct aa_profile *
87
 
                BUG();
88
 
        }
89
 
 
90
 
-       if (!IS_ERR(profile->isstale))
91
 
-               aa_put_profile(profile->isstale);
92
 
        aa_match_free(profile->file_rules);
93
 
 
94
 
        /* use free_aa_profile instead of aa_put_profile to destroy the
95
 
@@ -603,3 +600,21 @@ void free_aa_profile(struct aa_profile *
96
 
 
97
 
        kfree(profile);
98
 
 }
99
 
+
100
 
+/**
101
 
+ * aa_unconfine_tasks - remove tasks on @profiles task_contexts list
102
 
+ * @profile: profile to remove associated tasks
103
 
+ *
104
 
+ * Assumes that @profile lock is held
105
 
+ */
106
 
+void aa_unconfine_tasks(struct aa_profile *profile)
107
 
+{
108
 
+       while (!list_empty(&profile->task_contexts)) {
109
 
+               struct task_struct *task =
110
 
+                       list_entry(profile->task_contexts.next,
111
 
+                                  struct aa_task_context, list)->task;
112
 
+               task_lock(task);
113
 
+               aa_change_task_context(task, NULL, NULL, 0);
114
 
+               task_unlock(task);
115
 
+       }
116
 
+}
117
 
Index: linux-2.6-apparmor/security/apparmor/inline.h
118
 
===================================================================
119
 
--- linux-2.6-apparmor.orig/security/apparmor/inline.h
120
 
+++ linux-2.6-apparmor/security/apparmor/inline.h
121
 
@@ -104,24 +104,6 @@ static inline struct aa_profile *alloc_a
122
 
 }
123
 
 
124
 
 /**
125
 
- * remove_tasks_on_context_list - remove tasks on @profiles task_contexts list
126
 
- * @profile: profile to remove associated tasks
127
 
- *
128
 
- * Assumes that @profile lock is held
129
 
- */
130
 
-static inline void remove_tasks_on_context_list(struct aa_profile *profile)
131
 
-{
132
 
-       while (!list_empty(&profile->task_contexts)) {
133
 
-               struct task_struct *task =
134
 
-                       list_entry(profile->task_contexts.next,
135
 
-                                  struct aa_task_context, list)->task;
136
 
-               task_lock(task);
137
 
-               aa_change_task_context(task, NULL, NULL, 0);
138
 
-               task_unlock(task);
139
 
-       }
140
 
-}
141
 
-
142
 
-/**
143
 
  * lock_profile - lock a profile
144
 
  * @profile: the profile to lock
145
 
  *
146
 
Index: linux-2.6-apparmor/security/apparmor/main.c
147
 
===================================================================
148
 
--- linux-2.6-apparmor.orig/security/apparmor/main.c
149
 
+++ linux-2.6-apparmor/security/apparmor/main.c
150
 
@@ -1201,7 +1201,7 @@ struct aa_profile *aa_replace_profile(st
151
 
        }
152
 
 
153
 
        cxt = lock_task_and_profiles(task, profile);
154
 
-       if (profile && profile->isstale) {
155
 
+       if (unlikely(profile && profile->isstale)) {
156
 
                task_unlock(task);
157
 
                unlock_both_profiles(profile, cxt ? cxt->profile : NULL);
158
 
                aa_free_task_context(new_cxt);