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>
14 struct tomoyo_gc_entry
{
15 struct list_head list
;
17 struct list_head
*element
;
19 static LIST_HEAD(tomoyo_gc_queue
);
20 static DEFINE_MUTEX(tomoyo_gc_mutex
);
22 /* Caller holds tomoyo_policy_lock mutex. */
23 static bool tomoyo_add_to_gc(const int type
, struct list_head
*element
)
25 struct tomoyo_gc_entry
*entry
= kzalloc(sizeof(*entry
), GFP_ATOMIC
);
29 entry
->element
= element
;
30 list_add(&entry
->list
, &tomoyo_gc_queue
);
31 list_del_rcu(element
);
35 static void tomoyo_del_allow_read(struct list_head
*element
)
37 struct tomoyo_globally_readable_file_entry
*ptr
=
38 container_of(element
, typeof(*ptr
), head
.list
);
39 tomoyo_put_name(ptr
->filename
);
42 static void tomoyo_del_file_pattern(struct list_head
*element
)
44 struct tomoyo_pattern_entry
*ptr
=
45 container_of(element
, typeof(*ptr
), head
.list
);
46 tomoyo_put_name(ptr
->pattern
);
49 static void tomoyo_del_no_rewrite(struct list_head
*element
)
51 struct tomoyo_no_rewrite_entry
*ptr
=
52 container_of(element
, typeof(*ptr
), head
.list
);
53 tomoyo_put_name(ptr
->pattern
);
56 static void tomoyo_del_domain_initializer(struct list_head
*element
)
58 struct tomoyo_domain_initializer_entry
*ptr
=
59 container_of(element
, typeof(*ptr
), head
.list
);
60 tomoyo_put_name(ptr
->domainname
);
61 tomoyo_put_name(ptr
->program
);
64 static void tomoyo_del_domain_keeper(struct list_head
*element
)
66 struct tomoyo_domain_keeper_entry
*ptr
=
67 container_of(element
, typeof(*ptr
), head
.list
);
68 tomoyo_put_name(ptr
->domainname
);
69 tomoyo_put_name(ptr
->program
);
72 static void tomoyo_del_aggregator(struct list_head
*element
)
74 struct tomoyo_aggregator_entry
*ptr
=
75 container_of(element
, typeof(*ptr
), head
.list
);
76 tomoyo_put_name(ptr
->original_name
);
77 tomoyo_put_name(ptr
->aggregated_name
);
80 static void tomoyo_del_alias(struct list_head
*element
)
82 struct tomoyo_alias_entry
*ptr
=
83 container_of(element
, typeof(*ptr
), head
.list
);
84 tomoyo_put_name(ptr
->original_name
);
85 tomoyo_put_name(ptr
->aliased_name
);
88 static void tomoyo_del_manager(struct list_head
*element
)
90 struct tomoyo_policy_manager_entry
*ptr
=
91 container_of(element
, typeof(*ptr
), head
.list
);
92 tomoyo_put_name(ptr
->manager
);
95 static void tomoyo_del_acl(struct list_head
*element
)
97 struct tomoyo_acl_info
*acl
=
98 container_of(element
, typeof(*acl
), list
);
100 case TOMOYO_TYPE_PATH_ACL
:
102 struct tomoyo_path_acl
*entry
103 = container_of(acl
, typeof(*entry
), head
);
104 tomoyo_put_name_union(&entry
->name
);
107 case TOMOYO_TYPE_PATH2_ACL
:
109 struct tomoyo_path2_acl
*entry
110 = container_of(acl
, typeof(*entry
), head
);
111 tomoyo_put_name_union(&entry
->name1
);
112 tomoyo_put_name_union(&entry
->name2
);
115 case TOMOYO_TYPE_PATH_NUMBER_ACL
:
117 struct tomoyo_path_number_acl
*entry
118 = container_of(acl
, typeof(*entry
), head
);
119 tomoyo_put_name_union(&entry
->name
);
120 tomoyo_put_number_union(&entry
->number
);
123 case TOMOYO_TYPE_MKDEV_ACL
:
125 struct tomoyo_mkdev_acl
*entry
126 = container_of(acl
, typeof(*entry
), head
);
127 tomoyo_put_name_union(&entry
->name
);
128 tomoyo_put_number_union(&entry
->mode
);
129 tomoyo_put_number_union(&entry
->major
);
130 tomoyo_put_number_union(&entry
->minor
);
133 case TOMOYO_TYPE_MOUNT_ACL
:
135 struct tomoyo_mount_acl
*entry
136 = container_of(acl
, typeof(*entry
), head
);
137 tomoyo_put_name_union(&entry
->dev_name
);
138 tomoyo_put_name_union(&entry
->dir_name
);
139 tomoyo_put_name_union(&entry
->fs_type
);
140 tomoyo_put_number_union(&entry
->flags
);
146 static bool tomoyo_del_domain(struct list_head
*element
)
148 struct tomoyo_domain_info
*domain
=
149 container_of(element
, typeof(*domain
), list
);
150 struct tomoyo_acl_info
*acl
;
151 struct tomoyo_acl_info
*tmp
;
153 * Since we don't protect whole execve() operation using SRCU,
154 * we need to recheck domain->users at this point.
156 * (1) Reader starts SRCU section upon execve().
157 * (2) Reader traverses tomoyo_domain_list and finds this domain.
158 * (3) Writer marks this domain as deleted.
159 * (4) Garbage collector removes this domain from tomoyo_domain_list
160 * because this domain is marked as deleted and used by nobody.
161 * (5) Reader saves reference to this domain into
162 * "struct linux_binprm"->cred->security .
163 * (6) Reader finishes SRCU section, although execve() operation has
165 * (7) Garbage collector waits for SRCU synchronization.
166 * (8) Garbage collector kfree() this domain because this domain is
168 * (9) Reader finishes execve() operation and restores this domain from
169 * "struct linux_binprm"->cred->security.
171 * By updating domain->users at (5), we can solve this race problem
172 * by rechecking domain->users at (8).
174 if (atomic_read(&domain
->users
))
176 list_for_each_entry_safe(acl
, tmp
, &domain
->acl_info_list
, list
) {
177 tomoyo_del_acl(&acl
->list
);
178 tomoyo_memory_free(acl
);
180 tomoyo_put_name(domain
->domainname
);
185 static void tomoyo_del_name(struct list_head
*element
)
187 const struct tomoyo_name_entry
*ptr
=
188 container_of(element
, typeof(*ptr
), list
);
191 static void tomoyo_del_path_group(struct list_head
*element
)
193 struct tomoyo_path_group
*member
=
194 container_of(element
, typeof(*member
), head
.list
);
195 tomoyo_put_name(member
->member_name
);
198 static void tomoyo_del_group(struct list_head
*element
)
200 struct tomoyo_group
*group
=
201 container_of(element
, typeof(*group
), list
);
202 tomoyo_put_name(group
->group_name
);
205 static void tomoyo_del_number_group(struct list_head
*element
)
207 struct tomoyo_number_group
*member
=
208 container_of(element
, typeof(*member
), head
.list
);
211 static bool tomoyo_collect_member(struct list_head
*member_list
, int id
)
213 struct tomoyo_acl_head
*member
;
214 list_for_each_entry(member
, member_list
, list
) {
215 if (!member
->is_deleted
)
217 if (!tomoyo_add_to_gc(id
, &member
->list
))
223 static bool tomoyo_collect_acl(struct tomoyo_domain_info
*domain
)
225 struct tomoyo_acl_info
*acl
;
226 list_for_each_entry(acl
, &domain
->acl_info_list
, list
) {
227 if (!acl
->is_deleted
)
229 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL
, &acl
->list
))
235 static void tomoyo_collect_entry(void)
238 if (mutex_lock_interruptible(&tomoyo_policy_lock
))
240 for (i
= 0; i
< TOMOYO_MAX_POLICY
; i
++) {
241 if (!tomoyo_collect_member(&tomoyo_policy_list
[i
], i
))
245 struct tomoyo_domain_info
*domain
;
246 list_for_each_entry_rcu(domain
, &tomoyo_domain_list
, list
) {
247 if (!tomoyo_collect_acl(domain
))
249 if (!domain
->is_deleted
|| atomic_read(&domain
->users
))
252 * Nobody is referring this domain. But somebody may
253 * refer this domain after successful execve().
254 * We recheck domain->users after SRCU synchronization.
256 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN
, &domain
->list
))
260 for (i
= 0; i
< TOMOYO_MAX_HASH
; i
++) {
261 struct tomoyo_name_entry
*ptr
;
262 list_for_each_entry_rcu(ptr
, &tomoyo_name_list
[i
], list
) {
263 if (atomic_read(&ptr
->users
))
265 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME
, &ptr
->list
))
269 for (i
= 0; i
< TOMOYO_MAX_GROUP
; i
++) {
270 struct list_head
*list
= &tomoyo_group_list
[i
];
272 struct tomoyo_group
*group
;
275 id
= TOMOYO_ID_PATH_GROUP
;
278 id
= TOMOYO_ID_NUMBER_GROUP
;
281 list_for_each_entry(group
, list
, list
) {
282 if (!tomoyo_collect_member(&group
->member_list
, id
))
284 if (!list_empty(&group
->member_list
) ||
285 atomic_read(&group
->users
))
287 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP
, &group
->list
))
292 mutex_unlock(&tomoyo_policy_lock
);
295 static void tomoyo_kfree_entry(void)
297 struct tomoyo_gc_entry
*p
;
298 struct tomoyo_gc_entry
*tmp
;
300 list_for_each_entry_safe(p
, tmp
, &tomoyo_gc_queue
, list
) {
301 struct list_head
*element
= p
->element
;
303 case TOMOYO_ID_DOMAIN_INITIALIZER
:
304 tomoyo_del_domain_initializer(element
);
306 case TOMOYO_ID_DOMAIN_KEEPER
:
307 tomoyo_del_domain_keeper(element
);
309 case TOMOYO_ID_AGGREGATOR
:
310 tomoyo_del_aggregator(element
);
312 case TOMOYO_ID_ALIAS
:
313 tomoyo_del_alias(element
);
315 case TOMOYO_ID_GLOBALLY_READABLE
:
316 tomoyo_del_allow_read(element
);
318 case TOMOYO_ID_PATTERN
:
319 tomoyo_del_file_pattern(element
);
321 case TOMOYO_ID_NO_REWRITE
:
322 tomoyo_del_no_rewrite(element
);
324 case TOMOYO_ID_MANAGER
:
325 tomoyo_del_manager(element
);
328 tomoyo_del_name(element
);
331 tomoyo_del_acl(element
);
333 case TOMOYO_ID_DOMAIN
:
334 if (!tomoyo_del_domain(element
))
337 case TOMOYO_ID_PATH_GROUP
:
338 tomoyo_del_path_group(element
);
340 case TOMOYO_ID_GROUP
:
341 tomoyo_del_group(element
);
343 case TOMOYO_ID_NUMBER_GROUP
:
344 tomoyo_del_number_group(element
);
347 tomoyo_memory_free(element
);
353 static int tomoyo_gc_thread(void *unused
)
355 daemonize("GC for TOMOYO");
356 if (mutex_trylock(&tomoyo_gc_mutex
)) {
358 for (i
= 0; i
< 10; i
++) {
359 tomoyo_collect_entry();
360 if (list_empty(&tomoyo_gc_queue
))
362 synchronize_srcu(&tomoyo_ss
);
363 tomoyo_kfree_entry();
365 mutex_unlock(&tomoyo_gc_mutex
);
370 void tomoyo_run_gc(void)
372 struct task_struct
*task
= kthread_create(tomoyo_gc_thread
, NULL
,
375 wake_up_process(task
);