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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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