3 |
* |
* |
4 |
* Common functions for SAKURA and TOMOYO. |
* Common functions for SAKURA and TOMOYO. |
5 |
* |
* |
6 |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
* Copyright (C) 2005-2008 NTT DATA CORPORATION |
7 |
* |
* |
8 |
* Version: 1.5.2-pre 2007/11/29 |
* Version: 1.5.3-pre 2008/01/02 |
9 |
* |
* |
10 |
* 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. |
11 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
52 |
/************************* VARIABLES *************************/ |
/************************* VARIABLES *************************/ |
53 |
|
|
54 |
/* /sbin/init started? */ |
/* /sbin/init started? */ |
55 |
int sbin_init_started = 0; |
bool sbin_init_started = 0; |
56 |
|
|
57 |
const char *ccs_log_level = KERN_DEBUG; |
const char *ccs_log_level = KERN_DEBUG; |
58 |
|
|
131 |
* Check whether the given filename follows the naming rules. |
* Check whether the given filename follows the naming rules. |
132 |
* Returns nonzero if follows, zero otherwise. |
* Returns nonzero if follows, zero otherwise. |
133 |
*/ |
*/ |
134 |
bool IsCorrectPath(const char *filename, const int start_type, const int pattern_type, const int end_type, const char *function) |
bool IsCorrectPath(const char *filename, const s8 start_type, const s8 pattern_type, const s8 end_type, const char *function) |
135 |
{ |
{ |
136 |
int contains_pattern = 0; |
int contains_pattern = 0; |
137 |
char c, d, e; |
char c, d, e; |
503 |
/************************* DOMAIN POLICY HANDLER *************************/ |
/************************* DOMAIN POLICY HANDLER *************************/ |
504 |
|
|
505 |
/* Check whether the given access control is enabled. */ |
/* Check whether the given access control is enabled. */ |
506 |
unsigned int CheckCCSFlags(const unsigned int index) |
unsigned int CheckCCSFlags(const u8 index) |
507 |
{ |
{ |
508 |
const u8 profile = current->domain_info->profile; |
const u8 profile = current->domain_info->profile; |
509 |
return sbin_init_started && index < CCS_MAX_CONTROL_INDEX |
return sbin_init_started && index < CCS_MAX_CONTROL_INDEX |
512 |
#endif |
#endif |
513 |
&& profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0; |
&& profile_ptr[profile] ? profile_ptr[profile]->value[index] : 0; |
514 |
} |
} |
|
EXPORT_SYMBOL(CheckCCSFlags); |
|
515 |
|
|
516 |
bool TomoyoVerboseMode(void) |
bool TomoyoVerboseMode(void) |
517 |
{ |
{ |
518 |
return CheckCCSFlags(CCS_TOMOYO_VERBOSE) != 0; |
return CheckCCSFlags(CCS_TOMOYO_VERBOSE) != 0; |
519 |
} |
} |
520 |
|
|
|
/* Check whether the given access control is enforce mode. */ |
|
|
bool CheckCCSEnforce(const unsigned int index) |
|
|
{ |
|
|
return CheckCCSFlags(index) == 3; |
|
|
} |
|
|
EXPORT_SYMBOL(CheckCCSEnforce); |
|
|
|
|
521 |
bool CheckDomainQuota(struct domain_info * const domain) |
bool CheckDomainQuota(struct domain_info * const domain) |
522 |
{ |
{ |
523 |
unsigned int count = 0; |
unsigned int count = 0; |
534 |
return 0; |
return 0; |
535 |
} |
} |
536 |
|
|
|
/* Check whether the given access control is learning mode. */ |
|
|
bool CheckCCSAccept(const unsigned int index, struct domain_info * const domain) |
|
|
{ |
|
|
if (CheckCCSFlags(index) != 1) return 0; |
|
|
return CheckDomainQuota(domain); |
|
|
} |
|
|
EXPORT_SYMBOL(CheckCCSAccept); |
|
|
|
|
537 |
static struct profile *FindOrAssignNewProfile(const unsigned int profile) |
static struct profile *FindOrAssignNewProfile(const unsigned int profile) |
538 |
{ |
{ |
539 |
static DEFINE_MUTEX(profile_lock); |
static DEFINE_MUTEX(profile_lock); |
866 |
if (ptr->is_deleted) continue; |
if (ptr->is_deleted) continue; |
867 |
pos = head->read_avail; |
pos = head->read_avail; |
868 |
acl_type = ptr->type; |
acl_type = ptr->type; |
869 |
if (acl_type == TYPE_FILE_ACL) { |
if (acl_type == TYPE_SINGLE_PATH_ACL) { |
870 |
struct file_acl_record *ptr2 = container_of(ptr, struct file_acl_record, head); |
struct single_acl_record *ptr2 = container_of(ptr, struct single_acl_record, head); |
871 |
const unsigned char b = ptr2->u_is_group; |
const bool b = ptr2->u_is_group; |
872 |
if (io_printf(head, "%d %s%s", ptr2->perm, |
const u16 perm = ptr2->perm; |
873 |
b ? "@" : "", |
u8 bit = head->read_bit; |
874 |
b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)) goto print_acl_rollback; |
while (bit < MAX_SINGLE_PATH_OPERATION) { |
875 |
|
if (perm & (1 << bit)) { |
876 |
|
pos = head->read_avail; |
877 |
|
if (io_printf(head, "allow_%s %s%s ", sp_operation2keyword(bit), |
878 |
|
b ? "@" : "", b ? ptr2->u.group->group_name->name : ptr2->u.filename->name) |
879 |
|
|| DumpCondition(head, ptr->cond)) { |
880 |
|
head->read_bit = bit; |
881 |
|
head->read_avail = pos; |
882 |
|
return 0; |
883 |
|
} |
884 |
|
} |
885 |
|
bit++; |
886 |
|
} |
887 |
|
head->read_bit = 0; |
888 |
|
} else if (acl_type == TYPE_DOUBLE_PATH_ACL) { |
889 |
|
struct double_acl_record *ptr2 = container_of(ptr, struct double_acl_record, head); |
890 |
|
const bool b0 = ptr2->u1_is_group, b1 = ptr2->u2_is_group; |
891 |
|
const u8 perm = ptr2->perm; |
892 |
|
u8 bit = head->read_bit; |
893 |
|
while (bit < MAX_DOUBLE_PATH_OPERATION) { |
894 |
|
if (perm & (1 << bit)) { |
895 |
|
pos = head->read_avail; |
896 |
|
if (io_printf(head, "allow_%s %s%s %s%s", dp_operation2keyword(bit), |
897 |
|
b0 ? "@" : "", b0 ? ptr2->u1.group1->group_name->name : ptr2->u1.filename1->name, |
898 |
|
b1 ? "@" : "", b1 ? ptr2->u2.group2->group_name->name : ptr2->u2.filename2->name) |
899 |
|
|| DumpCondition(head, ptr->cond)) { |
900 |
|
head->read_bit = bit; |
901 |
|
head->read_avail = pos; |
902 |
|
return 0; |
903 |
|
} |
904 |
|
} |
905 |
|
bit++; |
906 |
|
} |
907 |
|
head->read_bit = 0; |
908 |
} else if (acl_type == TYPE_ARGV0_ACL) { |
} else if (acl_type == TYPE_ARGV0_ACL) { |
909 |
struct argv0_acl_record *ptr2 = container_of(ptr, struct argv0_acl_record, head); |
struct argv0_acl_record *ptr2 = container_of(ptr, struct argv0_acl_record, head); |
910 |
if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s", |
if (io_printf(head, KEYWORD_ALLOW_ARGV0 "%s %s", |
914 |
if (io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr2->env->name)) goto print_acl_rollback; |
if (io_printf(head, KEYWORD_ALLOW_ENV "%s", ptr2->env->name)) goto print_acl_rollback; |
915 |
} else if (acl_type == TYPE_CAPABILITY_ACL) { |
} else if (acl_type == TYPE_CAPABILITY_ACL) { |
916 |
struct capability_acl_record *ptr2 = container_of(ptr, struct capability_acl_record, head); |
struct capability_acl_record *ptr2 = container_of(ptr, struct capability_acl_record, head); |
917 |
if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", capability2keyword(ptr2->capability))) goto print_acl_rollback; |
const u32 capability = ptr2->capability; |
918 |
|
u8 bit = head->read_bit; |
919 |
|
while (bit < TOMOYO_MAX_CAPABILITY_INDEX) { |
920 |
|
if (capability & (1 << bit)) { |
921 |
|
pos = head->read_avail; |
922 |
|
if (io_printf(head, KEYWORD_ALLOW_CAPABILITY "%s", cap_operation2keyword(bit)) || |
923 |
|
DumpCondition(head, ptr->cond)) { |
924 |
|
head->read_bit = bit; |
925 |
|
head->read_avail = pos; |
926 |
|
return 0; |
927 |
|
} |
928 |
|
} |
929 |
|
bit++; |
930 |
|
} |
931 |
|
head->read_bit = 0; |
932 |
} else if (acl_type == TYPE_IP_NETWORK_ACL) { |
} else if (acl_type == TYPE_IP_NETWORK_ACL) { |
933 |
struct ip_network_acl_record *ptr2 = container_of(ptr, struct ip_network_acl_record, head); |
struct ip_network_acl_record *ptr2 = container_of(ptr, struct ip_network_acl_record, head); |
934 |
if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", network2keyword(ptr2->operation_type))) goto print_acl_rollback; |
if (io_printf(head, KEYWORD_ALLOW_NETWORK "%s ", net_operation2keyword(ptr2->operation_type))) goto print_acl_rollback; |
935 |
switch (ptr2->record_type) { |
switch (ptr2->record_type) { |
936 |
case IP_RECORD_TYPE_ADDRESS_GROUP: |
case IP_RECORD_TYPE_ADDRESS_GROUP: |
937 |
if (io_printf(head, "@%s", ptr2->u.group->group_name->name)) goto print_acl_rollback; |
if (io_printf(head, "@%s", ptr2->u.group->group_name->name)) goto print_acl_rollback; |
965 |
struct signal_acl_record *ptr2 = container_of(ptr, struct signal_acl_record, head); |
struct signal_acl_record *ptr2 = container_of(ptr, struct signal_acl_record, head); |
966 |
if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr2->sig, ptr2->domainname->name)) goto print_acl_rollback; |
if (io_printf(head, KEYWORD_ALLOW_SIGNAL "%u %s", ptr2->sig, ptr2->domainname->name)) goto print_acl_rollback; |
967 |
} else { |
} else { |
968 |
const char *keyword = acltype2keyword(acl_type); |
BUG(); |
|
if (!keyword) continue; |
|
|
if (acltype2paths(acl_type) == 2) { |
|
|
struct double_acl_record *ptr2 = container_of(ptr, struct double_acl_record, head); |
|
|
const bool b0 = ptr2->u1_is_group, b1 = ptr2->u2_is_group; |
|
|
if (io_printf(head, "allow_%s %s%s %s%s", keyword, |
|
|
b0 ? "@" : "", b0 ? ptr2->u1.group1->group_name->name : ptr2->u1.filename1->name, |
|
|
b1 ? "@" : "", b1 ? ptr2->u2.group2->group_name->name : ptr2->u2.filename2->name)) goto print_acl_rollback; |
|
|
} else { |
|
|
struct single_acl_record *ptr2 = container_of(ptr, struct single_acl_record, head); |
|
|
const bool b = ptr2->u_is_group; |
|
|
if (io_printf(head, "allow_%s %s%s", keyword, |
|
|
b ? "@" : "", b ? ptr2->u.group->group_name->name : ptr2->u.filename->name)) goto print_acl_rollback; |
|
|
} |
|
969 |
} |
} |
970 |
if (DumpCondition(head, ptr->cond)) { |
if (acl_type != TYPE_SINGLE_PATH_ACL && acl_type != TYPE_DOUBLE_PATH_ACL && acl_type != TYPE_CAPABILITY_ACL && DumpCondition(head, ptr->cond)) { |
971 |
print_acl_rollback: ; |
print_acl_rollback: ; |
972 |
head->read_avail = pos; |
head->read_avail = pos; |
973 |
return 0; |
return 0; |
1071 |
} else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) { |
} else if (strncmp(data, KEYWORD_ALLOW_ENV, KEYWORD_ALLOW_ENV_LEN) == 0) { |
1072 |
return AddGloballyUsableEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, is_delete); |
return AddGloballyUsableEnvPolicy(data + KEYWORD_ALLOW_ENV_LEN, is_delete); |
1073 |
} else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) { |
} else if (strncmp(data, KEYWORD_FILE_PATTERN, KEYWORD_FILE_PATTERN_LEN) == 0) { |
1074 |
return AddPatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete); |
return AddFilePatternPolicy(data + KEYWORD_FILE_PATTERN_LEN, is_delete); |
1075 |
} else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) { |
} else if (strncmp(data, KEYWORD_PATH_GROUP, KEYWORD_PATH_GROUP_LEN) == 0) { |
1076 |
return AddPathGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete); |
return AddPathGroupPolicy(data + KEYWORD_PATH_GROUP_LEN, is_delete); |
1077 |
} else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) { |
} else if (strncmp(data, KEYWORD_DENY_REWRITE, KEYWORD_DENY_REWRITE_LEN) == 0) { |
1108 |
if (ReadAggregatorPolicy(head)) break; |
if (ReadAggregatorPolicy(head)) break; |
1109 |
head->read_var2 = NULL; head->read_step = 7; |
head->read_var2 = NULL; head->read_step = 7; |
1110 |
case 7: |
case 7: |
1111 |
if (ReadPatternPolicy(head)) break; |
if (ReadFilePatternPolicy(head)) break; |
1112 |
head->read_var2 = NULL; head->read_step = 8; |
head->read_var2 = NULL; head->read_step = 8; |
1113 |
case 8: |
case 8: |
1114 |
if (ReadNoRewritePolicy(head)) break; |
if (ReadNoRewritePolicy(head)) break; |
1246 |
} |
} |
1247 |
} |
} |
1248 |
#ifdef CONFIG_SAKURA |
#ifdef CONFIG_SAKURA |
1249 |
printk("SAKURA: 1.5.2-pre 2007/11/29\n"); |
printk("SAKURA: 1.5.3-pre 2008/01/02\n"); |
1250 |
#endif |
#endif |
1251 |
#ifdef CONFIG_TOMOYO |
#ifdef CONFIG_TOMOYO |
1252 |
printk("TOMOYO: 1.5.2-pre 2007/11/29\n"); |
printk("TOMOYO: 1.5.3-pre 2008/01/02\n"); |
1253 |
#endif |
#endif |
1254 |
//if (!profile_loaded) panic("No profiles loaded. Run policy loader using 'init=' option.\n"); |
//if (!profile_loaded) panic("No profiles loaded. Run policy loader using 'init=' option.\n"); |
1255 |
printk("Mandatory Access Control activated.\n"); |
printk("Mandatory Access Control activated.\n"); |
1291 |
static unsigned int serial = 0; |
static unsigned int serial = 0; |
1292 |
struct query_entry *query_entry; |
struct query_entry *query_entry; |
1293 |
if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE) || !atomic_read(&queryd_watcher)) { |
if (!CheckCCSFlags(CCS_ALLOW_ENFORCE_GRACE) || !atomic_read(&queryd_watcher)) { |
1294 |
#ifndef ALT_EXEC |
#ifdef ALT_EXEC |
1295 |
if ((current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) == 0) { |
if ((current->tomoyo_flags & CCS_DONT_SLEEP_ON_ENFORCE_ERROR) == 0) { |
1296 |
int i; |
int i; |
1297 |
for (i = 0; i < CheckCCSFlags(CCS_SLEEP_PERIOD); i++) { |
for (i = 0; i < CheckCCSFlags(CCS_SLEEP_PERIOD); i++) { |
1501 |
static int ReadVersion(struct io_buffer *head) |
static int ReadVersion(struct io_buffer *head) |
1502 |
{ |
{ |
1503 |
if (!head->read_eof) { |
if (!head->read_eof) { |
1504 |
if (io_printf(head, "1.5.2-pre") == 0) head->read_eof = 1; |
if (io_printf(head, "1.5.3-pre") == 0) head->read_eof = 1; |
1505 |
} |
} |
1506 |
return 0; |
return 0; |
1507 |
} |
} |
1524 |
return 0; |
return 0; |
1525 |
} |
} |
1526 |
|
|
1527 |
int CCS_OpenControl(const int type, struct file *file) |
int CCS_OpenControl(const u8 type, struct file *file) |
1528 |
{ |
{ |
1529 |
struct io_buffer *head = ccs_alloc(sizeof(*head)); |
struct io_buffer *head = ccs_alloc(sizeof(*head)); |
1530 |
if (!head) return -ENOMEM; |
if (!head) return -ENOMEM; |