|
@@ -213,6 +213,8 @@ static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_update_globally_readable_entry(const char *filename,
|
|
|
const bool is_delete)
|
|
@@ -228,7 +230,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
|
|
|
if (!saved_filename)
|
|
|
return -ENOMEM;
|
|
|
down_write(&tomoyo_globally_readable_list_lock);
|
|
|
- list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
|
|
|
if (ptr->filename != saved_filename)
|
|
|
continue;
|
|
|
ptr->is_deleted = is_delete;
|
|
@@ -243,7 +245,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
|
|
|
if (!new_entry)
|
|
|
goto out;
|
|
|
new_entry->filename = saved_filename;
|
|
|
- list_add_tail(&new_entry->list, &tomoyo_globally_readable_list);
|
|
|
+ list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list);
|
|
|
error = 0;
|
|
|
out:
|
|
|
up_write(&tomoyo_globally_readable_list_lock);
|
|
@@ -256,21 +258,22 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
|
|
|
* @filename: The filename to check.
|
|
|
*
|
|
|
* Returns true if any domain can open @filename for reading, false otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
|
|
|
filename)
|
|
|
{
|
|
|
struct tomoyo_globally_readable_file_entry *ptr;
|
|
|
bool found = false;
|
|
|
- down_read(&tomoyo_globally_readable_list_lock);
|
|
|
- list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) {
|
|
|
+
|
|
|
+ list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
|
|
|
if (!ptr->is_deleted &&
|
|
|
tomoyo_path_matches_pattern(filename, ptr->filename)) {
|
|
|
found = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- up_read(&tomoyo_globally_readable_list_lock);
|
|
|
return found;
|
|
|
}
|
|
|
|
|
@@ -281,6 +284,8 @@ static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
|
|
|
{
|
|
@@ -293,13 +298,14 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
|
|
|
* @head: Pointer to "struct tomoyo_io_buffer".
|
|
|
*
|
|
|
* Returns true on success, false otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
|
|
|
{
|
|
|
struct list_head *pos;
|
|
|
bool done = true;
|
|
|
|
|
|
- down_read(&tomoyo_globally_readable_list_lock);
|
|
|
list_for_each_cookie(pos, head->read_var2,
|
|
|
&tomoyo_globally_readable_list) {
|
|
|
struct tomoyo_globally_readable_file_entry *ptr;
|
|
@@ -313,7 +319,6 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
|
|
|
if (!done)
|
|
|
break;
|
|
|
}
|
|
|
- up_read(&tomoyo_globally_readable_list_lock);
|
|
|
return done;
|
|
|
}
|
|
|
|
|
@@ -356,6 +361,8 @@ static DECLARE_RWSEM(tomoyo_pattern_list_lock);
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_update_file_pattern_entry(const char *pattern,
|
|
|
const bool is_delete)
|
|
@@ -371,7 +378,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
|
|
|
if (!saved_pattern)
|
|
|
return -ENOMEM;
|
|
|
down_write(&tomoyo_pattern_list_lock);
|
|
|
- list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
|
|
|
if (saved_pattern != ptr->pattern)
|
|
|
continue;
|
|
|
ptr->is_deleted = is_delete;
|
|
@@ -386,7 +393,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
|
|
|
if (!new_entry)
|
|
|
goto out;
|
|
|
new_entry->pattern = saved_pattern;
|
|
|
- list_add_tail(&new_entry->list, &tomoyo_pattern_list);
|
|
|
+ list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list);
|
|
|
error = 0;
|
|
|
out:
|
|
|
up_write(&tomoyo_pattern_list_lock);
|
|
@@ -399,6 +406,8 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
|
|
|
* @filename: The filename to find patterned pathname.
|
|
|
*
|
|
|
* Returns pointer to pathname pattern if matched, @filename otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static const struct tomoyo_path_info *
|
|
|
tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
|
|
@@ -406,8 +415,7 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
|
|
|
struct tomoyo_pattern_entry *ptr;
|
|
|
const struct tomoyo_path_info *pattern = NULL;
|
|
|
|
|
|
- down_read(&tomoyo_pattern_list_lock);
|
|
|
- list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
|
|
|
if (ptr->is_deleted)
|
|
|
continue;
|
|
|
if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
|
|
@@ -420,7 +428,6 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- up_read(&tomoyo_pattern_list_lock);
|
|
|
if (pattern)
|
|
|
filename = pattern;
|
|
|
return filename;
|
|
@@ -433,6 +440,8 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
int tomoyo_write_pattern_policy(char *data, const bool is_delete)
|
|
|
{
|
|
@@ -445,13 +454,14 @@ int tomoyo_write_pattern_policy(char *data, const bool is_delete)
|
|
|
* @head: Pointer to "struct tomoyo_io_buffer".
|
|
|
*
|
|
|
* Returns true on success, false otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
|
|
|
{
|
|
|
struct list_head *pos;
|
|
|
bool done = true;
|
|
|
|
|
|
- down_read(&tomoyo_pattern_list_lock);
|
|
|
list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
|
|
|
struct tomoyo_pattern_entry *ptr;
|
|
|
ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
|
|
@@ -462,7 +472,6 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
|
|
|
if (!done)
|
|
|
break;
|
|
|
}
|
|
|
- up_read(&tomoyo_pattern_list_lock);
|
|
|
return done;
|
|
|
}
|
|
|
|
|
@@ -505,6 +514,8 @@ static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_update_no_rewrite_entry(const char *pattern,
|
|
|
const bool is_delete)
|
|
@@ -519,7 +530,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
|
|
|
if (!saved_pattern)
|
|
|
return -ENOMEM;
|
|
|
down_write(&tomoyo_no_rewrite_list_lock);
|
|
|
- list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
|
|
|
if (ptr->pattern != saved_pattern)
|
|
|
continue;
|
|
|
ptr->is_deleted = is_delete;
|
|
@@ -534,7 +545,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
|
|
|
if (!new_entry)
|
|
|
goto out;
|
|
|
new_entry->pattern = saved_pattern;
|
|
|
- list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list);
|
|
|
+ list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list);
|
|
|
error = 0;
|
|
|
out:
|
|
|
up_write(&tomoyo_no_rewrite_list_lock);
|
|
@@ -548,14 +559,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
|
|
|
*
|
|
|
* Returns true if @filename is specified by "deny_rewrite" directive,
|
|
|
* false otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
|
|
|
{
|
|
|
struct tomoyo_no_rewrite_entry *ptr;
|
|
|
bool found = false;
|
|
|
|
|
|
- down_read(&tomoyo_no_rewrite_list_lock);
|
|
|
- list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
|
|
|
if (ptr->is_deleted)
|
|
|
continue;
|
|
|
if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
|
|
@@ -563,7 +575,6 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
|
|
|
found = true;
|
|
|
break;
|
|
|
}
|
|
|
- up_read(&tomoyo_no_rewrite_list_lock);
|
|
|
return found;
|
|
|
}
|
|
|
|
|
@@ -574,6 +585,8 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
|
|
|
{
|
|
@@ -586,13 +599,14 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
|
|
|
* @head: Pointer to "struct tomoyo_io_buffer".
|
|
|
*
|
|
|
* Returns true on success, false otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
|
|
|
{
|
|
|
struct list_head *pos;
|
|
|
bool done = true;
|
|
|
|
|
|
- down_read(&tomoyo_no_rewrite_list_lock);
|
|
|
list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
|
|
|
struct tomoyo_no_rewrite_entry *ptr;
|
|
|
ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
|
|
@@ -603,7 +617,6 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
|
|
|
if (!done)
|
|
|
break;
|
|
|
}
|
|
|
- up_read(&tomoyo_no_rewrite_list_lock);
|
|
|
return done;
|
|
|
}
|
|
|
|
|
@@ -621,6 +634,8 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
|
|
|
* Current policy syntax uses "allow_read/write" instead of "6",
|
|
|
* "allow_read" instead of "4", "allow_write" instead of "2",
|
|
|
* "allow_execute" instead of "1".
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_update_file_acl(const char *filename, u8 perm,
|
|
|
struct tomoyo_domain_info * const domain,
|
|
@@ -658,6 +673,8 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
|
|
|
* @may_use_pattern: True if patterned ACL is permitted.
|
|
|
*
|
|
|
* Returns 0 on success, -EPERM otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
|
|
|
domain,
|
|
@@ -669,8 +686,7 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
|
|
|
struct tomoyo_acl_info *ptr;
|
|
|
int error = -EPERM;
|
|
|
|
|
|
- down_read(&tomoyo_domain_acl_info_list_lock);
|
|
|
- list_for_each_entry(ptr, &domain->acl_info_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
|
struct tomoyo_single_path_acl_record *acl;
|
|
|
if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
|
|
|
continue;
|
|
@@ -693,7 +709,6 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
|
|
|
error = 0;
|
|
|
break;
|
|
|
}
|
|
|
- up_read(&tomoyo_domain_acl_info_list_lock);
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -705,6 +720,8 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
|
|
|
* @operation: Mode ("read" or "write" or "read/write" or "execute").
|
|
|
*
|
|
|
* Returns 0 on success, -EPERM otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
|
|
|
const struct tomoyo_path_info *filename,
|
|
@@ -738,6 +755,8 @@ static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
|
|
|
* @mode: Access control mode.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
|
|
|
const struct tomoyo_path_info *filename,
|
|
@@ -791,6 +810,8 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
|
|
|
const bool is_delete)
|
|
@@ -838,6 +859,8 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
|
|
|
struct tomoyo_domain_info *
|
|
@@ -861,7 +884,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
|
|
|
down_write(&tomoyo_domain_acl_info_list_lock);
|
|
|
if (is_delete)
|
|
|
goto delete;
|
|
|
- list_for_each_entry(ptr, &domain->acl_info_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
|
if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
|
|
|
continue;
|
|
|
acl = container_of(ptr, struct tomoyo_single_path_acl_record,
|
|
@@ -894,12 +917,12 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
|
|
|
if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
|
|
|
acl->perm |= rw_mask;
|
|
|
acl->filename = saved_filename;
|
|
|
- list_add_tail(&acl->head.list, &domain->acl_info_list);
|
|
|
+ list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
|
|
|
error = 0;
|
|
|
goto out;
|
|
|
delete:
|
|
|
error = -ENOENT;
|
|
|
- list_for_each_entry(ptr, &domain->acl_info_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
|
if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
|
|
|
continue;
|
|
|
acl = container_of(ptr, struct tomoyo_single_path_acl_record,
|
|
@@ -934,6 +957,8 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
|
|
|
* @is_delete: True if it is a delete request.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
|
|
|
const char *filename2,
|
|
@@ -959,7 +984,7 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
|
|
|
down_write(&tomoyo_domain_acl_info_list_lock);
|
|
|
if (is_delete)
|
|
|
goto delete;
|
|
|
- list_for_each_entry(ptr, &domain->acl_info_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
|
if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
|
|
|
continue;
|
|
|
acl = container_of(ptr, struct tomoyo_double_path_acl_record,
|
|
@@ -982,12 +1007,12 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
|
|
|
acl->perm = perm;
|
|
|
acl->filename1 = saved_filename1;
|
|
|
acl->filename2 = saved_filename2;
|
|
|
- list_add_tail(&acl->head.list, &domain->acl_info_list);
|
|
|
+ list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
|
|
|
error = 0;
|
|
|
goto out;
|
|
|
delete:
|
|
|
error = -ENOENT;
|
|
|
- list_for_each_entry(ptr, &domain->acl_info_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
|
if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
|
|
|
continue;
|
|
|
acl = container_of(ptr, struct tomoyo_double_path_acl_record,
|
|
@@ -1014,6 +1039,8 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
|
|
|
* @filename: Filename to check.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
|
|
|
const u8 type,
|
|
@@ -1033,6 +1060,8 @@ static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
|
|
|
* @filename2: Second filename to check.
|
|
|
*
|
|
|
* Returns 0 on success, -EPERM otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
|
|
|
const u8 type,
|
|
@@ -1047,8 +1076,7 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
|
|
|
|
|
|
if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
|
|
|
return 0;
|
|
|
- down_read(&tomoyo_domain_acl_info_list_lock);
|
|
|
- list_for_each_entry(ptr, &domain->acl_info_list, list) {
|
|
|
+ list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
|
|
struct tomoyo_double_path_acl_record *acl;
|
|
|
if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
|
|
|
continue;
|
|
@@ -1063,7 +1091,6 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
|
|
|
error = 0;
|
|
|
break;
|
|
|
}
|
|
|
- up_read(&tomoyo_domain_acl_info_list_lock);
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -1076,6 +1103,8 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
|
|
|
* @mode: Access control mode.
|
|
|
*
|
|
|
* Returns 0 on success, negative value otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
|
|
|
const domain, u8 operation,
|
|
@@ -1124,6 +1153,8 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
|
|
|
* @filename: Check permission for "execute".
|
|
|
*
|
|
|
* Returns 0 on success, negativevalue otherwise.
|
|
|
+ *
|
|
|
+ * Caller holds tomoyo_read_lock().
|
|
|
*/
|
|
|
int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
|
|
|
const struct tomoyo_path_info *filename)
|
|
@@ -1152,6 +1183,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
|
|
|
struct tomoyo_path_info *buf;
|
|
|
const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
|
|
|
const bool is_enforce = (mode == 3);
|
|
|
+ int idx;
|
|
|
|
|
|
if (!mode || !path->mnt)
|
|
|
return 0;
|
|
@@ -1163,6 +1195,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
|
|
|
* don't call me.
|
|
|
*/
|
|
|
return 0;
|
|
|
+ idx = tomoyo_read_lock();
|
|
|
buf = tomoyo_get_path(path);
|
|
|
if (!buf)
|
|
|
goto out;
|
|
@@ -1188,6 +1221,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
|
|
|
buf, mode);
|
|
|
out:
|
|
|
tomoyo_free(buf);
|
|
|
+ tomoyo_read_unlock(idx);
|
|
|
if (!is_enforce)
|
|
|
error = 0;
|
|
|
return error;
|
|
@@ -1209,9 +1243,11 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
|
|
|
struct tomoyo_path_info *buf;
|
|
|
const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
|
|
|
const bool is_enforce = (mode == 3);
|
|
|
+ int idx;
|
|
|
|
|
|
if (!mode || !path->mnt)
|
|
|
return 0;
|
|
|
+ idx = tomoyo_read_lock();
|
|
|
buf = tomoyo_get_path(path);
|
|
|
if (!buf)
|
|
|
goto out;
|
|
@@ -1231,6 +1267,7 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
|
|
|
mode);
|
|
|
out:
|
|
|
tomoyo_free(buf);
|
|
|
+ tomoyo_read_unlock(idx);
|
|
|
if (!is_enforce)
|
|
|
error = 0;
|
|
|
return error;
|
|
@@ -1251,9 +1288,12 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
|
|
|
const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
|
|
|
const bool is_enforce = (mode == 3);
|
|
|
struct tomoyo_path_info *buf;
|
|
|
+ int idx;
|
|
|
|
|
|
if (!mode || !filp->f_path.mnt)
|
|
|
return 0;
|
|
|
+
|
|
|
+ idx = tomoyo_read_lock();
|
|
|
buf = tomoyo_get_path(&filp->f_path);
|
|
|
if (!buf)
|
|
|
goto out;
|
|
@@ -1266,6 +1306,7 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
|
|
|
buf, mode);
|
|
|
out:
|
|
|
tomoyo_free(buf);
|
|
|
+ tomoyo_read_unlock(idx);
|
|
|
if (!is_enforce)
|
|
|
error = 0;
|
|
|
return error;
|
|
@@ -1290,9 +1331,11 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
|
|
|
const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
|
|
|
const bool is_enforce = (mode == 3);
|
|
|
const char *msg;
|
|
|
+ int idx;
|
|
|
|
|
|
if (!mode || !path1->mnt || !path2->mnt)
|
|
|
return 0;
|
|
|
+ idx = tomoyo_read_lock();
|
|
|
buf1 = tomoyo_get_path(path1);
|
|
|
buf2 = tomoyo_get_path(path2);
|
|
|
if (!buf1 || !buf2)
|
|
@@ -1331,6 +1374,7 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
|
|
|
out:
|
|
|
tomoyo_free(buf1);
|
|
|
tomoyo_free(buf2);
|
|
|
+ tomoyo_read_unlock(idx);
|
|
|
if (!is_enforce)
|
|
|
error = 0;
|
|
|
return error;
|