diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2011-09-10 02:23:54 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-09-13 18:27:05 -0400 |
commit | 059d84dbb3897d4ee494a9c842c5dda54316cb47 (patch) | |
tree | 483ca0cb613b1304184b92f075b3f5283d36c723 /security/tomoyo/group.c | |
parent | d58e0da854376841ac99defeb117a83f086715c6 (diff) |
TOMOYO: Add socket operation restriction support.
This patch adds support for permission checks for PF_INET/PF_INET6/PF_UNIX
socket's bind()/listen()/connect()/send() operations.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/group.c')
-rw-r--r-- | security/tomoyo/group.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c index 5fb0e1298400..50092534ec54 100644 --- a/security/tomoyo/group.c +++ b/security/tomoyo/group.c | |||
@@ -42,7 +42,26 @@ static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a, | |||
42 | } | 42 | } |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list. | 45 | * tomoyo_same_address_group - Check for duplicated "struct tomoyo_address_group" entry. |
46 | * | ||
47 | * @a: Pointer to "struct tomoyo_acl_head". | ||
48 | * @b: Pointer to "struct tomoyo_acl_head". | ||
49 | * | ||
50 | * Returns true if @a == @b, false otherwise. | ||
51 | */ | ||
52 | static bool tomoyo_same_address_group(const struct tomoyo_acl_head *a, | ||
53 | const struct tomoyo_acl_head *b) | ||
54 | { | ||
55 | const struct tomoyo_address_group *p1 = container_of(a, typeof(*p1), | ||
56 | head); | ||
57 | const struct tomoyo_address_group *p2 = container_of(b, typeof(*p2), | ||
58 | head); | ||
59 | |||
60 | return tomoyo_same_ipaddr_union(&p1->address, &p2->address); | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group"/"struct tomoyo_address_group" list. | ||
46 | * | 65 | * |
47 | * @param: Pointer to "struct tomoyo_acl_param". | 66 | * @param: Pointer to "struct tomoyo_acl_param". |
48 | * @type: Type of this group. | 67 | * @type: Type of this group. |
@@ -77,6 +96,14 @@ int tomoyo_write_group(struct tomoyo_acl_param *param, const u8 type) | |||
77 | * tomoyo_put_number_union() is not needed because | 96 | * tomoyo_put_number_union() is not needed because |
78 | * param->data[0] != '@'. | 97 | * param->data[0] != '@'. |
79 | */ | 98 | */ |
99 | } else { | ||
100 | struct tomoyo_address_group e = { }; | ||
101 | |||
102 | if (param->data[0] == '@' || | ||
103 | !tomoyo_parse_ipaddr_union(param, &e.address)) | ||
104 | goto out; | ||
105 | error = tomoyo_update_policy(&e.head, sizeof(e), param, | ||
106 | tomoyo_same_address_group); | ||
80 | } | 107 | } |
81 | out: | 108 | out: |
82 | tomoyo_put_group(group); | 109 | tomoyo_put_group(group); |
@@ -137,3 +164,35 @@ bool tomoyo_number_matches_group(const unsigned long min, | |||
137 | } | 164 | } |
138 | return matched; | 165 | return matched; |
139 | } | 166 | } |
167 | |||
168 | /** | ||
169 | * tomoyo_address_matches_group - Check whether the given address matches members of the given address group. | ||
170 | * | ||
171 | * @is_ipv6: True if @address is an IPv6 address. | ||
172 | * @address: An IPv4 or IPv6 address. | ||
173 | * @group: Pointer to "struct tomoyo_address_group". | ||
174 | * | ||
175 | * Returns true if @address matches addresses in @group group, false otherwise. | ||
176 | * | ||
177 | * Caller holds tomoyo_read_lock(). | ||
178 | */ | ||
179 | bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address, | ||
180 | const struct tomoyo_group *group) | ||
181 | { | ||
182 | struct tomoyo_address_group *member; | ||
183 | bool matched = false; | ||
184 | const u8 size = is_ipv6 ? 16 : 4; | ||
185 | |||
186 | list_for_each_entry_rcu(member, &group->member_list, head.list) { | ||
187 | if (member->head.is_deleted) | ||
188 | continue; | ||
189 | if (member->address.is_ipv6 != is_ipv6) | ||
190 | continue; | ||
191 | if (memcmp(&member->address.ip[0], address, size) > 0 || | ||
192 | memcmp(address, &member->address.ip[1], size) > 0) | ||
193 | continue; | ||
194 | matched = true; | ||
195 | break; | ||
196 | } | ||
197 | return matched; | ||
198 | } | ||