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
8
aa_change_profile(cxt, sub, hat_magic);
10
+ * aa_change_profile switches profile lists but we don't
11
+ * want this for change_hat. Switch back to the parents
13
+ * FIXME: update to a full profile change mechanism
14
+ * to get rid of this special casing
16
+ list_move(&cxt->list, &sub->parent->task_contexts);
18
struct aa_profile *profile = cxt->profile;
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.
23
aa_change_profile(cxt, cxt->profile->null_profile, hat_magic);
25
+ * aa_change_profile switches profile lists but we don't
26
+ * want this for change_hat. Switch back to the parents
28
+ * FIXME: update to a full profile change mechanism
29
+ * to get rid of this special casing
31
+ list_move(&cxt->list, &cxt->profile->parent->task_contexts);
35
@@ -1157,6 +1173,11 @@ repeat:
37
/* Return from subprofile back to parent. */
38
aa_change_profile(cxt, cxt->profile->parent, 0);
40
+ * switching lists is not needed here because
41
+ * aa_change_profile list move will leave the
42
+ * cxt on the correct list
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);
54
aa_change_profile(cxt, hat, cxt->hat_magic);
56
+ * aa_change_profile switches profile lists but we don't
57
+ * want this for change_hat. Switch back to the parents
59
+ * FIXME: update to a full profile change mechanism
60
+ * to get rid of this special casing
62
+ list_move(&cxt->list, &hat->parent->task_contexts);
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);
70
- lock_profile(old_profile);
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
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);
86
- unlock_profile(old_profile);
87
+ unlock_both_profiles(old_profile, new_profile);
89
list_del_init(&old_profile->list);
90
aa_put_profile(old_profile);