4 * Implementation of the Domain-Based Mandatory Access Control.
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
11 #include <linux/kthread.h>
12 #include <linux/slab.h>
16 TOMOYO_ID_PATH_GROUP_MEMBER,
17 TOMOYO_ID_NUMBER_GROUP,
18 TOMOYO_ID_NUMBER_GROUP_MEMBER,
19 TOMOYO_ID_DOMAIN_INITIALIZER,
20 TOMOYO_ID_DOMAIN_KEEPER,
22 TOMOYO_ID_GLOBALLY_READABLE,
31 struct tomoyo_gc_entry {
32 struct list_head list;
36 static LIST_HEAD(tomoyo_gc_queue);
37 static DEFINE_MUTEX(tomoyo_gc_mutex);
39 /* Caller holds tomoyo_policy_lock mutex. */
40 static bool tomoyo_add_to_gc(const int type, void *element)
42 struct tomoyo_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
46 entry->element = element;
47 list_add(&entry->list, &tomoyo_gc_queue);
51 static void tomoyo_del_allow_read
52 (struct tomoyo_globally_readable_file_entry *ptr)
54 tomoyo_put_name(ptr->filename);
57 static void tomoyo_del_file_pattern(struct tomoyo_pattern_entry *ptr)
59 tomoyo_put_name(ptr->pattern);
62 static void tomoyo_del_no_rewrite(struct tomoyo_no_rewrite_entry *ptr)
64 tomoyo_put_name(ptr->pattern);
67 static void tomoyo_del_domain_initializer
68 (struct tomoyo_domain_initializer_entry *ptr)
70 tomoyo_put_name(ptr->domainname);
71 tomoyo_put_name(ptr->program);
74 static void tomoyo_del_domain_keeper(struct tomoyo_domain_keeper_entry *ptr)
76 tomoyo_put_name(ptr->domainname);
77 tomoyo_put_name(ptr->program);
80 static void tomoyo_del_alias(struct tomoyo_alias_entry *ptr)
82 tomoyo_put_name(ptr->original_name);
83 tomoyo_put_name(ptr->aliased_name);
86 static void tomoyo_del_manager(struct tomoyo_policy_manager_entry *ptr)
88 tomoyo_put_name(ptr->manager);
91 static void tomoyo_del_acl(struct tomoyo_acl_info *acl)
94 case TOMOYO_TYPE_PATH_ACL:
96 struct tomoyo_path_acl *entry
97 = container_of(acl, typeof(*entry), head);
98 tomoyo_put_name_union(&entry->name);
101 case TOMOYO_TYPE_PATH2_ACL:
103 struct tomoyo_path2_acl *entry
104 = container_of(acl, typeof(*entry), head);
105 tomoyo_put_name_union(&entry->name1);
106 tomoyo_put_name_union(&entry->name2);
109 case TOMOYO_TYPE_PATH_NUMBER_ACL:
111 struct tomoyo_path_number_acl *entry
112 = container_of(acl, typeof(*entry), head);
113 tomoyo_put_name_union(&entry->name);
114 tomoyo_put_number_union(&entry->number);
117 case TOMOYO_TYPE_PATH_NUMBER3_ACL:
119 struct tomoyo_path_number3_acl *entry
120 = container_of(acl, typeof(*entry), head);
121 tomoyo_put_name_union(&entry->name);
122 tomoyo_put_number_union(&entry->mode);
123 tomoyo_put_number_union(&entry->major);
124 tomoyo_put_number_union(&entry->minor);
127 case TOMOYO_TYPE_MOUNT_ACL:
129 struct tomoyo_mount_acl *entry
130 = container_of(acl, typeof(*entry), head);
131 tomoyo_put_name_union(&entry->dev_name);
132 tomoyo_put_name_union(&entry->dir_name);
133 tomoyo_put_name_union(&entry->fs_type);
134 tomoyo_put_number_union(&entry->flags);
138 printk(KERN_WARNING "Unknown type\n");
143 static bool tomoyo_del_domain(struct tomoyo_domain_info *domain)
145 struct tomoyo_acl_info *acl;
146 struct tomoyo_acl_info *tmp;
148 * Since we don't protect whole execve() operation using SRCU,
149 * we need to recheck domain->users at this point.
151 * (1) Reader starts SRCU section upon execve().
152 * (2) Reader traverses tomoyo_domain_list and finds this domain.
153 * (3) Writer marks this domain as deleted.
154 * (4) Garbage collector removes this domain from tomoyo_domain_list
155 * because this domain is marked as deleted and used by nobody.
156 * (5) Reader saves reference to this domain into
157 * "struct linux_binprm"->cred->security .
158 * (6) Reader finishes SRCU section, although execve() operation has
160 * (7) Garbage collector waits for SRCU synchronization.
161 * (8) Garbage collector kfree() this domain because this domain is
163 * (9) Reader finishes execve() operation and restores this domain from
164 * "struct linux_binprm"->cred->security.
166 * By updating domain->users at (5), we can solve this race problem
167 * by rechecking domain->users at (8).
169 if (atomic_read(&domain->users))
171 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
173 tomoyo_memory_free(acl);
175 tomoyo_put_name(domain->domainname);
180 static void tomoyo_del_name(const struct tomoyo_name_entry *ptr)
184 static void tomoyo_del_path_group_member(struct tomoyo_path_group_member
187 tomoyo_put_name(member->member_name);
190 static void tomoyo_del_path_group(struct tomoyo_path_group *group)
192 tomoyo_put_name(group->group_name);
195 static void tomoyo_del_number_group_member(struct tomoyo_number_group_member
200 static void tomoyo_del_number_group(struct tomoyo_number_group *group)
202 tomoyo_put_name(group->group_name);
205 static void tomoyo_collect_entry(void)
207 if (mutex_lock_interruptible(&tomoyo_policy_lock))
210 struct tomoyo_globally_readable_file_entry *ptr;
211 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list,
213 if (!ptr->is_deleted)
215 if (tomoyo_add_to_gc(TOMOYO_ID_GLOBALLY_READABLE, ptr))
216 list_del_rcu(&ptr->list);
222 struct tomoyo_pattern_entry *ptr;
223 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
224 if (!ptr->is_deleted)
226 if (tomoyo_add_to_gc(TOMOYO_ID_PATTERN, ptr))
227 list_del_rcu(&ptr->list);
233 struct tomoyo_no_rewrite_entry *ptr;
234 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
235 if (!ptr->is_deleted)
237 if (tomoyo_add_to_gc(TOMOYO_ID_NO_REWRITE, ptr))
238 list_del_rcu(&ptr->list);
244 struct tomoyo_domain_initializer_entry *ptr;
245 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list,
247 if (!ptr->is_deleted)
249 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN_INITIALIZER, ptr))
250 list_del_rcu(&ptr->list);
256 struct tomoyo_domain_keeper_entry *ptr;
257 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
258 if (!ptr->is_deleted)
260 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN_KEEPER, ptr))
261 list_del_rcu(&ptr->list);
267 struct tomoyo_alias_entry *ptr;
268 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
269 if (!ptr->is_deleted)
271 if (tomoyo_add_to_gc(TOMOYO_ID_ALIAS, ptr))
272 list_del_rcu(&ptr->list);
278 struct tomoyo_policy_manager_entry *ptr;
279 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list,
281 if (!ptr->is_deleted)
283 if (tomoyo_add_to_gc(TOMOYO_ID_MANAGER, ptr))
284 list_del_rcu(&ptr->list);
290 struct tomoyo_domain_info *domain;
291 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
292 struct tomoyo_acl_info *acl;
293 list_for_each_entry_rcu(acl, &domain->acl_info_list,
296 case TOMOYO_TYPE_PATH_ACL:
297 if (container_of(acl,
298 struct tomoyo_path_acl,
302 case TOMOYO_TYPE_PATH2_ACL:
303 if (container_of(acl,
304 struct tomoyo_path2_acl,
308 case TOMOYO_TYPE_PATH_NUMBER_ACL:
309 if (container_of(acl,
310 struct tomoyo_path_number_acl,
314 case TOMOYO_TYPE_PATH_NUMBER3_ACL:
315 if (container_of(acl,
316 struct tomoyo_path_number3_acl,
323 if (tomoyo_add_to_gc(TOMOYO_ID_ACL, acl))
324 list_del_rcu(&acl->list);
328 if (!domain->is_deleted || atomic_read(&domain->users))
331 * Nobody is referring this domain. But somebody may
332 * refer this domain after successful execve().
333 * We recheck domain->users after SRCU synchronization.
335 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, domain))
336 list_del_rcu(&domain->list);
343 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
344 struct tomoyo_name_entry *ptr;
345 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i],
347 if (atomic_read(&ptr->users))
349 if (tomoyo_add_to_gc(TOMOYO_ID_NAME, ptr))
350 list_del_rcu(&ptr->list);
359 struct tomoyo_path_group *group;
360 list_for_each_entry_rcu(group, &tomoyo_path_group_list, list) {
361 struct tomoyo_path_group_member *member;
362 list_for_each_entry_rcu(member, &group->member_list,
364 if (!member->is_deleted)
366 if (tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP_MEMBER,
368 list_del_rcu(&member->list);
372 if (!list_empty(&group->member_list) ||
373 atomic_read(&group->users))
375 if (tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP, group))
376 list_del_rcu(&group->list);
382 struct tomoyo_number_group *group;
383 list_for_each_entry_rcu(group, &tomoyo_number_group_list, list) {
384 struct tomoyo_number_group_member *member;
385 list_for_each_entry_rcu(member, &group->member_list,
387 if (!member->is_deleted)
389 if (tomoyo_add_to_gc(TOMOYO_ID_NUMBER_GROUP_MEMBER,
391 list_del_rcu(&member->list);
395 if (!list_empty(&group->member_list) ||
396 atomic_read(&group->users))
398 if (tomoyo_add_to_gc(TOMOYO_ID_NUMBER_GROUP, group))
399 list_del_rcu(&group->list);
404 mutex_unlock(&tomoyo_policy_lock);
407 static void tomoyo_kfree_entry(void)
409 struct tomoyo_gc_entry *p;
410 struct tomoyo_gc_entry *tmp;
412 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) {
414 case TOMOYO_ID_DOMAIN_INITIALIZER:
415 tomoyo_del_domain_initializer(p->element);
417 case TOMOYO_ID_DOMAIN_KEEPER:
418 tomoyo_del_domain_keeper(p->element);
420 case TOMOYO_ID_ALIAS:
421 tomoyo_del_alias(p->element);
423 case TOMOYO_ID_GLOBALLY_READABLE:
424 tomoyo_del_allow_read(p->element);
426 case TOMOYO_ID_PATTERN:
427 tomoyo_del_file_pattern(p->element);
429 case TOMOYO_ID_NO_REWRITE:
430 tomoyo_del_no_rewrite(p->element);
432 case TOMOYO_ID_MANAGER:
433 tomoyo_del_manager(p->element);
436 tomoyo_del_name(p->element);
439 tomoyo_del_acl(p->element);
441 case TOMOYO_ID_DOMAIN:
442 if (!tomoyo_del_domain(p->element))
445 case TOMOYO_ID_PATH_GROUP_MEMBER:
446 tomoyo_del_path_group_member(p->element);
448 case TOMOYO_ID_PATH_GROUP:
449 tomoyo_del_path_group(p->element);
451 case TOMOYO_ID_NUMBER_GROUP_MEMBER:
452 tomoyo_del_number_group_member(p->element);
454 case TOMOYO_ID_NUMBER_GROUP:
455 tomoyo_del_number_group(p->element);
458 printk(KERN_WARNING "Unknown type\n");
461 tomoyo_memory_free(p->element);
467 static int tomoyo_gc_thread(void *unused)
469 daemonize("GC for TOMOYO");
470 if (mutex_trylock(&tomoyo_gc_mutex)) {
472 for (i = 0; i < 10; i++) {
473 tomoyo_collect_entry();
474 if (list_empty(&tomoyo_gc_queue))
476 synchronize_srcu(&tomoyo_ss);
477 tomoyo_kfree_entry();
479 mutex_unlock(&tomoyo_gc_mutex);
484 void tomoyo_run_gc(void)
486 struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL,
489 wake_up_process(task);