* tomoyo_read_profile - Read profile table.
*
* @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0.
*/
-static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
+static void tomoyo_read_profile(struct tomoyo_io_buffer *head)
{
int index;
if (head->read_eof)
- return 0;
+ return;
if (head->read_bit)
goto body;
tomoyo_io_printf(head, "PROFILE_VERSION=%s\n", "20090903");
}
if (index == TOMOYO_MAX_PROFILES)
head->read_eof = true;
- return 0;
}
-/*
- * tomoyo_policy_manager_list is used for holding list of domainnames or
- * programs which are permitted to modify configuration via
- * /sys/kernel/security/tomoyo/ interface.
- *
- * An entry is added by
- *
- * # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \
- * /sys/kernel/security/tomoyo/manager
- * (if you want to specify by a domainname)
- *
- * or
- *
- * # echo '/usr/sbin/tomoyo-editpolicy' > /sys/kernel/security/tomoyo/manager
- * (if you want to specify by a program's location)
- *
- * and is deleted by
- *
- * # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \
- * /sys/kernel/security/tomoyo/manager
- *
- * or
- *
- * # echo 'delete /usr/sbin/tomoyo-editpolicy' > \
- * /sys/kernel/security/tomoyo/manager
- *
- * and all entries are retrieved by
- *
- * # cat /sys/kernel/security/tomoyo/manager
- */
-LIST_HEAD(tomoyo_policy_manager_list);
+static bool tomoyo_same_manager_entry(const struct tomoyo_acl_head *a,
+ const struct tomoyo_acl_head *b)
+{
+ return container_of(a, struct tomoyo_policy_manager_entry, head)
+ ->manager ==
+ container_of(b, struct tomoyo_policy_manager_entry, head)
+ ->manager;
+}
/**
* tomoyo_update_manager_entry - Add a manager entry.
static int tomoyo_update_manager_entry(const char *manager,
const bool is_delete)
{
- struct tomoyo_policy_manager_entry *ptr;
struct tomoyo_policy_manager_entry e = { };
- int error = is_delete ? -ENOENT : -ENOMEM;
+ int error;
- if (tomoyo_is_domain_def(manager)) {
- if (!tomoyo_is_correct_domain(manager))
+ if (tomoyo_domain_def(manager)) {
+ if (!tomoyo_correct_domain(manager))
return -EINVAL;
e.is_domain = true;
} else {
- if (!tomoyo_is_correct_path(manager))
+ if (!tomoyo_correct_path(manager))
return -EINVAL;
}
e.manager = tomoyo_get_name(manager);
if (!e.manager)
return -ENOMEM;
- if (mutex_lock_interruptible(&tomoyo_policy_lock))
- goto out;
- list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
- if (ptr->manager != e.manager)
- continue;
- ptr->is_deleted = is_delete;
- error = 0;
- break;
- }
- if (!is_delete && error) {
- struct tomoyo_policy_manager_entry *entry =
- tomoyo_commit_ok(&e, sizeof(e));
- if (entry) {
- list_add_tail_rcu(&entry->list,
- &tomoyo_policy_manager_list);
- error = 0;
- }
- }
- mutex_unlock(&tomoyo_policy_lock);
- out:
+ error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
+ &tomoyo_policy_list[TOMOYO_ID_MANAGER],
+ tomoyo_same_manager_entry);
tomoyo_put_name(e.manager);
return error;
}
*
* @head: Pointer to "struct tomoyo_io_buffer".
*
- * Returns 0.
- *
* Caller holds tomoyo_read_lock().
*/
-static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
+static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
{
- struct list_head *pos;
bool done = true;
if (head->read_eof)
- return 0;
- list_for_each_cookie(pos, head->read_var2,
- &tomoyo_policy_manager_list) {
- struct tomoyo_policy_manager_entry *ptr;
- ptr = list_entry(pos, struct tomoyo_policy_manager_entry,
- list);
- if (ptr->is_deleted)
+ return;
+ list_for_each_cookie(head->read_var2,
+ &tomoyo_policy_list[TOMOYO_ID_MANAGER]) {
+ struct tomoyo_policy_manager_entry *ptr =
+ list_entry(head->read_var2, typeof(*ptr), head.list);
+ if (ptr->head.is_deleted)
continue;
done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
if (!done)
break;
}
head->read_eof = done;
- return 0;
}
/**
- * tomoyo_is_policy_manager - Check whether the current process is a policy manager.
+ * tomoyo_policy_manager - Check whether the current process is a policy manager.
*
* Returns true if the current process is permitted to modify policy
* via /sys/kernel/security/tomoyo/ interface.
*
* Caller holds tomoyo_read_lock().
*/
-static bool tomoyo_is_policy_manager(void)
+static bool tomoyo_policy_manager(void)
{
struct tomoyo_policy_manager_entry *ptr;
const char *exe;
return true;
if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
return false;
- list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
- if (!ptr->is_deleted && ptr->is_domain
+ list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER],
+ head.list) {
+ if (!ptr->head.is_deleted && ptr->is_domain
&& !tomoyo_pathcmp(domainname, ptr->manager)) {
found = true;
break;
exe = tomoyo_get_exe();
if (!exe)
return false;
- list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
- if (!ptr->is_deleted && !ptr->is_domain
+ list_for_each_entry_rcu(ptr, &tomoyo_policy_list[TOMOYO_ID_MANAGER],
+ head.list) {
+ if (!ptr->head.is_deleted && !ptr->is_domain
&& !strcmp(exe, ptr->manager->name)) {
found = true;
break;
}
/**
- * tomoyo_is_select_one - Parse select command.
+ * tomoyo_select_one - Parse select command.
*
* @head: Pointer to "struct tomoyo_io_buffer".
* @data: String to parse.
*
* Caller holds tomoyo_read_lock().
*/
-static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
- const char *data)
+static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
{
unsigned int pid;
struct tomoyo_domain_info *domain = NULL;
read_unlock(&tasklist_lock);
rcu_read_unlock();
} else if (!strncmp(data, "domain=", 7)) {
- if (tomoyo_is_domain_def(data + 7))
+ if (tomoyo_domain_def(data + 7))
domain = tomoyo_find_domain(data + 7);
} else
return false;
tomoyo_io_printf(head, "# select %s\n", data);
head->read_single_domain = true;
head->read_eof = !domain;
- if (domain) {
- struct tomoyo_domain_info *d;
- head->read_var1 = NULL;
- list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
- if (d == domain)
- break;
- head->read_var1 = &d->list;
- }
- head->read_var2 = NULL;
- head->read_bit = 0;
- head->read_step = 0;
- if (domain->is_deleted)
- tomoyo_io_printf(head, "# This is a deleted domain.\n");
- }
+ head->read_var1 = &domain->list;
+ head->read_var2 = NULL;
+ head->read_bit = 0;
+ head->read_step = 0;
+ if (domain && domain->is_deleted)
+ tomoyo_io_printf(head, "# This is a deleted domain.\n");
return true;
}
is_delete = true;
else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
is_select = true;
- if (is_select && tomoyo_is_select_one(head, data))
+ if (is_select && tomoyo_select_one(head, data))
return 0;
/* Don't allow updating policies by non manager programs. */
- if (!tomoyo_is_policy_manager())
+ if (!tomoyo_policy_manager())
return -EPERM;
- if (tomoyo_is_domain_def(data)) {
+ if (tomoyo_domain_def(data)) {
domain = NULL;
if (is_delete)
tomoyo_delete_domain(data);
continue;
pos = head->read_avail;
if (!tomoyo_io_printf(head, "allow_%s ",
- tomoyo_path2keyword(bit)) ||
+ tomoyo_path_keyword[bit]) ||
!tomoyo_print_name_union(head, &ptr->name) ||
!tomoyo_io_printf(head, "\n"))
goto out;
continue;
pos = head->read_avail;
if (!tomoyo_io_printf(head, "allow_%s ",
- tomoyo_path22keyword(bit)) ||
+ tomoyo_path2_keyword[bit]) ||
!tomoyo_print_name_union(head, &ptr->name1) ||
!tomoyo_print_name_union(head, &ptr->name2) ||
!tomoyo_io_printf(head, "\n"))
continue;
pos = head->read_avail;
if (!tomoyo_io_printf(head, "allow_%s",
- tomoyo_path_number2keyword(bit)) ||
+ tomoyo_path_number_keyword[bit]) ||
!tomoyo_print_name_union(head, &ptr->name) ||
!tomoyo_print_number_union(head, &ptr->number) ||
!tomoyo_io_printf(head, "\n"))
}
/**
- * tomoyo_print_path_number3_acl - Print a path_number3 ACL entry.
+ * tomoyo_print_mkdev_acl - Print a mkdev ACL entry.
*
* @head: Pointer to "struct tomoyo_io_buffer".
- * @ptr: Pointer to "struct tomoyo_path_number3_acl".
+ * @ptr: Pointer to "struct tomoyo_mkdev_acl".
*
* Returns true on success, false otherwise.
*/
-static bool tomoyo_print_path_number3_acl(struct tomoyo_io_buffer *head,
- struct tomoyo_path_number3_acl *ptr)
+static bool tomoyo_print_mkdev_acl(struct tomoyo_io_buffer *head,
+ struct tomoyo_mkdev_acl *ptr)
{
int pos;
u8 bit;
const u16 perm = ptr->perm;
- for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_NUMBER3_OPERATION;
+ for (bit = head->read_bit; bit < TOMOYO_MAX_MKDEV_OPERATION;
bit++) {
if (!(perm & (1 << bit)))
continue;
pos = head->read_avail;
if (!tomoyo_io_printf(head, "allow_%s",
- tomoyo_path_number32keyword(bit)) ||
+ tomoyo_mkdev_keyword[bit]) ||
!tomoyo_print_name_union(head, &ptr->name) ||
!tomoyo_print_number_union(head, &ptr->mode) ||
!tomoyo_print_number_union(head, &ptr->major) ||
struct tomoyo_mount_acl *ptr)
{
const int pos = head->read_avail;
- if (ptr->is_deleted)
- return true;
if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_MOUNT) ||
!tomoyo_print_name_union(head, &ptr->dev_name) ||
!tomoyo_print_name_union(head, &ptr->dir_name) ||
{
const u8 acl_type = ptr->type;
+ if (ptr->is_deleted)
+ return true;
if (acl_type == TOMOYO_TYPE_PATH_ACL) {
struct tomoyo_path_acl *acl
= container_of(ptr, struct tomoyo_path_acl, head);
head);
return tomoyo_print_path_number_acl(head, acl);
}
- if (acl_type == TOMOYO_TYPE_PATH_NUMBER3_ACL) {
- struct tomoyo_path_number3_acl *acl
- = container_of(ptr, struct tomoyo_path_number3_acl,
+ if (acl_type == TOMOYO_TYPE_MKDEV_ACL) {
+ struct tomoyo_mkdev_acl *acl
+ = container_of(ptr, struct tomoyo_mkdev_acl,
head);
- return tomoyo_print_path_number3_acl(head, acl);
+ return tomoyo_print_mkdev_acl(head, acl);
}
if (acl_type == TOMOYO_TYPE_MOUNT_ACL) {
struct tomoyo_mount_acl *acl
*
* @head: Pointer to "struct tomoyo_io_buffer".
*
- * Returns 0.
- *
* Caller holds tomoyo_read_lock().
*/
-static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
+static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
{
- struct list_head *dpos;
- struct list_head *apos;
bool done = true;
if (head->read_eof)
- return 0;
+ return;
if (head->read_step == 0)
head->read_step = 1;
- list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
- struct tomoyo_domain_info *domain;
+ list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
+ struct tomoyo_domain_info *domain =
+ list_entry(head->read_var1, typeof(*domain), list);
const char *quota_exceeded = "";
const char *transition_failed = "";
const char *ignore_global_allow_read = "";
- domain = list_entry(dpos, struct tomoyo_domain_info, list);
if (head->read_step != 1)
goto acl_loop;
if (domain->is_deleted && !head->read_single_domain)
if (head->read_step == 3)
goto tail_mark;
/* Print ACL entries in the domain. */
- list_for_each_cookie(apos, head->read_var2,
+ list_for_each_cookie(head->read_var2,
&domain->acl_info_list) {
- struct tomoyo_acl_info *ptr
- = list_entry(apos, struct tomoyo_acl_info,
- list);
+ struct tomoyo_acl_info *ptr =
+ list_entry(head->read_var2, typeof(*ptr), list);
done = tomoyo_print_entry(head, ptr);
if (!done)
break;
}
if (!done)
break;
+ head->read_var2 = NULL;
head->read_step = 3;
tail_mark:
done = tomoyo_io_printf(head, "\n");
break;
}
head->read_eof = done;
- return 0;
}
/**
*
* Caller holds tomoyo_read_lock().
*/
-static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
+static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
{
- struct list_head *pos;
bool done = true;
if (head->read_eof)
- return 0;
- list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
- struct tomoyo_domain_info *domain;
- domain = list_entry(pos, struct tomoyo_domain_info, list);
+ return;
+ list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
+ struct tomoyo_domain_info *domain =
+ list_entry(head->read_var1, typeof(*domain), list);
if (domain->is_deleted)
continue;
done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
break;
}
head->read_eof = done;
- return 0;
}
/**
* The PID is specified by tomoyo_write_pid() so that the user can obtain
* using read()/write() interface rather than sysctl() interface.
*/
-static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
+static void tomoyo_read_pid(struct tomoyo_io_buffer *head)
{
if (head->read_avail == 0 && !head->read_eof) {
const int pid = head->read_step;
domain->domainname->name);
head->read_eof = true;
}
- return 0;
}
+static const char *tomoyo_transition_type[TOMOYO_MAX_TRANSITION_TYPE] = {
+ [TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE]
+ = TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN,
+ [TOMOYO_TRANSITION_CONTROL_INITIALIZE]
+ = TOMOYO_KEYWORD_INITIALIZE_DOMAIN,
+ [TOMOYO_TRANSITION_CONTROL_NO_KEEP] = TOMOYO_KEYWORD_NO_KEEP_DOMAIN,
+ [TOMOYO_TRANSITION_CONTROL_KEEP] = TOMOYO_KEYWORD_KEEP_DOMAIN
+};
+
/**
* tomoyo_write_exception_policy - Write exception policy.
*
{
char *data = head->write_buf;
bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
+ u8 i;
- if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN))
- return tomoyo_write_domain_keeper_policy(data, false,
- is_delete);
- if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN))
- return tomoyo_write_domain_keeper_policy(data, true, is_delete);
- if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN))
- return tomoyo_write_domain_initializer_policy(data, false,
- is_delete);
- if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN))
- return tomoyo_write_domain_initializer_policy(data, true,
- is_delete);
+ for (i = 0; i < TOMOYO_MAX_TRANSITION_TYPE; i++) {
+ if (tomoyo_str_starts(&data, tomoyo_transition_type[i]))
+ return tomoyo_write_transition_control(data, is_delete,
+ i);
+ }
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_AGGREGATOR))
return tomoyo_write_aggregator_policy(data, is_delete);
- if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS))
- return tomoyo_write_alias_policy(data, is_delete);
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ))
return tomoyo_write_globally_readable_policy(data, is_delete);
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN))
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE))
return tomoyo_write_no_rewrite_policy(data, is_delete);
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP))
- return tomoyo_write_path_group_policy(data, is_delete);
+ return tomoyo_write_group(data, is_delete, TOMOYO_PATH_GROUP);
if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NUMBER_GROUP))
- return tomoyo_write_number_group_policy(data, is_delete);
+ return tomoyo_write_group(data, is_delete, TOMOYO_NUMBER_GROUP);
return -EINVAL;
}
+static void tomoyo_print_number(char *buffer, int buffer_len,
+ const struct tomoyo_number_union *ptr)
+{
+ int i;
+ unsigned long min = ptr->values[0];
+ const unsigned long max = ptr->values[1];
+ u8 min_type = ptr->min_type;
+ const u8 max_type = ptr->max_type;
+ memset(buffer, 0, buffer_len);
+ buffer_len -= 2;
+ for (i = 0; i < 2; i++) {
+ int len;
+ switch (min_type) {
+ case TOMOYO_VALUE_TYPE_HEXADECIMAL:
+ snprintf(buffer, buffer_len, "0x%lX", min);
+ break;
+ case TOMOYO_VALUE_TYPE_OCTAL:
+ snprintf(buffer, buffer_len, "0%lo", min);
+ break;
+ default:
+ snprintf(buffer, buffer_len, "%lu", min);
+ break;
+ }
+ if (min == max && min_type == max_type)
+ break;
+ len = strlen(buffer);
+ buffer[len++] = '-';
+ buffer += len;
+ buffer_len -= len;
+ min_type = max_type;
+ min = max;
+ }
+}
+
+static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
+ [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP,
+ [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP
+};
+
/**
- * tomoyo_read_exception_policy - Read exception policy.
+ * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
*
* @head: Pointer to "struct tomoyo_io_buffer".
+ * @idx: Index number.
*
- * Returns 0 on success, -EINVAL otherwise.
+ * Returns true on success, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
-static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
+static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
{
- if (!head->read_eof) {
- switch (head->read_step) {
- case 0:
- head->read_var2 = NULL;
- head->read_step = 1;
- case 1:
- if (!tomoyo_read_domain_keeper_policy(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 2;
- case 2:
- if (!tomoyo_read_globally_readable_policy(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 3;
- case 3:
- head->read_var2 = NULL;
- head->read_step = 4;
- case 4:
- if (!tomoyo_read_domain_initializer_policy(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 5;
- case 5:
- if (!tomoyo_read_alias_policy(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 6;
- case 6:
- if (!tomoyo_read_aggregator_policy(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 7;
- case 7:
- if (!tomoyo_read_file_pattern(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 8;
- case 8:
- if (!tomoyo_read_no_rewrite_policy(head))
- break;
- head->read_var2 = NULL;
- head->read_step = 9;
- case 9:
- if (!tomoyo_read_path_group_policy(head))
- break;
- head->read_var1 = NULL;
- head->read_var2 = NULL;
- head->read_step = 10;
- case 10:
- if (!tomoyo_read_number_group_policy(head))
- break;
- head->read_var1 = NULL;
- head->read_var2 = NULL;
- head->read_step = 11;
- case 11:
- head->read_eof = true;
+ const char *w[3] = { "", "", "" };
+ w[0] = tomoyo_group_name[idx];
+ list_for_each_cookie(head->read_var1, &tomoyo_group_list[idx]) {
+ struct tomoyo_group *group =
+ list_entry(head->read_var1, typeof(*group), list);
+ w[1] = group->group_name->name;
+ list_for_each_cookie(head->read_var2, &group->member_list) {
+ char buffer[128];
+ struct tomoyo_acl_head *ptr =
+ list_entry(head->read_var2, typeof(*ptr), list);
+ if (ptr->is_deleted)
+ continue;
+ if (idx == TOMOYO_PATH_GROUP) {
+ w[2] = container_of(ptr,
+ struct tomoyo_path_group,
+ head)->member_name->name;
+ } else if (idx == TOMOYO_NUMBER_GROUP) {
+ tomoyo_print_number(buffer, sizeof(buffer),
+ &container_of
+ (ptr, struct
+ tomoyo_number_group,
+ head)->number);
+ w[2] = buffer;
+ }
+ if (!tomoyo_io_printf(head, "%s%s %s\n", w[0], w[1],
+ w[2]))
+ return false;
+ }
+ head->read_var2 = NULL;
+ }
+ head->read_var1 = NULL;
+ return true;
+}
+
+/**
+ * tomoyo_read_policy - Read "struct tomoyo_..._entry" list.
+ *
+ * @head: Pointer to "struct tomoyo_io_buffer".
+ * @idx: Index number.
+ *
+ * Returns true on success, false otherwise.
+ *
+ * Caller holds tomoyo_read_lock().
+ */
+static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
+{
+ list_for_each_cookie(head->read_var2, &tomoyo_policy_list[idx]) {
+ const char *w[4] = { "", "", "", "" };
+ struct tomoyo_acl_head *acl =
+ container_of(head->read_var2, typeof(*acl), list);
+ if (acl->is_deleted)
+ continue;
+ switch (idx) {
+ case TOMOYO_ID_TRANSITION_CONTROL:
+ {
+ struct tomoyo_transition_control *ptr =
+ container_of(acl, typeof(*ptr), head);
+ w[0] = tomoyo_transition_type[ptr->type];
+ if (ptr->program)
+ w[1] = ptr->program->name;
+ if (ptr->domainname)
+ w[3] = ptr->domainname->name;
+ if (w[1][0] && w[3][0])
+ w[2] = " from ";
+ }
+ break;
+ case TOMOYO_ID_GLOBALLY_READABLE:
+ {
+ struct tomoyo_globally_readable_file_entry *ptr
+ = container_of(acl, typeof(*ptr), head);
+ w[0] = TOMOYO_KEYWORD_ALLOW_READ;
+ w[1] = ptr->filename->name;
+ }
+ break;
+ case TOMOYO_ID_AGGREGATOR:
+ {
+ struct tomoyo_aggregator_entry *ptr =
+ container_of(acl, typeof(*ptr), head);
+ w[0] = TOMOYO_KEYWORD_AGGREGATOR;
+ w[1] = ptr->original_name->name;
+ w[2] = " ";
+ w[3] = ptr->aggregated_name->name;
+ }
+ break;
+ case TOMOYO_ID_PATTERN:
+ {
+ struct tomoyo_pattern_entry *ptr =
+ container_of(acl, typeof(*ptr), head);
+ w[0] = TOMOYO_KEYWORD_FILE_PATTERN;
+ w[1] = ptr->pattern->name;
+ }
+ break;
+ case TOMOYO_ID_NO_REWRITE:
+ {
+ struct tomoyo_no_rewrite_entry *ptr =
+ container_of(acl, typeof(*ptr), head);
+ w[0] = TOMOYO_KEYWORD_DENY_REWRITE;
+ w[1] = ptr->pattern->name;
+ }
break;
default:
- return -EINVAL;
+ continue;
}
+ if (!tomoyo_io_printf(head, "%s%s%s%s\n", w[0], w[1], w[2],
+ w[3]))
+ return false;
}
- return 0;
+ head->read_var2 = NULL;
+ return true;
+}
+
+/**
+ * tomoyo_read_exception_policy - Read exception policy.
+ *
+ * @head: Pointer to "struct tomoyo_io_buffer".
+ *
+ * Caller holds tomoyo_read_lock().
+ */
+static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
+{
+ if (head->read_eof)
+ return;
+ while (head->read_step < TOMOYO_MAX_POLICY &&
+ tomoyo_read_policy(head, head->read_step))
+ head->read_step++;
+ if (head->read_step < TOMOYO_MAX_POLICY)
+ return;
+ while (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP &&
+ tomoyo_read_group(head, head->read_step - TOMOYO_MAX_POLICY))
+ head->read_step++;
+ if (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP)
+ return;
+ head->read_eof = true;
}
/**
* tomoyo_read_query - Read access requests which violated policy in enforcing mode.
*
* @head: Pointer to "struct tomoyo_io_buffer".
- *
- * Returns 0.
*/
-static int tomoyo_read_query(struct tomoyo_io_buffer *head)
+static void tomoyo_read_query(struct tomoyo_io_buffer *head)
{
struct list_head *tmp;
int pos = 0;
int len = 0;
char *buf;
if (head->read_avail)
- return 0;
+ return;
if (head->read_buf) {
kfree(head->read_buf);
head->read_buf = NULL;
spin_unlock(&tomoyo_query_list_lock);
if (!len) {
head->read_step = 0;
- return 0;
+ return;
}
buf = kzalloc(len, GFP_NOFS);
if (!buf)
- return 0;
+ return;
pos = 0;
spin_lock(&tomoyo_query_list_lock);
list_for_each(tmp, &tomoyo_query_list) {
} else {
kfree(buf);
}
- return 0;
}
/**
*
* Returns version information.
*/
-static int tomoyo_read_version(struct tomoyo_io_buffer *head)
+static void tomoyo_read_version(struct tomoyo_io_buffer *head)
{
if (!head->read_eof) {
tomoyo_io_printf(head, "2.3.0-pre");
head->read_eof = true;
}
- return 0;
}
/**
*
* Returns the current process's domainname.
*/
-static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
+static void tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
{
if (!head->read_eof) {
/*
tomoyo_io_printf(head, "%s", tomoyo_domain()->domainname->name);
head->read_eof = true;
}
- return 0;
}
/**
if (mutex_lock_interruptible(&head->io_sem))
return -EINTR;
/* Call the policy handler. */
- len = head->read(head);
+ head->read(head);
if (len < 0)
goto out;
/* Write to buffer. */
/* Don't allow updating policies by non manager programs. */
if (head->write != tomoyo_write_pid &&
head->write != tomoyo_write_domain_policy &&
- !tomoyo_is_policy_manager())
+ !tomoyo_policy_manager())
return -EPERM;
if (mutex_lock_interruptible(&head->io_sem))
return -EINTR;