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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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