blob: 7747ceb9a2214350c43aebaad5ef5da2c11cccbb [file] [log] [blame]
Tetsuo Handa847b1732010-02-11 09:43:54 +09001/*
2 * security/tomoyo/gc.c
3 *
Tetsuo Handa0f2a55d2011-07-14 14:46:51 +09004 * Copyright (C) 2005-2011 NTT DATA CORPORATION
Tetsuo Handa847b1732010-02-11 09:43:54 +09005 */
6
7#include "common.h"
8#include <linux/kthread.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +09009#include <linux/slab.h>
Tetsuo Handa847b1732010-02-11 09:43:54 +090010
Tetsuo Handa2e503bb2011-06-26 23:20:55 +090011/* The list for "struct tomoyo_io_buffer". */
12static LIST_HEAD(tomoyo_io_buffer_list);
13/* Lock for protecting tomoyo_io_buffer_list. */
14static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
15
16/* Size of an element. */
17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
Tetsuo Handa059d84d2011-09-10 15:23:54 +090019 [TOMOYO_ID_ADDRESS_GROUP] = sizeof(struct tomoyo_address_group),
Tetsuo Handa2e503bb2011-06-26 23:20:55 +090020 [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),
Tetsuo Handa2066a362011-07-08 13:21:37 +090026 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
Tetsuo Handa2e503bb2011-06-26 23:20:55 +090027 /* [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),
Tetsuo Handa059d84d2011-09-10 15:23:54 +090040 [TOMOYO_TYPE_INET_ACL] = sizeof(struct tomoyo_inet_acl),
41 [TOMOYO_TYPE_UNIX_ACL] = sizeof(struct tomoyo_unix_acl),
Tetsuo Handad58e0da2011-09-10 15:22:48 +090042 [TOMOYO_TYPE_ENV_ACL] = sizeof(struct tomoyo_env_acl),
Tetsuo Handa2e503bb2011-06-26 23:20:55 +090043};
44
45/**
46 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
47 *
48 * @element: Pointer to "struct list_head".
49 *
50 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
51 * false otherwise.
52 */
53static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
54{
55 struct tomoyo_io_buffer *head;
56 bool in_use = false;
57
58 spin_lock(&tomoyo_io_buffer_list_lock);
59 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
60 head->users++;
61 spin_unlock(&tomoyo_io_buffer_list_lock);
62 if (mutex_lock_interruptible(&head->io_sem)) {
63 in_use = true;
64 goto out;
65 }
66 if (head->r.domain == element || head->r.group == element ||
67 head->r.acl == element || &head->w.domain->list == element)
68 in_use = true;
69 mutex_unlock(&head->io_sem);
70out:
71 spin_lock(&tomoyo_io_buffer_list_lock);
72 head->users--;
73 if (in_use)
74 break;
75 }
76 spin_unlock(&tomoyo_io_buffer_list_lock);
77 return in_use;
78}
79
80/**
81 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
82 *
83 * @string: String to check.
84 * @size: Memory allocated for @string .
85 *
86 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
87 * false otherwise.
88 */
89static bool tomoyo_name_used_by_io_buffer(const char *string,
90 const size_t size)
91{
92 struct tomoyo_io_buffer *head;
93 bool in_use = false;
94
95 spin_lock(&tomoyo_io_buffer_list_lock);
96 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
97 int i;
98 head->users++;
99 spin_unlock(&tomoyo_io_buffer_list_lock);
100 if (mutex_lock_interruptible(&head->io_sem)) {
101 in_use = true;
102 goto out;
103 }
104 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
105 const char *w = head->r.w[i];
106 if (w < string || w > string + size)
107 continue;
108 in_use = true;
109 break;
110 }
111 mutex_unlock(&head->io_sem);
112out:
113 spin_lock(&tomoyo_io_buffer_list_lock);
114 head->users--;
115 if (in_use)
116 break;
117 }
118 spin_unlock(&tomoyo_io_buffer_list_lock);
119 return in_use;
120}
121
122/* Structure for garbage collection. */
Tetsuo Handae2bf6902010-06-25 11:16:00 +0900123struct tomoyo_gc {
Tetsuo Handa847b1732010-02-11 09:43:54 +0900124 struct list_head list;
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900125 enum tomoyo_policy_id type;
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900126 size_t size;
Tetsuo Handae79acf02010-06-16 16:31:50 +0900127 struct list_head *element;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900128};
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900129/* List of entries to be deleted. */
130static LIST_HEAD(tomoyo_gc_list);
131/* Length of tomoyo_gc_list. */
132static int tomoyo_gc_list_len;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900133
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900134/**
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 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900152static bool tomoyo_add_to_gc(const int type, struct list_head *element)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900153{
Tetsuo Handae2bf6902010-06-25 11:16:00 +0900154 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900155 if (!entry)
156 return false;
157 entry->type = type;
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900158 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;
Tetsuo Handa2066a362011-07-08 13:21:37 +0900167 else if (type == TOMOYO_ID_CONDITION)
168 entry->size =
169 container_of(element, typeof(struct tomoyo_condition),
170 head.list)->size;
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900171 else
172 entry->size = tomoyo_element_size[type];
Tetsuo Handa847b1732010-02-11 09:43:54 +0900173 entry->element = element;
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900174 list_add(&entry->list, &tomoyo_gc_list);
Tetsuo Handae79acf02010-06-16 16:31:50 +0900175 list_del_rcu(element);
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900176 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;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900198}
199
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900200/**
201 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
202 *
203 * @element: Pointer to "struct list_head".
204 *
205 * Returns nothing.
206 */
Tetsuo Handa5448ec42010-06-21 11:14:39 +0900207static void tomoyo_del_transition_control(struct list_head *element)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900208{
Tetsuo Handa5448ec42010-06-21 11:14:39 +0900209 struct tomoyo_transition_control *ptr =
Tetsuo Handae79acf02010-06-16 16:31:50 +0900210 container_of(element, typeof(*ptr), head.list);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900211 tomoyo_put_name(ptr->domainname);
212 tomoyo_put_name(ptr->program);
213}
214
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900215/**
216 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
217 *
218 * @element: Pointer to "struct list_head".
219 *
220 * Returns nothing.
221 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900222static void tomoyo_del_aggregator(struct list_head *element)
Tetsuo Handa10843072010-06-03 20:38:03 +0900223{
Tetsuo Handae2bf6902010-06-25 11:16:00 +0900224 struct tomoyo_aggregator *ptr =
Tetsuo Handae79acf02010-06-16 16:31:50 +0900225 container_of(element, typeof(*ptr), head.list);
Tetsuo Handa10843072010-06-03 20:38:03 +0900226 tomoyo_put_name(ptr->original_name);
227 tomoyo_put_name(ptr->aggregated_name);
228}
229
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900230/**
231 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
232 *
233 * @element: Pointer to "struct list_head".
234 *
235 * Returns nothing.
236 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900237static void tomoyo_del_manager(struct list_head *element)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900238{
Tetsuo Handae2bf6902010-06-25 11:16:00 +0900239 struct tomoyo_manager *ptr =
Tetsuo Handae79acf02010-06-16 16:31:50 +0900240 container_of(element, typeof(*ptr), head.list);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900241 tomoyo_put_name(ptr->manager);
242}
243
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900244/**
245 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
246 *
247 * @element: Pointer to "struct list_head".
248 *
249 * Returns nothing.
250 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900251static void tomoyo_del_acl(struct list_head *element)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900252{
Tetsuo Handae79acf02010-06-16 16:31:50 +0900253 struct tomoyo_acl_info *acl =
254 container_of(element, typeof(*acl), list);
Tetsuo Handa2066a362011-07-08 13:21:37 +0900255 tomoyo_put_condition(acl->cond);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900256 switch (acl->type) {
Tetsuo Handa7ef61232010-02-16 08:03:30 +0900257 case TOMOYO_TYPE_PATH_ACL:
Tetsuo Handa847b1732010-02-11 09:43:54 +0900258 {
Tetsuo Handa7ef61232010-02-16 08:03:30 +0900259 struct tomoyo_path_acl *entry
Tetsuo Handa847b1732010-02-11 09:43:54 +0900260 = container_of(acl, typeof(*entry), head);
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900261 tomoyo_put_name_union(&entry->name);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900262 }
263 break;
Tetsuo Handa7ef61232010-02-16 08:03:30 +0900264 case TOMOYO_TYPE_PATH2_ACL:
Tetsuo Handa847b1732010-02-11 09:43:54 +0900265 {
Tetsuo Handa7ef61232010-02-16 08:03:30 +0900266 struct tomoyo_path2_acl *entry
Tetsuo Handa847b1732010-02-11 09:43:54 +0900267 = container_of(acl, typeof(*entry), head);
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900268 tomoyo_put_name_union(&entry->name1);
269 tomoyo_put_name_union(&entry->name2);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900270 }
271 break;
Tetsuo Handaa1f9bb62010-05-17 10:09:15 +0900272 case TOMOYO_TYPE_PATH_NUMBER_ACL:
273 {
274 struct tomoyo_path_number_acl *entry
275 = container_of(acl, typeof(*entry), head);
276 tomoyo_put_name_union(&entry->name);
277 tomoyo_put_number_union(&entry->number);
278 }
279 break;
Tetsuo Handa75093152010-06-16 16:23:55 +0900280 case TOMOYO_TYPE_MKDEV_ACL:
Tetsuo Handaa1f9bb62010-05-17 10:09:15 +0900281 {
Tetsuo Handa75093152010-06-16 16:23:55 +0900282 struct tomoyo_mkdev_acl *entry
Tetsuo Handaa1f9bb62010-05-17 10:09:15 +0900283 = container_of(acl, typeof(*entry), head);
284 tomoyo_put_name_union(&entry->name);
285 tomoyo_put_number_union(&entry->mode);
286 tomoyo_put_number_union(&entry->major);
287 tomoyo_put_number_union(&entry->minor);
288 }
289 break;
Tetsuo Handa2106ccd2010-05-17 10:10:31 +0900290 case TOMOYO_TYPE_MOUNT_ACL:
291 {
292 struct tomoyo_mount_acl *entry
293 = container_of(acl, typeof(*entry), head);
294 tomoyo_put_name_union(&entry->dev_name);
295 tomoyo_put_name_union(&entry->dir_name);
296 tomoyo_put_name_union(&entry->fs_type);
297 tomoyo_put_number_union(&entry->flags);
298 }
299 break;
Tetsuo Handad58e0da2011-09-10 15:22:48 +0900300 case TOMOYO_TYPE_ENV_ACL:
301 {
302 struct tomoyo_env_acl *entry =
303 container_of(acl, typeof(*entry), head);
304
305 tomoyo_put_name(entry->env);
306 }
307 break;
Tetsuo Handa059d84d2011-09-10 15:23:54 +0900308 case TOMOYO_TYPE_INET_ACL:
309 {
310 struct tomoyo_inet_acl *entry =
311 container_of(acl, typeof(*entry), head);
312
313 tomoyo_put_group(entry->address.group);
314 tomoyo_put_number_union(&entry->port);
315 }
316 break;
317 case TOMOYO_TYPE_UNIX_ACL:
318 {
319 struct tomoyo_unix_acl *entry =
320 container_of(acl, typeof(*entry), head);
321
322 tomoyo_put_name_union(&entry->name);
323 }
324 break;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900325 }
326}
327
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900328/**
329 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
330 *
331 * @element: Pointer to "struct list_head".
332 *
333 * Returns true if deleted, false otherwise.
334 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900335static bool tomoyo_del_domain(struct list_head *element)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900336{
Tetsuo Handae79acf02010-06-16 16:31:50 +0900337 struct tomoyo_domain_info *domain =
338 container_of(element, typeof(*domain), list);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900339 struct tomoyo_acl_info *acl;
340 struct tomoyo_acl_info *tmp;
341 /*
342 * Since we don't protect whole execve() operation using SRCU,
343 * we need to recheck domain->users at this point.
344 *
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 */
363 if (atomic_read(&domain->users))
364 return false;
365 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
Tetsuo Handae79acf02010-06-16 16:31:50 +0900366 tomoyo_del_acl(&acl->list);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900367 tomoyo_memory_free(acl);
368 }
369 tomoyo_put_name(domain->domainname);
370 return true;
371}
372
Tetsuo Handa2066a362011-07-08 13:21:37 +0900373/**
374 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
375 *
376 * @element: Pointer to "struct list_head".
377 *
378 * Returns nothing.
379 */
380void tomoyo_del_condition(struct list_head *element)
381{
382 struct tomoyo_condition *cond = container_of(element, typeof(*cond),
383 head.list);
384 const u16 condc = cond->condc;
385 const u16 numbers_count = cond->numbers_count;
Tetsuo Handa2ca9bf42011-07-08 13:23:44 +0900386 const u16 names_count = cond->names_count;
Tetsuo Handa5b636852011-07-08 13:24:54 +0900387 const u16 argc = cond->argc;
388 const u16 envc = cond->envc;
Tetsuo Handa2066a362011-07-08 13:21:37 +0900389 unsigned int i;
390 const struct tomoyo_condition_element *condp
391 = (const struct tomoyo_condition_element *) (cond + 1);
392 struct tomoyo_number_union *numbers_p
393 = (struct tomoyo_number_union *) (condp + condc);
Tetsuo Handa2ca9bf42011-07-08 13:23:44 +0900394 struct tomoyo_name_union *names_p
395 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
Tetsuo Handa5b636852011-07-08 13:24:54 +0900396 const struct tomoyo_argv *argv
397 = (const struct tomoyo_argv *) (names_p + names_count);
398 const struct tomoyo_envp *envp
399 = (const struct tomoyo_envp *) (argv + argc);
Tetsuo Handa2066a362011-07-08 13:21:37 +0900400 for (i = 0; i < numbers_count; i++)
401 tomoyo_put_number_union(numbers_p++);
Tetsuo Handa2ca9bf42011-07-08 13:23:44 +0900402 for (i = 0; i < names_count; i++)
403 tomoyo_put_name_union(names_p++);
Tetsuo Handa5b636852011-07-08 13:24:54 +0900404 for (i = 0; i < argc; argv++, i++)
405 tomoyo_put_name(argv->value);
406 for (i = 0; i < envc; envp++, i++) {
407 tomoyo_put_name(envp->name);
408 tomoyo_put_name(envp->value);
409 }
Tetsuo Handa2066a362011-07-08 13:21:37 +0900410}
Tetsuo Handa847b1732010-02-11 09:43:54 +0900411
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900412/**
413 * tomoyo_del_name - Delete members in "struct tomoyo_name".
414 *
415 * @element: Pointer to "struct list_head".
416 *
417 * Returns nothing.
418 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900419static void tomoyo_del_name(struct list_head *element)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900420{
Tetsuo Handae2bf6902010-06-25 11:16:00 +0900421 const struct tomoyo_name *ptr =
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900422 container_of(element, typeof(*ptr), head.list);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900423}
424
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900425/**
426 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
427 *
428 * @element: Pointer to "struct list_head".
429 *
430 * Returns nothing.
431 */
Tetsuo Handaa98aa4d2010-06-17 16:52:29 +0900432static void tomoyo_del_path_group(struct list_head *element)
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900433{
Tetsuo Handaa98aa4d2010-06-17 16:52:29 +0900434 struct tomoyo_path_group *member =
Tetsuo Handae79acf02010-06-16 16:31:50 +0900435 container_of(element, typeof(*member), head.list);
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900436 tomoyo_put_name(member->member_name);
437}
438
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900439/**
440 * tomoyo_del_group - Delete "struct tomoyo_group".
441 *
442 * @element: Pointer to "struct list_head".
443 *
444 * Returns nothing.
445 */
Tetsuo Handaa98aa4d2010-06-17 16:52:29 +0900446static void tomoyo_del_group(struct list_head *element)
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900447{
Tetsuo Handaa98aa4d2010-06-17 16:52:29 +0900448 struct tomoyo_group *group =
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900449 container_of(element, typeof(*group), head.list);
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900450 tomoyo_put_name(group->group_name);
451}
452
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900453/**
Tetsuo Handa059d84d2011-09-10 15:23:54 +0900454 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
455 *
456 * @element: Pointer to "struct list_head".
457 *
458 * Returns nothing.
459 */
460static inline void tomoyo_del_address_group(struct list_head *element)
461{
462 /* Nothing to do. */
463}
464
465/**
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900466 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
467 *
468 * @element: Pointer to "struct list_head".
469 *
470 * Returns nothing.
471 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900472static void tomoyo_del_number_group(struct list_head *element)
Tetsuo Handa4c3e9e22010-05-17 10:06:58 +0900473{
Tetsuo Handaa98aa4d2010-06-17 16:52:29 +0900474 struct tomoyo_number_group *member =
475 container_of(element, typeof(*member), head.list);
Tetsuo Handa4c3e9e22010-05-17 10:06:58 +0900476}
477
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900478/**
479 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
480 *
481 * @id: One of values in "enum tomoyo_policy_id".
482 * @member_list: Pointer to "struct list_head".
483 *
484 * Returns true if some elements are deleted, false otherwise.
485 */
486static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
487 struct list_head *member_list)
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900488{
489 struct tomoyo_acl_head *member;
490 list_for_each_entry(member, member_list, list) {
491 if (!member->is_deleted)
492 continue;
493 if (!tomoyo_add_to_gc(id, &member->list))
494 return false;
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900495 }
Tetsuo Handa0f2a55d2011-07-14 14:46:51 +0900496 return true;
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900497}
498
Tetsuo Handa32997142011-06-26 23:19:28 +0900499/**
500 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
501 *
502 * @list: Pointer to "struct list_head".
503 *
504 * Returns true if some elements are deleted, false otherwise.
505 */
506static bool tomoyo_collect_acl(struct list_head *list)
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900507{
508 struct tomoyo_acl_info *acl;
Tetsuo Handa32997142011-06-26 23:19:28 +0900509 list_for_each_entry(acl, list, list) {
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900510 if (!acl->is_deleted)
511 continue;
512 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
513 return false;
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900514 }
515 return true;
516}
517
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900518/**
519 * tomoyo_collect_entry - Scan lists for deleted elements.
520 *
521 * Returns nothing.
522 */
Tetsuo Handa847b1732010-02-11 09:43:54 +0900523static void tomoyo_collect_entry(void)
524{
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900525 int i;
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900526 enum tomoyo_policy_id id;
527 struct tomoyo_policy_namespace *ns;
528 int idx;
Tetsuo Handa29282382010-05-06 00:18:15 +0900529 if (mutex_lock_interruptible(&tomoyo_policy_lock))
530 return;
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900531 idx = tomoyo_read_lock();
Tetsuo Handa847b1732010-02-11 09:43:54 +0900532 {
533 struct tomoyo_domain_info *domain;
534 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
Tetsuo Handa32997142011-06-26 23:19:28 +0900535 if (!tomoyo_collect_acl(&domain->acl_info_list))
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900536 goto unlock;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900537 if (!domain->is_deleted || atomic_read(&domain->users))
538 continue;
539 /*
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 */
Tetsuo Handae79acf02010-06-16 16:31:50 +0900544 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900545 goto unlock;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900546 }
547 }
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900548 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
549 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
550 if (!tomoyo_collect_member(id, &ns->policy_list[id]))
551 goto unlock;
552 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
553 if (!tomoyo_collect_acl(&ns->acl_group[i]))
554 goto unlock;
555 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
556 struct list_head *list = &ns->group_list[i];
557 struct tomoyo_group *group;
558 switch (i) {
559 case 0:
560 id = TOMOYO_ID_PATH_GROUP;
561 break;
Tetsuo Handa059d84d2011-09-10 15:23:54 +0900562 case 1:
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900563 id = TOMOYO_ID_NUMBER_GROUP;
564 break;
Tetsuo Handa059d84d2011-09-10 15:23:54 +0900565 default:
566 id = TOMOYO_ID_ADDRESS_GROUP;
567 break;
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900568 }
569 list_for_each_entry(group, list, head.list) {
570 if (!tomoyo_collect_member
571 (id, &group->member_list))
572 goto unlock;
573 if (!list_empty(&group->member_list) ||
574 atomic_read(&group->head.users))
575 continue;
576 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
577 &group->head.list))
578 goto unlock;
579 }
580 }
581 }
Tetsuo Handa2066a362011-07-08 13:21:37 +0900582 id = TOMOYO_ID_CONDITION;
583 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
584 struct list_head *list = !i ?
585 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900586 struct tomoyo_shared_acl_head *ptr;
587 list_for_each_entry(ptr, list, list) {
588 if (atomic_read(&ptr->users))
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900589 continue;
Tetsuo Handa2066a362011-07-08 13:21:37 +0900590 if (!tomoyo_add_to_gc(id, &ptr->list))
Tetsuo Handad2f8b232010-06-15 10:10:37 +0900591 goto unlock;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900592 }
Tetsuo Handa2066a362011-07-08 13:21:37 +0900593 id = TOMOYO_ID_NAME;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900594 }
Tetsuo Handabd03a3e2011-06-26 23:19:52 +0900595unlock:
596 tomoyo_read_unlock(idx);
Tetsuo Handa29282382010-05-06 00:18:15 +0900597 mutex_unlock(&tomoyo_policy_lock);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900598}
599
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900600/**
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)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900606{
Tetsuo Handae2bf6902010-06-25 11:16:00 +0900607 struct tomoyo_gc *p;
608 struct tomoyo_gc *tmp;
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900609 bool result = false;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900610
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900611 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
Tetsuo Handae79acf02010-06-16 16:31:50 +0900612 struct list_head *element = p->element;
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900613
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;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900638 switch (p->type) {
Tetsuo Handa5448ec42010-06-21 11:14:39 +0900639 case TOMOYO_ID_TRANSITION_CONTROL:
640 tomoyo_del_transition_control(element);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900641 break;
Tetsuo Handa10843072010-06-03 20:38:03 +0900642 case TOMOYO_ID_AGGREGATOR:
Tetsuo Handae79acf02010-06-16 16:31:50 +0900643 tomoyo_del_aggregator(element);
Tetsuo Handa10843072010-06-03 20:38:03 +0900644 break;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900645 case TOMOYO_ID_MANAGER:
Tetsuo Handae79acf02010-06-16 16:31:50 +0900646 tomoyo_del_manager(element);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900647 break;
Tetsuo Handa2066a362011-07-08 13:21:37 +0900648 case TOMOYO_ID_CONDITION:
649 tomoyo_del_condition(element);
650 break;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900651 case TOMOYO_ID_NAME:
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900652 /*
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;
Tetsuo Handae79acf02010-06-16 16:31:50 +0900660 tomoyo_del_name(element);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900661 break;
662 case TOMOYO_ID_ACL:
Tetsuo Handae79acf02010-06-16 16:31:50 +0900663 tomoyo_del_acl(element);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900664 break;
665 case TOMOYO_ID_DOMAIN:
Tetsuo Handae79acf02010-06-16 16:31:50 +0900666 if (!tomoyo_del_domain(element))
Tetsuo Handa847b1732010-02-11 09:43:54 +0900667 continue;
668 break;
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900669 case TOMOYO_ID_PATH_GROUP:
Tetsuo Handae79acf02010-06-16 16:31:50 +0900670 tomoyo_del_path_group(element);
Tetsuo Handa7762fbf2010-05-10 17:30:26 +0900671 break;
Tetsuo Handa059d84d2011-09-10 15:23:54 +0900672 case TOMOYO_ID_ADDRESS_GROUP:
673 tomoyo_del_address_group(element);
674 break;
Tetsuo Handaa98aa4d2010-06-17 16:52:29 +0900675 case TOMOYO_ID_GROUP:
676 tomoyo_del_group(element);
Tetsuo Handa4c3e9e22010-05-17 10:06:58 +0900677 break;
678 case TOMOYO_ID_NUMBER_GROUP:
Tetsuo Handae79acf02010-06-16 16:31:50 +0900679 tomoyo_del_number_group(element);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900680 break;
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900681 case TOMOYO_MAX_POLICY:
682 break;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900683 }
Tetsuo Handae79acf02010-06-16 16:31:50 +0900684 tomoyo_memory_free(element);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900685 list_del(&p->list);
686 kfree(p);
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900687 tomoyo_gc_list_len--;
688 result = true;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900689 }
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900690 return result;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900691}
692
Tetsuo Handa0df7e8b2011-06-26 23:16:36 +0900693/**
694 * tomoyo_gc_thread - Garbage collector thread function.
695 *
696 * @unused: Unused.
697 *
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.
703 */
Tetsuo Handa847b1732010-02-11 09:43:54 +0900704static int tomoyo_gc_thread(void *unused)
705{
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900706 /* Garbage collector thread is exclusive. */
707 static DEFINE_MUTEX(tomoyo_gc_mutex);
708 if (!mutex_trylock(&tomoyo_gc_mutex))
709 goto out;
Oleg Nesterov09f464b2011-08-16 20:34:05 +0200710
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900711 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 {
718 struct tomoyo_io_buffer *head;
719 struct tomoyo_io_buffer *tmp;
720
721 spin_lock(&tomoyo_io_buffer_list_lock);
722 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
723 list) {
724 if (head->users)
725 continue;
726 list_del(&head->list);
727 kfree(head->read_buf);
728 kfree(head->write_buf);
729 kfree(head);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900730 }
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900731 spin_unlock(&tomoyo_io_buffer_list_lock);
Tetsuo Handa847b1732010-02-11 09:43:54 +0900732 }
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900733 mutex_unlock(&tomoyo_gc_mutex);
734out:
735 /* This acts as do_exit(0). */
736 return 0;
Tetsuo Handa847b1732010-02-11 09:43:54 +0900737}
738
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900739/**
740 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
741 *
742 * @head: Pointer to "struct tomoyo_io_buffer".
743 * @is_register: True if register, false if unregister.
744 *
745 * Returns nothing.
746 */
747void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
Tetsuo Handa847b1732010-02-11 09:43:54 +0900748{
Tetsuo Handa2e503bb2011-06-26 23:20:55 +0900749 bool is_write = false;
750
751 spin_lock(&tomoyo_io_buffer_list_lock);
752 if (is_register) {
753 head->users = 1;
754 list_add(&head->list, &tomoyo_io_buffer_list);
755 } else {
756 is_write = head->write_buf != NULL;
757 if (!--head->users) {
758 list_del(&head->list);
759 kfree(head->read_buf);
760 kfree(head->write_buf);
761 kfree(head);
762 }
763 }
764 spin_unlock(&tomoyo_io_buffer_list_lock);
765 if (is_write) {
766 struct task_struct *task = kthread_create(tomoyo_gc_thread,
767 NULL,
768 "GC for TOMOYO");
769 if (!IS_ERR(task))
770 wake_up_process(task);
771 }
Tetsuo Handa847b1732010-02-11 09:43:54 +0900772}