77 |
return error; |
return error; |
78 |
} |
} |
79 |
|
|
|
static void ccs_delete_type(struct ccs_domain_info *domain, u8 type) |
|
|
{ |
|
|
struct ccs_acl_info *ptr; |
|
|
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
|
|
if (ptr->type == type) |
|
|
ptr->is_deleted = true; |
|
|
} |
|
|
} |
|
|
|
|
80 |
/** |
/** |
81 |
* ccs_update_domain - Update an entry for domain policy. |
* ccs_update_domain - Update an entry for domain policy. |
82 |
* |
* |
101 |
{ |
{ |
102 |
int error = is_delete ? -ENOENT : -ENOMEM; |
int error = is_delete ? -ENOENT : -ENOMEM; |
103 |
struct ccs_acl_info *entry; |
struct ccs_acl_info *entry; |
|
/* |
|
|
* Only one "execute_handler" and "denied_execute_handler" can exist |
|
|
* in a domain. |
|
|
*/ |
|
104 |
const u8 type = new_entry->type; |
const u8 type = new_entry->type; |
105 |
const bool exclusive = !is_delete && |
const u8 i = type == CCS_TYPE_AUTO_EXECUTE_HANDLER || |
106 |
(type == CCS_TYPE_EXECUTE_HANDLER || |
type == CCS_TYPE_DENIED_EXECUTE_HANDLER || |
107 |
type == CCS_TYPE_DENIED_EXECUTE_HANDLER); |
type == CCS_TYPE_AUTO_TASK_ACL; |
108 |
if (mutex_lock_interruptible(&ccs_policy_lock)) |
if (mutex_lock_interruptible(&ccs_policy_lock)) |
109 |
return error; |
return error; |
110 |
list_for_each_entry_rcu(entry, &domain->acl_info_list, list) { |
list_for_each_entry_rcu(entry, &domain->acl_info_list[i], list) { |
111 |
if (!check_duplicate(entry, new_entry)) |
if (!check_duplicate(entry, new_entry)) |
112 |
continue; |
continue; |
|
if (exclusive) |
|
|
ccs_delete_type(domain, type); |
|
113 |
if (merge_duplicate) |
if (merge_duplicate) |
114 |
entry->is_deleted = merge_duplicate(entry, new_entry, |
entry->is_deleted = merge_duplicate(entry, new_entry, |
115 |
is_delete); |
is_delete); |
121 |
if (error && !is_delete) { |
if (error && !is_delete) { |
122 |
entry = ccs_commit_ok(new_entry, size); |
entry = ccs_commit_ok(new_entry, size); |
123 |
if (entry) { |
if (entry) { |
|
if (exclusive) |
|
|
ccs_delete_type(domain, type); |
|
124 |
if (entry->cond) |
if (entry->cond) |
125 |
atomic_inc(&entry->cond->head.users); |
atomic_inc(&entry->cond->head.users); |
126 |
list_add_tail_rcu(&entry->list, |
list_add_tail_rcu(&entry->list, |
127 |
&domain->acl_info_list); |
&domain->acl_info_list[i]); |
128 |
error = 0; |
error = 0; |
129 |
} |
} |
130 |
} |
} |
139 |
const struct ccs_domain_info *domain = ccs_current_domain(); |
const struct ccs_domain_info *domain = ccs_current_domain(); |
140 |
struct ccs_acl_info *ptr; |
struct ccs_acl_info *ptr; |
141 |
bool retried = false; |
bool retried = false; |
142 |
|
const u8 i = !check_entry; |
143 |
retry: |
retry: |
144 |
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
list_for_each_entry_rcu(ptr, &domain->acl_info_list[i], list) { |
145 |
if (ptr->is_deleted || ptr->type != r->param_type) |
if (ptr->is_deleted) |
146 |
continue; |
continue; |
147 |
if (check_entry(r, ptr) && ccs_condition(r, ptr->cond)) { |
if (ptr->type != r->param_type) |
148 |
r->cond = ptr->cond; |
continue; |
149 |
r->granted = true; |
if (check_entry && !check_entry(r, ptr)) |
150 |
return; |
continue; |
151 |
} |
if (!ccs_condition(r, ptr->cond)) |
152 |
|
continue; |
153 |
|
r->matched_acl = ptr; |
154 |
|
r->granted = true; |
155 |
|
return; |
156 |
} |
} |
157 |
if (!retried) { |
if (!retried) { |
158 |
retried = true; |
retried = true; |
422 |
if (!entry) { |
if (!entry) { |
423 |
entry = ccs_commit_ok(&e, sizeof(e)); |
entry = ccs_commit_ok(&e, sizeof(e)); |
424 |
if (entry) { |
if (entry) { |
425 |
INIT_LIST_HEAD(&entry->acl_info_list); |
INIT_LIST_HEAD(&entry->acl_info_list[0]); |
426 |
|
INIT_LIST_HEAD(&entry->acl_info_list[1]); |
427 |
list_add_tail_rcu(&entry->list, &ccs_domain_list); |
list_add_tail_rcu(&entry->list, &ccs_domain_list); |
428 |
created = true; |
created = true; |
429 |
} |
} |
460 |
struct ccs_domain_info * const old_domain = ccs_current_domain(); |
struct ccs_domain_info * const old_domain = ccs_current_domain(); |
461 |
struct linux_binprm *bprm = ee->bprm; |
struct linux_binprm *bprm = ee->bprm; |
462 |
struct task_struct *task = current; |
struct task_struct *task = current; |
|
const u32 ccs_flags = task->ccs_flags; |
|
463 |
struct ccs_path_info rn = { }; /* real name */ |
struct ccs_path_info rn = { }; /* real name */ |
464 |
int retval; |
int retval; |
465 |
bool need_kfree = false; |
bool need_kfree = false; |
466 |
retry: |
retry: |
467 |
current->ccs_flags = ccs_flags; |
r->matched_acl = NULL; |
|
r->cond = NULL; |
|
468 |
if (need_kfree) { |
if (need_kfree) { |
469 |
kfree(rn.name); |
kfree(rn.name); |
470 |
need_kfree = false; |
need_kfree = false; |
487 |
} |
} |
488 |
goto out; |
goto out; |
489 |
} |
} |
|
r->type = CCS_MAC_FILE_EXECUTE; |
|
|
r->mode = ccs_get_mode(r->profile, CCS_MAC_FILE_EXECUTE); |
|
|
r->granted = true; |
|
|
ccs_write_log(r, "%s %s\n", ee->handler_type == |
|
|
CCS_TYPE_DENIED_EXECUTE_HANDLER ? |
|
|
CCS_KEYWORD_DENIED_EXECUTE_HANDLER : |
|
|
CCS_KEYWORD_EXECUTE_HANDLER, handler->name); |
|
490 |
} else { |
} else { |
491 |
struct ccs_aggregator *ptr; |
struct ccs_aggregator *ptr; |
492 |
/* Check 'aggregator' directive. */ |
/* Check 'aggregator' directive. */ |
752 |
* = 0 |
* = 0 |
753 |
* |
* |
754 |
* modified bprm->argv[0] |
* modified bprm->argv[0] |
755 |
* = the program's name specified by execute_handler |
* = the program's name specified by *_execute_handler |
756 |
* modified bprm->argv[1] |
* modified bprm->argv[1] |
757 |
* = ccs_current_domain()->domainname->name |
* = ccs_current_domain()->domainname->name |
758 |
* modified bprm->argv[2] |
* modified bprm->argv[2] |
823 |
|
|
824 |
/* Set argv[3] */ |
/* Set argv[3] */ |
825 |
{ |
{ |
|
const u32 ccs_flags = task->ccs_flags; |
|
826 |
snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, |
snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, |
827 |
"pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d " |
"pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d " |
828 |
"sgid=%d fsuid=%d fsgid=%d state[0]=%u " |
"sgid=%d fsuid=%d fsgid=%d", |
|
"state[1]=%u state[2]=%u", |
|
829 |
(pid_t) ccsecurity_exports.sys_getpid(), |
(pid_t) ccsecurity_exports.sys_getpid(), |
830 |
current_uid(), current_gid(), current_euid(), |
current_uid(), current_gid(), current_euid(), |
831 |
current_egid(), current_suid(), current_sgid(), |
current_egid(), current_suid(), current_sgid(), |
832 |
current_fsuid(), current_fsgid(), |
current_fsuid(), current_fsgid()); |
|
(u8) (ccs_flags >> 24), (u8) (ccs_flags >> 16), |
|
|
(u8) (ccs_flags >> 8)); |
|
833 |
retval = ccs_copy_argv(ee->tmp, bprm); |
retval = ccs_copy_argv(ee->tmp, bprm); |
834 |
if (retval < 0) |
if (retval < 0) |
835 |
goto out; |
goto out; |
950 |
static bool ccs_find_execute_handler(struct ccs_execve *ee, const u8 type) |
static bool ccs_find_execute_handler(struct ccs_execve *ee, const u8 type) |
951 |
{ |
{ |
952 |
struct ccs_request_info *r = &ee->r; |
struct ccs_request_info *r = &ee->r; |
|
const struct ccs_domain_info *domain = ccs_current_domain(); |
|
|
struct ccs_acl_info *ptr; |
|
|
bool retried = false; |
|
953 |
/* |
/* |
954 |
* To avoid infinite execute handler loop, don't use execute handler |
* To avoid infinite execute handler loop, don't use execute handler |
955 |
* if the current process is marked as execute handler . |
* if the current process is marked as execute handler . |
956 |
*/ |
*/ |
957 |
if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) |
if (current->ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER) |
958 |
return false; |
return false; |
959 |
retry: |
r->param_type = type; |
960 |
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { |
ccs_check_acl(r, NULL); |
961 |
struct ccs_execute_handler *acl; |
if (!r->granted) |
962 |
if (ptr->type != type || !ccs_condition(r, ptr->cond)) |
return false; |
963 |
continue; |
ee->handler = container_of(r->matched_acl, struct ccs_handler_acl, |
964 |
acl = container_of(ptr, struct ccs_execute_handler, head); |
head)->handler; |
965 |
ee->handler = acl->handler; |
return true; |
|
ee->handler_type = type; |
|
|
r->cond = ptr->cond; |
|
|
return true; |
|
|
} |
|
|
if (!retried) { |
|
|
retried = true; |
|
|
domain = &ccs_acl_group[domain->group]; |
|
|
goto retry; |
|
|
} |
|
|
return false; |
|
966 |
} |
} |
967 |
|
|
968 |
#ifdef CONFIG_MMU |
#ifdef CONFIG_MMU |
1060 |
* No need to call ccs_environ() for execute handler because envp[] is |
* No need to call ccs_environ() for execute handler because envp[] is |
1061 |
* moved to argv[]. |
* moved to argv[]. |
1062 |
*/ |
*/ |
1063 |
if (ccs_find_execute_handler(ee, CCS_TYPE_EXECUTE_HANDLER)) |
if (ccs_find_execute_handler(ee, CCS_TYPE_AUTO_EXECUTE_HANDLER)) |
1064 |
return ccs_try_alt_exec(ee); |
return ccs_try_alt_exec(ee); |
1065 |
retval = ccs_find_next_domain(ee); |
retval = ccs_find_next_domain(ee); |
1066 |
if (retval == -EPERM) { |
if (retval == -EPERM) { |