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

Subversion リポジトリの参照

Annotation of /trunk/1.7.x/ccs-patch/security/ccsecurity/domain.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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