52 |
} |
} |
53 |
|
|
54 |
/** |
/** |
|
* ccs_add_domain_acl - Add the given ACL to the given domain. |
|
|
* |
|
|
* @domain: Pointer to "struct ccs_domain_info". May be NULL. |
|
|
* @acl: Pointer to "struct ccs_acl_info". |
|
|
* |
|
|
* Returns 0. |
|
|
*/ |
|
|
int ccs_add_domain_acl(struct ccs_domain_info *domain, struct ccs_acl_info *acl) |
|
|
{ |
|
|
if (domain) { |
|
|
if (acl->cond) |
|
|
atomic_inc(&acl->cond->users); |
|
|
list_add_tail_rcu(&acl->list, &domain->acl_info_list); |
|
|
} else { |
|
|
acl->type &= ~CCS_ACL_DELETED; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
/** |
|
|
* ccs_del_domain_acl - Delete the given ACL from the domain. |
|
|
* |
|
|
* @acl: Pointer to "struct ccs_acl_info". May be NULL. |
|
|
* |
|
|
* Returns 0. |
|
|
*/ |
|
|
int ccs_del_domain_acl(struct ccs_acl_info *acl) |
|
|
{ |
|
|
if (acl) |
|
|
acl->type |= CCS_ACL_DELETED; |
|
|
return 0; |
|
|
} |
|
|
|
|
|
/** |
|
55 |
* ccs_audit_execute_handler_log - Audit execute_handler log. |
* ccs_audit_execute_handler_log - Audit execute_handler log. |
56 |
* |
* |
57 |
* @ee: Pointer to "struct ccs_execve_entry". |
* @ee: Pointer to "struct ccs_execve_entry". |
106 |
{ |
{ |
107 |
struct ccs_domain_initializer_entry *entry = NULL; |
struct ccs_domain_initializer_entry *entry = NULL; |
108 |
struct ccs_domain_initializer_entry *ptr; |
struct ccs_domain_initializer_entry *ptr; |
109 |
const struct ccs_path_info *saved_program; |
struct ccs_domain_initializer_entry e = { .is_not = is_not }; |
|
const struct ccs_path_info *saved_domainname = NULL; |
|
110 |
int error = is_delete ? -ENOENT : -ENOMEM; |
int error = is_delete ? -ENOENT : -ENOMEM; |
|
bool is_last_name = false; |
|
111 |
if (!ccs_is_correct_path(program, 1, -1, -1)) |
if (!ccs_is_correct_path(program, 1, -1, -1)) |
112 |
return -EINVAL; /* No patterns allowed. */ |
return -EINVAL; /* No patterns allowed. */ |
113 |
if (domainname) { |
if (domainname) { |
114 |
if (!ccs_is_domain_def(domainname) && |
if (!ccs_is_domain_def(domainname) && |
115 |
ccs_is_correct_path(domainname, 1, -1, -1)) |
ccs_is_correct_path(domainname, 1, -1, -1)) |
116 |
is_last_name = true; |
e.is_last_name = true; |
117 |
else if (!ccs_is_correct_domain(domainname)) |
else if (!ccs_is_correct_domain(domainname)) |
118 |
return -EINVAL; |
return -EINVAL; |
119 |
saved_domainname = ccs_get_name(domainname); |
e.domainname = ccs_get_name(domainname); |
120 |
if (!saved_domainname) |
if (!e.domainname) |
121 |
return -ENOMEM; |
goto out; |
122 |
} |
} |
123 |
saved_program = ccs_get_name(program); |
e.program = ccs_get_name(program); |
124 |
if (!saved_program) { |
if (!e.program) |
125 |
ccs_put_name(saved_domainname); |
goto out; |
|
return -ENOMEM; |
|
|
} |
|
126 |
if (!is_delete) |
if (!is_delete) |
127 |
entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
entry = kmalloc(sizeof(e), GFP_KERNEL); |
128 |
mutex_lock(&ccs_policy_lock); |
mutex_lock(&ccs_policy_lock); |
129 |
list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list, list) { |
list_for_each_entry_rcu(ptr, &ccs_domain_initializer_list, list) { |
130 |
if (ptr->is_not != is_not || |
if (ccs_memcmp(ptr, &e, offsetof(typeof(e), is_not), |
131 |
ptr->domainname != saved_domainname || |
sizeof(e))) |
|
ptr->program != saved_program) |
|
132 |
continue; |
continue; |
133 |
ptr->is_deleted = is_delete; |
ptr->is_deleted = is_delete; |
134 |
error = 0; |
error = 0; |
135 |
break; |
break; |
136 |
} |
} |
137 |
if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) { |
if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) { |
|
entry->domainname = saved_domainname; |
|
|
saved_domainname = NULL; |
|
|
entry->program = saved_program; |
|
|
saved_program = NULL; |
|
|
entry->is_not = is_not; |
|
|
entry->is_last_name = is_last_name; |
|
138 |
list_add_tail_rcu(&entry->list, &ccs_domain_initializer_list); |
list_add_tail_rcu(&entry->list, &ccs_domain_initializer_list); |
139 |
entry = NULL; |
entry = NULL; |
140 |
error = 0; |
error = 0; |
141 |
} |
} |
142 |
mutex_unlock(&ccs_policy_lock); |
mutex_unlock(&ccs_policy_lock); |
143 |
ccs_put_name(saved_domainname); |
out: |
144 |
ccs_put_name(saved_program); |
ccs_put_name(e.domainname); |
145 |
|
ccs_put_name(e.program); |
146 |
kfree(entry); |
kfree(entry); |
147 |
return error; |
return error; |
148 |
} |
} |
269 |
{ |
{ |
270 |
struct ccs_domain_keeper_entry *entry = NULL; |
struct ccs_domain_keeper_entry *entry = NULL; |
271 |
struct ccs_domain_keeper_entry *ptr; |
struct ccs_domain_keeper_entry *ptr; |
272 |
const struct ccs_path_info *saved_domainname; |
struct ccs_domain_keeper_entry e = { .is_not = is_not }; |
|
const struct ccs_path_info *saved_program = NULL; |
|
273 |
int error = is_delete ? -ENOENT : -ENOMEM; |
int error = is_delete ? -ENOENT : -ENOMEM; |
|
bool is_last_name = false; |
|
274 |
if (!ccs_is_domain_def(domainname) && |
if (!ccs_is_domain_def(domainname) && |
275 |
ccs_is_correct_path(domainname, 1, -1, -1)) |
ccs_is_correct_path(domainname, 1, -1, -1)) |
276 |
is_last_name = true; |
e.is_last_name = true; |
277 |
else if (!ccs_is_correct_domain(domainname)) |
else if (!ccs_is_correct_domain(domainname)) |
278 |
return -EINVAL; |
return -EINVAL; |
279 |
if (program) { |
if (program) { |
280 |
if (!ccs_is_correct_path(program, 1, -1, -1)) |
if (!ccs_is_correct_path(program, 1, -1, -1)) |
281 |
return -EINVAL; |
return -EINVAL; |
282 |
saved_program = ccs_get_name(program); |
e.program = ccs_get_name(program); |
283 |
if (!saved_program) |
if (!e.program) |
284 |
return -ENOMEM; |
goto out; |
285 |
} |
} |
286 |
saved_domainname = ccs_get_name(domainname); |
e.domainname = ccs_get_name(domainname); |
287 |
if (!saved_domainname) { |
if (!e.domainname) |
288 |
ccs_put_name(saved_program); |
goto out; |
|
return -ENOMEM; |
|
|
} |
|
289 |
if (!is_delete) |
if (!is_delete) |
290 |
entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
entry = kmalloc(sizeof(e), GFP_KERNEL); |
291 |
mutex_lock(&ccs_policy_lock); |
mutex_lock(&ccs_policy_lock); |
292 |
list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) { |
list_for_each_entry_rcu(ptr, &ccs_domain_keeper_list, list) { |
293 |
if (ptr->is_not != is_not || |
if (ccs_memcmp(ptr, &e, offsetof(typeof(e), is_not), |
294 |
ptr->domainname != saved_domainname || |
sizeof(e))) |
|
ptr->program != saved_program) |
|
295 |
continue; |
continue; |
296 |
ptr->is_deleted = is_delete; |
ptr->is_deleted = is_delete; |
297 |
error = 0; |
error = 0; |
298 |
break; |
break; |
299 |
} |
} |
300 |
if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) { |
if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) { |
|
entry->domainname = saved_domainname; |
|
|
saved_domainname = NULL; |
|
|
entry->program = saved_program; |
|
|
saved_program = NULL; |
|
|
entry->is_not = is_not; |
|
|
entry->is_last_name = is_last_name; |
|
301 |
list_add_tail_rcu(&entry->list, &ccs_domain_keeper_list); |
list_add_tail_rcu(&entry->list, &ccs_domain_keeper_list); |
302 |
entry = NULL; |
entry = NULL; |
303 |
error = 0; |
error = 0; |
304 |
} |
} |
305 |
mutex_unlock(&ccs_policy_lock); |
mutex_unlock(&ccs_policy_lock); |
306 |
ccs_put_name(saved_domainname); |
out: |
307 |
ccs_put_name(saved_program); |
ccs_put_name(e.domainname); |
308 |
|
ccs_put_name(e.program); |
309 |
kfree(entry); |
kfree(entry); |
310 |
return error; |
return error; |
311 |
} |
} |
425 |
{ |
{ |
426 |
struct ccs_aggregator_entry *entry = NULL; |
struct ccs_aggregator_entry *entry = NULL; |
427 |
struct ccs_aggregator_entry *ptr; |
struct ccs_aggregator_entry *ptr; |
428 |
const struct ccs_path_info *saved_original_name; |
struct ccs_aggregator_entry e = { }; |
|
const struct ccs_path_info *saved_aggregated_name; |
|
429 |
int error = is_delete ? -ENOENT : -ENOMEM; |
int error = is_delete ? -ENOENT : -ENOMEM; |
430 |
if (!ccs_is_correct_path(original_name, 1, 0, -1) || |
if (!ccs_is_correct_path(original_name, 1, 0, -1) || |
431 |
!ccs_is_correct_path(aggregated_name, 1, -1, -1)) |
!ccs_is_correct_path(aggregated_name, 1, -1, -1)) |
432 |
return -EINVAL; |
return -EINVAL; |
433 |
saved_original_name = ccs_get_name(original_name); |
e.original_name = ccs_get_name(original_name); |
434 |
saved_aggregated_name = ccs_get_name(aggregated_name); |
e.aggregated_name = ccs_get_name(aggregated_name); |
435 |
if (!saved_original_name || !saved_aggregated_name) { |
if (!e.original_name || !e.aggregated_name) |
436 |
ccs_put_name(saved_original_name); |
goto out; |
|
ccs_put_name(saved_aggregated_name); |
|
|
return -ENOMEM; |
|
|
} |
|
437 |
if (!is_delete) |
if (!is_delete) |
438 |
entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
entry = kmalloc(sizeof(e), GFP_KERNEL); |
439 |
mutex_lock(&ccs_policy_lock); |
mutex_lock(&ccs_policy_lock); |
440 |
list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) { |
list_for_each_entry_rcu(ptr, &ccs_aggregator_list, list) { |
441 |
if (ptr->original_name != saved_original_name || |
if (ccs_memcmp(ptr, &e, offsetof(typeof(e), original_name), |
442 |
ptr->aggregated_name != saved_aggregated_name) |
sizeof(e))) |
443 |
continue; |
continue; |
444 |
ptr->is_deleted = is_delete; |
ptr->is_deleted = is_delete; |
445 |
error = 0; |
error = 0; |
446 |
break; |
break; |
447 |
} |
} |
448 |
if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) { |
if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) { |
|
entry->original_name = saved_original_name; |
|
|
saved_original_name = NULL; |
|
|
entry->aggregated_name = saved_aggregated_name; |
|
|
saved_aggregated_name = NULL; |
|
449 |
list_add_tail_rcu(&entry->list, &ccs_aggregator_list); |
list_add_tail_rcu(&entry->list, &ccs_aggregator_list); |
450 |
entry = NULL; |
entry = NULL; |
451 |
error = 0; |
error = 0; |
452 |
} |
} |
453 |
mutex_unlock(&ccs_policy_lock); |
mutex_unlock(&ccs_policy_lock); |
454 |
ccs_put_name(saved_original_name); |
out: |
455 |
ccs_put_name(saved_aggregated_name); |
ccs_put_name(e.original_name); |
456 |
|
ccs_put_name(e.aggregated_name); |
457 |
kfree(entry); |
kfree(entry); |
458 |
return error; |
return error; |
459 |
} |
} |