526 |
static int ccs_read_manager_policy(struct ccs_io_buffer *head) |
static int ccs_read_manager_policy(struct ccs_io_buffer *head) |
527 |
{ |
{ |
528 |
struct list_head *pos; |
struct list_head *pos; |
529 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
530 |
if (head->read_eof) |
if (head->read_eof) |
531 |
return 0; |
return 0; |
532 |
list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) { |
list_for_each_cookie(pos, head->read_var2, &ccs_policy_manager_list) { |
557 |
const struct ccs_path_info *domainname |
const struct ccs_path_info *domainname |
558 |
= ccs_current_domain()->domainname; |
= ccs_current_domain()->domainname; |
559 |
bool found = false; |
bool found = false; |
560 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
561 |
if (!ccs_policy_loaded) |
if (!ccs_policy_loaded) |
562 |
return true; |
return true; |
563 |
if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER) |
if (task->ccs_flags & CCS_TASK_IS_POLICY_MANAGER) |
638 |
{ |
{ |
639 |
unsigned int pid; |
unsigned int pid; |
640 |
struct ccs_domain_info *domain = NULL; |
struct ccs_domain_info *domain = NULL; |
641 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
642 |
if (!strcmp(data, "allow_execute")) { |
if (!strcmp(data, "allow_execute")) { |
643 |
head->read_execute_only = true; |
head->read_execute_only = true; |
644 |
return true; |
return true; |
999 |
} |
} |
1000 |
|
|
1001 |
/** |
/** |
1002 |
* ccs_print_path_number_number_acl - Print a path_number_number ACL entry. |
* ccs_print_path_number3_acl - Print a path_number3 ACL entry. |
1003 |
* |
* |
1004 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
1005 |
* @ptr: Pointer to "struct ccs_path_number_number_acl". |
* @ptr: Pointer to "struct ccs_path_number3_acl". |
1006 |
* @cond: Pointer to "struct ccs_condition". May be NULL. |
* @cond: Pointer to "struct ccs_condition". May be NULL. |
1007 |
* |
* |
1008 |
* Returns true on success, false otherwise. |
* Returns true on success, false otherwise. |
1009 |
*/ |
*/ |
1010 |
static bool ccs_print_path_number_number_acl(struct ccs_io_buffer *head, |
static bool ccs_print_path_number3_acl(struct ccs_io_buffer *head, |
1011 |
struct ccs_path_number_number_acl *ptr, |
struct ccs_path_number3_acl *ptr, |
1012 |
const struct ccs_condition *cond) |
const struct ccs_condition *cond) |
1013 |
{ |
{ |
1014 |
int pos; |
int pos; |
1015 |
u8 bit; |
u8 bit; |
1016 |
const u16 perm = ptr->perm; |
const u16 perm = ptr->perm; |
1017 |
for (bit = head->read_bit; bit < CCS_MAX_PATH_NUMBER_NUMBER_OPERATION; |
for (bit = head->read_bit; bit < CCS_MAX_PATH_NUMBER3_OPERATION; |
1018 |
bit++) { |
bit++) { |
1019 |
if (!(perm & (1 << bit))) |
if (!(perm & (1 << bit))) |
1020 |
continue; |
continue; |
1021 |
pos = head->read_avail; |
pos = head->read_avail; |
1022 |
if (!ccs_io_printf(head, "allow_%s", |
if (!ccs_io_printf(head, "allow_%s", |
1023 |
ccs_path_number_number2keyword(bit)) || |
ccs_path_number32keyword(bit)) || |
1024 |
!ccs_print_name_union(head, &ptr->name) || |
!ccs_print_name_union(head, &ptr->name) || |
1025 |
|
!ccs_print_number_union(head, &ptr->mode) || |
1026 |
!ccs_print_number_union(head, &ptr->major) || |
!ccs_print_number_union(head, &ptr->major) || |
1027 |
!ccs_print_number_union(head, &ptr->minor) || |
!ccs_print_number_union(head, &ptr->minor) || |
1028 |
!ccs_print_condition(head, cond)) { |
!ccs_print_condition(head, cond)) { |
1036 |
} |
} |
1037 |
|
|
1038 |
/** |
/** |
1039 |
* ccs_print_path_path_acl - Print a double path ACL entry. |
* ccs_print_path2_acl - Print a double path ACL entry. |
1040 |
* |
* |
1041 |
* @head: Pointer to "struct ccs_io_buffer". |
* @head: Pointer to "struct ccs_io_buffer". |
1042 |
* @ptr: Pointer to "struct ccs_path_path_acl". |
* @ptr: Pointer to "struct ccs_path2_acl". |
1043 |
* @cond: Pointer to "struct ccs_condition". May be NULL. |
* @cond: Pointer to "struct ccs_condition". May be NULL. |
1044 |
* |
* |
1045 |
* Returns true on success, false otherwise. |
* Returns true on success, false otherwise. |
1046 |
*/ |
*/ |
1047 |
static bool ccs_print_path_path_acl(struct ccs_io_buffer *head, |
static bool ccs_print_path2_acl(struct ccs_io_buffer *head, |
1048 |
struct ccs_path_path_acl *ptr, |
struct ccs_path2_acl *ptr, |
1049 |
const struct ccs_condition *cond) |
const struct ccs_condition *cond) |
1050 |
{ |
{ |
1051 |
int pos; |
int pos; |
1052 |
u8 bit; |
u8 bit; |
1053 |
const u8 perm = ptr->perm; |
const u8 perm = ptr->perm; |
1054 |
for (bit = head->read_bit; bit < CCS_MAX_PATH_PATH_OPERATION; bit++) { |
for (bit = head->read_bit; bit < CCS_MAX_PATH2_OPERATION; bit++) { |
1055 |
if (!(perm & (1 << bit))) |
if (!(perm & (1 << bit))) |
1056 |
continue; |
continue; |
1057 |
pos = head->read_avail; |
pos = head->read_avail; |
1058 |
if (!ccs_io_printf(head, "allow_%s", |
if (!ccs_io_printf(head, "allow_%s", |
1059 |
ccs_path_path2keyword(bit)) || |
ccs_path22keyword(bit)) || |
1060 |
!ccs_print_name_union(head, &ptr->name1) || |
!ccs_print_name_union(head, &ptr->name1) || |
1061 |
!ccs_print_name_union(head, &ptr->name2) || |
!ccs_print_name_union(head, &ptr->name2) || |
1062 |
!ccs_print_condition(head, cond)) { |
!ccs_print_condition(head, cond)) { |
1418 |
} |
} |
1419 |
if (head->read_execute_only) |
if (head->read_execute_only) |
1420 |
return true; |
return true; |
1421 |
if (acl_type == CCS_TYPE_PATH_NUMBER_NUMBER_ACL) { |
if (acl_type == CCS_TYPE_PATH_NUMBER3_ACL) { |
1422 |
struct ccs_path_number_number_acl *acl |
struct ccs_path_number3_acl *acl |
1423 |
= container_of(ptr, struct ccs_path_number_number_acl, head); |
= container_of(ptr, struct ccs_path_number3_acl, head); |
1424 |
return ccs_print_path_number_number_acl(head, acl, cond); |
return ccs_print_path_number3_acl(head, acl, cond); |
1425 |
} |
} |
1426 |
if (acl_type == CCS_TYPE_PATH_PATH_ACL) { |
if (acl_type == CCS_TYPE_PATH2_ACL) { |
1427 |
struct ccs_path_path_acl *acl |
struct ccs_path2_acl *acl |
1428 |
= container_of(ptr, struct ccs_path_path_acl, |
= container_of(ptr, struct ccs_path2_acl, |
1429 |
head); |
head); |
1430 |
return ccs_print_path_path_acl(head, acl, cond); |
return ccs_print_path2_acl(head, acl, cond); |
1431 |
} |
} |
1432 |
if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) { |
if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) { |
1433 |
struct ccs_path_number_acl *acl |
struct ccs_path_number_acl *acl |
1495 |
{ |
{ |
1496 |
struct list_head *dpos; |
struct list_head *dpos; |
1497 |
struct list_head *apos; |
struct list_head *apos; |
1498 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
1499 |
if (head->read_eof) |
if (head->read_eof) |
1500 |
return 0; |
return 0; |
1501 |
if (head->read_step == 0) |
if (head->read_step == 0) |
1573 |
char *cp = strchr(data, ' '); |
char *cp = strchr(data, ' '); |
1574 |
struct ccs_domain_info *domain; |
struct ccs_domain_info *domain; |
1575 |
unsigned int profile; |
unsigned int profile; |
1576 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
1577 |
if (!cp) |
if (!cp) |
1578 |
return -EINVAL; |
return -EINVAL; |
1579 |
*cp = '\0'; |
*cp = '\0'; |
1605 |
static int ccs_read_domain_profile(struct ccs_io_buffer *head) |
static int ccs_read_domain_profile(struct ccs_io_buffer *head) |
1606 |
{ |
{ |
1607 |
struct list_head *pos; |
struct list_head *pos; |
1608 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
1609 |
if (head->read_eof) |
if (head->read_eof) |
1610 |
return 0; |
return 0; |
1611 |
list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) { |
list_for_each_cookie(pos, head->read_var1, &ccs_domain_list) { |
1653 |
struct task_struct *p; |
struct task_struct *p; |
1654 |
struct ccs_domain_info *domain = NULL; |
struct ccs_domain_info *domain = NULL; |
1655 |
u32 ccs_flags = 0; |
u32 ccs_flags = 0; |
1656 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
1657 |
/* Accessing write_buf is safe because head->io_sem is held. */ |
/* Accessing write_buf is safe because head->io_sem is held. */ |
1658 |
if (!buf) |
if (!buf) |
1659 |
goto done; /* Do nothing if open(O_RDONLY). */ |
goto done; /* Do nothing if open(O_RDONLY). */ |
1744 |
*/ |
*/ |
1745 |
static int ccs_read_exception_policy(struct ccs_io_buffer *head) |
static int ccs_read_exception_policy(struct ccs_io_buffer *head) |
1746 |
{ |
{ |
1747 |
ccs_check_read_lock(); |
ccs_assert_read_lock(); |
1748 |
if (!head->read_eof) { |
if (!head->read_eof) { |
1749 |
switch (head->read_step) { |
switch (head->read_step) { |
1750 |
case 0: |
case 0: |
1877 |
int len = 256; |
int len = 256; |
1878 |
char *realpath = NULL; |
char *realpath = NULL; |
1879 |
char *argv0 = NULL; |
char *argv0 = NULL; |
1880 |
if (ccs_check_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) { |
if (ccs_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) { |
1881 |
struct file *file = ee->bprm->file; |
struct file *file = ee->bprm->file; |
1882 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) |
1883 |
struct path path = { file->f_vfsmnt, file->f_dentry }; |
struct path path = { file->f_vfsmnt, file->f_dentry }; |
1888 |
if (realpath) |
if (realpath) |
1889 |
len += strlen(realpath) + 17; |
len += strlen(realpath) + 17; |
1890 |
} |
} |
1891 |
if (ccs_check_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) { |
if (ccs_flags(NULL, CCS_AUTOLEARN_EXEC_REALPATH)) { |
1892 |
if (ccs_get_argv0(ee)) { |
if (ccs_get_argv0(ee)) { |
1893 |
argv0 = ee->tmp; |
argv0 = ee->tmp; |
1894 |
len += strlen(argv0) + 16; |
len += strlen(argv0) + 16; |
1942 |
static atomic_t ccs_query_observers = ATOMIC_INIT(0); |
static atomic_t ccs_query_observers = ATOMIC_INIT(0); |
1943 |
|
|
1944 |
/** |
/** |
1945 |
* ccs_check_supervisor - Ask for the supervisor's decision. |
* ccs_supervisor - Ask for the supervisor's decision. |
1946 |
* |
* |
1947 |
* @r: Pointer to "struct ccs_request_info". |
* @r: Pointer to "struct ccs_request_info". |
1948 |
* @fmt: The printf()'s format string, followed by parameters. |
* @fmt: The printf()'s format string, followed by parameters. |
1952 |
* retry the access request which violated the policy in enforcing mode, |
* retry the access request which violated the policy in enforcing mode, |
1953 |
* 0 if it is not in enforcing mode, -EPERM otherwise. |
* 0 if it is not in enforcing mode, -EPERM otherwise. |
1954 |
*/ |
*/ |
1955 |
int ccs_check_supervisor(struct ccs_request_info *r, const char *fmt, ...) |
int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...) |
1956 |
{ |
{ |
1957 |
va_list args; |
va_list args; |
1958 |
int error = -EPERM; |
int error = -EPERM; |
1998 |
int i; |
int i; |
1999 |
if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) |
if (current->ccs_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) |
2000 |
return -EPERM; |
return -EPERM; |
2001 |
for (i = 0; i < ccs_check_flags(r->domain, CCS_SLEEP_PERIOD); |
for (i = 0; i < ccs_flags(r->domain, CCS_SLEEP_PERIOD); |
2002 |
i++) { |
i++) { |
2003 |
set_current_state(TASK_INTERRUPTIBLE); |
set_current_state(TASK_INTERRUPTIBLE); |
2004 |
schedule_timeout(HZ / 10); |
schedule_timeout(HZ / 10); |
2396 |
ccs_read_control(file, NULL, 0); |
ccs_read_control(file, NULL, 0); |
2397 |
/* |
/* |
2398 |
* If the file is /proc/ccs/query , increment the observer counter. |
* If the file is /proc/ccs/query , increment the observer counter. |
2399 |
* The obserber counter is used by ccs_check_supervisor() to see if |
* The obserber counter is used by ccs_supervisor() to see if |
2400 |
* there is some process monitoring /proc/ccs/query. |
* there is some process monitoring /proc/ccs/query. |
2401 |
*/ |
*/ |
2402 |
else if (type == CCS_QUERY) |
else if (type == CCS_QUERY) |