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

Subversion リポジトリの参照

Annotation of /trunk/1.6.x/ccs-patch/fs/tomoyo_network.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1644 - (hide annotations) (download) (as text)
Wed Oct 1 07:12:42 2008 UTC (15 years, 8 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 26763 byte(s)


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

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