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

Subversion リポジトリの参照

Annotation of /trunk/1.8.x/ccs-patch/security/ccsecurity/network.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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