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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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