aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/tomoyo/common.c6
-rw-r--r--security/tomoyo/common.h12
-rw-r--r--security/tomoyo/condition.c8
-rw-r--r--security/tomoyo/domain.c5
-rw-r--r--security/tomoyo/file.c4
-rw-r--r--security/tomoyo/gc.c498
-rw-r--r--security/tomoyo/memory.c39
-rw-r--r--security/tomoyo/securityfs_if.c1
8 files changed, 221 insertions, 352 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 0994948f3edc..2e2802060eef 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -262,13 +262,17 @@ static void tomoyo_set_string(struct tomoyo_io_buffer *head, const char *string)
262 WARN_ON(1); 262 WARN_ON(1);
263} 263}
264 264
265static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
266 ...) __printf(2, 3);
267
265/** 268/**
266 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure. 269 * tomoyo_io_printf - printf() to "struct tomoyo_io_buffer" structure.
267 * 270 *
268 * @head: Pointer to "struct tomoyo_io_buffer". 271 * @head: Pointer to "struct tomoyo_io_buffer".
269 * @fmt: The printf()'s format string, followed by parameters. 272 * @fmt: The printf()'s format string, followed by parameters.
270 */ 273 */
271void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 274static void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt,
275 ...)
272{ 276{
273 va_list args; 277 va_list args;
274 size_t len; 278 size_t len;
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index a2bc33fc60b6..ed311d7a8ce0 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -52,6 +52,9 @@
52 52
53#define TOMOYO_EXEC_TMPSIZE 4096 53#define TOMOYO_EXEC_TMPSIZE 4096
54 54
55/* Garbage collector is trying to kfree() this element. */
56#define TOMOYO_GC_IN_PROGRESS -1
57
55/* Profile number is an integer between 0 and 255. */ 58/* Profile number is an integer between 0 and 255. */
56#define TOMOYO_MAX_PROFILES 256 59#define TOMOYO_MAX_PROFILES 256
57 60
@@ -398,7 +401,7 @@ enum tomoyo_pref_index {
398/* Common header for holding ACL entries. */ 401/* Common header for holding ACL entries. */
399struct tomoyo_acl_head { 402struct tomoyo_acl_head {
400 struct list_head list; 403 struct list_head list;
401 bool is_deleted; 404 s8 is_deleted; /* true or false or TOMOYO_GC_IN_PROGRESS */
402} __packed; 405} __packed;
403 406
404/* Common header for shared entries. */ 407/* Common header for shared entries. */
@@ -665,7 +668,7 @@ struct tomoyo_condition {
665struct tomoyo_acl_info { 668struct tomoyo_acl_info {
666 struct list_head list; 669 struct list_head list;
667 struct tomoyo_condition *cond; /* Maybe NULL. */ 670 struct tomoyo_condition *cond; /* Maybe NULL. */
668 bool is_deleted; 671 s8 is_deleted; /* true or false or TOMOYO_GC_IN_PROGRESS */
669 u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */ 672 u8 type; /* One of values in "enum tomoyo_acl_entry_type_index". */
670} __packed; 673} __packed;
671 674
@@ -978,8 +981,6 @@ int tomoyo_path_number_perm(const u8 operation, struct path *path,
978 unsigned long number); 981 unsigned long number);
979int tomoyo_path_perm(const u8 operation, struct path *path, 982int tomoyo_path_perm(const u8 operation, struct path *path,
980 const char *target); 983 const char *target);
981int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
982 const struct tomoyo_path_info *filename);
983int tomoyo_poll_control(struct file *file, poll_table *wait); 984int tomoyo_poll_control(struct file *file, poll_table *wait);
984int tomoyo_poll_log(struct file *file, poll_table *wait); 985int tomoyo_poll_log(struct file *file, poll_table *wait);
985int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr, 986int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
@@ -1041,10 +1042,7 @@ void tomoyo_del_condition(struct list_head *element);
1041void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 1042void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
1042void tomoyo_get_attributes(struct tomoyo_obj_info *obj); 1043void tomoyo_get_attributes(struct tomoyo_obj_info *obj);
1043void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns); 1044void tomoyo_init_policy_namespace(struct tomoyo_policy_namespace *ns);
1044void tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
1045 __printf(2, 3);
1046void tomoyo_load_policy(const char *filename); 1045void tomoyo_load_policy(const char *filename);
1047void tomoyo_memory_free(void *ptr);
1048void tomoyo_normalize_line(unsigned char *buffer); 1046void tomoyo_normalize_line(unsigned char *buffer);
1049void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register); 1047void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register);
1050void tomoyo_print_ip(char *buf, const unsigned int size, 1048void tomoyo_print_ip(char *buf, const unsigned int size,
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
index b854959c0fd4..986330b8c73e 100644
--- a/security/tomoyo/condition.c
+++ b/security/tomoyo/condition.c
@@ -400,8 +400,9 @@ static struct tomoyo_condition *tomoyo_commit_condition
400 found = true; 400 found = true;
401 goto out; 401 goto out;
402 } 402 }
403 list_for_each_entry_rcu(ptr, &tomoyo_condition_list, head.list) { 403 list_for_each_entry(ptr, &tomoyo_condition_list, head.list) {
404 if (!tomoyo_same_condition(ptr, entry)) 404 if (!tomoyo_same_condition(ptr, entry) ||
405 atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
405 continue; 406 continue;
406 /* Same entry found. Share this entry. */ 407 /* Same entry found. Share this entry. */
407 atomic_inc(&ptr->head.users); 408 atomic_inc(&ptr->head.users);
@@ -411,8 +412,7 @@ static struct tomoyo_condition *tomoyo_commit_condition
411 if (!found) { 412 if (!found) {
412 if (tomoyo_memory_ok(entry)) { 413 if (tomoyo_memory_ok(entry)) {
413 atomic_set(&entry->head.users, 1); 414 atomic_set(&entry->head.users, 1);
414 list_add_rcu(&entry->head.list, 415 list_add(&entry->head.list, &tomoyo_condition_list);
415 &tomoyo_condition_list);
416 } else { 416 } else {
417 found = true; 417 found = true;
418 ptr = NULL; 418 ptr = NULL;
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 860390ee1fbe..da16dfeed728 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -39,6 +39,8 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
39 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 39 if (mutex_lock_interruptible(&tomoyo_policy_lock))
40 return -ENOMEM; 40 return -ENOMEM;
41 list_for_each_entry_rcu(entry, list, list) { 41 list_for_each_entry_rcu(entry, list, list) {
42 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
43 continue;
42 if (!check_duplicate(entry, new_entry)) 44 if (!check_duplicate(entry, new_entry))
43 continue; 45 continue;
44 entry->is_deleted = param->is_delete; 46 entry->is_deleted = param->is_delete;
@@ -115,6 +117,8 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
115 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 117 if (mutex_lock_interruptible(&tomoyo_policy_lock))
116 goto out; 118 goto out;
117 list_for_each_entry_rcu(entry, list, list) { 119 list_for_each_entry_rcu(entry, list, list) {
120 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
121 continue;
118 if (!tomoyo_same_acl_head(entry, new_entry) || 122 if (!tomoyo_same_acl_head(entry, new_entry) ||
119 !check_duplicate(entry, new_entry)) 123 !check_duplicate(entry, new_entry))
120 continue; 124 continue;
@@ -567,6 +571,7 @@ out:
567 tomoyo_write_log(&r, "use_profile %u\n", 571 tomoyo_write_log(&r, "use_profile %u\n",
568 entry->profile); 572 entry->profile);
569 tomoyo_write_log(&r, "use_group %u\n", entry->group); 573 tomoyo_write_log(&r, "use_group %u\n", entry->group);
574 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
570 } 575 }
571 } 576 }
572 return entry; 577 return entry;
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index b280c1bd652d..400390790745 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -555,8 +555,8 @@ static int tomoyo_update_path2_acl(const u8 perm,
555 * 555 *
556 * Caller holds tomoyo_read_lock(). 556 * Caller holds tomoyo_read_lock().
557 */ 557 */
558int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 558static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
559 const struct tomoyo_path_info *filename) 559 const struct tomoyo_path_info *filename)
560{ 560{
561 int error; 561 int error;
562 562
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index 7747ceb9a221..c3214b32dbfb 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -8,40 +8,26 @@
8#include <linux/kthread.h> 8#include <linux/kthread.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10 10
11/**
12 * tomoyo_memory_free - Free memory for elements.
13 *
14 * @ptr: Pointer to allocated memory.
15 *
16 * Returns nothing.
17 *
18 * Caller holds tomoyo_policy_lock mutex.
19 */
20static inline void tomoyo_memory_free(void *ptr)
21{
22 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr);
23 kfree(ptr);
24}
25
11/* The list for "struct tomoyo_io_buffer". */ 26/* The list for "struct tomoyo_io_buffer". */
12static LIST_HEAD(tomoyo_io_buffer_list); 27static LIST_HEAD(tomoyo_io_buffer_list);
13/* Lock for protecting tomoyo_io_buffer_list. */ 28/* Lock for protecting tomoyo_io_buffer_list. */
14static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock); 29static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
15 30
16/* Size of an element. */
17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
19 [TOMOYO_ID_ADDRESS_GROUP] = sizeof(struct tomoyo_address_group),
20 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
21 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
22 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
23 [TOMOYO_ID_TRANSITION_CONTROL] =
24 sizeof(struct tomoyo_transition_control),
25 [TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
26 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
27 /* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
28 /* [TOMOYO_ID_ACL] =
29 tomoyo_acl_size["struct tomoyo_acl_info"->type], */
30 [TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info),
31};
32
33/* Size of a domain ACL element. */
34static const u8 tomoyo_acl_size[] = {
35 [TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl),
36 [TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl),
37 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
38 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
39 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
40 [TOMOYO_TYPE_INET_ACL] = sizeof(struct tomoyo_inet_acl),
41 [TOMOYO_TYPE_UNIX_ACL] = sizeof(struct tomoyo_unix_acl),
42 [TOMOYO_TYPE_ENV_ACL] = sizeof(struct tomoyo_env_acl),
43};
44
45/** 31/**
46 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not. 32 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
47 * 33 *
@@ -59,15 +45,11 @@ static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
59 list_for_each_entry(head, &tomoyo_io_buffer_list, list) { 45 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
60 head->users++; 46 head->users++;
61 spin_unlock(&tomoyo_io_buffer_list_lock); 47 spin_unlock(&tomoyo_io_buffer_list_lock);
62 if (mutex_lock_interruptible(&head->io_sem)) { 48 mutex_lock(&head->io_sem);
63 in_use = true;
64 goto out;
65 }
66 if (head->r.domain == element || head->r.group == element || 49 if (head->r.domain == element || head->r.group == element ||
67 head->r.acl == element || &head->w.domain->list == element) 50 head->r.acl == element || &head->w.domain->list == element)
68 in_use = true; 51 in_use = true;
69 mutex_unlock(&head->io_sem); 52 mutex_unlock(&head->io_sem);
70out:
71 spin_lock(&tomoyo_io_buffer_list_lock); 53 spin_lock(&tomoyo_io_buffer_list_lock);
72 head->users--; 54 head->users--;
73 if (in_use) 55 if (in_use)
@@ -81,15 +63,14 @@ out:
81 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not. 63 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
82 * 64 *
83 * @string: String to check. 65 * @string: String to check.
84 * @size: Memory allocated for @string .
85 * 66 *
86 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users, 67 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
87 * false otherwise. 68 * false otherwise.
88 */ 69 */
89static bool tomoyo_name_used_by_io_buffer(const char *string, 70static bool tomoyo_name_used_by_io_buffer(const char *string)
90 const size_t size)
91{ 71{
92 struct tomoyo_io_buffer *head; 72 struct tomoyo_io_buffer *head;
73 const size_t size = strlen(string) + 1;
93 bool in_use = false; 74 bool in_use = false;
94 75
95 spin_lock(&tomoyo_io_buffer_list_lock); 76 spin_lock(&tomoyo_io_buffer_list_lock);
@@ -97,10 +78,7 @@ static bool tomoyo_name_used_by_io_buffer(const char *string,
97 int i; 78 int i;
98 head->users++; 79 head->users++;
99 spin_unlock(&tomoyo_io_buffer_list_lock); 80 spin_unlock(&tomoyo_io_buffer_list_lock);
100 if (mutex_lock_interruptible(&head->io_sem)) { 81 mutex_lock(&head->io_sem);
101 in_use = true;
102 goto out;
103 }
104 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) { 82 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
105 const char *w = head->r.w[i]; 83 const char *w = head->r.w[i];
106 if (w < string || w > string + size) 84 if (w < string || w > string + size)
@@ -109,7 +87,6 @@ static bool tomoyo_name_used_by_io_buffer(const char *string,
109 break; 87 break;
110 } 88 }
111 mutex_unlock(&head->io_sem); 89 mutex_unlock(&head->io_sem);
112out:
113 spin_lock(&tomoyo_io_buffer_list_lock); 90 spin_lock(&tomoyo_io_buffer_list_lock);
114 head->users--; 91 head->users--;
115 if (in_use) 92 if (in_use)
@@ -119,84 +96,6 @@ out:
119 return in_use; 96 return in_use;
120} 97}
121 98
122/* Structure for garbage collection. */
123struct tomoyo_gc {
124 struct list_head list;
125 enum tomoyo_policy_id type;
126 size_t size;
127 struct list_head *element;
128};
129/* List of entries to be deleted. */
130static LIST_HEAD(tomoyo_gc_list);
131/* Length of tomoyo_gc_list. */
132static int tomoyo_gc_list_len;
133
134/**
135 * tomoyo_add_to_gc - Add an entry to to be deleted list.
136 *
137 * @type: One of values in "enum tomoyo_policy_id".
138 * @element: Pointer to "struct list_head".
139 *
140 * Returns true on success, false otherwise.
141 *
142 * Caller holds tomoyo_policy_lock mutex.
143 *
144 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
145 * entries at once, it will take too long time. Thus, do not add more than 128
146 * entries per a scan. But to be able to handle worst case where all entries
147 * are in-use, we accept one more entry per a scan.
148 *
149 * If we use singly linked list using "struct list_head"->prev (which is
150 * LIST_POISON2), we can avoid kmalloc().
151 */
152static bool tomoyo_add_to_gc(const int type, struct list_head *element)
153{
154 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
155 if (!entry)
156 return false;
157 entry->type = type;
158 if (type == TOMOYO_ID_ACL)
159 entry->size = tomoyo_acl_size[
160 container_of(element,
161 typeof(struct tomoyo_acl_info),
162 list)->type];
163 else if (type == TOMOYO_ID_NAME)
164 entry->size = strlen(container_of(element,
165 typeof(struct tomoyo_name),
166 head.list)->entry.name) + 1;
167 else if (type == TOMOYO_ID_CONDITION)
168 entry->size =
169 container_of(element, typeof(struct tomoyo_condition),
170 head.list)->size;
171 else
172 entry->size = tomoyo_element_size[type];
173 entry->element = element;
174 list_add(&entry->list, &tomoyo_gc_list);
175 list_del_rcu(element);
176 return tomoyo_gc_list_len++ < 128;
177}
178
179/**
180 * tomoyo_element_linked_by_gc - Validate next element of an entry.
181 *
182 * @element: Pointer to an element.
183 * @size: Size of @element in byte.
184 *
185 * Returns true if @element is linked by other elements in the garbage
186 * collector's queue, false otherwise.
187 */
188static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
189{
190 struct tomoyo_gc *p;
191 list_for_each_entry(p, &tomoyo_gc_list, list) {
192 const u8 *ptr = (const u8 *) p->element->next;
193 if (ptr < element || element + size < ptr)
194 continue;
195 return true;
196 }
197 return false;
198}
199
200/** 99/**
201 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control". 100 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
202 * 101 *
@@ -204,7 +103,7 @@ static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
204 * 103 *
205 * Returns nothing. 104 * Returns nothing.
206 */ 105 */
207static void tomoyo_del_transition_control(struct list_head *element) 106static inline void tomoyo_del_transition_control(struct list_head *element)
208{ 107{
209 struct tomoyo_transition_control *ptr = 108 struct tomoyo_transition_control *ptr =
210 container_of(element, typeof(*ptr), head.list); 109 container_of(element, typeof(*ptr), head.list);
@@ -219,7 +118,7 @@ static void tomoyo_del_transition_control(struct list_head *element)
219 * 118 *
220 * Returns nothing. 119 * Returns nothing.
221 */ 120 */
222static void tomoyo_del_aggregator(struct list_head *element) 121static inline void tomoyo_del_aggregator(struct list_head *element)
223{ 122{
224 struct tomoyo_aggregator *ptr = 123 struct tomoyo_aggregator *ptr =
225 container_of(element, typeof(*ptr), head.list); 124 container_of(element, typeof(*ptr), head.list);
@@ -234,7 +133,7 @@ static void tomoyo_del_aggregator(struct list_head *element)
234 * 133 *
235 * Returns nothing. 134 * Returns nothing.
236 */ 135 */
237static void tomoyo_del_manager(struct list_head *element) 136static inline void tomoyo_del_manager(struct list_head *element)
238{ 137{
239 struct tomoyo_manager *ptr = 138 struct tomoyo_manager *ptr =
240 container_of(element, typeof(*ptr), head.list); 139 container_of(element, typeof(*ptr), head.list);
@@ -330,44 +229,26 @@ static void tomoyo_del_acl(struct list_head *element)
330 * 229 *
331 * @element: Pointer to "struct list_head". 230 * @element: Pointer to "struct list_head".
332 * 231 *
333 * Returns true if deleted, false otherwise. 232 * Returns nothing.
233 *
234 * Caller holds tomoyo_policy_lock mutex.
334 */ 235 */
335static bool tomoyo_del_domain(struct list_head *element) 236static inline void tomoyo_del_domain(struct list_head *element)
336{ 237{
337 struct tomoyo_domain_info *domain = 238 struct tomoyo_domain_info *domain =
338 container_of(element, typeof(*domain), list); 239 container_of(element, typeof(*domain), list);
339 struct tomoyo_acl_info *acl; 240 struct tomoyo_acl_info *acl;
340 struct tomoyo_acl_info *tmp; 241 struct tomoyo_acl_info *tmp;
341 /* 242 /*
342 * Since we don't protect whole execve() operation using SRCU, 243 * Since this domain is referenced from neither
343 * we need to recheck domain->users at this point. 244 * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
344 * 245 * elements without checking for is_deleted flag.
345 * (1) Reader starts SRCU section upon execve().
346 * (2) Reader traverses tomoyo_domain_list and finds this domain.
347 * (3) Writer marks this domain as deleted.
348 * (4) Garbage collector removes this domain from tomoyo_domain_list
349 * because this domain is marked as deleted and used by nobody.
350 * (5) Reader saves reference to this domain into
351 * "struct linux_binprm"->cred->security .
352 * (6) Reader finishes SRCU section, although execve() operation has
353 * not finished yet.
354 * (7) Garbage collector waits for SRCU synchronization.
355 * (8) Garbage collector kfree() this domain because this domain is
356 * used by nobody.
357 * (9) Reader finishes execve() operation and restores this domain from
358 * "struct linux_binprm"->cred->security.
359 *
360 * By updating domain->users at (5), we can solve this race problem
361 * by rechecking domain->users at (8).
362 */ 246 */
363 if (atomic_read(&domain->users))
364 return false;
365 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 247 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
366 tomoyo_del_acl(&acl->list); 248 tomoyo_del_acl(&acl->list);
367 tomoyo_memory_free(acl); 249 tomoyo_memory_free(acl);
368 } 250 }
369 tomoyo_put_name(domain->domainname); 251 tomoyo_put_name(domain->domainname);
370 return true;
371} 252}
372 253
373/** 254/**
@@ -416,10 +297,9 @@ void tomoyo_del_condition(struct list_head *element)
416 * 297 *
417 * Returns nothing. 298 * Returns nothing.
418 */ 299 */
419static void tomoyo_del_name(struct list_head *element) 300static inline void tomoyo_del_name(struct list_head *element)
420{ 301{
421 const struct tomoyo_name *ptr = 302 /* Nothing to do. */
422 container_of(element, typeof(*ptr), head.list);
423} 303}
424 304
425/** 305/**
@@ -429,7 +309,7 @@ static void tomoyo_del_name(struct list_head *element)
429 * 309 *
430 * Returns nothing. 310 * Returns nothing.
431 */ 311 */
432static void tomoyo_del_path_group(struct list_head *element) 312static inline void tomoyo_del_path_group(struct list_head *element)
433{ 313{
434 struct tomoyo_path_group *member = 314 struct tomoyo_path_group *member =
435 container_of(element, typeof(*member), head.list); 315 container_of(element, typeof(*member), head.list);
@@ -443,7 +323,7 @@ static void tomoyo_del_path_group(struct list_head *element)
443 * 323 *
444 * Returns nothing. 324 * Returns nothing.
445 */ 325 */
446static void tomoyo_del_group(struct list_head *element) 326static inline void tomoyo_del_group(struct list_head *element)
447{ 327{
448 struct tomoyo_group *group = 328 struct tomoyo_group *group =
449 container_of(element, typeof(*group), head.list); 329 container_of(element, typeof(*group), head.list);
@@ -469,10 +349,110 @@ static inline void tomoyo_del_address_group(struct list_head *element)
469 * 349 *
470 * Returns nothing. 350 * Returns nothing.
471 */ 351 */
472static void tomoyo_del_number_group(struct list_head *element) 352static inline void tomoyo_del_number_group(struct list_head *element)
473{ 353{
474 struct tomoyo_number_group *member = 354 /* Nothing to do. */
475 container_of(element, typeof(*member), head.list); 355}
356
357/**
358 * tomoyo_try_to_gc - Try to kfree() an entry.
359 *
360 * @type: One of values in "enum tomoyo_policy_id".
361 * @element: Pointer to "struct list_head".
362 *
363 * Returns nothing.
364 *
365 * Caller holds tomoyo_policy_lock mutex.
366 */
367static void tomoyo_try_to_gc(const enum tomoyo_policy_id type,
368 struct list_head *element)
369{
370 /*
371 * __list_del_entry() guarantees that the list element became no longer
372 * reachable from the list which the element was originally on (e.g.
373 * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the
374 * list element became no longer referenced by syscall users.
375 */
376 __list_del_entry(element);
377 mutex_unlock(&tomoyo_policy_lock);
378 synchronize_srcu(&tomoyo_ss);
379 /*
380 * However, there are two users which may still be using the list
381 * element. We need to defer until both users forget this element.
382 *
383 * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl}
384 * and "struct tomoyo_io_buffer"->w.domain forget this element.
385 */
386 if (tomoyo_struct_used_by_io_buffer(element))
387 goto reinject;
388 switch (type) {
389 case TOMOYO_ID_TRANSITION_CONTROL:
390 tomoyo_del_transition_control(element);
391 break;
392 case TOMOYO_ID_MANAGER:
393 tomoyo_del_manager(element);
394 break;
395 case TOMOYO_ID_AGGREGATOR:
396 tomoyo_del_aggregator(element);
397 break;
398 case TOMOYO_ID_GROUP:
399 tomoyo_del_group(element);
400 break;
401 case TOMOYO_ID_PATH_GROUP:
402 tomoyo_del_path_group(element);
403 break;
404 case TOMOYO_ID_ADDRESS_GROUP:
405 tomoyo_del_address_group(element);
406 break;
407 case TOMOYO_ID_NUMBER_GROUP:
408 tomoyo_del_number_group(element);
409 break;
410 case TOMOYO_ID_CONDITION:
411 tomoyo_del_condition(element);
412 break;
413 case TOMOYO_ID_NAME:
414 /*
415 * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[]
416 * forget this element.
417 */
418 if (tomoyo_name_used_by_io_buffer
419 (container_of(element, typeof(struct tomoyo_name),
420 head.list)->entry.name))
421 goto reinject;
422 tomoyo_del_name(element);
423 break;
424 case TOMOYO_ID_ACL:
425 tomoyo_del_acl(element);
426 break;
427 case TOMOYO_ID_DOMAIN:
428 /*
429 * Don't kfree() until all "struct cred"->security forget this
430 * element.
431 */
432 if (atomic_read(&container_of
433 (element, typeof(struct tomoyo_domain_info),
434 list)->users))
435 goto reinject;
436 break;
437 case TOMOYO_MAX_POLICY:
438 break;
439 }
440 mutex_lock(&tomoyo_policy_lock);
441 if (type == TOMOYO_ID_DOMAIN)
442 tomoyo_del_domain(element);
443 tomoyo_memory_free(element);
444 return;
445reinject:
446 /*
447 * We can safely reinject this element here bacause
448 * (1) Appending list elements and removing list elements are protected
449 * by tomoyo_policy_lock mutex.
450 * (2) Only this function removes list elements and this function is
451 * exclusively executed by tomoyo_gc_mutex mutex.
452 * are true.
453 */
454 mutex_lock(&tomoyo_policy_lock);
455 list_add_rcu(element, element->prev);
476} 456}
477 457
478/** 458/**
@@ -481,19 +461,19 @@ static void tomoyo_del_number_group(struct list_head *element)
481 * @id: One of values in "enum tomoyo_policy_id". 461 * @id: One of values in "enum tomoyo_policy_id".
482 * @member_list: Pointer to "struct list_head". 462 * @member_list: Pointer to "struct list_head".
483 * 463 *
484 * Returns true if some elements are deleted, false otherwise. 464 * Returns nothing.
485 */ 465 */
486static bool tomoyo_collect_member(const enum tomoyo_policy_id id, 466static void tomoyo_collect_member(const enum tomoyo_policy_id id,
487 struct list_head *member_list) 467 struct list_head *member_list)
488{ 468{
489 struct tomoyo_acl_head *member; 469 struct tomoyo_acl_head *member;
490 list_for_each_entry(member, member_list, list) { 470 struct tomoyo_acl_head *tmp;
471 list_for_each_entry_safe(member, tmp, member_list, list) {
491 if (!member->is_deleted) 472 if (!member->is_deleted)
492 continue; 473 continue;
493 if (!tomoyo_add_to_gc(id, &member->list)) 474 member->is_deleted = TOMOYO_GC_IN_PROGRESS;
494 return false; 475 tomoyo_try_to_gc(id, &member->list);
495 } 476 }
496 return true;
497} 477}
498 478
499/** 479/**
@@ -501,22 +481,22 @@ static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
501 * 481 *
502 * @list: Pointer to "struct list_head". 482 * @list: Pointer to "struct list_head".
503 * 483 *
504 * Returns true if some elements are deleted, false otherwise. 484 * Returns nothing.
505 */ 485 */
506static bool tomoyo_collect_acl(struct list_head *list) 486static void tomoyo_collect_acl(struct list_head *list)
507{ 487{
508 struct tomoyo_acl_info *acl; 488 struct tomoyo_acl_info *acl;
509 list_for_each_entry(acl, list, list) { 489 struct tomoyo_acl_info *tmp;
490 list_for_each_entry_safe(acl, tmp, list, list) {
510 if (!acl->is_deleted) 491 if (!acl->is_deleted)
511 continue; 492 continue;
512 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 493 acl->is_deleted = TOMOYO_GC_IN_PROGRESS;
513 return false; 494 tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list);
514 } 495 }
515 return true;
516} 496}
517 497
518/** 498/**
519 * tomoyo_collect_entry - Scan lists for deleted elements. 499 * tomoyo_collect_entry - Try to kfree() deleted elements.
520 * 500 *
521 * Returns nothing. 501 * Returns nothing.
522 */ 502 */
@@ -525,36 +505,40 @@ static void tomoyo_collect_entry(void)
525 int i; 505 int i;
526 enum tomoyo_policy_id id; 506 enum tomoyo_policy_id id;
527 struct tomoyo_policy_namespace *ns; 507 struct tomoyo_policy_namespace *ns;
528 int idx; 508 mutex_lock(&tomoyo_policy_lock);
529 if (mutex_lock_interruptible(&tomoyo_policy_lock))
530 return;
531 idx = tomoyo_read_lock();
532 { 509 {
533 struct tomoyo_domain_info *domain; 510 struct tomoyo_domain_info *domain;
534 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 511 struct tomoyo_domain_info *tmp;
535 if (!tomoyo_collect_acl(&domain->acl_info_list)) 512 list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
536 goto unlock; 513 list) {
514 tomoyo_collect_acl(&domain->acl_info_list);
537 if (!domain->is_deleted || atomic_read(&domain->users)) 515 if (!domain->is_deleted || atomic_read(&domain->users))
538 continue; 516 continue;
539 /* 517 tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list);
540 * Nobody is referring this domain. But somebody may
541 * refer this domain after successful execve().
542 * We recheck domain->users after SRCU synchronization.
543 */
544 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
545 goto unlock;
546 } 518 }
547 } 519 }
548 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) { 520 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
549 for (id = 0; id < TOMOYO_MAX_POLICY; id++) 521 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
550 if (!tomoyo_collect_member(id, &ns->policy_list[id])) 522 tomoyo_collect_member(id, &ns->policy_list[id]);
551 goto unlock;
552 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++) 523 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
553 if (!tomoyo_collect_acl(&ns->acl_group[i])) 524 tomoyo_collect_acl(&ns->acl_group[i]);
554 goto unlock; 525 }
526 {
527 struct tomoyo_shared_acl_head *ptr;
528 struct tomoyo_shared_acl_head *tmp;
529 list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
530 list) {
531 if (atomic_read(&ptr->users) > 0)
532 continue;
533 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
534 tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list);
535 }
536 }
537 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
555 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 538 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
556 struct list_head *list = &ns->group_list[i]; 539 struct list_head *list = &ns->group_list[i];
557 struct tomoyo_group *group; 540 struct tomoyo_group *group;
541 struct tomoyo_group *tmp;
558 switch (i) { 542 switch (i) {
559 case 0: 543 case 0:
560 id = TOMOYO_ID_PATH_GROUP; 544 id = TOMOYO_ID_PATH_GROUP;
@@ -566,139 +550,37 @@ static void tomoyo_collect_entry(void)
566 id = TOMOYO_ID_ADDRESS_GROUP; 550 id = TOMOYO_ID_ADDRESS_GROUP;
567 break; 551 break;
568 } 552 }
569 list_for_each_entry(group, list, head.list) { 553 list_for_each_entry_safe(group, tmp, list, head.list) {
570 if (!tomoyo_collect_member 554 tomoyo_collect_member(id, &group->member_list);
571 (id, &group->member_list))
572 goto unlock;
573 if (!list_empty(&group->member_list) || 555 if (!list_empty(&group->member_list) ||
574 atomic_read(&group->head.users)) 556 atomic_read(&group->head.users) > 0)
575 continue; 557 continue;
576 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, 558 atomic_set(&group->head.users,
577 &group->head.list)) 559 TOMOYO_GC_IN_PROGRESS);
578 goto unlock; 560 tomoyo_try_to_gc(TOMOYO_ID_GROUP,
561 &group->head.list);
579 } 562 }
580 } 563 }
581 } 564 }
582 id = TOMOYO_ID_CONDITION; 565 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
583 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) { 566 struct list_head *list = &tomoyo_name_list[i];
584 struct list_head *list = !i ?
585 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
586 struct tomoyo_shared_acl_head *ptr; 567 struct tomoyo_shared_acl_head *ptr;
587 list_for_each_entry(ptr, list, list) { 568 struct tomoyo_shared_acl_head *tmp;
588 if (atomic_read(&ptr->users)) 569 list_for_each_entry_safe(ptr, tmp, list, list) {
570 if (atomic_read(&ptr->users) > 0)
589 continue; 571 continue;
590 if (!tomoyo_add_to_gc(id, &ptr->list)) 572 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
591 goto unlock; 573 tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list);
592 } 574 }
593 id = TOMOYO_ID_NAME;
594 } 575 }
595unlock:
596 tomoyo_read_unlock(idx);
597 mutex_unlock(&tomoyo_policy_lock); 576 mutex_unlock(&tomoyo_policy_lock);
598} 577}
599 578
600/** 579/**
601 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list.
602 *
603 * Returns true if some entries were kfree()d, false otherwise.
604 */
605static bool tomoyo_kfree_entry(void)
606{
607 struct tomoyo_gc *p;
608 struct tomoyo_gc *tmp;
609 bool result = false;
610
611 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
612 struct list_head *element = p->element;
613
614 /*
615 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the
616 * list element became no longer reachable from the list which
617 * the element was originally on (e.g. tomoyo_domain_list).
618 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees
619 * that the list element became no longer referenced by syscall
620 * users.
621 *
622 * However, there are three users which may still be using the
623 * list element. We need to defer until all of these users
624 * forget the list element.
625 *
626 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain,
627 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget
628 * the list element.
629 */
630 if (tomoyo_struct_used_by_io_buffer(element))
631 continue;
632 /*
633 * Secondly, defer until all other elements in the
634 * tomoyo_gc_list list forget the list element.
635 */
636 if (tomoyo_element_linked_by_gc((const u8 *) element, p->size))
637 continue;
638 switch (p->type) {
639 case TOMOYO_ID_TRANSITION_CONTROL:
640 tomoyo_del_transition_control(element);
641 break;
642 case TOMOYO_ID_AGGREGATOR:
643 tomoyo_del_aggregator(element);
644 break;
645 case TOMOYO_ID_MANAGER:
646 tomoyo_del_manager(element);
647 break;
648 case TOMOYO_ID_CONDITION:
649 tomoyo_del_condition(element);
650 break;
651 case TOMOYO_ID_NAME:
652 /*
653 * Thirdly, defer until all "struct tomoyo_io_buffer"
654 * ->r.w[] forget the list element.
655 */
656 if (tomoyo_name_used_by_io_buffer(
657 container_of(element, typeof(struct tomoyo_name),
658 head.list)->entry.name, p->size))
659 continue;
660 tomoyo_del_name(element);
661 break;
662 case TOMOYO_ID_ACL:
663 tomoyo_del_acl(element);
664 break;
665 case TOMOYO_ID_DOMAIN:
666 if (!tomoyo_del_domain(element))
667 continue;
668 break;
669 case TOMOYO_ID_PATH_GROUP:
670 tomoyo_del_path_group(element);
671 break;
672 case TOMOYO_ID_ADDRESS_GROUP:
673 tomoyo_del_address_group(element);
674 break;
675 case TOMOYO_ID_GROUP:
676 tomoyo_del_group(element);
677 break;
678 case TOMOYO_ID_NUMBER_GROUP:
679 tomoyo_del_number_group(element);
680 break;
681 case TOMOYO_MAX_POLICY:
682 break;
683 }
684 tomoyo_memory_free(element);
685 list_del(&p->list);
686 kfree(p);
687 tomoyo_gc_list_len--;
688 result = true;
689 }
690 return result;
691}
692
693/**
694 * tomoyo_gc_thread - Garbage collector thread function. 580 * tomoyo_gc_thread - Garbage collector thread function.
695 * 581 *
696 * @unused: Unused. 582 * @unused: Unused.
697 * 583 *
698 * In case OOM-killer choose this thread for termination, we create this thread
699 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
700 * close()d.
701 *
702 * Returns 0. 584 * Returns 0.
703 */ 585 */
704static int tomoyo_gc_thread(void *unused) 586static int tomoyo_gc_thread(void *unused)
@@ -707,13 +589,7 @@ static int tomoyo_gc_thread(void *unused)
707 static DEFINE_MUTEX(tomoyo_gc_mutex); 589 static DEFINE_MUTEX(tomoyo_gc_mutex);
708 if (!mutex_trylock(&tomoyo_gc_mutex)) 590 if (!mutex_trylock(&tomoyo_gc_mutex))
709 goto out; 591 goto out;
710 592 tomoyo_collect_entry();
711 do {
712 tomoyo_collect_entry();
713 if (list_empty(&tomoyo_gc_list))
714 break;
715 synchronize_srcu(&tomoyo_ss);
716 } while (tomoyo_kfree_entry());
717 { 593 {
718 struct tomoyo_io_buffer *head; 594 struct tomoyo_io_buffer *head;
719 struct tomoyo_io_buffer *tmp; 595 struct tomoyo_io_buffer *tmp;
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 7a56051146c2..0e995716cc25 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -27,8 +27,6 @@ void tomoyo_warn_oom(const char *function)
27 panic("MAC Initialization failed.\n"); 27 panic("MAC Initialization failed.\n");
28} 28}
29 29
30/* Lock for protecting tomoyo_memory_used. */
31static DEFINE_SPINLOCK(tomoyo_policy_memory_lock);
32/* Memoy currently used by policy/audit log/query. */ 30/* Memoy currently used by policy/audit log/query. */
33unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT]; 31unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
34/* Memory quota for "policy"/"audit log"/"query". */ 32/* Memory quota for "policy"/"audit log"/"query". */
@@ -42,22 +40,19 @@ unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
42 * Returns true on success, false otherwise. 40 * Returns true on success, false otherwise.
43 * 41 *
44 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise. 42 * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
43 *
44 * Caller holds tomoyo_policy_lock mutex.
45 */ 45 */
46bool tomoyo_memory_ok(void *ptr) 46bool tomoyo_memory_ok(void *ptr)
47{ 47{
48 if (ptr) { 48 if (ptr) {
49 const size_t s = ksize(ptr); 49 const size_t s = ksize(ptr);
50 bool result;
51 spin_lock(&tomoyo_policy_memory_lock);
52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s; 50 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] += s;
53 result = !tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] || 51 if (!tomoyo_memory_quota[TOMOYO_MEMORY_POLICY] ||
54 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <= 52 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] <=
55 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY]; 53 tomoyo_memory_quota[TOMOYO_MEMORY_POLICY])
56 if (!result)
57 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
58 spin_unlock(&tomoyo_policy_memory_lock);
59 if (result)
60 return true; 54 return true;
55 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
61 } 56 }
62 tomoyo_warn_oom(__func__); 57 tomoyo_warn_oom(__func__);
63 return false; 58 return false;
@@ -71,6 +66,8 @@ bool tomoyo_memory_ok(void *ptr)
71 * 66 *
72 * Returns pointer to allocated memory on success, NULL otherwise. 67 * Returns pointer to allocated memory on success, NULL otherwise.
73 * @data is zero-cleared on success. 68 * @data is zero-cleared on success.
69 *
70 * Caller holds tomoyo_policy_lock mutex.
74 */ 71 */
75void *tomoyo_commit_ok(void *data, const unsigned int size) 72void *tomoyo_commit_ok(void *data, const unsigned int size)
76{ 73{
@@ -85,20 +82,6 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
85} 82}
86 83
87/** 84/**
88 * tomoyo_memory_free - Free memory for elements.
89 *
90 * @ptr: Pointer to allocated memory.
91 */
92void tomoyo_memory_free(void *ptr)
93{
94 size_t s = ksize(ptr);
95 spin_lock(&tomoyo_policy_memory_lock);
96 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= s;
97 spin_unlock(&tomoyo_policy_memory_lock);
98 kfree(ptr);
99}
100
101/**
102 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group". 85 * tomoyo_get_group - Allocate memory for "struct tomoyo_path_group"/"struct tomoyo_number_group".
103 * 86 *
104 * @param: Pointer to "struct tomoyo_acl_param". 87 * @param: Pointer to "struct tomoyo_acl_param".
@@ -123,7 +106,8 @@ struct tomoyo_group *tomoyo_get_group(struct tomoyo_acl_param *param,
123 goto out; 106 goto out;
124 list = &param->ns->group_list[idx]; 107 list = &param->ns->group_list[idx];
125 list_for_each_entry(group, list, head.list) { 108 list_for_each_entry(group, list, head.list) {
126 if (e.group_name != group->group_name) 109 if (e.group_name != group->group_name ||
110 atomic_read(&group->head.users) == TOMOYO_GC_IN_PROGRESS)
127 continue; 111 continue;
128 atomic_inc(&group->head.users); 112 atomic_inc(&group->head.users);
129 found = true; 113 found = true;
@@ -175,7 +159,8 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
175 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 159 if (mutex_lock_interruptible(&tomoyo_policy_lock))
176 return NULL; 160 return NULL;
177 list_for_each_entry(ptr, head, head.list) { 161 list_for_each_entry(ptr, head, head.list) {
178 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 162 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name) ||
163 atomic_read(&ptr->head.users) == TOMOYO_GC_IN_PROGRESS)
179 continue; 164 continue;
180 atomic_inc(&ptr->head.users); 165 atomic_inc(&ptr->head.users);
181 goto out; 166 goto out;
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c
index d08296a4882b..2672ac4f3beb 100644
--- a/security/tomoyo/securityfs_if.c
+++ b/security/tomoyo/securityfs_if.c
@@ -265,6 +265,7 @@ static int __init tomoyo_initerface_init(void)
265 TOMOYO_VERSION); 265 TOMOYO_VERSION);
266 securityfs_create_file("self_domain", 0666, tomoyo_dir, NULL, 266 securityfs_create_file("self_domain", 0666, tomoyo_dir, NULL,
267 &tomoyo_self_operations); 267 &tomoyo_self_operations);
268 tomoyo_load_builtin_policy();
268 return 0; 269 return 0;
269} 270}
270 271