オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /branches/ccs-patch/fs/tomoyo_network.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2030 - (hide annotations) (download) (as text)
Thu Jan 1 01:40:06 2009 UTC (15 years, 5 months ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/tomoyo_network.c
File MIME type: text/x-csrc
File size: 25552 byte(s)


1 kumaneko 111 /*
2     * fs/tomoyo_network.c
3     *
4     * Implementation of the Domain-Based Mandatory Access Control.
5     *
6 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 kumaneko 111 *
8 kumaneko 2002 * Version: 1.6.6-pre 2008/12/24
9 kumaneko 111 *
10     * This file is applicable to both 2.4.30 and 2.6.11 and later.
11     * See README.ccs for ChangeLog.
12     *
13     */
14    
15     #include <linux/ccs_common.h>
16     #include <linux/tomoyo.h>
17     #include <linux/realpath.h>
18 kumaneko 1084 #include <linux/net.h>
19     #include <linux/inet.h>
20     #include <linux/in.h>
21     #include <linux/in6.h>
22 kumaneko 111
23 kumaneko 1052 /**
24 kumaneko 2002 * ccs_audit_network_log - Audit network log.
25 kumaneko 1052 *
26 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
27 kumaneko 1052 * @operation: The name of operation.
28     * @address: An IPv4 or IPv6 address.
29     * @port: Port number.
30     * @is_granted: True if this is a granted log.
31     *
32     * Returns 0 on success, negative value otherwise.
33     */
34 kumaneko 2002 static int ccs_audit_network_log(struct ccs_request_info *r,
35     const char *operation, const char *address,
36     const u16 port, const bool is_granted)
37 kumaneko 111 {
38 kumaneko 1657 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_NETWORK
39     "%s %s %u\n", operation, address, port);
40 kumaneko 111 }
41    
42 kumaneko 1052 /**
43 kumaneko 2002 * ccs_save_ipv6_address - Keep the given IPv6 address on the RAM.
44 kumaneko 1052 *
45     * @addr: Pointer to "struct in6_addr".
46     *
47     * Returns pointer to "struct in6_addr" on success, NULL otherwise.
48     *
49     * The RAM is shared, so NEVER try to modify or kfree() the returned address.
50     */
51 kumaneko 2002 static const struct in6_addr *ccs_save_ipv6_address(const struct in6_addr *addr)
52 kumaneko 719 {
53 kumaneko 2002 static const u8 ccs_block_size = 16;
54     struct ccs_addr_list {
55 kumaneko 1438 /* Workaround for gcc 4.3's bug. */
56 kumaneko 2002 struct in6_addr addr[16]; /* = ccs_block_size */
57 kumaneko 731 struct list1_head list;
58 kumaneko 719 u32 in_use_count;
59     };
60 kumaneko 2002 static LIST1_HEAD(ccs_address_list);
61     struct ccs_addr_list *ptr;
62 kumaneko 719 static DEFINE_MUTEX(lock);
63 kumaneko 2002 u8 i = ccs_block_size;
64 kumaneko 1052 if (!addr)
65     return NULL;
66 kumaneko 719 mutex_lock(&lock);
67 kumaneko 2002 list1_for_each_entry(ptr, &ccs_address_list, list) {
68 kumaneko 719 for (i = 0; i < ptr->in_use_count; i++) {
69 kumaneko 1064 if (!memcmp(&ptr->addr[i], addr, sizeof(*addr)))
70 kumaneko 1052 goto ok;
71 kumaneko 719 }
72 kumaneko 2002 if (i < ccs_block_size)
73 kumaneko 1052 break;
74 kumaneko 719 }
75 kumaneko 2002 if (i == ccs_block_size) {
76 kumaneko 1052 ptr = ccs_alloc_element(sizeof(*ptr));
77     if (!ptr)
78     goto ok;
79 kumaneko 2002 list1_add_tail_mb(&ptr->list, &ccs_address_list);
80 kumaneko 719 i = 0;
81     }
82 kumaneko 731 ptr->addr[ptr->in_use_count++] = *addr;
83 kumaneko 1052 ok:
84 kumaneko 719 mutex_unlock(&lock);
85     return ptr ? &ptr->addr[i] : NULL;
86     }
87    
88 kumaneko 2002 /* The list for "struct ccs_address_group_entry". */
89     static LIST1_HEAD(ccs_address_group_list);
90 kumaneko 111
91 kumaneko 1052 /**
92 kumaneko 2002 * ccs_update_address_group_entry - Update "struct ccs_address_group_entry" list.
93 kumaneko 1052 *
94 kumaneko 1064 * @group_name: The name of address group.
95     * @is_ipv6: True if @min_address and @max_address are IPv6 addresses.
96 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
97     * @max_address: End of IPv4 or IPv6 address range.
98     * @is_delete: True if it is a delete request.
99     *
100     * Returns 0 on success, negative value otherwise.
101     */
102 kumaneko 2002 static int ccs_update_address_group_entry(const char *group_name,
103     const bool is_ipv6,
104     const u16 *min_address,
105     const u16 *max_address,
106     const bool is_delete)
107 kumaneko 111 {
108 kumaneko 652 static DEFINE_MUTEX(lock);
109 kumaneko 2002 struct ccs_address_group_entry *new_group;
110     struct ccs_address_group_entry *group;
111     struct ccs_address_group_member *new_member;
112     struct ccs_address_group_member *member;
113     const struct ccs_path_info *saved_group_name;
114 kumaneko 1052 const struct in6_addr *saved_min_address = NULL;
115     const struct in6_addr *saved_max_address = NULL;
116 kumaneko 111 int error = -ENOMEM;
117 kumaneko 1016 bool found = false;
118 kumaneko 1052 if (!ccs_is_correct_path(group_name, 0, 0, 0, __func__) ||
119     !group_name[0])
120     return -EINVAL;
121     saved_group_name = ccs_save_name(group_name);
122     if (!saved_group_name)
123     return -ENOMEM;
124     if (!is_ipv6)
125     goto not_ipv6;
126     saved_min_address
127 kumaneko 2002 = ccs_save_ipv6_address((struct in6_addr *) min_address);
128 kumaneko 1052 saved_max_address
129 kumaneko 2002 = ccs_save_ipv6_address((struct in6_addr *) max_address);
130 kumaneko 1052 if (!saved_min_address || !saved_max_address)
131     return -ENOMEM;
132     not_ipv6:
133 kumaneko 652 mutex_lock(&lock);
134 kumaneko 2002 list1_for_each_entry(group, &ccs_address_group_list, list) {
135 kumaneko 1052 if (saved_group_name != group->group_name)
136     continue;
137 kumaneko 2002 list1_for_each_entry(member,
138     &group->address_group_member_list,
139 kumaneko 1052 list) {
140     if (member->is_ipv6 != is_ipv6)
141     continue;
142 kumaneko 111 if (is_ipv6) {
143 kumaneko 1052 if (member->min.ipv6 != saved_min_address ||
144     member->max.ipv6 != saved_max_address)
145     continue;
146 kumaneko 111 } else {
147 kumaneko 1052 if (member->min.ipv4 != *(u32 *) min_address ||
148     member->max.ipv4 != *(u32 *) max_address)
149     continue;
150 kumaneko 111 }
151     member->is_deleted = is_delete;
152     error = 0;
153     goto out;
154     }
155 kumaneko 1016 found = true;
156 kumaneko 111 break;
157     }
158     if (is_delete) {
159     error = -ENOENT;
160     goto out;
161     }
162 kumaneko 708 if (!found) {
163 kumaneko 1052 new_group = ccs_alloc_element(sizeof(*new_group));
164     if (!new_group)
165     goto out;
166 kumaneko 722 INIT_LIST1_HEAD(&new_group->address_group_member_list);
167 kumaneko 111 new_group->group_name = saved_group_name;
168 kumaneko 2002 list1_add_tail_mb(&new_group->list, &ccs_address_group_list);
169 kumaneko 111 group = new_group;
170     }
171 kumaneko 1052 new_member = ccs_alloc_element(sizeof(*new_member));
172     if (!new_member)
173     goto out;
174 kumaneko 111 new_member->is_ipv6 = is_ipv6;
175     if (is_ipv6) {
176 kumaneko 719 new_member->min.ipv6 = saved_min_address;
177     new_member->max.ipv6 = saved_max_address;
178 kumaneko 111 } else {
179 kumaneko 1052 new_member->min.ipv4 = *(u32 *) min_address;
180     new_member->max.ipv4 = *(u32 *) max_address;
181 kumaneko 111 }
182 kumaneko 2002 list1_add_tail_mb(&new_member->list,
183     &group->address_group_member_list);
184 kumaneko 111 error = 0;
185     out:
186 kumaneko 652 mutex_unlock(&lock);
187 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
188 kumaneko 111 return error;
189     }
190    
191 kumaneko 1052 /**
192 kumaneko 2002 * ccs_parse_ip_address - Parse an IP address.
193 kumaneko 1657 *
194     * @address: String to parse.
195     * @min: Pointer to store min address.
196     * @max: Pointer to store max address.
197     *
198     * Returns 2 if @address is an IPv6, 1 if @address is an IPv4, 0 otherwise.
199     */
200 kumaneko 2002 static int ccs_parse_ip_address(char *address, u16 *min, u16 *max)
201 kumaneko 1657 {
202     int count = sscanf(address, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"
203     "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
204     &min[0], &min[1], &min[2], &min[3],
205     &min[4], &min[5], &min[6], &min[7],
206     &max[0], &max[1], &max[2], &max[3],
207     &max[4], &max[5], &max[6], &max[7]);
208     if (count == 8 || count == 16) {
209     u8 i;
210     if (count == 8)
211     memmove(max, min, sizeof(u16) * 8);
212     for (i = 0; i < 8; i++) {
213     min[i] = htons(min[i]);
214     max[i] = htons(max[i]);
215     }
216     return 2;
217     }
218     count = sscanf(address, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
219     &min[0], &min[1], &min[2], &min[3],
220     &max[0], &max[1], &max[2], &max[3]);
221     if (count == 4 || count == 8) {
222 kumaneko 1658 u32 ip = htonl((((u8) min[0]) << 24) + (((u8) min[1]) << 16)
223     + (((u8) min[2]) << 8) + (u8) min[3]);
224     memmove(min, &ip, sizeof(ip));
225     if (count == 8)
226     ip = htonl((((u8) max[0]) << 24) + (((u8) max[1]) << 16)
227     + (((u8) max[2]) << 8) + (u8) max[3]);
228     memmove(max, &ip, sizeof(ip));
229 kumaneko 1657 return 1;
230     }
231     return 0;
232     }
233    
234     /**
235 kumaneko 2002 * ccs_write_address_group_policy - Write "struct ccs_address_group_entry" list.
236 kumaneko 1052 *
237     * @data: String to parse.
238     * @is_delete: True if it is a delete request.
239     *
240     * Returns 0 on success, negative value otherwise.
241     */
242     int ccs_write_address_group_policy(char *data, const bool is_delete)
243 kumaneko 111 {
244 kumaneko 853 bool is_ipv6;
245 kumaneko 1064 u16 min_address[8];
246     u16 max_address[8];
247 kumaneko 111 char *cp = strchr(data, ' ');
248 kumaneko 1052 if (!cp)
249     return -EINVAL;
250 kumaneko 111 *cp++ = '\0';
251 kumaneko 2002 switch (ccs_parse_ip_address(cp, min_address, max_address)) {
252 kumaneko 1657 case 2:
253 kumaneko 1016 is_ipv6 = true;
254 kumaneko 1657 break;
255     case 1:
256 kumaneko 1016 is_ipv6 = false;
257 kumaneko 1657 break;
258     default:
259     return -EINVAL;
260 kumaneko 111 }
261 kumaneko 2002 return ccs_update_address_group_entry(data, is_ipv6, min_address,
262     max_address, is_delete);
263 kumaneko 111 }
264    
265 kumaneko 1052 /**
266 kumaneko 2002 * ccs_find_or_assign_new_address_group - Create address group.
267 kumaneko 1052 *
268 kumaneko 1064 * @group_name: The name of address group.
269 kumaneko 1052 *
270 kumaneko 2002 * Returns pointer to "struct ccs_address_group_entry" on success,
271     * NULL otherwise.
272 kumaneko 1052 */
273 kumaneko 2002 static struct ccs_address_group_entry *
274     ccs_find_or_assign_new_address_group(const char *group_name)
275 kumaneko 111 {
276 kumaneko 853 u8 i;
277 kumaneko 2002 struct ccs_address_group_entry *group;
278 kumaneko 111 for (i = 0; i <= 1; i++) {
279 kumaneko 2002 list1_for_each_entry(group, &ccs_address_group_list, list) {
280 kumaneko 1064 if (!strcmp(group_name, group->group_name->name))
281 kumaneko 1052 return group;
282 kumaneko 111 }
283 kumaneko 1064 if (!i) {
284 kumaneko 111 const u16 dummy[2] = { 0, 0 };
285 kumaneko 2002 ccs_update_address_group_entry(group_name, false,
286     dummy, dummy, false);
287     ccs_update_address_group_entry(group_name, false,
288     dummy, dummy, true);
289 kumaneko 111 }
290     }
291     return NULL;
292     }
293    
294 kumaneko 1052 /**
295 kumaneko 2002 * ccs_address_matches_to_group - Check whether the given address matches members of the given address group.
296 kumaneko 1052 *
297     * @is_ipv6: True if @address is an IPv6 address.
298     * @address: An IPv4 or IPv6 address.
299 kumaneko 2002 * @group: Pointer to "struct ccs_address_group_entry".
300 kumaneko 1052 *
301     * Returns true if @address matches addresses in @group group, false otherwise.
302     */
303 kumaneko 2002 static bool ccs_address_matches_to_group(const bool is_ipv6, const u32 *address,
304     const struct ccs_address_group_entry *
305     group)
306 kumaneko 111 {
307 kumaneko 2002 struct ccs_address_group_member *member;
308 kumaneko 111 const u32 ip = ntohl(*address);
309 kumaneko 2002 list1_for_each_entry(member, &group->address_group_member_list,
310     list) {
311 kumaneko 1052 if (member->is_deleted)
312     continue;
313 kumaneko 111 if (member->is_ipv6) {
314 kumaneko 1052 if (is_ipv6 &&
315     memcmp(member->min.ipv6, address, 16) <= 0 &&
316     memcmp(address, member->max.ipv6, 16) <= 0)
317     return true;
318 kumaneko 111 } else {
319 kumaneko 1052 if (!is_ipv6 &&
320     member->min.ipv4 <= ip && ip <= member->max.ipv4)
321     return true;
322 kumaneko 111 }
323     }
324 kumaneko 1016 return false;
325 kumaneko 111 }
326    
327 kumaneko 1052 /**
328 kumaneko 2002 * ccs_read_address_group_policy - Read "struct ccs_address_group_entry" list.
329 kumaneko 1052 *
330     * @head: Pointer to "struct ccs_io_buffer".
331     *
332     * Returns true on success, false otherwise.
333     */
334     bool ccs_read_address_group_policy(struct ccs_io_buffer *head)
335 kumaneko 111 {
336 kumaneko 722 struct list1_head *gpos;
337     struct list1_head *mpos;
338 kumaneko 2002 list1_for_each_cookie(gpos, head->read_var1, &ccs_address_group_list) {
339     struct ccs_address_group_entry *group;
340     group = list1_entry(gpos, struct ccs_address_group_entry, list);
341 kumaneko 1052 list1_for_each_cookie(mpos, head->read_var2,
342     &group->address_group_member_list) {
343 kumaneko 708 char buf[128];
344 kumaneko 2002 struct ccs_address_group_member *member;
345     member = list1_entry(mpos,
346     struct ccs_address_group_member,
347 kumaneko 1052 list);
348     if (member->is_deleted)
349     continue;
350 kumaneko 1064 if (member->is_ipv6) {
351 kumaneko 1052 const struct in6_addr *min_address
352     = member->min.ipv6;
353     const struct in6_addr *max_address
354     = member->max.ipv6;
355     ccs_print_ipv6(buf, sizeof(buf), min_address);
356 kumaneko 719 if (min_address != max_address) {
357 kumaneko 1052 int len;
358 kumaneko 1795 char *cp = buf + strlen(buf);
359 kumaneko 708 *cp++ = '-';
360 kumaneko 1052 len = strlen(buf);
361     ccs_print_ipv6(cp, sizeof(buf) - len,
362     max_address);
363 kumaneko 111 }
364 kumaneko 708 } else {
365 kumaneko 1052 const u32 min_address = member->min.ipv4;
366     const u32 max_address = member->max.ipv4;
367 kumaneko 708 memset(buf, 0, sizeof(buf));
368 kumaneko 1052 snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u",
369     HIPQUAD(min_address));
370 kumaneko 708 if (min_address != max_address) {
371     const int len = strlen(buf);
372 kumaneko 1052 snprintf(buf + len,
373     sizeof(buf) - 1 - len,
374     "-%u.%u.%u.%u",
375     HIPQUAD(max_address));
376 kumaneko 708 }
377 kumaneko 111 }
378 kumaneko 1052 if (!ccs_io_printf(head, KEYWORD_ADDRESS_GROUP
379     "%s %s\n", group->group_name->name,
380     buf))
381     goto out;
382 kumaneko 111 }
383     }
384 kumaneko 1052 return true;
385     out:
386     return false;
387 kumaneko 111 }
388    
389 kumaneko 719 #if !defined(NIP6)
390 kumaneko 1052 #define NIP6(addr) \
391 kumaneko 1056 ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]), \
392     ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \
393     ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \
394     ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])
395 kumaneko 719 #endif
396    
397 kumaneko 1052 /**
398 kumaneko 1054 * ccs_print_ipv6 - Print an IPv6 address.
399 kumaneko 1052 *
400     * @buffer: Buffer to write to.
401 kumaneko 1064 * @buffer_len: Size of @buffer.
402 kumaneko 1052 * @ip: Pointer to "struct in6_addr".
403     *
404 kumaneko 1064 * Returns nothing.
405 kumaneko 1052 */
406 kumaneko 1064 void ccs_print_ipv6(char *buffer, const int buffer_len,
407     const struct in6_addr *ip)
408 kumaneko 111 {
409     memset(buffer, 0, buffer_len);
410 kumaneko 719 snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
411 kumaneko 111 }
412    
413 kumaneko 1052 /**
414     * ccs_net2keyword - Convert network operation index to network operation name.
415     *
416     * @operation: Type of operation.
417     *
418     * Returns the name of operation.
419     */
420     const char *ccs_net2keyword(const u8 operation)
421 kumaneko 111 {
422     const char *keyword = "unknown";
423     switch (operation) {
424     case NETWORK_ACL_UDP_BIND:
425     keyword = "UDP bind";
426     break;
427     case NETWORK_ACL_UDP_CONNECT:
428     keyword = "UDP connect";
429     break;
430     case NETWORK_ACL_TCP_BIND:
431     keyword = "TCP bind";
432     break;
433     case NETWORK_ACL_TCP_LISTEN:
434     keyword = "TCP listen";
435     break;
436     case NETWORK_ACL_TCP_CONNECT:
437     keyword = "TCP connect";
438     break;
439     case NETWORK_ACL_TCP_ACCEPT:
440     keyword = "TCP accept";
441     break;
442     case NETWORK_ACL_RAW_BIND:
443     keyword = "RAW bind";
444     break;
445     case NETWORK_ACL_RAW_CONNECT:
446     keyword = "RAW connect";
447     break;
448     }
449     return keyword;
450     }
451    
452 kumaneko 1052 /**
453 kumaneko 2002 * ccs_update_network_entry - Update "struct ccs_ip_network_acl_record" list.
454 kumaneko 1052 *
455     * @operation: Type of operation.
456     * @record_type: Type of address.
457 kumaneko 2002 * @group: Pointer to "struct ccs_address_group_entry". May be NULL.
458 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
459     * @max_address: End of IPv4 or IPv6 address range.
460     * @min_port: Start of port number range.
461     * @max_port: End of port number range.
462     * @domain: Pointer to "struct domain_info".
463 kumaneko 2002 * @condition: Pointer to "struct ccs_condition_list". May be NULL.
464 kumaneko 1052 * @is_delete: True if it is a delete request.
465     *
466     * Returns 0 on success, negative value otherwise.
467     */
468 kumaneko 2002 static int ccs_update_network_entry(const u8 operation, const u8 record_type,
469     const struct ccs_address_group_entry *group,
470     const u32 *min_address,
471     const u32 *max_address,
472     const u16 min_port, const u16 max_port,
473     struct domain_info *domain,
474     const struct ccs_condition_list *condition,
475     const bool is_delete)
476 kumaneko 111 {
477 kumaneko 1695 static DEFINE_MUTEX(lock);
478 kumaneko 2002 struct ccs_acl_info *ptr;
479     struct ccs_ip_network_acl_record *acl;
480 kumaneko 111 int error = -ENOMEM;
481 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
482     const u32 min_ip = ntohl(*min_address);
483     const u32 max_ip = ntohl(*max_address);
484     const struct in6_addr *saved_min_address = NULL;
485     const struct in6_addr *saved_max_address = NULL;
486     if (!domain)
487     return -EINVAL;
488     if (record_type != IP_RECORD_TYPE_IPv6)
489     goto not_ipv6;
490 kumaneko 2002 saved_min_address = ccs_save_ipv6_address((struct in6_addr *)
491     min_address);
492     saved_max_address = ccs_save_ipv6_address((struct in6_addr *)
493     max_address);
494 kumaneko 1052 if (!saved_min_address || !saved_max_address)
495     return -ENOMEM;
496     not_ipv6:
497 kumaneko 1695 mutex_lock(&lock);
498 kumaneko 1052 if (is_delete)
499     goto delete;
500     list1_for_each_entry(ptr, &domain->acl_info_list, list) {
501 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_IP_NETWORK_ACL)
502 kumaneko 1052 continue;
503     if (ccs_get_condition_part(ptr) != condition)
504     continue;
505 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
506 kumaneko 1052 if (acl->operation_type != operation ||
507     acl->record_type != record_type ||
508     acl->min_port != min_port || max_port != acl->max_port)
509     continue;
510 kumaneko 708 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
511 kumaneko 1052 if (acl->u.group != group)
512     continue;
513 kumaneko 708 } else if (record_type == IP_RECORD_TYPE_IPv4) {
514 kumaneko 1052 if (acl->u.ipv4.min != min_ip ||
515     max_ip != acl->u.ipv4.max)
516     continue;
517     } else if (record_type == IP_RECORD_TYPE_IPv6) {
518     if (acl->u.ipv6.min != saved_min_address ||
519     saved_max_address != acl->u.ipv6.max)
520     continue;
521 kumaneko 708 }
522 kumaneko 1052 error = ccs_add_domain_acl(NULL, ptr);
523     goto out;
524     }
525     /* Not found. Append it to the tail. */
526     acl = ccs_alloc_acl_element(TYPE_IP_NETWORK_ACL, condition);
527     if (!acl)
528     goto out;
529     acl->operation_type = operation;
530     acl->record_type = record_type;
531     if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
532     acl->u.group = group;
533     } else if (record_type == IP_RECORD_TYPE_IPv4) {
534     acl->u.ipv4.min = min_ip;
535     acl->u.ipv4.max = max_ip;
536 kumaneko 111 } else {
537 kumaneko 1052 acl->u.ipv6.min = saved_min_address;
538     acl->u.ipv6.max = saved_max_address;
539     }
540     acl->min_port = min_port;
541     acl->max_port = max_port;
542     error = ccs_add_domain_acl(domain, &acl->head);
543     goto out;
544     delete:
545     error = -ENOENT;
546     list1_for_each_entry(ptr, &domain->acl_info_list, list) {
547 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
548 kumaneko 1052 continue;
549     if (ccs_get_condition_part(ptr) != condition)
550     continue;
551 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
552 kumaneko 1052 if (acl->operation_type != operation ||
553     acl->record_type != record_type ||
554     acl->min_port != min_port || max_port != acl->max_port)
555     continue;
556     if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
557     if (acl->u.group != group)
558     continue;
559     } else if (record_type == IP_RECORD_TYPE_IPv4) {
560     if (acl->u.ipv4.min != min_ip ||
561     max_ip != acl->u.ipv4.max)
562     continue;
563     } else if (record_type == IP_RECORD_TYPE_IPv6) {
564     if (acl->u.ipv6.min != saved_min_address ||
565     saved_max_address != acl->u.ipv6.max)
566     continue;
567 kumaneko 111 }
568 kumaneko 1052 error = ccs_del_domain_acl(ptr);
569     break;
570 kumaneko 111 }
571 kumaneko 1052 out:
572 kumaneko 1695 mutex_unlock(&lock);
573 kumaneko 111 return error;
574     }
575    
576 kumaneko 1052 /**
577 kumaneko 2002 * ccs_check_network_entry - Check permission for network operation.
578 kumaneko 1052 *
579     * @is_ipv6: True if @address is an IPv6 address.
580     * @operation: Type of operation.
581     * @address: An IPv4 or IPv6 address.
582     * @port: Port number.
583     *
584     * Returns 0 on success, negative value otherwise.
585     */
586 kumaneko 2002 static int ccs_check_network_entry(const bool is_ipv6, const u8 operation,
587     const u32 *address, const u16 port)
588 kumaneko 111 {
589 kumaneko 1657 struct ccs_request_info r;
590 kumaneko 2002 struct ccs_acl_info *ptr;
591 kumaneko 1052 const char *keyword = ccs_net2keyword(operation);
592 kumaneko 1657 bool is_enforce;
593 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
594     const u32 ip = ntohl(*address);
595 kumaneko 1016 bool found = false;
596 kumaneko 1064 char buf[64];
597 kumaneko 1657 if (!ccs_can_sleep())
598 kumaneko 1052 return 0;
599 kumaneko 1657 ccs_init_request_info(&r, NULL, CCS_TOMOYO_MAC_FOR_NETWORK);
600     is_enforce = (r.mode == 3);
601     if (!r.mode)
602     return 0;
603 kumaneko 2002 retry:
604 kumaneko 1657 list1_for_each_entry(ptr, &r.domain->acl_info_list, list) {
605 kumaneko 2002 struct ccs_ip_network_acl_record *acl;
606 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
607 kumaneko 1052 continue;
608 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
609 kumaneko 1052 if (acl->operation_type != operation || port < acl->min_port ||
610 kumaneko 1657 acl->max_port < port || !ccs_check_condition(&r, ptr))
611 kumaneko 1052 continue;
612 kumaneko 708 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
613 kumaneko 2002 if (!ccs_address_matches_to_group(is_ipv6, address,
614     acl->u.group))
615 kumaneko 1052 continue;
616 kumaneko 708 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
617 kumaneko 1052 if (is_ipv6 ||
618     ip < acl->u.ipv4.min || acl->u.ipv4.max < ip)
619     continue;
620 kumaneko 111 } else {
621 kumaneko 1052 if (!is_ipv6 ||
622     memcmp(acl->u.ipv6.min, address, 16) > 0 ||
623     memcmp(address, acl->u.ipv6.max, 16) > 0)
624     continue;
625 kumaneko 111 }
626 kumaneko 1782 r.cond = ccs_get_condition_part(ptr);
627 kumaneko 1016 found = true;
628 kumaneko 708 break;
629 kumaneko 111 }
630 kumaneko 1064 memset(buf, 0, sizeof(buf));
631     if (is_ipv6)
632     ccs_print_ipv6(buf, sizeof(buf),
633     (const struct in6_addr *) address);
634     else
635     snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
636 kumaneko 2002 ccs_audit_network_log(&r, keyword, buf, port, found);
637 kumaneko 1052 if (found)
638     return 0;
639 kumaneko 1657 if (ccs_verbose_mode(r.domain))
640 kumaneko 1064 printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
641     ccs_get_msg(is_enforce), keyword, buf, port,
642 kumaneko 1657 ccs_get_last_name(r.domain));
643 kumaneko 1561 if (is_enforce) {
644 kumaneko 1657 int error = ccs_check_supervisor(&r, KEYWORD_ALLOW_NETWORK
645 kumaneko 1561 "%s %s %u\n", keyword, buf,
646     port);
647 kumaneko 1781 if (error == 1)
648 kumaneko 1561 goto retry;
649     return error;
650     }
651 kumaneko 1657 if (r.mode == 1 && ccs_check_domain_quota(r.domain))
652 kumaneko 2002 ccs_update_network_entry(operation, is_ipv6 ?
653     IP_RECORD_TYPE_IPv6 :
654     IP_RECORD_TYPE_IPv4,
655     NULL, address, address, port, port,
656     r.domain, ccs_handler_cond(), 0);
657 kumaneko 111 return 0;
658     }
659    
660 kumaneko 1052 /**
661 kumaneko 2002 * ccs_write_network_policy - Write "struct ccs_ip_network_acl_record" list.
662 kumaneko 1052 *
663     * @data: String to parse.
664     * @domain: Pointer to "struct domain_info".
665 kumaneko 2002 * @condition: Pointer to "struct ccs_condition_list". May be NULL.
666 kumaneko 1052 * @is_delete: True if it is a delete request.
667     *
668     * Returns 0 on success, negative value otherwise.
669     */
670     int ccs_write_network_policy(char *data, struct domain_info *domain,
671 kumaneko 2002 const struct ccs_condition_list *condition,
672 kumaneko 1052 const bool is_delete)
673 kumaneko 111 {
674 kumaneko 1064 u8 sock_type;
675     u8 operation;
676     u8 record_type;
677     u16 min_address[8];
678     u16 max_address[8];
679 kumaneko 2002 struct ccs_address_group_entry *group = NULL;
680 kumaneko 1064 u16 min_port;
681     u16 max_port;
682 kumaneko 853 u8 count;
683 kumaneko 1064 char *cp1 = strchr(data, ' ');
684     char *cp2;
685 kumaneko 1052 if (!cp1)
686     goto out;
687     cp1++;
688     if (!strncmp(data, "TCP ", 4))
689     sock_type = SOCK_STREAM;
690     else if (!strncmp(data, "UDP ", 4))
691     sock_type = SOCK_DGRAM;
692     else if (!strncmp(data, "RAW ", 4))
693     sock_type = SOCK_RAW;
694     else
695     goto out;
696     cp2 = strchr(cp1, ' ');
697     if (!cp2)
698     goto out;
699     cp2++;
700     if (!strncmp(cp1, "bind ", 5))
701     switch (sock_type) {
702     case SOCK_STREAM:
703     operation = NETWORK_ACL_TCP_BIND;
704     break;
705     case SOCK_DGRAM:
706     operation = NETWORK_ACL_UDP_BIND;
707     break;
708     default:
709     operation = NETWORK_ACL_RAW_BIND;
710     }
711     else if (!strncmp(cp1, "connect ", 8))
712     switch (sock_type) {
713     case SOCK_STREAM:
714     operation = NETWORK_ACL_TCP_CONNECT;
715     break;
716     case SOCK_DGRAM:
717     operation = NETWORK_ACL_UDP_CONNECT;
718     break;
719     default:
720     operation = NETWORK_ACL_RAW_CONNECT;
721     }
722     else if (sock_type == SOCK_STREAM && !strncmp(cp1, "listen ", 7))
723 kumaneko 111 operation = NETWORK_ACL_TCP_LISTEN;
724 kumaneko 1052 else if (sock_type == SOCK_STREAM && !strncmp(cp1, "accept ", 7))
725 kumaneko 111 operation = NETWORK_ACL_TCP_ACCEPT;
726 kumaneko 1052 else
727 kumaneko 111 goto out;
728 kumaneko 1052 cp1 = strchr(cp2, ' ');
729     if (!cp1)
730     goto out;
731     *cp1++ = '\0';
732 kumaneko 2002 switch (ccs_parse_ip_address(cp2, min_address, max_address)) {
733 kumaneko 1657 case 2:
734 kumaneko 111 record_type = IP_RECORD_TYPE_IPv6;
735 kumaneko 1657 break;
736     case 1:
737 kumaneko 111 record_type = IP_RECORD_TYPE_IPv4;
738 kumaneko 1657 break;
739     default:
740     if (*cp2 != '@')
741     goto out;
742 kumaneko 2002 group = ccs_find_or_assign_new_address_group(cp2 + 1);
743 kumaneko 1052 if (!group)
744     return -ENOMEM;
745 kumaneko 111 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
746 kumaneko 1657 break;
747 kumaneko 111 }
748 kumaneko 1052 if (strchr(cp1, ' '))
749     goto out;
750     count = sscanf(cp1, "%hu-%hu", &min_port, &max_port);
751     if (count != 1 && count != 2)
752     goto out;
753     if (count == 1)
754     max_port = min_port;
755 kumaneko 2002 return ccs_update_network_entry(operation, record_type, group,
756     (u32 *) min_address,
757     (u32 *) max_address,
758     min_port, max_port, domain, condition,
759     is_delete);
760 kumaneko 1657 out:
761     return -EINVAL;
762 kumaneko 111 }
763    
764 kumaneko 1052 /**
765     * ccs_check_network_listen_acl - Check permission for listen() operation.
766     *
767     * @is_ipv6: True if @address is an IPv6 address.
768     * @address: An IPv4 or IPv6 address.
769     * @port: Port number.
770     *
771     * Returns 0 on success, negative value otherwise.
772     */
773     int ccs_check_network_listen_acl(const _Bool is_ipv6, const u8 *address,
774     const u16 port)
775 kumaneko 111 {
776 kumaneko 2002 return ccs_check_network_entry(is_ipv6, NETWORK_ACL_TCP_LISTEN,
777     (const u32 *) address, ntohs(port));
778 kumaneko 111 }
779    
780 kumaneko 1052 /**
781     * ccs_check_network_connect_acl - Check permission for connect() operation.
782     *
783     * @is_ipv6: True if @address is an IPv6 address.
784     * @sock_type: Type of socket. (TCP or UDP or RAW)
785     * @address: An IPv4 or IPv6 address.
786     * @port: Port number.
787     *
788     * Returns 0 on success, negative value otherwise.
789     */
790     int ccs_check_network_connect_acl(const _Bool is_ipv6, const int sock_type,
791     const u8 *address, const u16 port)
792 kumaneko 111 {
793 kumaneko 1052 u8 operation;
794     switch (sock_type) {
795     case SOCK_STREAM:
796     operation = NETWORK_ACL_TCP_CONNECT;
797     break;
798     case SOCK_DGRAM:
799     operation = NETWORK_ACL_UDP_CONNECT;
800     break;
801     default:
802     operation = NETWORK_ACL_RAW_CONNECT;
803     }
804 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
805     (const u32 *) address, ntohs(port));
806 kumaneko 111 }
807    
808 kumaneko 1052 /**
809     * ccs_check_network_bind_acl - Check permission for bind() operation.
810     *
811     * @is_ipv6: True if @address is an IPv6 address.
812     * @sock_type: Type of socket. (TCP or UDP or RAW)
813     * @address: An IPv4 or IPv6 address.
814     * @port: Port number.
815     *
816     * Returns 0 on success, negative value otherwise.
817     */
818     int ccs_check_network_bind_acl(const _Bool is_ipv6, const int sock_type,
819     const u8 *address, const u16 port)
820 kumaneko 111 {
821 kumaneko 1052 u8 operation;
822     switch (sock_type) {
823     case SOCK_STREAM:
824     operation = NETWORK_ACL_TCP_BIND;
825     break;
826     case SOCK_DGRAM:
827     operation = NETWORK_ACL_UDP_BIND;
828     break;
829     default:
830     operation = NETWORK_ACL_RAW_BIND;
831     }
832 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
833     (const u32 *) address, ntohs(port));
834 kumaneko 111 }
835    
836 kumaneko 1052 /**
837     * ccs_check_network_accept_acl - Check permission for accept() operation.
838     *
839     * @is_ipv6: True if @address is an IPv6 address.
840     * @address: An IPv4 or IPv6 address.
841     * @port: Port number.
842     *
843     * Returns 0 on success, negative value otherwise.
844     */
845     int ccs_check_network_accept_acl(const _Bool is_ipv6, const u8 *address,
846     const u16 port)
847 kumaneko 111 {
848 kumaneko 708 int retval;
849     current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
850 kumaneko 2002 retval = ccs_check_network_entry(is_ipv6, NETWORK_ACL_TCP_ACCEPT,
851     (const u32 *) address, ntohs(port));
852 kumaneko 708 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
853     return retval;
854 kumaneko 111 }
855    
856 kumaneko 1052 /**
857     * ccs_check_network_sendmsg_acl - Check permission for sendmsg() operation.
858     *
859     * @is_ipv6: True if @address is an IPv6 address.
860     * @sock_type: Type of socket. (UDP or RAW)
861     * @address: An IPv4 or IPv6 address.
862     * @port: Port number.
863     *
864     * Returns 0 on success, negative value otherwise.
865     */
866     int ccs_check_network_sendmsg_acl(const _Bool is_ipv6, const int sock_type,
867     const u8 *address, const u16 port)
868 kumaneko 111 {
869 kumaneko 1052 u8 operation;
870     if (sock_type == SOCK_DGRAM)
871     operation = NETWORK_ACL_UDP_CONNECT;
872     else
873     operation = NETWORK_ACL_RAW_CONNECT;
874 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
875     (const u32 *) address, ntohs(port));
876 kumaneko 111 }
877    
878 kumaneko 1052 /**
879     * ccs_check_network_recvmsg_acl - Check permission for recvmsg() operation.
880     *
881     * @is_ipv6: True if @address is an IPv6 address.
882     * @sock_type: Type of socket. (UDP or RAW)
883     * @address: An IPv4 or IPv6 address.
884     * @port: Port number.
885     *
886     * Returns 0 on success, negative value otherwise.
887     */
888     int ccs_check_network_recvmsg_acl(const _Bool is_ipv6, const int sock_type,
889     const u8 *address, const u16 port)
890 kumaneko 111 {
891 kumaneko 708 int retval;
892 kumaneko 1052 const u8 operation
893 kumaneko 1064 = (sock_type == SOCK_DGRAM) ?
894 kumaneko 1052 NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
895 kumaneko 708 current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
896 kumaneko 2002 retval = ccs_check_network_entry(is_ipv6, operation,
897     (const u32 *) address, ntohs(port));
898 kumaneko 708 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
899     return retval;
900 kumaneko 111 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26