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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2577 - (hide annotations) (download) (as text)
Thu May 21 08:25:02 2009 UTC (15 years ago) by kumaneko
Original Path: branches/ccs-patch/fs/tomoyo_domain.c
File MIME type: text/x-csrc
File size: 45044 byte(s)


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

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