|
@@ -164,38 +164,36 @@ LIST_HEAD(tomoyo_globally_readable_list);
|
|
static int tomoyo_update_globally_readable_entry(const char *filename,
|
|
static int tomoyo_update_globally_readable_entry(const char *filename,
|
|
const bool is_delete)
|
|
const bool is_delete)
|
|
{
|
|
{
|
|
- struct tomoyo_globally_readable_file_entry *entry = NULL;
|
|
|
|
struct tomoyo_globally_readable_file_entry *ptr;
|
|
struct tomoyo_globally_readable_file_entry *ptr;
|
|
- const struct tomoyo_path_info *saved_filename;
|
|
|
|
|
|
+ struct tomoyo_globally_readable_file_entry e = { };
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
|
|
|
|
if (!tomoyo_is_correct_path(filename, 1, 0, -1))
|
|
if (!tomoyo_is_correct_path(filename, 1, 0, -1))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
- saved_filename = tomoyo_get_name(filename);
|
|
|
|
- if (!saved_filename)
|
|
|
|
|
|
+ e.filename = tomoyo_get_name(filename);
|
|
|
|
+ if (!e.filename)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
- if (!is_delete)
|
|
|
|
- entry = kmalloc(sizeof(*entry), GFP_NOFS);
|
|
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
goto out;
|
|
goto out;
|
|
list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
|
|
list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
|
|
- if (ptr->filename != saved_filename)
|
|
|
|
|
|
+ if (ptr->filename != e.filename)
|
|
continue;
|
|
continue;
|
|
ptr->is_deleted = is_delete;
|
|
ptr->is_deleted = is_delete;
|
|
error = 0;
|
|
error = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- if (!is_delete && error && tomoyo_memory_ok(entry)) {
|
|
|
|
- entry->filename = saved_filename;
|
|
|
|
- saved_filename = NULL;
|
|
|
|
- list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
|
|
|
|
- entry = NULL;
|
|
|
|
- error = 0;
|
|
|
|
|
|
+ if (!is_delete && error) {
|
|
|
|
+ struct tomoyo_globally_readable_file_entry *entry =
|
|
|
|
+ tomoyo_commit_ok(&e, sizeof(e));
|
|
|
|
+ if (entry) {
|
|
|
|
+ list_add_tail_rcu(&entry->list,
|
|
|
|
+ &tomoyo_globally_readable_list);
|
|
|
|
+ error = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
out:
|
|
out:
|
|
- tomoyo_put_name(saved_filename);
|
|
|
|
- kfree(entry);
|
|
|
|
|
|
+ tomoyo_put_name(e.filename);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -313,38 +311,34 @@ LIST_HEAD(tomoyo_pattern_list);
|
|
static int tomoyo_update_file_pattern_entry(const char *pattern,
|
|
static int tomoyo_update_file_pattern_entry(const char *pattern,
|
|
const bool is_delete)
|
|
const bool is_delete)
|
|
{
|
|
{
|
|
- struct tomoyo_pattern_entry *entry = NULL;
|
|
|
|
struct tomoyo_pattern_entry *ptr;
|
|
struct tomoyo_pattern_entry *ptr;
|
|
- const struct tomoyo_path_info *saved_pattern;
|
|
|
|
|
|
+ struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) };
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
|
|
|
|
- saved_pattern = tomoyo_get_name(pattern);
|
|
|
|
- if (!saved_pattern)
|
|
|
|
|
|
+ if (!e.pattern)
|
|
return error;
|
|
return error;
|
|
- if (!saved_pattern->is_patterned)
|
|
|
|
|
|
+ if (!e.pattern->is_patterned)
|
|
goto out;
|
|
goto out;
|
|
- if (!is_delete)
|
|
|
|
- entry = kmalloc(sizeof(*entry), GFP_NOFS);
|
|
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
goto out;
|
|
goto out;
|
|
list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
|
|
list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
|
|
- if (saved_pattern != ptr->pattern)
|
|
|
|
|
|
+ if (e.pattern != ptr->pattern)
|
|
continue;
|
|
continue;
|
|
ptr->is_deleted = is_delete;
|
|
ptr->is_deleted = is_delete;
|
|
error = 0;
|
|
error = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- if (!is_delete && error && tomoyo_memory_ok(entry)) {
|
|
|
|
- entry->pattern = saved_pattern;
|
|
|
|
- saved_pattern = NULL;
|
|
|
|
- list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
|
|
|
|
- entry = NULL;
|
|
|
|
- error = 0;
|
|
|
|
|
|
+ if (!is_delete && error) {
|
|
|
|
+ struct tomoyo_pattern_entry *entry =
|
|
|
|
+ tomoyo_commit_ok(&e, sizeof(e));
|
|
|
|
+ if (entry) {
|
|
|
|
+ list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
|
|
|
|
+ error = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
out:
|
|
out:
|
|
- kfree(entry);
|
|
|
|
- tomoyo_put_name(saved_pattern);
|
|
|
|
|
|
+ tomoyo_put_name(e.pattern);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -467,38 +461,36 @@ LIST_HEAD(tomoyo_no_rewrite_list);
|
|
static int tomoyo_update_no_rewrite_entry(const char *pattern,
|
|
static int tomoyo_update_no_rewrite_entry(const char *pattern,
|
|
const bool is_delete)
|
|
const bool is_delete)
|
|
{
|
|
{
|
|
- struct tomoyo_no_rewrite_entry *entry = NULL;
|
|
|
|
struct tomoyo_no_rewrite_entry *ptr;
|
|
struct tomoyo_no_rewrite_entry *ptr;
|
|
- const struct tomoyo_path_info *saved_pattern;
|
|
|
|
|
|
+ struct tomoyo_no_rewrite_entry e = { };
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
|
|
|
|
if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
|
|
if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
- saved_pattern = tomoyo_get_name(pattern);
|
|
|
|
- if (!saved_pattern)
|
|
|
|
|
|
+ e.pattern = tomoyo_get_name(pattern);
|
|
|
|
+ if (!e.pattern)
|
|
return error;
|
|
return error;
|
|
- if (!is_delete)
|
|
|
|
- entry = kmalloc(sizeof(*entry), GFP_NOFS);
|
|
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
goto out;
|
|
goto out;
|
|
list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
|
|
list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
|
|
- if (ptr->pattern != saved_pattern)
|
|
|
|
|
|
+ if (ptr->pattern != e.pattern)
|
|
continue;
|
|
continue;
|
|
ptr->is_deleted = is_delete;
|
|
ptr->is_deleted = is_delete;
|
|
error = 0;
|
|
error = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- if (!is_delete && error && tomoyo_memory_ok(entry)) {
|
|
|
|
- entry->pattern = saved_pattern;
|
|
|
|
- saved_pattern = NULL;
|
|
|
|
- list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
|
|
|
|
- entry = NULL;
|
|
|
|
- error = 0;
|
|
|
|
|
|
+ if (!is_delete && error) {
|
|
|
|
+ struct tomoyo_no_rewrite_entry *entry =
|
|
|
|
+ tomoyo_commit_ok(&e, sizeof(e));
|
|
|
|
+ if (entry) {
|
|
|
|
+ list_add_tail_rcu(&entry->list,
|
|
|
|
+ &tomoyo_no_rewrite_list);
|
|
|
|
+ error = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
out:
|
|
out:
|
|
- tomoyo_put_name(saved_pattern);
|
|
|
|
- kfree(entry);
|
|
|
|
|
|
+ tomoyo_put_name(e.pattern);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -810,23 +802,26 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
|
|
struct tomoyo_domain_info *const domain,
|
|
struct tomoyo_domain_info *const domain,
|
|
const bool is_delete)
|
|
const bool is_delete)
|
|
{
|
|
{
|
|
- static const u32 rw_mask =
|
|
|
|
|
|
+ static const u32 tomoyo_rw_mask =
|
|
(1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
|
|
(1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
|
|
- const struct tomoyo_path_info *saved_filename;
|
|
|
|
|
|
+ const u32 perm = 1 << type;
|
|
struct tomoyo_acl_info *ptr;
|
|
struct tomoyo_acl_info *ptr;
|
|
- struct tomoyo_path_acl *entry = NULL;
|
|
|
|
|
|
+ struct tomoyo_path_acl e = {
|
|
|
|
+ .head.type = TOMOYO_TYPE_PATH_ACL,
|
|
|
|
+ .perm_high = perm >> 16,
|
|
|
|
+ .perm = perm
|
|
|
|
+ };
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
- const u32 perm = 1 << type;
|
|
|
|
|
|
|
|
|
|
+ if (type == TOMOYO_TYPE_READ_WRITE)
|
|
|
|
+ e.perm |= tomoyo_rw_mask;
|
|
if (!domain)
|
|
if (!domain)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
if (!tomoyo_is_correct_path(filename, 0, 0, 0))
|
|
if (!tomoyo_is_correct_path(filename, 0, 0, 0))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
- saved_filename = tomoyo_get_name(filename);
|
|
|
|
- if (!saved_filename)
|
|
|
|
|
|
+ e.filename = tomoyo_get_name(filename);
|
|
|
|
+ if (!e.filename)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
- if (!is_delete)
|
|
|
|
- entry = kmalloc(sizeof(*entry), GFP_NOFS);
|
|
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
goto out;
|
|
goto out;
|
|
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
@@ -834,48 +829,42 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
|
|
container_of(ptr, struct tomoyo_path_acl, head);
|
|
container_of(ptr, struct tomoyo_path_acl, head);
|
|
if (ptr->type != TOMOYO_TYPE_PATH_ACL)
|
|
if (ptr->type != TOMOYO_TYPE_PATH_ACL)
|
|
continue;
|
|
continue;
|
|
- if (acl->filename != saved_filename)
|
|
|
|
|
|
+ if (acl->filename != e.filename)
|
|
continue;
|
|
continue;
|
|
if (is_delete) {
|
|
if (is_delete) {
|
|
if (perm <= 0xFFFF)
|
|
if (perm <= 0xFFFF)
|
|
acl->perm &= ~perm;
|
|
acl->perm &= ~perm;
|
|
else
|
|
else
|
|
acl->perm_high &= ~(perm >> 16);
|
|
acl->perm_high &= ~(perm >> 16);
|
|
- if ((acl->perm & rw_mask) != rw_mask)
|
|
|
|
|
|
+ if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask)
|
|
acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
|
|
acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
|
|
else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
|
|
else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
|
|
- acl->perm &= ~rw_mask;
|
|
|
|
|
|
+ acl->perm &= ~tomoyo_rw_mask;
|
|
} else {
|
|
} else {
|
|
if (perm <= 0xFFFF)
|
|
if (perm <= 0xFFFF)
|
|
acl->perm |= perm;
|
|
acl->perm |= perm;
|
|
else
|
|
else
|
|
acl->perm_high |= (perm >> 16);
|
|
acl->perm_high |= (perm >> 16);
|
|
- if ((acl->perm & rw_mask) == rw_mask)
|
|
|
|
|
|
+ if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask)
|
|
acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
|
|
acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
|
|
else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
|
|
else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
|
|
- acl->perm |= rw_mask;
|
|
|
|
|
|
+ acl->perm |= tomoyo_rw_mask;
|
|
}
|
|
}
|
|
error = 0;
|
|
error = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- if (!is_delete && error && tomoyo_memory_ok(entry)) {
|
|
|
|
- entry->head.type = TOMOYO_TYPE_PATH_ACL;
|
|
|
|
- if (perm <= 0xFFFF)
|
|
|
|
- entry->perm = perm;
|
|
|
|
- else
|
|
|
|
- entry->perm_high = (perm >> 16);
|
|
|
|
- if (perm == (1 << TOMOYO_TYPE_READ_WRITE))
|
|
|
|
- entry->perm |= rw_mask;
|
|
|
|
- entry->filename = saved_filename;
|
|
|
|
- saved_filename = NULL;
|
|
|
|
- list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
|
|
|
|
- entry = NULL;
|
|
|
|
- error = 0;
|
|
|
|
|
|
+ if (!is_delete && error) {
|
|
|
|
+ struct tomoyo_path_acl *entry =
|
|
|
|
+ tomoyo_commit_ok(&e, sizeof(e));
|
|
|
|
+ if (entry) {
|
|
|
|
+ list_add_tail_rcu(&entry->head.list,
|
|
|
|
+ &domain->acl_info_list);
|
|
|
|
+ error = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
out:
|
|
out:
|
|
- kfree(entry);
|
|
|
|
- tomoyo_put_name(saved_filename);
|
|
|
|
|
|
+ tomoyo_put_name(e.filename);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -897,24 +886,23 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
|
|
struct tomoyo_domain_info *const domain,
|
|
struct tomoyo_domain_info *const domain,
|
|
const bool is_delete)
|
|
const bool is_delete)
|
|
{
|
|
{
|
|
- const struct tomoyo_path_info *saved_filename1;
|
|
|
|
- const struct tomoyo_path_info *saved_filename2;
|
|
|
|
|
|
+ const u8 perm = 1 << type;
|
|
|
|
+ struct tomoyo_path2_acl e = {
|
|
|
|
+ .head.type = TOMOYO_TYPE_PATH2_ACL,
|
|
|
|
+ .perm = perm
|
|
|
|
+ };
|
|
struct tomoyo_acl_info *ptr;
|
|
struct tomoyo_acl_info *ptr;
|
|
- struct tomoyo_path2_acl *entry = NULL;
|
|
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
int error = is_delete ? -ENOENT : -ENOMEM;
|
|
- const u8 perm = 1 << type;
|
|
|
|
|
|
|
|
if (!domain)
|
|
if (!domain)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
|
|
if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
|
|
!tomoyo_is_correct_path(filename2, 0, 0, 0))
|
|
!tomoyo_is_correct_path(filename2, 0, 0, 0))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
- saved_filename1 = tomoyo_get_name(filename1);
|
|
|
|
- saved_filename2 = tomoyo_get_name(filename2);
|
|
|
|
- if (!saved_filename1 || !saved_filename2)
|
|
|
|
|
|
+ e.filename1 = tomoyo_get_name(filename1);
|
|
|
|
+ e.filename2 = tomoyo_get_name(filename2);
|
|
|
|
+ if (!e.filename1 || !e.filename2)
|
|
goto out;
|
|
goto out;
|
|
- if (!is_delete)
|
|
|
|
- entry = kmalloc(sizeof(*entry), GFP_NOFS);
|
|
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
if (mutex_lock_interruptible(&tomoyo_policy_lock))
|
|
goto out;
|
|
goto out;
|
|
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
@@ -922,8 +910,8 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
|
|
container_of(ptr, struct tomoyo_path2_acl, head);
|
|
container_of(ptr, struct tomoyo_path2_acl, head);
|
|
if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
|
|
if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
|
|
continue;
|
|
continue;
|
|
- if (acl->filename1 != saved_filename1 ||
|
|
|
|
- acl->filename2 != saved_filename2)
|
|
|
|
|
|
+ if (acl->filename1 != e.filename1 ||
|
|
|
|
+ acl->filename2 != e.filename2)
|
|
continue;
|
|
continue;
|
|
if (is_delete)
|
|
if (is_delete)
|
|
acl->perm &= ~perm;
|
|
acl->perm &= ~perm;
|
|
@@ -932,22 +920,19 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
|
|
error = 0;
|
|
error = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- if (!is_delete && error && tomoyo_memory_ok(entry)) {
|
|
|
|
- entry->head.type = TOMOYO_TYPE_PATH2_ACL;
|
|
|
|
- entry->perm = perm;
|
|
|
|
- entry->filename1 = saved_filename1;
|
|
|
|
- saved_filename1 = NULL;
|
|
|
|
- entry->filename2 = saved_filename2;
|
|
|
|
- saved_filename2 = NULL;
|
|
|
|
- list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
|
|
|
|
- entry = NULL;
|
|
|
|
- error = 0;
|
|
|
|
|
|
+ if (!is_delete && error) {
|
|
|
|
+ struct tomoyo_path2_acl *entry =
|
|
|
|
+ tomoyo_commit_ok(&e, sizeof(e));
|
|
|
|
+ if (entry) {
|
|
|
|
+ list_add_tail_rcu(&entry->head.list,
|
|
|
|
+ &domain->acl_info_list);
|
|
|
|
+ error = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
mutex_unlock(&tomoyo_policy_lock);
|
|
out:
|
|
out:
|
|
- tomoyo_put_name(saved_filename1);
|
|
|
|
- tomoyo_put_name(saved_filename2);
|
|
|
|
- kfree(entry);
|
|
|
|
|
|
+ tomoyo_put_name(e.filename1);
|
|
|
|
+ tomoyo_put_name(e.filename2);
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|