オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /branches/ccs-patch/fs/tomoyo_domain.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2016 - (hide annotations) (download) (as text)
Thu Dec 25 08:20:17 2008 UTC (15 years, 5 months ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/tomoyo_domain.c
File MIME type: text/x-csrc
File size: 47690 byte(s)


1 kumaneko 111 /*
2     * fs/tomoyo_domain.c
3     *
4     * Implementation of the Domain-Based Mandatory Access Control.
5     *
6 kumaneko 851 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 kumaneko 111 *
8 kumaneko 2002 * Version: 1.6.6-pre 2008/12/24
9 kumaneko 111 *
10     * This file is applicable to both 2.4.30 and 2.6.11 and later.
11     * See README.ccs for ChangeLog.
12     *
13     */
14    
15     #include <linux/ccs_common.h>
16     #include <linux/tomoyo.h>
17     #include <linux/realpath.h>
18 kumaneko 115 #include <linux/highmem.h>
19     #include <linux/binfmts.h>
20 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
21     #include <linux/namei.h>
22     #include <linux/mount.h>
23     #endif
24 kumaneko 115
25 kumaneko 1052 /* For compatibility with older kernels. */
26 kumaneko 111 #ifndef for_each_process
27     #define for_each_process for_each_task
28     #endif
29    
30 kumaneko 1052 /* Variables definitions.*/
31 kumaneko 111
32     /* The initial domain. */
33 kumaneko 708 struct domain_info KERNEL_DOMAIN;
34 kumaneko 111
35 kumaneko 1052 /* The list for "struct domain_info". */
36 kumaneko 2002 LIST1_HEAD(ccs_domain_list);
37 kumaneko 708
38 kumaneko 111 #ifdef CONFIG_TOMOYO
39    
40 kumaneko 1052 /* Domain creation lock. */
41 kumaneko 2002 static DEFINE_MUTEX(ccs_domain_list_lock);
42 kumaneko 111
43 kumaneko 1052 /* Structure for "initialize_domain" and "no_initialize_domain" keyword. */
44 kumaneko 2002 struct ccs_domain_initializer_entry {
45 kumaneko 722 struct list1_head list;
46 kumaneko 2002 const struct ccs_path_info *domainname; /* This may be NULL */
47     const struct ccs_path_info *program;
48 kumaneko 621 bool is_deleted;
49 kumaneko 1052 bool is_not; /* True if this entry is "no_initialize_domain". */
50     bool is_last_name; /* True if the domainname is ccs_get_last_name(). */
51 kumaneko 214 };
52 kumaneko 111
53 kumaneko 1052 /* Structure for "keep_domain" and "no_keep_domain" keyword. */
54 kumaneko 2002 struct ccs_domain_keeper_entry {
55 kumaneko 722 struct list1_head list;
56 kumaneko 2002 const struct ccs_path_info *domainname;
57     const struct ccs_path_info *program; /* This may be NULL */
58 kumaneko 621 bool is_deleted;
59 kumaneko 1052 bool is_not; /* True if this entry is "no_keep_domain". */
60     bool is_last_name; /* True if the domainname is ccs_get_last_name(). */
61 kumaneko 214 };
62 kumaneko 111
63 kumaneko 1052 /* Structure for "aggregator" keyword. */
64 kumaneko 2002 struct ccs_aggregator_entry {
65 kumaneko 722 struct list1_head list;
66 kumaneko 2002 const struct ccs_path_info *original_name;
67     const struct ccs_path_info *aggregated_name;
68 kumaneko 621 bool is_deleted;
69 kumaneko 214 };
70 kumaneko 111
71 kumaneko 1052 /* Structure for "alias" keyword. */
72 kumaneko 2002 struct ccs_alias_entry {
73 kumaneko 722 struct list1_head list;
74 kumaneko 2002 const struct ccs_path_info *original_name;
75     const struct ccs_path_info *aliased_name;
76 kumaneko 621 bool is_deleted;
77 kumaneko 214 };
78 kumaneko 111
79 kumaneko 1052 /**
80     * ccs_set_domain_flag - Set or clear domain's attribute flags.
81     *
82     * @domain: Pointer to "struct domain_info".
83     * @is_delete: True if it is a delete request.
84     * @flags: Flags to set or clear.
85     *
86     * Returns nothing.
87     */
88     void ccs_set_domain_flag(struct domain_info *domain, const bool is_delete,
89     const u8 flags)
90 kumaneko 1029 {
91 kumaneko 1700 /* We need to serialize because this is bitfield operation. */
92     static DEFINE_SPINLOCK(lock);
93     /***** CRITICAL SECTION START *****/
94     spin_lock(&lock);
95 kumaneko 1052 if (!is_delete)
96     domain->flags |= flags;
97     else
98     domain->flags &= ~flags;
99 kumaneko 1700 spin_unlock(&lock);
100     /***** CRITICAL SECTION END *****/
101 kumaneko 1029 }
102    
103 kumaneko 1052 /**
104     * ccs_get_last_name - Get last component of a domainname.
105     *
106     * @domain: Pointer to "struct domain_info".
107     *
108     * Returns the last component of the domainname.
109     */
110     const char *ccs_get_last_name(const struct domain_info *domain)
111 kumaneko 111 {
112 kumaneko 1687 const char *cp0 = domain->domainname->name;
113     const char *cp1 = strrchr(cp0, ' ');
114 kumaneko 1052 if (cp1)
115     return cp1 + 1;
116 kumaneko 111 return cp0;
117     }
118    
119 kumaneko 1052 /**
120     * ccs_add_domain_acl - Add the given ACL to the given domain.
121     *
122 kumaneko 1064 * @domain: Pointer to "struct domain_info". May be NULL.
123 kumaneko 2002 * @acl: Pointer to "struct ccs_acl_info".
124 kumaneko 1052 *
125     * Returns 0.
126     */
127 kumaneko 2002 int ccs_add_domain_acl(struct domain_info *domain, struct ccs_acl_info *acl)
128 kumaneko 111 {
129 kumaneko 1695 if (domain) {
130     /*
131     * We need to serialize because this function is called by
132     * various update functions.
133     */
134     static DEFINE_SPINLOCK(lock);
135     /***** CRITICAL SECTION START *****/
136     spin_lock(&lock);
137 kumaneko 1052 list1_add_tail_mb(&acl->list, &domain->acl_info_list);
138 kumaneko 1695 spin_unlock(&lock);
139     /***** CRITICAL SECTION END *****/
140     } else {
141 kumaneko 1052 acl->type &= ~ACL_DELETED;
142 kumaneko 1695 }
143 kumaneko 1052 ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
144 kumaneko 111 return 0;
145     }
146    
147 kumaneko 1052 /**
148     * ccs_del_domain_acl - Delete the given ACL from the domain.
149     *
150 kumaneko 2002 * @acl: Pointer to "struct ccs_acl_info". May be NULL.
151 kumaneko 1052 *
152     * Returns 0.
153     */
154 kumaneko 2002 int ccs_del_domain_acl(struct ccs_acl_info *acl)
155 kumaneko 111 {
156 kumaneko 1052 if (acl)
157     acl->type |= ACL_DELETED;
158     ccs_update_counter(CCS_UPDATES_COUNTER_DOMAIN_POLICY);
159 kumaneko 111 return 0;
160     }
161    
162 kumaneko 1052 /**
163 kumaneko 2002 * ccs_audit_execute_handler_log - Audit execute_handler log.
164 kumaneko 1052 *
165 kumaneko 1064 * @is_default: True if it is "execute_handler" log.
166     * @handler: The realpath of the handler.
167     * @bprm: Pointer to "struct linux_binprm".
168 kumaneko 1052 *
169     * Returns 0 on success, negative value otherwise.
170     */
171 kumaneko 2002 static int ccs_audit_execute_handler_log(const bool is_default,
172     const char *handler,
173     struct linux_binprm *bprm)
174 kumaneko 1052 {
175 kumaneko 1657 struct ccs_request_info r;
176     ccs_init_request_info(&r, NULL, CCS_TOMOYO_MAC_FOR_FILE);
177     r.bprm = bprm;
178     return ccs_write_audit_log(true, &r, "%s %s\n",
179     is_default ? KEYWORD_EXECUTE_HANDLER :
180     KEYWORD_DENIED_EXECUTE_HANDLER, handler);
181 kumaneko 1052 }
182 kumaneko 111
183 kumaneko 1052 /**
184 kumaneko 2002 * ccs_audit_domain_creation_log - Audit domain creation log.
185 kumaneko 1052 *
186 kumaneko 1657 * @domain: Pointer to "struct domain_info".
187 kumaneko 1052 *
188     * Returns 0 on success, negative value otherwise.
189     */
190 kumaneko 2002 static int ccs_audit_domain_creation_log(struct domain_info *domain)
191 kumaneko 1052 {
192 kumaneko 1657 struct ccs_request_info r;
193     ccs_init_request_info(&r, domain, CCS_TOMOYO_MAC_FOR_FILE);
194     return ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile);
195 kumaneko 1052 }
196    
197 kumaneko 2002 /* The list for "struct ccs_domain_initializer_entry". */
198     static LIST1_HEAD(ccs_domain_initializer_list);
199 kumaneko 111
200 kumaneko 1052 /**
201 kumaneko 2002 * ccs_update_domain_initializer_entry - Update "struct ccs_domain_initializer_entry" list.
202 kumaneko 1052 *
203     * @domainname: The name of domain. May be NULL.
204     * @program: The name of program.
205     * @is_not: True if it is "no_initialize_domain" entry.
206     * @is_delete: True if it is a delete request.
207     *
208     * Returns 0 on success, negative value otherwise.
209     */
210 kumaneko 2002 static int ccs_update_domain_initializer_entry(const char *domainname,
211     const char *program,
212     const bool is_not,
213     const bool is_delete)
214 kumaneko 111 {
215 kumaneko 2002 struct ccs_domain_initializer_entry *new_entry;
216     struct ccs_domain_initializer_entry *ptr;
217 kumaneko 652 static DEFINE_MUTEX(lock);
218 kumaneko 2002 const struct ccs_path_info *saved_program;
219     const struct ccs_path_info *saved_domainname = NULL;
220 kumaneko 111 int error = -ENOMEM;
221 kumaneko 1016 bool is_last_name = false;
222 kumaneko 1052 if (!ccs_is_correct_path(program, 1, -1, -1, __func__))
223     return -EINVAL; /* No patterns allowed. */
224 kumaneko 111 if (domainname) {
225 kumaneko 1052 if (!ccs_is_domain_def(domainname) &&
226     ccs_is_correct_path(domainname, 1, -1, -1, __func__))
227 kumaneko 1016 is_last_name = true;
228 kumaneko 1052 else if (!ccs_is_correct_domain(domainname, __func__))
229 kumaneko 111 return -EINVAL;
230 kumaneko 1052 saved_domainname = ccs_save_name(domainname);
231     if (!saved_domainname)
232     return -ENOMEM;
233 kumaneko 111 }
234 kumaneko 1052 saved_program = ccs_save_name(program);
235     if (!saved_program)
236     return -ENOMEM;
237 kumaneko 652 mutex_lock(&lock);
238 kumaneko 2002 list1_for_each_entry(ptr, &ccs_domain_initializer_list, list) {
239 kumaneko 1052 if (ptr->is_not != is_not ||
240     ptr->domainname != saved_domainname ||
241     ptr->program != saved_program)
242     continue;
243     ptr->is_deleted = is_delete;
244     error = 0;
245     goto out;
246 kumaneko 111 }
247     if (is_delete) {
248     error = -ENOENT;
249     goto out;
250     }
251 kumaneko 1052 new_entry = ccs_alloc_element(sizeof(*new_entry));
252     if (!new_entry)
253     goto out;
254 kumaneko 111 new_entry->domainname = saved_domainname;
255     new_entry->program = saved_program;
256     new_entry->is_not = is_not;
257     new_entry->is_last_name = is_last_name;
258 kumaneko 2002 list1_add_tail_mb(&new_entry->list, &ccs_domain_initializer_list);
259 kumaneko 111 error = 0;
260     out:
261 kumaneko 652 mutex_unlock(&lock);
262 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
263 kumaneko 111 return error;
264     }
265    
266 kumaneko 1052 /**
267 kumaneko 2002 * ccs_read_domain_initializer_policy - Read "struct ccs_domain_initializer_entry" list.
268 kumaneko 1052 *
269     * @head: Pointer to "struct ccs_io_buffer".
270     *
271     * Returns true on success, false otherwise.
272     */
273     bool ccs_read_domain_initializer_policy(struct ccs_io_buffer *head)
274 kumaneko 111 {
275 kumaneko 722 struct list1_head *pos;
276 kumaneko 2002 list1_for_each_cookie(pos, head->read_var2,
277     &ccs_domain_initializer_list) {
278 kumaneko 1064 const char *no;
279     const char *from = "";
280     const char *domain = "";
281 kumaneko 2002 struct ccs_domain_initializer_entry *ptr;
282     ptr = list1_entry(pos, struct ccs_domain_initializer_entry,
283     list);
284 kumaneko 1052 if (ptr->is_deleted)
285     continue;
286 kumaneko 1064 no = ptr->is_not ? "no_" : "";
287 kumaneko 708 if (ptr->domainname) {
288 kumaneko 1064 from = " from ";
289     domain = ptr->domainname->name;
290     }
291     if (!ccs_io_printf(head,
292     "%s" KEYWORD_INITIALIZE_DOMAIN "%s%s%s\n",
293     no, ptr->program->name, from, domain))
294 kumaneko 2002 goto out;
295 kumaneko 111 }
296 kumaneko 1052 return true;
297     out:
298     return false;
299 kumaneko 111 }
300    
301 kumaneko 1052 /**
302 kumaneko 2002 * ccs_write_domain_initializer_policy - Write "struct ccs_domain_initializer_entry" list.
303 kumaneko 1052 *
304     * @data: String to parse.
305     * @is_not: True if it is "no_initialize_domain" entry.
306     * @is_delete: True if it is a delete request.
307     *
308     * Returns 0 on success, negative value otherwise.
309     */
310     int ccs_write_domain_initializer_policy(char *data, const bool is_not,
311     const bool is_delete)
312 kumaneko 111 {
313     char *cp = strstr(data, " from ");
314     if (cp) {
315     *cp = '\0';
316 kumaneko 2002 return ccs_update_domain_initializer_entry(cp + 6, data,
317     is_not, is_delete);
318 kumaneko 111 }
319 kumaneko 2002 return ccs_update_domain_initializer_entry(NULL, data, is_not,
320     is_delete);
321 kumaneko 111 }
322    
323 kumaneko 1052 /**
324 kumaneko 2002 * ccs_is_domain_initializer - Check whether the given program causes domainname reinitialization.
325 kumaneko 1052 *
326     * @domainname: The name of domain.
327     * @program: The name of program.
328     * @last_name: The last component of @domainname.
329     *
330     * Returns true if executing @program reinitializes domain transition,
331     * false otherwise.
332     */
333 kumaneko 2002 static bool ccs_is_domain_initializer(const struct ccs_path_info *domainname,
334     const struct ccs_path_info *program,
335     const struct ccs_path_info *last_name)
336 kumaneko 111 {
337 kumaneko 2002 struct ccs_domain_initializer_entry *ptr;
338 kumaneko 1016 bool flag = false;
339 kumaneko 2002 list1_for_each_entry(ptr, &ccs_domain_initializer_list, list) {
340 kumaneko 1052 if (ptr->is_deleted)
341     continue;
342 kumaneko 111 if (ptr->domainname) {
343     if (!ptr->is_last_name) {
344 kumaneko 1052 if (ptr->domainname != domainname)
345     continue;
346 kumaneko 111 } else {
347 kumaneko 1052 if (ccs_pathcmp(ptr->domainname, last_name))
348     continue;
349 kumaneko 111 }
350     }
351 kumaneko 1052 if (ccs_pathcmp(ptr->program, program))
352     continue;
353     if (ptr->is_not)
354     return false;
355 kumaneko 1016 flag = true;
356 kumaneko 111 }
357     return flag;
358     }
359    
360 kumaneko 2002 /* The list for "struct ccs_domain_keeper_entry". */
361     static LIST1_HEAD(ccs_domain_keeper_list);
362 kumaneko 111
363 kumaneko 1052 /**
364 kumaneko 2002 * ccs_update_domain_keeper_entry - Update "struct ccs_domain_keeper_entry" list.
365 kumaneko 1052 *
366     * @domainname: The name of domain.
367     * @program: The name of program. May be NULL.
368     * @is_not: True if it is "no_keep_domain" entry.
369     * @is_delete: True if it is a delete request.
370     *
371     * Returns 0 on success, negative value otherwise.
372     */
373 kumaneko 2002 static int ccs_update_domain_keeper_entry(const char *domainname,
374     const char *program,
375     const bool is_not,
376     const bool is_delete)
377 kumaneko 111 {
378 kumaneko 2002 struct ccs_domain_keeper_entry *new_entry;
379     struct ccs_domain_keeper_entry *ptr;
380     const struct ccs_path_info *saved_domainname;
381     const struct ccs_path_info *saved_program = NULL;
382 kumaneko 652 static DEFINE_MUTEX(lock);
383 kumaneko 111 int error = -ENOMEM;
384 kumaneko 1016 bool is_last_name = false;
385 kumaneko 1052 if (!ccs_is_domain_def(domainname) &&
386     ccs_is_correct_path(domainname, 1, -1, -1, __func__))
387 kumaneko 1016 is_last_name = true;
388 kumaneko 1052 else if (!ccs_is_correct_domain(domainname, __func__))
389 kumaneko 111 return -EINVAL;
390     if (program) {
391 kumaneko 1052 if (!ccs_is_correct_path(program, 1, -1, -1, __func__))
392     return -EINVAL;
393     saved_program = ccs_save_name(program);
394     if (!saved_program)
395     return -ENOMEM;
396 kumaneko 111 }
397 kumaneko 1052 saved_domainname = ccs_save_name(domainname);
398     if (!saved_domainname)
399     return -ENOMEM;
400 kumaneko 652 mutex_lock(&lock);
401 kumaneko 2002 list1_for_each_entry(ptr, &ccs_domain_keeper_list, list) {
402 kumaneko 1052 if (ptr->is_not != is_not ||
403     ptr->domainname != saved_domainname ||
404     ptr->program != saved_program)
405     continue;
406     ptr->is_deleted = is_delete;
407     error = 0;
408     goto out;
409 kumaneko 111 }
410     if (is_delete) {
411     error = -ENOENT;
412     goto out;
413     }
414 kumaneko 1052 new_entry = ccs_alloc_element(sizeof(*new_entry));
415     if (!new_entry)
416     goto out;
417 kumaneko 111 new_entry->domainname = saved_domainname;
418     new_entry->program = saved_program;
419     new_entry->is_not = is_not;
420     new_entry->is_last_name = is_last_name;
421 kumaneko 2002 list1_add_tail_mb(&new_entry->list, &ccs_domain_keeper_list);
422 kumaneko 111 error = 0;
423     out:
424 kumaneko 652 mutex_unlock(&lock);
425 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
426 kumaneko 111 return error;
427     }
428    
429 kumaneko 1052 /**
430 kumaneko 2002 * ccs_write_domain_keeper_policy - Write "struct ccs_domain_keeper_entry" list.
431 kumaneko 1052 *
432     * @data: String to parse.
433     * @is_not: True if it is "no_keep_domain" entry.
434     * @is_delete: True if it is a delete request.
435     *
436     */
437     int ccs_write_domain_keeper_policy(char *data, const bool is_not,
438     const bool is_delete)
439 kumaneko 111 {
440     char *cp = strstr(data, " from ");
441     if (cp) {
442     *cp = '\0';
443 kumaneko 2002 return ccs_update_domain_keeper_entry(cp + 6, data,
444     is_not, is_delete);
445 kumaneko 111 }
446 kumaneko 2002 return ccs_update_domain_keeper_entry(data, NULL, is_not, is_delete);
447 kumaneko 111 }
448    
449 kumaneko 1052 /**
450 kumaneko 2002 * ccs_read_domain_keeper_policy - Read "struct ccs_domain_keeper_entry" list.
451 kumaneko 1052 *
452     * @head: Pointer to "struct ccs_io_buffer".
453     *
454     * Returns true on success, false otherwise.
455     */
456     bool ccs_read_domain_keeper_policy(struct ccs_io_buffer *head)
457 kumaneko 111 {
458 kumaneko 722 struct list1_head *pos;
459 kumaneko 2002 list1_for_each_cookie(pos, head->read_var2, &ccs_domain_keeper_list) {
460     struct ccs_domain_keeper_entry *ptr;
461 kumaneko 1064 const char *no;
462     const char *from = "";
463     const char *program = "";
464 kumaneko 2002 ptr = list1_entry(pos, struct ccs_domain_keeper_entry, list);
465 kumaneko 1052 if (ptr->is_deleted)
466     continue;
467 kumaneko 1064 no = ptr->is_not ? "no_" : "";
468 kumaneko 708 if (ptr->program) {
469 kumaneko 1064 from = " from ";
470     program = ptr->program->name;
471     }
472     if (!ccs_io_printf(head,
473     "%s" KEYWORD_KEEP_DOMAIN "%s%s%s\n", no,
474     program, from, ptr->domainname->name))
475 kumaneko 2002 goto out;
476 kumaneko 111 }
477 kumaneko 1052 return true;
478     out:
479     return false;
480 kumaneko 111 }
481    
482 kumaneko 1052 /**
483 kumaneko 2002 * ccs_is_domain_keeper - Check whether the given program causes domain transition suppression.
484 kumaneko 1052 *
485     * @domainname: The name of domain.
486     * @program: The name of program.
487     * @last_name: The last component of @domainname.
488     *
489     * Returns true if executing @program supresses domain transition,
490     * false otherwise.
491     */
492 kumaneko 2002 static bool ccs_is_domain_keeper(const struct ccs_path_info *domainname,
493     const struct ccs_path_info *program,
494     const struct ccs_path_info *last_name)
495 kumaneko 111 {
496 kumaneko 2002 struct ccs_domain_keeper_entry *ptr;
497 kumaneko 1016 bool flag = false;
498 kumaneko 2002 list1_for_each_entry(ptr, &ccs_domain_keeper_list, list) {
499 kumaneko 1052 if (ptr->is_deleted)
500     continue;
501 kumaneko 111 if (!ptr->is_last_name) {
502 kumaneko 1052 if (ptr->domainname != domainname)
503     continue;
504 kumaneko 111 } else {
505 kumaneko 1052 if (ccs_pathcmp(ptr->domainname, last_name))
506     continue;
507 kumaneko 111 }
508 kumaneko 1052 if (ptr->program && ccs_pathcmp(ptr->program, program))
509     continue;
510     if (ptr->is_not)
511     return false;
512 kumaneko 1016 flag = true;
513 kumaneko 111 }
514     return flag;
515     }
516    
517 kumaneko 2002 /* The list for "struct ccs_alias_entry". */
518     static LIST1_HEAD(ccs_alias_list);
519 kumaneko 111
520 kumaneko 1052 /**
521 kumaneko 2002 * ccs_update_alias_entry - Update "struct ccs_alias_entry" list.
522 kumaneko 1052 *
523     * @original_name: The original program's real name.
524     * @aliased_name: The symbolic program's symbolic link's name.
525     * @is_delete: True if it is a delete request.
526     *
527     * Returns 0 on success, negative value otherwise.
528     */
529 kumaneko 2002 static int ccs_update_alias_entry(const char *original_name,
530     const char *aliased_name,
531     const bool is_delete)
532 kumaneko 111 {
533 kumaneko 2002 struct ccs_alias_entry *new_entry;
534     struct ccs_alias_entry *ptr;
535 kumaneko 652 static DEFINE_MUTEX(lock);
536 kumaneko 2002 const struct ccs_path_info *saved_original_name;
537     const struct ccs_path_info *saved_aliased_name;
538 kumaneko 111 int error = -ENOMEM;
539 kumaneko 1052 if (!ccs_is_correct_path(original_name, 1, -1, -1, __func__) ||
540     !ccs_is_correct_path(aliased_name, 1, -1, -1, __func__))
541     return -EINVAL; /* No patterns allowed. */
542     saved_original_name = ccs_save_name(original_name);
543     saved_aliased_name = ccs_save_name(aliased_name);
544     if (!saved_original_name || !saved_aliased_name)
545     return -ENOMEM;
546 kumaneko 652 mutex_lock(&lock);
547 kumaneko 2002 list1_for_each_entry(ptr, &ccs_alias_list, list) {
548 kumaneko 1052 if (ptr->original_name != saved_original_name ||
549     ptr->aliased_name != saved_aliased_name)
550     continue;
551     ptr->is_deleted = is_delete;
552     error = 0;
553     goto out;
554 kumaneko 111 }
555     if (is_delete) {
556     error = -ENOENT;
557     goto out;
558     }
559 kumaneko 1052 new_entry = ccs_alloc_element(sizeof(*new_entry));
560     if (!new_entry)
561     goto out;
562 kumaneko 111 new_entry->original_name = saved_original_name;
563     new_entry->aliased_name = saved_aliased_name;
564 kumaneko 2002 list1_add_tail_mb(&new_entry->list, &ccs_alias_list);
565 kumaneko 111 error = 0;
566     out:
567 kumaneko 652 mutex_unlock(&lock);
568 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
569 kumaneko 111 return error;
570     }
571    
572 kumaneko 1052 /**
573 kumaneko 2002 * ccs_read_alias_policy - Read "struct ccs_alias_entry" list.
574 kumaneko 1052 *
575     * @head: Pointer to "struct ccs_io_buffer".
576     *
577     * Returns true on success, false otherwise.
578     */
579     bool ccs_read_alias_policy(struct ccs_io_buffer *head)
580 kumaneko 111 {
581 kumaneko 722 struct list1_head *pos;
582 kumaneko 2002 list1_for_each_cookie(pos, head->read_var2, &ccs_alias_list) {
583     struct ccs_alias_entry *ptr;
584     ptr = list1_entry(pos, struct ccs_alias_entry, list);
585 kumaneko 1052 if (ptr->is_deleted)
586     continue;
587     if (!ccs_io_printf(head, KEYWORD_ALIAS "%s %s\n",
588     ptr->original_name->name,
589     ptr->aliased_name->name))
590     goto out;
591 kumaneko 111 }
592 kumaneko 1052 return true;
593     out:
594     return false;
595 kumaneko 111 }
596    
597 kumaneko 1052 /**
598 kumaneko 2002 * ccs_write_alias_policy - Write "struct ccs_alias_entry" list.
599 kumaneko 1052 *
600     * @data: String to parse.
601     * @is_delete: True if it is a delete request.
602     *
603     * Returns 0 on success, negative value otherwise.
604     */
605     int ccs_write_alias_policy(char *data, const bool is_delete)
606 kumaneko 111 {
607     char *cp = strchr(data, ' ');
608 kumaneko 1052 if (!cp)
609     return -EINVAL;
610 kumaneko 111 *cp++ = '\0';
611 kumaneko 2002 return ccs_update_alias_entry(data, cp, is_delete);
612 kumaneko 111 }
613    
614 kumaneko 2002 /* The list for "struct ccs_aggregator_entry". */
615     static LIST1_HEAD(ccs_aggregator_list);
616 kumaneko 111
617 kumaneko 1052 /**
618 kumaneko 2002 * ccs_update_aggregator_entry - Update "struct ccs_aggregator_entry" list.
619 kumaneko 1052 *
620     * @original_name: The original program's name.
621     * @aggregated_name: The aggregated program's name.
622     * @is_delete: True if it is a delete request.
623     *
624     * Returns 0 on success, negative value otherwise.
625     */
626 kumaneko 2002 static int ccs_update_aggregator_entry(const char *original_name,
627     const char *aggregated_name,
628     const bool is_delete)
629 kumaneko 111 {
630 kumaneko 2002 struct ccs_aggregator_entry *new_entry;
631     struct ccs_aggregator_entry *ptr;
632 kumaneko 652 static DEFINE_MUTEX(lock);
633 kumaneko 2002 const struct ccs_path_info *saved_original_name;
634     const struct ccs_path_info *saved_aggregated_name;
635 kumaneko 111 int error = -ENOMEM;
636 kumaneko 1052 if (!ccs_is_correct_path(original_name, 1, 0, -1, __func__) ||
637     !ccs_is_correct_path(aggregated_name, 1, -1, -1, __func__))
638     return -EINVAL;
639     saved_original_name = ccs_save_name(original_name);
640     saved_aggregated_name = ccs_save_name(aggregated_name);
641     if (!saved_original_name || !saved_aggregated_name)
642     return -ENOMEM;
643 kumaneko 652 mutex_lock(&lock);
644 kumaneko 2002 list1_for_each_entry(ptr, &ccs_aggregator_list, list) {
645 kumaneko 1052 if (ptr->original_name != saved_original_name ||
646     ptr->aggregated_name != saved_aggregated_name)
647     continue;
648     ptr->is_deleted = is_delete;
649     error = 0;
650     goto out;
651 kumaneko 111 }
652     if (is_delete) {
653     error = -ENOENT;
654     goto out;
655     }
656 kumaneko 1052 new_entry = ccs_alloc_element(sizeof(*new_entry));
657     if (!new_entry)
658     goto out;
659 kumaneko 111 new_entry->original_name = saved_original_name;
660     new_entry->aggregated_name = saved_aggregated_name;
661 kumaneko 2002 list1_add_tail_mb(&new_entry->list, &ccs_aggregator_list);
662 kumaneko 111 error = 0;
663     out:
664 kumaneko 652 mutex_unlock(&lock);
665 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
666 kumaneko 111 return error;
667     }
668    
669 kumaneko 1052 /**
670 kumaneko 2002 * ccs_read_aggregator_policy - Read "struct ccs_aggregator_entry" list.
671 kumaneko 1052 *
672     * @head: Pointer to "struct ccs_io_buffer".
673     *
674     * Returns true on success, false otherwise.
675     */
676     bool ccs_read_aggregator_policy(struct ccs_io_buffer *head)
677 kumaneko 111 {
678 kumaneko 722 struct list1_head *pos;
679 kumaneko 2002 list1_for_each_cookie(pos, head->read_var2, &ccs_aggregator_list) {
680     struct ccs_aggregator_entry *ptr;
681     ptr = list1_entry(pos, struct ccs_aggregator_entry, list);
682 kumaneko 1052 if (ptr->is_deleted)
683     continue;
684     if (!ccs_io_printf(head, KEYWORD_AGGREGATOR "%s %s\n",
685     ptr->original_name->name,
686     ptr->aggregated_name->name))
687     goto out;
688 kumaneko 111 }
689 kumaneko 1052 return true;
690     out:
691     return false;
692 kumaneko 111 }
693    
694 kumaneko 1052 /**
695 kumaneko 2002 * ccs_write_aggregator_policy - Write "struct ccs_aggregator_entry" list.
696 kumaneko 1052 *
697     * @data: String to parse.
698     * @is_delete: True if it is a delete request.
699     *
700     * Returns 0 on success, negative value otherwise.
701     */
702     int ccs_write_aggregator_policy(char *data, const bool is_delete)
703 kumaneko 111 {
704     char *cp = strchr(data, ' ');
705 kumaneko 1052 if (!cp)
706     return -EINVAL;
707 kumaneko 111 *cp++ = '\0';
708 kumaneko 2002 return ccs_update_aggregator_entry(data, cp, is_delete);
709 kumaneko 111 }
710    
711 kumaneko 1052 /* Domain create/delete/undelete handler. */
712 kumaneko 111
713 kumaneko 240 /* #define DEBUG_DOMAIN_UNDELETE */
714 kumaneko 111
715 kumaneko 1052 /**
716     * ccs_delete_domain - Delete a domain.
717     *
718     * @domainname: The name of domain.
719     *
720     * Returns 0.
721     */
722     int ccs_delete_domain(char *domainname)
723 kumaneko 111 {
724     struct domain_info *domain;
725 kumaneko 2002 struct ccs_path_info name;
726 kumaneko 1052 name.name = domainname;
727     ccs_fill_path_info(&name);
728 kumaneko 2002 mutex_lock(&ccs_domain_list_lock);
729 kumaneko 111 #ifdef DEBUG_DOMAIN_UNDELETE
730 kumaneko 1052 printk(KERN_DEBUG "ccs_delete_domain %s\n", domainname);
731 kumaneko 2002 list1_for_each_entry(domain, &ccs_domain_list, list) {
732 kumaneko 1052 if (ccs_pathcmp(domain->domainname, &name))
733     continue;
734     printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);
735 kumaneko 111 }
736     #endif
737     /* Is there an active domain? */
738 kumaneko 2002 list1_for_each_entry(domain, &ccs_domain_list, list) {
739 kumaneko 111 struct domain_info *domain2;
740 kumaneko 708 /* Never delete KERNEL_DOMAIN */
741 kumaneko 1052 if (domain == &KERNEL_DOMAIN)
742     continue;
743     if (domain->is_deleted ||
744     ccs_pathcmp(domain->domainname, &name))
745     continue;
746 kumaneko 111 /* Mark already deleted domains as non undeletable. */
747 kumaneko 2002 list1_for_each_entry(domain2, &ccs_domain_list, list) {
748 kumaneko 1052 if (!domain2->is_deleted ||
749     ccs_pathcmp(domain2->domainname, &name))
750     continue;
751 kumaneko 111 #ifdef DEBUG_DOMAIN_UNDELETE
752 kumaneko 1052 if (domain2->is_deleted != 255)
753     printk(KERN_DEBUG
754     "Marked %p as non undeletable\n",
755     domain2);
756 kumaneko 111 #endif
757     domain2->is_deleted = 255;
758     }
759     /* Delete and mark active domain as undeletable. */
760     domain->is_deleted = 1;
761     #ifdef DEBUG_DOMAIN_UNDELETE
762 kumaneko 1052 printk(KERN_DEBUG "Marked %p as undeletable\n", domain);
763 kumaneko 111 #endif
764 kumaneko 708 break;
765 kumaneko 111 }
766 kumaneko 2002 mutex_unlock(&ccs_domain_list_lock);
767 kumaneko 111 return 0;
768     }
769    
770 kumaneko 1052 /**
771     * ccs_undelete_domain - Undelete a domain.
772     *
773     * @domainname: The name of domain.
774     *
775     * Returns pointer to "struct domain_info" on success, NULL otherwise.
776     */
777     struct domain_info *ccs_undelete_domain(const char *domainname)
778 kumaneko 111 {
779 kumaneko 1064 struct domain_info *domain;
780     struct domain_info *candidate_domain = NULL;
781 kumaneko 2002 struct ccs_path_info name;
782 kumaneko 1052 name.name = domainname;
783     ccs_fill_path_info(&name);
784 kumaneko 2002 mutex_lock(&ccs_domain_list_lock);
785 kumaneko 111 #ifdef DEBUG_DOMAIN_UNDELETE
786 kumaneko 1052 printk(KERN_DEBUG "ccs_undelete_domain %s\n", domainname);
787 kumaneko 2002 list1_for_each_entry(domain, &ccs_domain_list, list) {
788 kumaneko 1052 if (ccs_pathcmp(domain->domainname, &name))
789     continue;
790     printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted);
791 kumaneko 111 }
792     #endif
793 kumaneko 2002 list1_for_each_entry(domain, &ccs_domain_list, list) {
794 kumaneko 1052 if (ccs_pathcmp(&name, domain->domainname))
795     continue;
796 kumaneko 111 if (!domain->is_deleted) {
797     /* This domain is active. I can't undelete. */
798     candidate_domain = NULL;
799     #ifdef DEBUG_DOMAIN_UNDELETE
800 kumaneko 1052 printk(KERN_DEBUG "%p is active. I can't undelete.\n",
801     domain);
802 kumaneko 111 #endif
803     break;
804     }
805     /* Is this domain undeletable? */
806 kumaneko 1052 if (domain->is_deleted == 1)
807     candidate_domain = domain;
808 kumaneko 111 }
809     if (candidate_domain) {
810     candidate_domain->is_deleted = 0;
811     #ifdef DEBUG_DOMAIN_UNDELETE
812 kumaneko 1052 printk(KERN_DEBUG "%p was undeleted.\n", candidate_domain);
813 kumaneko 111 #endif
814     }
815 kumaneko 2002 mutex_unlock(&ccs_domain_list_lock);
816 kumaneko 111 return candidate_domain;
817     }
818    
819 kumaneko 1052 /**
820     * ccs_find_or_assign_new_domain - Create a domain.
821     *
822     * @domainname: The name of domain.
823     * @profile: Profile number to assign if the domain was newly created.
824     *
825     * Returns pointer to "struct domain_info" on success, NULL otherwise.
826     */
827     struct domain_info *ccs_find_or_assign_new_domain(const char *domainname,
828     const u8 profile)
829 kumaneko 111 {
830     struct domain_info *domain = NULL;
831 kumaneko 2002 const struct ccs_path_info *saved_domainname;
832     mutex_lock(&ccs_domain_list_lock);
833 kumaneko 1052 domain = ccs_find_domain(domainname);
834     if (domain)
835     goto out;
836     if (!ccs_is_correct_domain(domainname, __func__))
837     goto out;
838     saved_domainname = ccs_save_name(domainname);
839     if (!saved_domainname)
840     goto out;
841 kumaneko 111 /* Can I reuse memory of deleted domain? */
842 kumaneko 2002 list1_for_each_entry(domain, &ccs_domain_list, list) {
843 kumaneko 111 struct task_struct *p;
844 kumaneko 2002 struct ccs_acl_info *ptr;
845 kumaneko 853 bool flag;
846 kumaneko 1052 if (!domain->is_deleted ||
847     domain->domainname != saved_domainname)
848     continue;
849 kumaneko 1016 flag = false;
850 kumaneko 111 /***** CRITICAL SECTION START *****/
851     read_lock(&tasklist_lock);
852     for_each_process(p) {
853 kumaneko 1064 if (p->domain_info != domain)
854     continue;
855     flag = true;
856     break;
857 kumaneko 111 }
858     read_unlock(&tasklist_lock);
859     /***** CRITICAL SECTION END *****/
860 kumaneko 1052 if (flag)
861     continue;
862 kumaneko 111 #ifdef DEBUG_DOMAIN_UNDELETE
863 kumaneko 1052 printk(KERN_DEBUG "Reusing %p %s\n", domain,
864     domain->domainname->name);
865 kumaneko 111 #endif
866 kumaneko 860 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
867 kumaneko 906 ptr->type |= ACL_DELETED;
868 kumaneko 860 }
869 kumaneko 1700 ccs_set_domain_flag(domain, true, domain->flags);
870 kumaneko 111 domain->profile = profile;
871 kumaneko 1016 domain->quota_warned = false;
872 kumaneko 708 mb(); /* Avoid out-of-order execution. */
873 kumaneko 111 domain->is_deleted = 0;
874     goto out;
875     }
876     /* No memory reusable. Create using new memory. */
877 kumaneko 1052 domain = ccs_alloc_element(sizeof(*domain));
878     if (domain) {
879 kumaneko 722 INIT_LIST1_HEAD(&domain->acl_info_list);
880 kumaneko 111 domain->domainname = saved_domainname;
881     domain->profile = profile;
882 kumaneko 2002 list1_add_tail_mb(&domain->list, &ccs_domain_list);
883 kumaneko 111 }
884 kumaneko 1052 out:
885 kumaneko 2002 mutex_unlock(&ccs_domain_list_lock);
886 kumaneko 111 return domain;
887     }
888    
889 kumaneko 1052 /**
890 kumaneko 2002 * ccs_get_argv0 - Get argv[0].
891 kumaneko 1052 *
892     * @bprm: Pointer to "struct linux_binprm".
893 kumaneko 1793 * @tmp: Buffer for temporary use.
894 kumaneko 1052 *
895     * Returns true on success, false otherwise.
896     */
897 kumaneko 2002 static bool ccs_get_argv0(struct linux_binprm *bprm,
898     struct ccs_page_buffer *tmp)
899 kumaneko 111 {
900 kumaneko 1031 char *arg_ptr = tmp->buffer;
901 kumaneko 316 int arg_len = 0;
902     unsigned long pos = bprm->p;
903 kumaneko 1052 int i = pos / PAGE_SIZE;
904     int offset = pos % PAGE_SIZE;
905 kumaneko 1031 bool done = false;
906 kumaneko 1052 if (!bprm->argc)
907     goto out;
908 kumaneko 316 while (1) {
909     struct page *page;
910 kumaneko 1031 const char *kaddr;
911 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
912     if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page,
913     NULL) <= 0)
914     goto out;
915 kumaneko 1031 pos += PAGE_SIZE - offset;
916 kumaneko 316 #else
917     page = bprm->page[i];
918     #endif
919 kumaneko 1031 /* Map. */
920     kaddr = kmap(page);
921     if (!kaddr) { /* Mapping failed. */
922 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
923 kumaneko 1031 put_page(page);
924 kumaneko 316 #endif
925 kumaneko 1031 goto out;
926     }
927     /* Read. */
928     while (offset < PAGE_SIZE) {
929     const unsigned char c = kaddr[offset++];
930     if (c && arg_len < CCS_MAX_PATHNAME_LEN - 10) {
931     if (c == '\\') {
932     arg_ptr[arg_len++] = '\\';
933     arg_ptr[arg_len++] = '\\';
934     } else if (c == '/') {
935     arg_len = 0;
936     } else if (c > ' ' && c < 127) {
937     arg_ptr[arg_len++] = c;
938     } else {
939     arg_ptr[arg_len++] = '\\';
940     arg_ptr[arg_len++] = (c >> 6) + '0';
941 kumaneko 1052 arg_ptr[arg_len++]
942     = ((c >> 3) & 7) + '0';
943 kumaneko 1031 arg_ptr[arg_len++] = (c & 7) + '0';
944     }
945     } else {
946     arg_ptr[arg_len] = '\0';
947     done = true;
948     break;
949 kumaneko 316 }
950 kumaneko 115 }
951 kumaneko 1031 /* Unmap. */
952     kunmap(page);
953 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
954 kumaneko 316 put_page(page);
955     #endif
956     i++;
957     offset = 0;
958 kumaneko 1052 if (done)
959     break;
960 kumaneko 115 }
961 kumaneko 1031 return true;
962     out:
963     return false;
964 kumaneko 115 }
965    
966 kumaneko 1052 /**
967 kumaneko 2002 * ccs_find_next_domain - Find a domain.
968 kumaneko 1052 *
969 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
970     * @handler: Pathname to verify. May be NULL.
971 kumaneko 1052 *
972     * Returns 0 on success, negative value otherwise.
973     */
974 kumaneko 2002 static int ccs_find_next_domain(struct ccs_request_info *r,
975     const struct ccs_path_info *handler)
976 kumaneko 115 {
977 kumaneko 1052 /*
978     * This function assumes that the size of buffer returned by
979     * ccs_realpath() = CCS_MAX_PATHNAME_LEN.
980     */
981     struct domain_info *domain = NULL;
982 kumaneko 1657 const char *old_domain_name = r->domain->domainname->name;
983     struct linux_binprm *bprm = r->bprm;
984     struct ccs_page_buffer *tmp = r->obj->tmp;
985 kumaneko 115 const char *original_name = bprm->filename;
986 kumaneko 1657 const u8 mode = r->mode;
987     const bool is_enforce = (mode == 3);
988 kumaneko 1782 const u32 tomoyo_flags = current->tomoyo_flags;
989 kumaneko 111 char *new_domain_name = NULL;
990 kumaneko 1052 char *real_program_name = NULL;
991     char *symlink_program_name = NULL;
992 kumaneko 2002 struct ccs_path_info rn; /* real name */
993     struct ccs_path_info sn; /* symlink name */
994     struct ccs_path_info ln; /* last name */
995 kumaneko 111 int retval;
996    
997     {
998     /*
999 kumaneko 1052 * Built-in initializers. This is needed because policies are
1000 kumaneko 1064 * not loaded until starting /sbin/init.
1001 kumaneko 111 */
1002 kumaneko 1016 static bool first = true;
1003 kumaneko 111 if (first) {
1004 kumaneko 2002 ccs_update_domain_initializer_entry(NULL,
1005     "/sbin/hotplug",
1006     false, false);
1007     ccs_update_domain_initializer_entry(NULL,
1008     "/sbin/modprobe",
1009     false, false);
1010 kumaneko 1016 first = false;
1011 kumaneko 111 }
1012     }
1013    
1014 kumaneko 1561 retry:
1015     current->tomoyo_flags = tomoyo_flags;
1016 kumaneko 1782 r->cond = NULL;
1017 kumaneko 1052 /* Get ccs_realpath of program. */
1018     retval = -ENOENT; /* I hope ccs_realpath() won't fail with -ENOMEM. */
1019 kumaneko 1561 ccs_free(real_program_name);
1020 kumaneko 1052 real_program_name = ccs_realpath(original_name);
1021     if (!real_program_name)
1022     goto out;
1023     /* Get ccs_realpath of symbolic link. */
1024 kumaneko 1561 ccs_free(symlink_program_name);
1025 kumaneko 1052 symlink_program_name = ccs_realpath_nofollow(original_name);
1026     if (!symlink_program_name)
1027     goto out;
1028 kumaneko 111
1029 kumaneko 1657 rn.name = real_program_name;
1030     ccs_fill_path_info(&rn);
1031     sn.name = symlink_program_name;
1032     ccs_fill_path_info(&sn);
1033     ln.name = ccs_get_last_name(r->domain);
1034     ccs_fill_path_info(&ln);
1035 kumaneko 111
1036 kumaneko 1657 if (handler) {
1037     if (ccs_pathcmp(&rn, handler)) {
1038 kumaneko 1064 /* Failed to verify execute handler. */
1039 kumaneko 1029 static u8 counter = 20;
1040     if (counter) {
1041     counter--;
1042 kumaneko 1052 printk(KERN_WARNING "Failed to verify: %s\n",
1043 kumaneko 1657 handler->name);
1044 kumaneko 1029 }
1045     goto out;
1046     }
1047 kumaneko 1052 goto calculate_domain;
1048 kumaneko 1029 }
1049 kumaneko 708
1050 kumaneko 111 /* Check 'alias' directive. */
1051 kumaneko 1657 if (ccs_pathcmp(&rn, &sn)) {
1052 kumaneko 2002 struct ccs_alias_entry *ptr;
1053 kumaneko 111 /* Is this program allowed to be called via symbolic links? */
1054 kumaneko 2002 list1_for_each_entry(ptr, &ccs_alias_list, list) {
1055 kumaneko 1052 if (ptr->is_deleted ||
1056 kumaneko 1657 ccs_pathcmp(&rn, ptr->original_name) ||
1057     ccs_pathcmp(&sn, ptr->aliased_name))
1058 kumaneko 1052 continue;
1059 kumaneko 111 memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
1060 kumaneko 1052 strncpy(real_program_name, ptr->aliased_name->name,
1061     CCS_MAX_PATHNAME_LEN - 1);
1062 kumaneko 1657 ccs_fill_path_info(&rn);
1063 kumaneko 111 break;
1064     }
1065     }
1066 kumaneko 1032
1067 kumaneko 183 /* Compare basename of real_program_name and argv[0] */
1068 kumaneko 1657 r->mode = ccs_check_flags(r->domain, CCS_TOMOYO_MAC_FOR_ARGV0);
1069     if (bprm->argc > 0 && r->mode) {
1070 kumaneko 1031 char *base_argv0 = tmp->buffer;
1071     const char *base_filename;
1072 kumaneko 115 retval = -ENOMEM;
1073 kumaneko 2002 if (!ccs_get_argv0(bprm, tmp))
1074 kumaneko 1052 goto out;
1075     base_filename = strrchr(real_program_name, '/');
1076     if (!base_filename)
1077     base_filename = real_program_name;
1078     else
1079     base_filename++;
1080 kumaneko 1031 if (strcmp(base_argv0, base_filename)) {
1081 kumaneko 1657 retval = ccs_check_argv0_perm(r, &rn, base_argv0);
1082 kumaneko 1781 if (retval == 1)
1083 kumaneko 1561 goto retry;
1084     if (retval < 0)
1085 kumaneko 1052 goto out;
1086 kumaneko 111 }
1087     }
1088 kumaneko 1032
1089 kumaneko 183 /* Check 'aggregator' directive. */
1090     {
1091 kumaneko 2002 struct ccs_aggregator_entry *ptr;
1092 kumaneko 183 /* Is this program allowed to be aggregated? */
1093 kumaneko 2002 list1_for_each_entry(ptr, &ccs_aggregator_list, list) {
1094 kumaneko 1052 if (ptr->is_deleted ||
1095 kumaneko 1657 !ccs_path_matches_pattern(&rn, ptr->original_name))
1096 kumaneko 1052 continue;
1097 kumaneko 183 memset(real_program_name, 0, CCS_MAX_PATHNAME_LEN);
1098 kumaneko 1052 strncpy(real_program_name, ptr->aggregated_name->name,
1099     CCS_MAX_PATHNAME_LEN - 1);
1100 kumaneko 1657 ccs_fill_path_info(&rn);
1101 kumaneko 183 break;
1102     }
1103     }
1104    
1105 kumaneko 111 /* Check execute permission. */
1106 kumaneko 1657 r->mode = mode;
1107     retval = ccs_check_exec_perm(r, &rn);
1108 kumaneko 1781 if (retval == 1)
1109 kumaneko 1561 goto retry;
1110 kumaneko 1052 if (retval < 0)
1111     goto out;
1112 kumaneko 111
1113 kumaneko 1052 calculate_domain:
1114 kumaneko 1031 new_domain_name = tmp->buffer;
1115 kumaneko 2002 if (ccs_is_domain_initializer(r->domain->domainname, &rn, &ln)) {
1116 kumaneko 111 /* Transit to the child of KERNEL_DOMAIN domain. */
1117 kumaneko 1052 snprintf(new_domain_name, CCS_MAX_PATHNAME_LEN + 1,
1118     ROOT_NAME " " "%s", real_program_name);
1119 kumaneko 2002 } else if (r->domain == &KERNEL_DOMAIN && !ccs_sbin_init_started) {
1120 kumaneko 111 /*
1121 kumaneko 1052 * Needn't to transit from kernel domain before starting
1122 kumaneko 1064 * /sbin/init. But transit from kernel domain if executing
1123     * initializers because they might start before /sbin/init.
1124 kumaneko 111 */
1125 kumaneko 1657 domain = r->domain;
1126 kumaneko 2002 } else if (ccs_is_domain_keeper(r->domain->domainname, &rn, &ln)) {
1127 kumaneko 111 /* Keep current domain. */
1128 kumaneko 1657 domain = r->domain;
1129 kumaneko 111 } else {
1130     /* Normal domain transition. */
1131 kumaneko 1052 snprintf(new_domain_name, CCS_MAX_PATHNAME_LEN + 1,
1132     "%s %s", old_domain_name, real_program_name);
1133 kumaneko 111 }
1134 kumaneko 1052 if (domain || strlen(new_domain_name) >= CCS_MAX_PATHNAME_LEN)
1135     goto done;
1136     domain = ccs_find_domain(new_domain_name);
1137     if (domain)
1138     goto done;
1139 kumaneko 1561 if (is_enforce) {
1140 kumaneko 1657 int error = ccs_check_supervisor(r,
1141 kumaneko 1561 "# wants to create domain\n"
1142     "%s\n", new_domain_name);
1143 kumaneko 1781 if (error == 1)
1144 kumaneko 1561 goto retry;
1145     if (error < 0)
1146 kumaneko 1052 goto done;
1147 kumaneko 1561 }
1148 kumaneko 1657 domain = ccs_find_or_assign_new_domain(new_domain_name, r->profile);
1149 kumaneko 1052 if (domain)
1150 kumaneko 2002 ccs_audit_domain_creation_log(domain);
1151 kumaneko 1052 done:
1152 kumaneko 111 if (!domain) {
1153 kumaneko 1052 printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",
1154     new_domain_name);
1155     if (is_enforce)
1156     retval = -EPERM;
1157 kumaneko 1561 else {
1158     retval = 0;
1159 kumaneko 1657 ccs_set_domain_flag(r->domain, false,
1160 kumaneko 1180 DOMAIN_FLAGS_TRANSITION_FAILED);
1161 kumaneko 1561 }
1162 kumaneko 111 } else {
1163     retval = 0;
1164     }
1165 kumaneko 1052 out:
1166 kumaneko 111 ccs_free(real_program_name);
1167     ccs_free(symlink_program_name);
1168 kumaneko 1657 if (domain)
1169     r->domain = domain;
1170 kumaneko 111 return retval;
1171     }
1172    
1173 kumaneko 1052 /**
1174 kumaneko 2002 * ccs_check_environ - Check permission for environment variable names.
1175 kumaneko 1052 *
1176 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
1177 kumaneko 1052 *
1178     * Returns 0 on success, negative value otherwise.
1179     */
1180 kumaneko 2002 static int ccs_check_environ(struct ccs_request_info *r)
1181 kumaneko 581 {
1182 kumaneko 1657 struct linux_binprm *bprm = r->bprm;
1183     struct ccs_page_buffer *tmp = r->obj->tmp;
1184 kumaneko 1031 char *arg_ptr = tmp->buffer;
1185 kumaneko 581 int arg_len = 0;
1186     unsigned long pos = bprm->p;
1187 kumaneko 1064 int i = pos / PAGE_SIZE;
1188     int offset = pos % PAGE_SIZE;
1189 kumaneko 581 int argv_count = bprm->argc;
1190     int envp_count = bprm->envc;
1191 kumaneko 1052 /* printk(KERN_DEBUG "start %d %d\n", argv_count, envp_count); */
1192 kumaneko 581 int error = -ENOMEM;
1193 kumaneko 1657 if (!r->mode || !envp_count)
1194 kumaneko 1052 return 0;
1195 kumaneko 581 while (error == -ENOMEM) {
1196     struct page *page;
1197     const char *kaddr;
1198 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1199     if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page,
1200     NULL) <= 0)
1201     goto out;
1202 kumaneko 986 pos += PAGE_SIZE - offset;
1203 kumaneko 581 #else
1204     page = bprm->page[i];
1205 kumaneko 111 #endif
1206 kumaneko 1031 /* Map. */
1207 kumaneko 581 kaddr = kmap(page);
1208     if (!kaddr) { /* Mapping failed. */
1209 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1210 kumaneko 581 put_page(page);
1211     #endif
1212     goto out;
1213     }
1214     /* Read. */
1215     while (argv_count && offset < PAGE_SIZE) {
1216 kumaneko 1052 if (!kaddr[offset++])
1217     argv_count--;
1218 kumaneko 581 }
1219 kumaneko 1052 if (argv_count)
1220     goto unmap_page;
1221 kumaneko 581 while (offset < PAGE_SIZE) {
1222     const unsigned char c = kaddr[offset++];
1223 kumaneko 652 if (c && arg_len < CCS_MAX_PATHNAME_LEN - 10) {
1224 kumaneko 581 if (c == '=') {
1225     arg_ptr[arg_len++] = '\0';
1226     } else if (c == '\\') {
1227     arg_ptr[arg_len++] = '\\';
1228     arg_ptr[arg_len++] = '\\';
1229     } else if (c > ' ' && c < 127) {
1230     arg_ptr[arg_len++] = c;
1231     } else {
1232     arg_ptr[arg_len++] = '\\';
1233     arg_ptr[arg_len++] = (c >> 6) + '0';
1234 kumaneko 1052 arg_ptr[arg_len++]
1235     = ((c >> 3) & 7) + '0';
1236 kumaneko 581 arg_ptr[arg_len++] = (c & 7) + '0';
1237     }
1238     } else {
1239     arg_ptr[arg_len] = '\0';
1240     }
1241 kumaneko 1052 if (c)
1242     continue;
1243 kumaneko 1657 if (ccs_check_env_perm(r, arg_ptr)) {
1244 kumaneko 581 error = -EPERM;
1245     break;
1246     }
1247     if (!--envp_count) {
1248     error = 0;
1249     break;
1250     }
1251     arg_len = 0;
1252     }
1253 kumaneko 2002 unmap_page:
1254 kumaneko 581 /* Unmap. */
1255     kunmap(page);
1256 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) && defined(CONFIG_MMU)
1257 kumaneko 581 put_page(page);
1258     #endif
1259     i++;
1260     offset = 0;
1261     }
1262     out:
1263 kumaneko 1657 if (r->mode != 3)
1264 kumaneko 1052 error = 0;
1265 kumaneko 581 return error;
1266     }
1267 kumaneko 111
1268 kumaneko 1052 /**
1269 kumaneko 2002 * ccs_unescape - Unescape escaped string.
1270 kumaneko 1052 *
1271 kumaneko 2002 * @dest: String to ccs_unescape.
1272 kumaneko 1052 *
1273     * Returns nothing.
1274     */
1275 kumaneko 2002 static void ccs_unescape(unsigned char *dest)
1276 kumaneko 708 {
1277     unsigned char *src = dest;
1278 kumaneko 1064 unsigned char c;
1279     unsigned char d;
1280     unsigned char e;
1281 kumaneko 1747 while (1) {
1282     c = *src++;
1283     if (!c)
1284     break;
1285 kumaneko 708 if (c != '\\') {
1286     *dest++ = c;
1287     continue;
1288     }
1289     c = *src++;
1290     if (c == '\\') {
1291     *dest++ = c;
1292 kumaneko 1052 continue;
1293     }
1294     if (c < '0' || c > '3')
1295 kumaneko 708 break;
1296 kumaneko 1052 d = *src++;
1297     if (d < '0' || d > '7')
1298     break;
1299     e = *src++;
1300     if (e < '0' || e > '7')
1301     break;
1302     *dest++ = ((c - '0') << 6) + ((d - '0') << 3) + (e - '0');
1303 kumaneko 708 }
1304     *dest = '\0';
1305     }
1306    
1307 kumaneko 1052 /**
1308 kumaneko 2002 * ccs_root_depth - Get number of directories to strip.
1309 kumaneko 1052 *
1310     * @dentry: Pointer to "struct dentry".
1311     * @vfsmnt: Pointer to "struct vfsmount".
1312     *
1313     * Returns number of directories to strip.
1314 kumaneko 1029 */
1315 kumaneko 2002 static inline int ccs_root_depth(struct dentry *dentry, struct vfsmount *vfsmnt)
1316 kumaneko 708 {
1317 kumaneko 1029 int depth = 0;
1318     /***** CRITICAL SECTION START *****/
1319 kumaneko 1474 ccs_realpath_lock();
1320 kumaneko 1029 for (;;) {
1321     if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
1322     /* Global root? */
1323 kumaneko 1052 if (vfsmnt->mnt_parent == vfsmnt)
1324     break;
1325 kumaneko 1029 dentry = vfsmnt->mnt_mountpoint;
1326     vfsmnt = vfsmnt->mnt_parent;
1327     continue;
1328     }
1329     dentry = dentry->d_parent;
1330     depth++;
1331     }
1332 kumaneko 1474 ccs_realpath_unlock();
1333 kumaneko 1029 /***** CRITICAL SECTION END *****/
1334 kumaneko 1052 return depth;
1335     }
1336    
1337     /**
1338 kumaneko 2002 * ccs_get_root_depth - return the depth of root directory.
1339 kumaneko 1052 *
1340     * Returns number of directories to strip.
1341     */
1342 kumaneko 2002 static int ccs_get_root_depth(void)
1343 kumaneko 1052 {
1344     int depth;
1345     struct dentry *dentry;
1346     struct vfsmount *vfsmnt;
1347     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1348     struct path root;
1349     #endif
1350     /***** CRITICAL SECTION START *****/
1351     read_lock(&current->fs->lock);
1352     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1353     root = current->fs->root;
1354     path_get(&current->fs->root);
1355     dentry = root.dentry;
1356     vfsmnt = root.mnt;
1357     #else
1358     dentry = dget(current->fs->root);
1359     vfsmnt = mntget(current->fs->rootmnt);
1360     #endif
1361     read_unlock(&current->fs->lock);
1362     /***** CRITICAL SECTION END *****/
1363 kumaneko 2002 depth = ccs_root_depth(dentry, vfsmnt);
1364 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1365 kumaneko 1029 path_put(&root);
1366     #else
1367 kumaneko 1052 dput(dentry);
1368     mntput(vfsmnt);
1369 kumaneko 1029 #endif
1370     return depth;
1371     }
1372    
1373 kumaneko 1052 /**
1374 kumaneko 2002 * ccs_try_alt_exec - Try to start execute handler.
1375 kumaneko 1052 *
1376 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
1377 kumaneko 1319 * @handler: Pointer to the name of execute handler.
1378 kumaneko 1317 * @eh_path: Pointer to pointer to the name of execute handler.
1379 kumaneko 1052 *
1380     * Returns 0 on success, negative value otherwise.
1381     */
1382 kumaneko 2002 static int ccs_try_alt_exec(struct ccs_request_info *r,
1383     const struct ccs_path_info *handler, char **eh_path)
1384 kumaneko 1029 {
1385 kumaneko 1005 /*
1386     * Contents of modified bprm.
1387     * The envp[] in original bprm is moved to argv[] so that
1388     * the alternatively executed program won't be affected by
1389 kumaneko 1064 * some dangerous environment variables like LD_PRELOAD.
1390 kumaneko 1005 *
1391     * modified bprm->argc
1392     * = original bprm->argc + original bprm->envc + 7
1393     * modified bprm->envc
1394     * = 0
1395     *
1396     * modified bprm->argv[0]
1397 kumaneko 1029 * = the program's name specified by execute_handler
1398 kumaneko 1005 * modified bprm->argv[1]
1399     * = current->domain_info->domainname->name
1400     * modified bprm->argv[2]
1401     * = the current process's name
1402     * modified bprm->argv[3]
1403     * = the current process's information (e.g. uid/gid).
1404     * modified bprm->argv[4]
1405     * = original bprm->filename
1406     * modified bprm->argv[5]
1407     * = original bprm->argc in string expression
1408     * modified bprm->argv[6]
1409     * = original bprm->envc in string expression
1410     * modified bprm->argv[7]
1411     * = original bprm->argv[0]
1412     * ...
1413     * modified bprm->argv[bprm->argc + 6]
1414     * = original bprm->argv[bprm->argc - 1]
1415     * modified bprm->argv[bprm->argc + 7]
1416     * = original bprm->envp[0]
1417     * ...
1418     * modified bprm->argv[bprm->envc + bprm->argc + 6]
1419     * = original bprm->envp[bprm->envc - 1]
1420     */
1421 kumaneko 1657 struct linux_binprm *bprm = r->bprm;
1422 kumaneko 708 struct file *filp;
1423     int retval;
1424 kumaneko 1005 const int original_argc = bprm->argc;
1425     const int original_envc = bprm->envc;
1426     struct task_struct *task = current;
1427 kumaneko 1657 char *buffer = r->obj->tmp->buffer;
1428 kumaneko 1031 /* Allocate memory for execute handler's pathname. */
1429 kumaneko 1903 char *execute_handler = ccs_alloc(sizeof(struct ccs_page_buffer),
1430     false);
1431 kumaneko 1317 *eh_path = execute_handler;
1432 kumaneko 1052 if (!execute_handler)
1433     return -ENOMEM;
1434 kumaneko 1319 strncpy(execute_handler, handler->name,
1435 kumaneko 1052 sizeof(struct ccs_page_buffer) - 1);
1436 kumaneko 2002 ccs_unescape(execute_handler);
1437 kumaneko 1032
1438 kumaneko 1029 /* Close the requested program's dentry. */
1439 kumaneko 708 allow_write_access(bprm->file);
1440     fput(bprm->file);
1441     bprm->file = NULL;
1442 kumaneko 1005
1443 kumaneko 1031 { /* Adjust root directory for open_exec(). */
1444 kumaneko 2002 int depth = ccs_get_root_depth();
1445 kumaneko 1029 char *cp = execute_handler;
1446 kumaneko 1052 if (!*cp || *cp != '/')
1447     return -ENOENT;
1448 kumaneko 1029 while (depth) {
1449     cp = strchr(cp + 1, '/');
1450 kumaneko 1052 if (!cp)
1451     return -ENOENT;
1452 kumaneko 1029 depth--;
1453     }
1454     memmove(execute_handler, cp, strlen(cp) + 1);
1455     }
1456    
1457 kumaneko 1005 /* Move envp[] to argv[] */
1458     bprm->argc += bprm->envc;
1459     bprm->envc = 0;
1460    
1461     /* Set argv[6] */
1462     {
1463 kumaneko 1052 snprintf(buffer, sizeof(struct ccs_page_buffer) - 1, "%d",
1464     original_envc);
1465 kumaneko 1005 retval = copy_strings_kernel(1, &buffer, bprm);
1466 kumaneko 1052 if (retval < 0)
1467     goto out;
1468 kumaneko 1005 bprm->argc++;
1469     }
1470    
1471     /* Set argv[5] */
1472     {
1473 kumaneko 1052 snprintf(buffer, sizeof(struct ccs_page_buffer) - 1, "%d",
1474     original_argc);
1475 kumaneko 1005 retval = copy_strings_kernel(1, &buffer, bprm);
1476 kumaneko 1052 if (retval < 0)
1477     goto out;
1478 kumaneko 1005 bprm->argc++;
1479     }
1480    
1481     /* Set argv[4] */
1482     {
1483     retval = copy_strings_kernel(1, &bprm->filename, bprm);
1484 kumaneko 1052 if (retval < 0)
1485     goto out;
1486 kumaneko 1005 bprm->argc++;
1487     }
1488    
1489     /* Set argv[3] */
1490     {
1491     const u32 tomoyo_flags = task->tomoyo_flags;
1492 kumaneko 1052 snprintf(buffer, sizeof(struct ccs_page_buffer) - 1,
1493     "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
1494     "sgid=%d fsuid=%d fsgid=%d state[0]=%u "
1495     "state[1]=%u state[2]=%u",
1496 kumaneko 2016 (pid_t) sys_getpid(), current_uid(), current_gid(),
1497     current_euid(), current_egid(), current_suid(),
1498     current_sgid(), current_fsuid(), current_fsgid(),
1499     (u8) (tomoyo_flags >> 24), (u8) (tomoyo_flags >> 16),
1500     (u8) (tomoyo_flags >> 8));
1501 kumaneko 1005 retval = copy_strings_kernel(1, &buffer, bprm);
1502 kumaneko 1052 if (retval < 0)
1503     goto out;
1504 kumaneko 1005 bprm->argc++;
1505     }
1506    
1507     /* Set argv[2] */
1508     {
1509 kumaneko 1052 char *exe = (char *) ccs_get_exe();
1510 kumaneko 1005 if (exe) {
1511     retval = copy_strings_kernel(1, &exe, bprm);
1512     ccs_free(exe);
1513     } else {
1514 kumaneko 1052 snprintf(buffer, sizeof(struct ccs_page_buffer) - 1,
1515     "<unknown>");
1516 kumaneko 1005 retval = copy_strings_kernel(1, &buffer, bprm);
1517     }
1518 kumaneko 1052 if (retval < 0)
1519     goto out;
1520 kumaneko 1005 bprm->argc++;
1521     }
1522    
1523     /* Set argv[1] */
1524     {
1525 kumaneko 1052 strncpy(buffer, task->domain_info->domainname->name,
1526     sizeof(struct ccs_page_buffer) - 1);
1527 kumaneko 1005 retval = copy_strings_kernel(1, &buffer, bprm);
1528 kumaneko 1052 if (retval < 0)
1529     goto out;
1530 kumaneko 1005 bprm->argc++;
1531     }
1532    
1533     /* Set argv[0] */
1534     {
1535 kumaneko 1029 retval = copy_strings_kernel(1, &execute_handler, bprm);
1536 kumaneko 1052 if (retval < 0)
1537     goto out;
1538 kumaneko 1005 bprm->argc++;
1539     }
1540 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
1541     #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1542 kumaneko 1007 bprm->argv_len = bprm->exec - bprm->p;
1543     #endif
1544 kumaneko 1052 #endif
1545 kumaneko 1005
1546 kumaneko 1029 /* OK, now restart the process with execute handler program's dentry. */
1547     filp = open_exec(execute_handler);
1548 kumaneko 1005 if (IS_ERR(filp)) {
1549     retval = PTR_ERR(filp);
1550     goto out;
1551     }
1552 kumaneko 1052 bprm->file = filp;
1553 kumaneko 1029 bprm->filename = execute_handler;
1554 kumaneko 1052 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1555 kumaneko 1029 bprm->interp = execute_handler;
1556 kumaneko 708 #endif
1557 kumaneko 1029 retval = prepare_binprm(bprm);
1558 kumaneko 1052 if (retval < 0)
1559     goto out;
1560 kumaneko 1029 task->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
1561 kumaneko 2002 retval = ccs_find_next_domain(r, handler);
1562 kumaneko 1029 task->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
1563 kumaneko 1005 out:
1564     return retval;
1565 kumaneko 708 }
1566 kumaneko 581
1567 kumaneko 1052 /**
1568 kumaneko 2002 * ccs_find_execute_handler - Find an execute handler.
1569 kumaneko 1052 *
1570     * @type: Type of execute handler.
1571     *
1572 kumaneko 2002 * Returns pointer to "struct ccs_path_info" if found, NULL otherwise.
1573 kumaneko 1052 */
1574 kumaneko 2002 static const struct ccs_path_info *ccs_find_execute_handler(const u8 type)
1575 kumaneko 1029 {
1576 kumaneko 1064 struct task_struct *task = current;
1577     const struct domain_info *domain = task->domain_info;
1578 kumaneko 2002 struct ccs_acl_info *ptr;
1579 kumaneko 1064 /*
1580     * Don't use execute handler if the current process is
1581     * marked as execute handler to avoid infinite execute handler loop.
1582     */
1583     if (task->tomoyo_flags & TOMOYO_TASK_IS_EXECUTE_HANDLER)
1584     return NULL;
1585 kumaneko 1029 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
1586 kumaneko 2002 struct ccs_execute_handler_record *acl;
1587 kumaneko 1058 if (ptr->type != type)
1588 kumaneko 1052 continue;
1589 kumaneko 2002 acl = container_of(ptr, struct ccs_execute_handler_record,
1590     head);
1591 kumaneko 1029 return acl->handler;
1592     }
1593     return NULL;
1594     }
1595    
1596 kumaneko 1657 /* List of next_domain which is used for checking interpreter's permissions. */
1597 kumaneko 2002 struct ccs_execve_entry {
1598 kumaneko 1657 struct list_head list;
1599     struct task_struct *task;
1600     struct domain_info *next_domain;
1601     };
1602    
1603 kumaneko 2002 static LIST_HEAD(ccs_execve_list);
1604     static DEFINE_SPINLOCK(ccs_execve_list_lock);
1605 kumaneko 1657
1606 kumaneko 1052 /**
1607 kumaneko 1657 * ccs_register_next_domain - Remember next_domain.
1608     *
1609     * @next_domain: Pointer to "struct domain_info".
1610     *
1611     * Returns 0 on success, -ENOMEM otherwise.
1612     */
1613     static int ccs_register_next_domain(struct domain_info *next_domain)
1614     {
1615 kumaneko 2002 struct ccs_execve_entry *ee = kmalloc(sizeof(*ee), GFP_KERNEL);
1616 kumaneko 1657 if (!ee)
1617     return -ENOMEM;
1618     ee->task = current;
1619     ee->next_domain = next_domain;
1620     /***** CRITICAL SECTION START *****/
1621 kumaneko 2002 spin_lock(&ccs_execve_list_lock);
1622     list_add(&ee->list, &ccs_execve_list);
1623     spin_unlock(&ccs_execve_list_lock);
1624 kumaneko 1657 /***** CRITICAL SECTION END *****/
1625     return 0;
1626     }
1627    
1628     /**
1629     * ccs_fetch_next_domain - Fetch next_domain from the list.
1630     *
1631     * Returns pointer to "struct domain_info" which will be used if execve()
1632     * succeeds. This function does not return NULL.
1633     */
1634     struct domain_info *ccs_fetch_next_domain(void)
1635     {
1636     struct task_struct *task = current;
1637     struct domain_info *next_domain = task->domain_info;
1638 kumaneko 2002 struct ccs_execve_entry *p;
1639 kumaneko 1657 /***** CRITICAL SECTION START *****/
1640 kumaneko 2002 spin_lock(&ccs_execve_list_lock);
1641     list_for_each_entry(p, &ccs_execve_list, list) {
1642 kumaneko 1657 if (p->task != task)
1643     continue;
1644     next_domain = p->next_domain;
1645     break;
1646     }
1647 kumaneko 2002 spin_unlock(&ccs_execve_list_lock);
1648 kumaneko 1657 /***** CRITICAL SECTION END *****/
1649     return next_domain;
1650     }
1651    
1652     /**
1653     * ccs_unregister_next_domain - Forget next_domain.
1654     */
1655     static void ccs_unregister_next_domain(void)
1656     {
1657     struct task_struct *task = current;
1658 kumaneko 2002 struct ccs_execve_entry *p;
1659     struct ccs_execve_entry *ee = NULL;
1660 kumaneko 1657 /***** CRITICAL SECTION START *****/
1661 kumaneko 2002 spin_lock(&ccs_execve_list_lock);
1662     list_for_each_entry(p, &ccs_execve_list, list) {
1663 kumaneko 1657 if (p->task != task)
1664     continue;
1665     list_del(&p->list);
1666     ee = p;
1667     break;
1668     }
1669 kumaneko 2002 spin_unlock(&ccs_execve_list_lock);
1670 kumaneko 1657 /***** CRITICAL SECTION END *****/
1671     kfree(ee);
1672     }
1673    
1674     /**
1675 kumaneko 1052 * search_binary_handler_with_transition - Perform domain transition.
1676     *
1677     * @bprm: Pointer to "struct linux_binprm".
1678     * @regs: Pointer to "struct pt_regs".
1679     *
1680     * Returns result of search_binary_handler() on success,
1681     * negative value otherwise.
1682     */
1683     int search_binary_handler_with_transition(struct linux_binprm *bprm,
1684     struct pt_regs *regs)
1685 kumaneko 115 {
1686 kumaneko 1657 int retval;
1687 kumaneko 1029 struct task_struct *task = current;
1688 kumaneko 2002 const struct ccs_path_info *handler;
1689 kumaneko 1657 struct ccs_request_info r;
1690 kumaneko 2002 struct ccs_obj_info obj;
1691 kumaneko 1052 /*
1692 kumaneko 1317 * "eh_path" holds path to execute handler program.
1693 kumaneko 1052 * Thus, keep valid until search_binary_handler() finishes.
1694     */
1695 kumaneko 1317 char *eh_path = NULL;
1696 kumaneko 1903 struct ccs_page_buffer *tmp = ccs_alloc(sizeof(struct ccs_page_buffer),
1697     false);
1698 kumaneko 1657 memset(&obj, 0, sizeof(obj));
1699 kumaneko 2002 if (!ccs_sbin_init_started)
1700 kumaneko 1657 ccs_load_policy(bprm->filename);
1701 kumaneko 1317 if (!tmp)
1702 kumaneko 1052 return -ENOMEM;
1703 kumaneko 1657
1704     ccs_init_request_info(&r, NULL, CCS_TOMOYO_MAC_FOR_FILE);
1705     r.bprm = bprm;
1706     r.obj = &obj;
1707     obj.path1_dentry = bprm->file->f_dentry;
1708     obj.path1_vfsmnt = bprm->file->f_vfsmnt;
1709     obj.tmp = tmp;
1710    
1711 kumaneko 1578 /* Clear manager flag. */
1712     task->tomoyo_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
1713 kumaneko 2002 handler = ccs_find_execute_handler(TYPE_EXECUTE_HANDLER);
1714 kumaneko 1029 if (handler) {
1715 kumaneko 2002 retval = ccs_try_alt_exec(&r, handler, &eh_path);
1716 kumaneko 1052 if (!retval)
1717 kumaneko 2002 ccs_audit_execute_handler_log(true, handler->name,
1718     bprm);
1719 kumaneko 1052 goto ok;
1720 kumaneko 708 }
1721 kumaneko 2002 retval = ccs_find_next_domain(&r, NULL);
1722 kumaneko 1052 if (retval != -EPERM)
1723     goto ok;
1724 kumaneko 2002 handler = ccs_find_execute_handler(TYPE_DENIED_EXECUTE_HANDLER);
1725 kumaneko 1052 if (handler) {
1726 kumaneko 2002 retval = ccs_try_alt_exec(&r, handler, &eh_path);
1727 kumaneko 1052 if (!retval)
1728 kumaneko 2002 ccs_audit_execute_handler_log(false, handler->name,
1729     bprm);
1730 kumaneko 1052 }
1731     ok:
1732 kumaneko 1561 if (retval < 0)
1733 kumaneko 1052 goto out;
1734 kumaneko 1657 r.mode = ccs_check_flags(r.domain, CCS_TOMOYO_MAC_FOR_ENV);
1735 kumaneko 2002 retval = ccs_check_environ(&r);
1736 kumaneko 1561 if (retval < 0)
1737 kumaneko 1052 goto out;
1738 kumaneko 1657 retval = ccs_register_next_domain(r.domain);
1739     if (retval < 0)
1740     goto out;
1741 kumaneko 1029 task->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
1742     retval = search_binary_handler(bprm, regs);
1743     task->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC;
1744 kumaneko 1052 if (retval < 0)
1745 kumaneko 1657 goto out;
1746     /* Proceed to next domain if execution suceeded. */
1747     task->domain_info = r.domain;
1748     mb(); /* Make domain transition visible to other CPUs. */
1749 kumaneko 1064 /* Mark the current process as execute handler. */
1750 kumaneko 1657 if (handler)
1751 kumaneko 1064 task->tomoyo_flags |= TOMOYO_TASK_IS_EXECUTE_HANDLER;
1752     /* Mark the current process as normal process. */
1753     else
1754     task->tomoyo_flags &= ~TOMOYO_TASK_IS_EXECUTE_HANDLER;
1755 kumaneko 1657 out:
1756     ccs_unregister_next_domain();
1757 kumaneko 1317 ccs_free(eh_path);
1758     ccs_free(tmp);
1759 kumaneko 815 return retval;
1760 kumaneko 115 }
1761    
1762 kumaneko 1015 #else
1763    
1764 kumaneko 1052 /**
1765     * search_binary_handler_with_transition - Wrapper for search_binary_handler().
1766     *
1767     * @bprm: Pointer to "struct linux_binprm".
1768     * @regs: Pointer to "struct pt_regs".
1769     *
1770     * Returns the result of search_binary_handler().
1771     */
1772     int search_binary_handler_with_transition(struct linux_binprm *bprm,
1773     struct pt_regs *regs)
1774 kumaneko 1015 {
1775     #ifdef CONFIG_SAKURA
1776 kumaneko 1578 /* Clear manager flag. */
1777     current->tomoyo_flags &= ~CCS_TASK_IS_POLICY_MANAGER;
1778 kumaneko 1052 ccs_load_policy(bprm->filename);
1779 kumaneko 1012 #endif
1780 kumaneko 1015 return search_binary_handler(bprm, regs);
1781     }
1782 kumaneko 1012
1783 kumaneko 1015 #endif

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26