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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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