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

Subversion リポジトリの参照

Annotation of /branches/ccs-patch/security/ccsecurity/domain.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1780 - (hide annotations) (download) (as text)
Tue Nov 4 05:58:07 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: 46879 byte(s)


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

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