diff options
Diffstat (limited to 'security/tomoyo/number_group.c')
-rw-r--r-- | security/tomoyo/number_group.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/security/tomoyo/number_group.c b/security/tomoyo/number_group.c index afc5b6972129..7266a7462c45 100644 --- a/security/tomoyo/number_group.c +++ b/security/tomoyo/number_group.c | |||
@@ -56,6 +56,18 @@ struct tomoyo_number_group *tomoyo_get_number_group(const char *group_name) | |||
56 | return !error ? group : NULL; | 56 | return !error ? group : NULL; |
57 | } | 57 | } |
58 | 58 | ||
59 | static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, | ||
60 | const struct tomoyo_acl_head *b) | ||
61 | { | ||
62 | return !memcmp(&container_of(a, struct tomoyo_number_group_member, | ||
63 | head)->number, | ||
64 | &container_of(b, struct tomoyo_number_group_member, | ||
65 | head)->number, | ||
66 | sizeof(container_of(a, | ||
67 | struct tomoyo_number_group_member, | ||
68 | head)->number)); | ||
69 | } | ||
70 | |||
59 | /** | 71 | /** |
60 | * tomoyo_write_number_group_policy - Write "struct tomoyo_number_group" list. | 72 | * tomoyo_write_number_group_policy - Write "struct tomoyo_number_group" list. |
61 | * | 73 | * |
@@ -68,40 +80,19 @@ int tomoyo_write_number_group_policy(char *data, const bool is_delete) | |||
68 | { | 80 | { |
69 | struct tomoyo_number_group *group; | 81 | struct tomoyo_number_group *group; |
70 | struct tomoyo_number_group_member e = { }; | 82 | struct tomoyo_number_group_member e = { }; |
71 | struct tomoyo_number_group_member *member; | 83 | int error; |
72 | int error = is_delete ? -ENOENT : -ENOMEM; | ||
73 | char *w[2]; | 84 | char *w[2]; |
74 | if (!tomoyo_tokenize(data, w, sizeof(w))) | 85 | if (!tomoyo_tokenize(data, w, sizeof(w))) |
75 | return -EINVAL; | 86 | return -EINVAL; |
76 | if (!tomoyo_parse_number_union(w[1], &e.number)) | 87 | if (w[1][0] == '@' || !tomoyo_parse_number_union(w[1], &e.number) || |
77 | return -EINVAL; | 88 | e.number.values[0] > e.number.values[1]) |
78 | if (e.number.is_group || e.number.values[0] > e.number.values[1]) { | ||
79 | tomoyo_put_number_union(&e.number); | ||
80 | return -EINVAL; | 89 | return -EINVAL; |
81 | } | ||
82 | group = tomoyo_get_number_group(w[0]); | 90 | group = tomoyo_get_number_group(w[0]); |
83 | if (!group) | 91 | if (!group) |
84 | return -ENOMEM; | 92 | return -ENOMEM; |
85 | if (mutex_lock_interruptible(&tomoyo_policy_lock)) | 93 | error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
86 | goto out; | 94 | &group->member_list, |
87 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | 95 | tomoyo_same_number_group); |
88 | if (memcmp(&member->number, &e.number, sizeof(e.number))) | ||
89 | continue; | ||
90 | member->head.is_deleted = is_delete; | ||
91 | error = 0; | ||
92 | break; | ||
93 | } | ||
94 | if (!is_delete && error) { | ||
95 | struct tomoyo_number_group_member *entry = | ||
96 | tomoyo_commit_ok(&e, sizeof(e)); | ||
97 | if (entry) { | ||
98 | list_add_tail_rcu(&entry->head.list, | ||
99 | &group->member_list); | ||
100 | error = 0; | ||
101 | } | ||
102 | } | ||
103 | mutex_unlock(&tomoyo_policy_lock); | ||
104 | out: | ||
105 | tomoyo_put_number_group(group); | 96 | tomoyo_put_number_group(group); |
106 | return error; | 97 | return error; |
107 | } | 98 | } |