3 |
* |
* |
4 |
* Copyright (C) 2005-2009 NTT DATA CORPORATION |
* Copyright (C) 2005-2009 NTT DATA CORPORATION |
5 |
* |
* |
6 |
* Version: 1.7.0-pre 2009/08/08 |
* Version: 1.7.0-pre 2009/08/24 |
7 |
* |
* |
8 |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
9 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
36 |
LIST_HEAD(ccs_domain_list); |
LIST_HEAD(ccs_domain_list); |
37 |
|
|
38 |
/** |
/** |
|
* ccs_get_last_name - Get last component of a domainname. |
|
|
* |
|
|
* @domain: Pointer to "struct ccs_domain_info". |
|
|
* |
|
|
* Returns the last component of the domainname. |
|
|
*/ |
|
|
const char *ccs_get_last_name(const struct ccs_domain_info *domain) |
|
|
{ |
|
|
const char *cp0 = domain->domainname->name; |
|
|
const char *cp1 = strrchr(cp0, ' '); |
|
|
if (cp1) |
|
|
return cp1 + 1; |
|
|
return cp0; |
|
|
} |
|
|
|
|
|
/** |
|
39 |
* ccs_audit_execute_handler_log - Audit execute_handler log. |
* ccs_audit_execute_handler_log - Audit execute_handler log. |
40 |
* |
* |
41 |
* @ee: Pointer to "struct ccs_execve_entry". |
* @ee: Pointer to "struct ccs_execve_entry". |
48 |
{ |
{ |
49 |
struct ccs_request_info *r = &ee->r; |
struct ccs_request_info *r = &ee->r; |
50 |
const char *handler = ee->handler->name; |
const char *handler = ee->handler->name; |
51 |
r->mode = ccs_flags(r->domain, CCS_MAC_EXECUTE); |
r->mode = ccs_get_mode(r->profile, CCS_MAC_FILE_EXECUTE); |
52 |
return ccs_write_audit_log(true, r, "%s %s\n", |
return ccs_write_audit_log(true, r, "%s %s\n", |
53 |
is_default ? CCS_KEYWORD_EXECUTE_HANDLER : |
is_default ? CCS_KEYWORD_EXECUTE_HANDLER : |
54 |
CCS_KEYWORD_DENIED_EXECUTE_HANDLER, handler); |
CCS_KEYWORD_DENIED_EXECUTE_HANDLER, handler); |
65 |
{ |
{ |
66 |
int error; |
int error; |
67 |
struct ccs_request_info r; |
struct ccs_request_info r; |
68 |
ccs_init_request_info(&r, domain, CCS_MAC_EXECUTE); |
ccs_init_request_info(&r, domain, CCS_MAC_FILE_EXECUTE); |
69 |
error = ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile); |
error = ccs_write_audit_log(false, &r, "use_profile %u\n", r.profile); |
70 |
return error; |
return error; |
71 |
} |
} |
152 |
const char *domain = ""; |
const char *domain = ""; |
153 |
struct ccs_domain_initializer_entry *ptr; |
struct ccs_domain_initializer_entry *ptr; |
154 |
ptr = list_entry(pos, struct ccs_domain_initializer_entry, |
ptr = list_entry(pos, struct ccs_domain_initializer_entry, |
155 |
list); |
list); |
156 |
if (ptr->is_deleted) |
if (ptr->is_deleted) |
157 |
continue; |
continue; |
158 |
no = ptr->is_not ? "no_" : ""; |
no = ptr->is_not ? "no_" : ""; |
160 |
from = " from "; |
from = " from "; |
161 |
domain = ptr->domainname->name; |
domain = ptr->domainname->name; |
162 |
} |
} |
163 |
done = ccs_io_printf(head, |
done = ccs_io_printf(head, "%s" CCS_KEYWORD_INITIALIZE_DOMAIN |
164 |
"%s" CCS_KEYWORD_INITIALIZE_DOMAIN "%s%s%s\n", |
"%s%s%s\n", no, ptr->program->name, from, |
165 |
no, ptr->program->name, from, domain); |
domain); |
166 |
if (!done) |
if (!done) |
167 |
break; |
break; |
168 |
} |
} |
579 |
struct ccs_domain_info *domain = NULL; |
struct ccs_domain_info *domain = NULL; |
580 |
const char *old_domain_name = r->domain->domainname->name; |
const char *old_domain_name = r->domain->domainname->name; |
581 |
struct linux_binprm *bprm = ee->bprm; |
struct linux_binprm *bprm = ee->bprm; |
|
const u8 mode = r->mode; |
|
|
const bool is_enforce = (mode == 3); |
|
582 |
const u32 ccs_flags = current->ccs_flags; |
const u32 ccs_flags = current->ccs_flags; |
583 |
struct ccs_path_info rn = { }; /* real name */ |
struct ccs_path_info rn = { }; /* real name */ |
584 |
struct ccs_path_info ln; /* last name */ |
struct ccs_path_info ln; /* last name */ |
585 |
int retval; |
int retval; |
586 |
bool need_kfree = false; |
bool need_kfree = false; |
587 |
ccs_assert_read_lock(); |
ccs_assert_read_lock(); |
588 |
|
ln.name = ccs_last_word(old_domain_name); |
589 |
|
ccs_fill_path_info(&ln); |
590 |
retry: |
retry: |
591 |
current->ccs_flags = ccs_flags; |
current->ccs_flags = ccs_flags; |
592 |
r->cond = NULL; |
r->cond = NULL; |
593 |
|
if (need_kfree) { |
594 |
|
kfree(rn.name); |
595 |
|
need_kfree = false; |
596 |
|
} |
597 |
|
|
598 |
/* Get symlink's pathname of program. */ |
/* Get symlink's pathname of program. */ |
599 |
retval = ccs_symlink_path(bprm->filename, &rn); |
retval = ccs_symlink_path(bprm->filename, &rn); |
600 |
if (retval < 0) |
if (retval < 0) |
601 |
goto out; |
goto out; |
602 |
need_kfree = true; |
need_kfree = true; |
603 |
|
|
|
ln.name = ccs_get_last_name(r->domain); |
|
|
ccs_fill_path_info(&ln); |
|
|
|
|
604 |
if (handler) { |
if (handler) { |
605 |
if (ccs_pathcmp(&rn, handler)) { |
if (ccs_pathcmp(&rn, handler)) { |
606 |
/* Failed to verify execute handler. */ |
/* Failed to verify execute handler. */ |
612 |
} |
} |
613 |
goto out; |
goto out; |
614 |
} |
} |
615 |
goto calculate_domain; |
} else { |
|
} |
|
|
|
|
|
/* Check 'aggregator' directive. */ |
|
|
{ |
|
616 |
struct ccs_aggregator_entry *ptr; |
struct ccs_aggregator_entry *ptr; |
617 |
/* Is this program allowed to be aggregated? */ |
/* Check 'aggregator' directive. */ |
618 |
list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) { |
list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) { |
619 |
if (ptr->is_deleted || |
if (ptr->is_deleted || |
620 |
!ccs_path_matches_pattern(&rn, ptr->original_name)) |
!ccs_path_matches_pattern(&rn, ptr->original_name)) |
621 |
continue; |
continue; |
622 |
kfree(rn.name); |
kfree(rn.name); |
623 |
need_kfree = false; |
need_kfree = false; |
624 |
|
/* This is OK because it is read only. */ |
625 |
rn = *ptr->aggregated_name; |
rn = *ptr->aggregated_name; |
626 |
break; |
break; |
627 |
} |
} |
|
} |
|
628 |
|
|
629 |
/* Check execute permission. */ |
/* Check execute permission. */ |
630 |
r->mode = mode; |
retval = ccs_exec_perm(r, &rn); |
631 |
retval = ccs_exec_perm(r, &rn); |
if (retval == 1) |
632 |
if (retval == 1) |
goto retry; |
633 |
goto retry; |
if (retval < 0) |
634 |
if (retval < 0) |
goto out; |
635 |
goto out; |
} |
636 |
|
|
637 |
calculate_domain: |
/* Calculate domain to transit to. */ |
638 |
if (ccs_is_domain_initializer(r->domain->domainname, &rn, &ln)) { |
if (ccs_is_domain_initializer(r->domain->domainname, &rn, &ln)) { |
639 |
/* Transit to the child of ccs_kernel_domain domain. */ |
/* Transit to the child of ccs_kernel_domain domain. */ |
640 |
snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, ROOT_NAME " " "%s", |
snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, ROOT_NAME " " "%s", |
659 |
domain = ccs_find_domain(ee->tmp); |
domain = ccs_find_domain(ee->tmp); |
660 |
if (domain) |
if (domain) |
661 |
goto done; |
goto done; |
662 |
if (is_enforce) { |
if (r->mode == CCS_MAC_MODE_ENFORCING) { |
663 |
int error = ccs_supervisor(r, "# wants to create domain\n" |
int error = ccs_supervisor(r, "# wants to create domain\n" |
664 |
"%s\n", ee->tmp); |
"%s\n", ee->tmp); |
665 |
if (error == 1) |
if (error == 1) |
674 |
if (!domain) { |
if (!domain) { |
675 |
printk(KERN_WARNING "ERROR: Domain '%s' not defined.\n", |
printk(KERN_WARNING "ERROR: Domain '%s' not defined.\n", |
676 |
ee->tmp); |
ee->tmp); |
677 |
if (is_enforce) |
if (r->mode == CCS_MAC_MODE_ENFORCING) |
678 |
retval = -EPERM; |
retval = -EPERM; |
679 |
else { |
else { |
680 |
retval = 0; |
retval = 0; |
1249 |
ccs_load_policy(bprm->filename); |
ccs_load_policy(bprm->filename); |
1250 |
if (!ee) |
if (!ee) |
1251 |
return -ENOMEM; |
return -ENOMEM; |
1252 |
ccs_init_request_info(&ee->r, NULL, CCS_MAC_EXECUTE); |
ccs_init_request_info(&ee->r, NULL, CCS_MAC_FILE_EXECUTE); |
1253 |
ee->r.ee = ee; |
ee->r.ee = ee; |
1254 |
ee->bprm = bprm; |
ee->bprm = bprm; |
1255 |
ee->r.obj = &ee->obj; |
ee->r.obj = &ee->obj; |
1274 |
ok: |
ok: |
1275 |
if (retval < 0) |
if (retval < 0) |
1276 |
goto out; |
goto out; |
1277 |
ee->r.mode = ccs_flags(ee->r.domain, CCS_MAC_ENVIRON); |
ee->r.mode = ccs_get_mode(ee->r.profile, CCS_MAC_ENVIRON); |
1278 |
retval = ccs_environ(ee); |
retval = ccs_environ(ee); |
1279 |
if (retval < 0) |
if (retval < 0) |
1280 |
goto out; |
goto out; |