static int tomoyo_update_globally_readable_entry(const char *filename,
const bool is_delete)
{
- struct tomoyo_globally_readable_file_entry *new_entry;
+ struct tomoyo_globally_readable_file_entry *entry = NULL;
struct tomoyo_globally_readable_file_entry *ptr;
const struct tomoyo_path_info *saved_filename;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__))
return -EINVAL;
saved_filename = tomoyo_save_name(filename);
if (!saved_filename)
return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
if (ptr->filename != saved_filename)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->filename = saved_filename;
+ list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
+ entry = NULL;
+ error = 0;
}
- if (!tomoyo_memory_ok(new_entry))
- goto out;
- new_entry->filename = saved_filename;
- list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list);
- new_entry = NULL;
- error = 0;
- out:
mutex_unlock(&tomoyo_policy_lock);
- kfree(new_entry);
+ kfree(entry);
return error;
}
static int tomoyo_update_file_pattern_entry(const char *pattern,
const bool is_delete)
{
- struct tomoyo_pattern_entry *new_entry;
+ struct tomoyo_pattern_entry *entry = NULL;
struct tomoyo_pattern_entry *ptr;
const struct tomoyo_path_info *saved_pattern;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
- if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__))
- return -EINVAL;
saved_pattern = tomoyo_save_name(pattern);
if (!saved_pattern)
- return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ return error;
+ if (!saved_pattern->is_patterned)
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
if (saved_pattern != ptr->pattern)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->pattern = saved_pattern;
+ list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
+ entry = NULL;
+ error = 0;
}
- if (!tomoyo_memory_ok(new_entry))
- goto out;
- new_entry->pattern = saved_pattern;
- list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list);
- new_entry = NULL;
- error = 0;
- out:
mutex_unlock(&tomoyo_policy_lock);
- kfree(new_entry);
+ out:
+ kfree(entry);
return error;
}
static int tomoyo_update_no_rewrite_entry(const char *pattern,
const bool is_delete)
{
- struct tomoyo_no_rewrite_entry *new_entry, *ptr;
+ struct tomoyo_no_rewrite_entry *entry = NULL;
+ struct tomoyo_no_rewrite_entry *ptr;
const struct tomoyo_path_info *saved_pattern;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__))
return -EINVAL;
saved_pattern = tomoyo_save_name(pattern);
if (!saved_pattern)
- return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ return error;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
if (ptr->pattern != saved_pattern)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->pattern = saved_pattern;
+ list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
+ entry = NULL;
+ error = 0;
}
- if (!tomoyo_memory_ok(new_entry))
- goto out;
- new_entry->pattern = saved_pattern;
- list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list);
- new_entry = NULL;
- error = 0;
- out:
mutex_unlock(&tomoyo_policy_lock);
- kfree(new_entry);
+ kfree(entry);
return error;
}
(1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL);
const struct tomoyo_path_info *saved_filename;
struct tomoyo_acl_info *ptr;
- struct tomoyo_single_path_acl_record *acl;
- int error = -ENOMEM;
+ struct tomoyo_single_path_acl_record *entry = NULL;
+ int error = is_delete ? -ENOENT : -ENOMEM;
const u32 perm = 1 << type;
if (!domain)
saved_filename = tomoyo_save_name(filename);
if (!saved_filename)
return -ENOMEM;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
- if (is_delete)
- goto delete;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
+ struct tomoyo_single_path_acl_record *acl =
+ container_of(ptr, struct tomoyo_single_path_acl_record,
+ head);
if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL)
continue;
- acl = container_of(ptr, struct tomoyo_single_path_acl_record,
- head);
if (acl->filename != saved_filename)
continue;
- if (perm <= 0xFFFF)
- acl->perm |= perm;
- else
- acl->perm_high |= (perm >> 16);
- if ((acl->perm & rw_mask) == rw_mask)
- acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
- else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
- acl->perm |= rw_mask;
+ if (is_delete) {
+ if (perm <= 0xFFFF)
+ acl->perm &= ~perm;
+ else
+ acl->perm_high &= ~(perm >> 16);
+ if ((acl->perm & rw_mask) != rw_mask)
+ acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
+ else if (!(acl->perm &
+ (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
+ acl->perm &= ~rw_mask;
+ } else {
+ if (perm <= 0xFFFF)
+ acl->perm |= perm;
+ else
+ acl->perm_high |= (perm >> 16);
+ if ((acl->perm & rw_mask) == rw_mask)
+ acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
+ else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
+ acl->perm |= rw_mask;
+ }
error = 0;
- goto out;
- }
- /* Not found. Append it to the tail. */
- acl = kmalloc(sizeof(*acl), GFP_KERNEL);
- if (!tomoyo_memory_ok(acl)) {
- kfree(acl);
- acl = NULL;
- goto out;
+ break;
}
- acl->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
- if (perm <= 0xFFFF)
- acl->perm = perm;
- else
- acl->perm_high = (perm >> 16);
- if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
- acl->perm |= rw_mask;
- acl->filename = saved_filename;
- list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
- error = 0;
- goto out;
- delete:
- error = -ENOENT;
- list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
- if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL)
- continue;
- acl = container_of(ptr, struct tomoyo_single_path_acl_record,
- head);
- if (acl->filename != saved_filename)
- continue;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
if (perm <= 0xFFFF)
- acl->perm &= ~perm;
+ entry->perm = perm;
else
- acl->perm_high &= ~(perm >> 16);
- if ((acl->perm & rw_mask) != rw_mask)
- acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
- else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
- acl->perm &= ~rw_mask;
+ entry->perm_high = (perm >> 16);
+ if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
+ entry->perm |= rw_mask;
+ entry->filename = saved_filename;
+ list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
+ entry = NULL;
error = 0;
- break;
}
- out:
mutex_unlock(&tomoyo_policy_lock);
+ kfree(entry);
return error;
}
const struct tomoyo_path_info *saved_filename1;
const struct tomoyo_path_info *saved_filename2;
struct tomoyo_acl_info *ptr;
- struct tomoyo_double_path_acl_record *acl;
- int error = -ENOMEM;
+ struct tomoyo_double_path_acl_record *entry = NULL;
+ int error = is_delete ? -ENOENT : -ENOMEM;
const u8 perm = 1 << type;
if (!domain)
saved_filename1 = tomoyo_save_name(filename1);
saved_filename2 = tomoyo_save_name(filename2);
if (!saved_filename1 || !saved_filename2)
- return -ENOMEM;
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
- if (is_delete)
- goto delete;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
+ struct tomoyo_double_path_acl_record *acl =
+ container_of(ptr, struct tomoyo_double_path_acl_record,
+ head);
if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL)
continue;
- acl = container_of(ptr, struct tomoyo_double_path_acl_record,
- head);
if (acl->filename1 != saved_filename1 ||
acl->filename2 != saved_filename2)
continue;
- acl->perm |= perm;
+ if (is_delete)
+ acl->perm &= ~perm;
+ else
+ acl->perm |= perm;
error = 0;
- goto out;
- }
- /* Not found. Append it to the tail. */
- acl = kmalloc(sizeof(*acl), GFP_KERNEL);
- if (!tomoyo_memory_ok(acl)) {
- kfree(acl);
- acl = NULL;
- goto out;
+ break;
}
- acl->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
- acl->perm = perm;
- acl->filename1 = saved_filename1;
- acl->filename2 = saved_filename2;
- list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
- error = 0;
- goto out;
- delete:
- error = -ENOENT;
- list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
- if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL)
- continue;
- acl = container_of(ptr, struct tomoyo_double_path_acl_record,
- head);
- if (acl->filename1 != saved_filename1 ||
- acl->filename2 != saved_filename2)
- continue;
- acl->perm &= ~perm;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
+ entry->perm = perm;
+ entry->filename1 = saved_filename1;
+ entry->filename2 = saved_filename2;
+ list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
+ entry = NULL;
error = 0;
- break;
}
- out:
mutex_unlock(&tomoyo_policy_lock);
+ out:
+ kfree(entry);
return error;
}