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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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