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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1498 - (hide annotations) (download) (as text)
Fri Aug 29 12:08:57 2008 UTC (15 years, 9 months ago) by kumaneko
Original Path: trunk/1.6.x/ccs-patch/fs/tomoyo_network.c
File MIME type: text/x-csrc
File size: 26625 byte(s)
1.5.5-rc/1.6.4-rc
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 1498 * Version: 1.6.4-rc 2008/08/29
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     struct domain_info * const domain = current->domain_info;
584     struct acl_info *ptr;
585 kumaneko 1052 const char *keyword = ccs_net2keyword(operation);
586 kumaneko 815 const u8 profile = current->domain_info->profile;
587 kumaneko 1052 const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_NETWORK);
588 kumaneko 815 const bool is_enforce = (mode == 3);
589 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
590     const u32 ip = ntohl(*address);
591 kumaneko 1016 bool found = false;
592 kumaneko 1064 char buf[64];
593 kumaneko 1052 if (!mode)
594     return 0;
595 kumaneko 722 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
596 kumaneko 708 struct ip_network_acl_record *acl;
597 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
598 kumaneko 1052 continue;
599 kumaneko 912 acl = container_of(ptr, struct ip_network_acl_record, head);
600 kumaneko 1052 if (acl->operation_type != operation || port < acl->min_port ||
601     acl->max_port < port || !ccs_check_condition(ptr, NULL))
602     continue;
603 kumaneko 708 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
604 kumaneko 1052 if (!address_matches_to_group(is_ipv6, address,
605     acl->u.group))
606     continue;
607 kumaneko 708 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
608 kumaneko 1052 if (is_ipv6 ||
609     ip < acl->u.ipv4.min || acl->u.ipv4.max < ip)
610     continue;
611 kumaneko 111 } else {
612 kumaneko 1052 if (!is_ipv6 ||
613     memcmp(acl->u.ipv6.min, address, 16) > 0 ||
614     memcmp(address, acl->u.ipv6.max, 16) > 0)
615     continue;
616 kumaneko 111 }
617 kumaneko 1052 ccs_update_condition(ptr);
618 kumaneko 1016 found = true;
619 kumaneko 708 break;
620 kumaneko 111 }
621 kumaneko 1064 memset(buf, 0, sizeof(buf));
622     if (is_ipv6)
623     ccs_print_ipv6(buf, sizeof(buf),
624     (const struct in6_addr *) address);
625     else
626     snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
627     audit_network_log(is_ipv6, keyword, buf, port, found, profile, mode);
628 kumaneko 1052 if (found)
629     return 0;
630 kumaneko 1064 if (ccs_verbose_mode())
631     printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
632     ccs_get_msg(is_enforce), keyword, buf, port,
633     ccs_get_last_name(domain));
634     if (is_enforce)
635 kumaneko 1260 return ccs_check_supervisor(NULL, KEYWORD_ALLOW_NETWORK "%s "
636     "%s %u\n", keyword, buf, port);
637 kumaneko 1064 if (mode == 1 && ccs_check_domain_quota(domain))
638 kumaneko 1052 update_network_entry(operation, is_ipv6 ?
639     IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4,
640     NULL, address, address, port, port, domain,
641     NULL, 0);
642 kumaneko 111 return 0;
643     }
644    
645 kumaneko 1052 /**
646     * ccs_write_network_policy - Write "struct ip_network_acl_record" list.
647     *
648     * @data: String to parse.
649     * @domain: Pointer to "struct domain_info".
650     * @condition: Pointer to "struct condition_list". May be NULL.
651     * @is_delete: True if it is a delete request.
652     *
653     * Returns 0 on success, negative value otherwise.
654     */
655     int ccs_write_network_policy(char *data, struct domain_info *domain,
656     const struct condition_list *condition,
657     const bool is_delete)
658 kumaneko 111 {
659 kumaneko 1064 u8 sock_type;
660     u8 operation;
661     u8 record_type;
662     u16 min_address[8];
663     u16 max_address[8];
664 kumaneko 111 struct address_group_entry *group = NULL;
665 kumaneko 1064 u16 min_port;
666     u16 max_port;
667 kumaneko 853 u8 count;
668 kumaneko 1064 char *cp1 = strchr(data, ' ');
669     char *cp2;
670 kumaneko 1052 if (!cp1)
671     goto out;
672     cp1++;
673     if (!strncmp(data, "TCP ", 4))
674     sock_type = SOCK_STREAM;
675     else if (!strncmp(data, "UDP ", 4))
676     sock_type = SOCK_DGRAM;
677     else if (!strncmp(data, "RAW ", 4))
678     sock_type = SOCK_RAW;
679     else
680     goto out;
681     cp2 = strchr(cp1, ' ');
682     if (!cp2)
683     goto out;
684     cp2++;
685     if (!strncmp(cp1, "bind ", 5))
686     switch (sock_type) {
687     case SOCK_STREAM:
688     operation = NETWORK_ACL_TCP_BIND;
689     break;
690     case SOCK_DGRAM:
691     operation = NETWORK_ACL_UDP_BIND;
692     break;
693     default:
694     operation = NETWORK_ACL_RAW_BIND;
695     }
696     else if (!strncmp(cp1, "connect ", 8))
697     switch (sock_type) {
698     case SOCK_STREAM:
699     operation = NETWORK_ACL_TCP_CONNECT;
700     break;
701     case SOCK_DGRAM:
702     operation = NETWORK_ACL_UDP_CONNECT;
703     break;
704     default:
705     operation = NETWORK_ACL_RAW_CONNECT;
706     }
707     else if (sock_type == SOCK_STREAM && !strncmp(cp1, "listen ", 7))
708 kumaneko 111 operation = NETWORK_ACL_TCP_LISTEN;
709 kumaneko 1052 else if (sock_type == SOCK_STREAM && !strncmp(cp1, "accept ", 7))
710 kumaneko 111 operation = NETWORK_ACL_TCP_ACCEPT;
711 kumaneko 1052 else
712 kumaneko 111 goto out;
713 kumaneko 1052 cp1 = strchr(cp2, ' ');
714     if (!cp1)
715     goto out;
716     *cp1++ = '\0';
717     count = sscanf(cp2, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"
718     "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
719     &min_address[0], &min_address[1],
720     &min_address[2], &min_address[3],
721     &min_address[4], &min_address[5],
722     &min_address[6], &min_address[7],
723     &max_address[0], &max_address[1],
724     &max_address[2], &max_address[3],
725     &max_address[4], &max_address[5],
726     &max_address[6], &max_address[7]);
727     if (count == 8 || count == 16) {
728 kumaneko 853 u8 i;
729 kumaneko 111 for (i = 0; i < 8; i++) {
730     min_address[i] = htons(min_address[i]);
731     max_address[i] = htons(max_address[i]);
732     }
733 kumaneko 1052 if (count == 8)
734     memmove(max_address, min_address, sizeof(min_address));
735 kumaneko 111 record_type = IP_RECORD_TYPE_IPv6;
736 kumaneko 1052 goto ok;
737     }
738     count = sscanf(cp2, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
739     &min_address[0], &min_address[1],
740     &min_address[2], &min_address[3],
741     &max_address[0], &max_address[1],
742     &max_address[2], &max_address[3]);
743     if (count == 4 || count == 8) {
744     u32 ip = htonl((((u8) min_address[0]) << 24)
745     + (((u8) min_address[1]) << 16)
746     + (((u8) min_address[2]) << 8)
747     + (u8) min_address[3]);
748     *(u32 *) min_address = ip;
749     if (count == 8)
750     ip = htonl((((u8) max_address[0]) << 24)
751     + (((u8) max_address[1]) << 16)
752     + (((u8) max_address[2]) << 8)
753     + (u8) max_address[3]);
754     *(u32 *) max_address = ip;
755 kumaneko 111 record_type = IP_RECORD_TYPE_IPv4;
756 kumaneko 1064 goto ok;
757     }
758     if (*cp2 == '@') {
759 kumaneko 1052 group = find_or_assign_new_address_group(cp2 + 1);
760     if (!group)
761     return -ENOMEM;
762 kumaneko 111 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
763 kumaneko 1064 goto ok;
764 kumaneko 111 }
765 kumaneko 1064 out:
766     return -EINVAL;
767 kumaneko 1052 ok:
768     if (strchr(cp1, ' '))
769     goto out;
770     count = sscanf(cp1, "%hu-%hu", &min_port, &max_port);
771     if (count != 1 && count != 2)
772     goto out;
773     if (count == 1)
774     max_port = min_port;
775     return update_network_entry(operation, record_type, group,
776     (u32 *) min_address, (u32 *) max_address,
777     min_port, max_port, domain, condition,
778     is_delete);
779 kumaneko 111 }
780    
781 kumaneko 1052 /**
782     * ccs_check_network_listen_acl - Check permission for listen() operation.
783     *
784     * @is_ipv6: True if @address is an IPv6 address.
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_listen_acl(const _Bool is_ipv6, const u8 *address,
791     const u16 port)
792 kumaneko 111 {
793 kumaneko 1052 return check_network_entry(is_ipv6, NETWORK_ACL_TCP_LISTEN,
794     (const u32 *) address, ntohs(port));
795 kumaneko 111 }
796    
797 kumaneko 1052 /**
798     * ccs_check_network_connect_acl - Check permission for connect() operation.
799     *
800     * @is_ipv6: True if @address is an IPv6 address.
801     * @sock_type: Type of socket. (TCP or UDP or RAW)
802     * @address: An IPv4 or IPv6 address.
803     * @port: Port number.
804     *
805     * Returns 0 on success, negative value otherwise.
806     */
807     int ccs_check_network_connect_acl(const _Bool is_ipv6, const int sock_type,
808     const u8 *address, const u16 port)
809 kumaneko 111 {
810 kumaneko 1052 u8 operation;
811     switch (sock_type) {
812     case SOCK_STREAM:
813     operation = NETWORK_ACL_TCP_CONNECT;
814     break;
815     case SOCK_DGRAM:
816     operation = NETWORK_ACL_UDP_CONNECT;
817     break;
818     default:
819     operation = NETWORK_ACL_RAW_CONNECT;
820     }
821     return check_network_entry(is_ipv6, operation, (const u32 *) address,
822     ntohs(port));
823 kumaneko 111 }
824    
825 kumaneko 1052 /**
826     * ccs_check_network_bind_acl - Check permission for bind() operation.
827     *
828     * @is_ipv6: True if @address is an IPv6 address.
829     * @sock_type: Type of socket. (TCP or UDP or RAW)
830     * @address: An IPv4 or IPv6 address.
831     * @port: Port number.
832     *
833     * Returns 0 on success, negative value otherwise.
834     */
835     int ccs_check_network_bind_acl(const _Bool is_ipv6, const int sock_type,
836     const u8 *address, const u16 port)
837 kumaneko 111 {
838 kumaneko 1052 u8 operation;
839     switch (sock_type) {
840     case SOCK_STREAM:
841     operation = NETWORK_ACL_TCP_BIND;
842     break;
843     case SOCK_DGRAM:
844     operation = NETWORK_ACL_UDP_BIND;
845     break;
846     default:
847     operation = NETWORK_ACL_RAW_BIND;
848     }
849     return check_network_entry(is_ipv6, operation, (const u32 *) address,
850     ntohs(port));
851 kumaneko 111 }
852    
853 kumaneko 1052 /**
854     * ccs_check_network_accept_acl - Check permission for accept() operation.
855     *
856     * @is_ipv6: True if @address is an IPv6 address.
857     * @address: An IPv4 or IPv6 address.
858     * @port: Port number.
859     *
860     * Returns 0 on success, negative value otherwise.
861     */
862     int ccs_check_network_accept_acl(const _Bool is_ipv6, const u8 *address,
863     const u16 port)
864 kumaneko 111 {
865 kumaneko 708 int retval;
866     current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
867 kumaneko 1052 retval = check_network_entry(is_ipv6, NETWORK_ACL_TCP_ACCEPT,
868     (const u32 *) address, ntohs(port));
869 kumaneko 708 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
870     return retval;
871 kumaneko 111 }
872    
873 kumaneko 1052 /**
874     * ccs_check_network_sendmsg_acl - Check permission for sendmsg() operation.
875     *
876     * @is_ipv6: True if @address is an IPv6 address.
877     * @sock_type: Type of socket. (UDP or RAW)
878     * @address: An IPv4 or IPv6 address.
879     * @port: Port number.
880     *
881     * Returns 0 on success, negative value otherwise.
882     */
883     int ccs_check_network_sendmsg_acl(const _Bool is_ipv6, const int sock_type,
884     const u8 *address, const u16 port)
885 kumaneko 111 {
886 kumaneko 1052 u8 operation;
887     if (sock_type == SOCK_DGRAM)
888     operation = NETWORK_ACL_UDP_CONNECT;
889     else
890     operation = NETWORK_ACL_RAW_CONNECT;
891     return check_network_entry(is_ipv6, operation, (const u32 *) address,
892     ntohs(port));
893 kumaneko 111 }
894    
895 kumaneko 1052 /**
896     * ccs_check_network_recvmsg_acl - Check permission for recvmsg() operation.
897     *
898     * @is_ipv6: True if @address is an IPv6 address.
899     * @sock_type: Type of socket. (UDP or RAW)
900     * @address: An IPv4 or IPv6 address.
901     * @port: Port number.
902     *
903     * Returns 0 on success, negative value otherwise.
904     */
905     int ccs_check_network_recvmsg_acl(const _Bool is_ipv6, const int sock_type,
906     const u8 *address, const u16 port)
907 kumaneko 111 {
908 kumaneko 708 int retval;
909 kumaneko 1052 const u8 operation
910 kumaneko 1064 = (sock_type == SOCK_DGRAM) ?
911 kumaneko 1052 NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
912 kumaneko 708 current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
913 kumaneko 1052 retval = check_network_entry(is_ipv6, operation, (const u32 *) address,
914     ntohs(port));
915 kumaneko 708 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
916     return retval;
917 kumaneko 111 }

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