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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2863 - (hide annotations) (download) (as text)
Fri Aug 7 06:27:45 2009 UTC (14 years, 9 months ago) by kumaneko
Original Path: branches/ccs-patch/security/ccsecurity/network.c
File MIME type: text/x-csrc
File size: 35125 byte(s)


1 kumaneko 111 /*
2 kumaneko 2853 * fs/ccsecurity/network.c
3 kumaneko 111 *
4 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 kumaneko 111 *
6 kumaneko 2727 * Version: 1.7.0-pre 2009/07/03
7 kumaneko 111 *
8     * This file is applicable to both 2.4.30 and 2.6.11 and later.
9     * See README.ccs for ChangeLog.
10     *
11     */
12    
13 kumaneko 1084 #include <linux/net.h>
14     #include <linux/inet.h>
15     #include <linux/in.h>
16     #include <linux/in6.h>
17 kumaneko 2037 #include <net/ip.h>
18     #include <net/ipv6.h>
19     #include <net/udp.h>
20 kumaneko 2854 #include "internal.h"
21 kumaneko 111
22 kumaneko 2037 /* Index numbers for Network Controls. */
23     enum ccs_network_acl_index {
24     NETWORK_ACL_UDP_BIND,
25     NETWORK_ACL_UDP_CONNECT,
26     NETWORK_ACL_TCP_BIND,
27     NETWORK_ACL_TCP_LISTEN,
28     NETWORK_ACL_TCP_CONNECT,
29     NETWORK_ACL_TCP_ACCEPT,
30     NETWORK_ACL_RAW_BIND,
31     NETWORK_ACL_RAW_CONNECT
32     };
33    
34 kumaneko 1052 /**
35 kumaneko 2002 * ccs_audit_network_log - Audit network log.
36 kumaneko 1052 *
37 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
38 kumaneko 1052 * @operation: The name of operation.
39     * @address: An IPv4 or IPv6 address.
40     * @port: Port number.
41     * @is_granted: True if this is a granted log.
42     *
43     * Returns 0 on success, negative value otherwise.
44     */
45 kumaneko 2002 static int ccs_audit_network_log(struct ccs_request_info *r,
46     const char *operation, const char *address,
47     const u16 port, const bool is_granted)
48 kumaneko 111 {
49 kumaneko 2780 if (!is_granted && ccs_verbose_mode(r->domain))
50     printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
51     ccs_get_msg(r->mode == 3), operation, address, port,
52     ccs_get_last_name(r->domain));
53 kumaneko 1657 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_NETWORK
54     "%s %s %u\n", operation, address, port);
55 kumaneko 111 }
56    
57 kumaneko 2540 /* The list for "struct ccs_address_group_entry". */
58     LIST_HEAD(ccs_address_group_list);
59    
60 kumaneko 1052 /**
61 kumaneko 2540 * ccs_get_address_group - Allocate memory for "struct ccs_address_group_entry".
62 kumaneko 1052 *
63 kumaneko 2540 * @group_name: The name of address group.
64 kumaneko 1052 *
65 kumaneko 2540 * Returns pointer to "struct ccs_address_group_entry" on success,
66     * NULL otherwise.
67 kumaneko 1052 */
68 kumaneko 2540 static struct ccs_address_group_entry *ccs_get_address_group(const char *
69     group_name)
70 kumaneko 719 {
71 kumaneko 2540 struct ccs_address_group_entry *entry = NULL;
72     struct ccs_address_group_entry *group;
73     const struct ccs_path_info *saved_group_name;
74     int error = -ENOMEM;
75 kumaneko 2577 if (!ccs_is_correct_path(group_name, 0, 0, 0) ||
76 kumaneko 2540 !group_name[0])
77 kumaneko 1052 return NULL;
78 kumaneko 2540 saved_group_name = ccs_get_name(group_name);
79     if (!saved_group_name)
80     return NULL;
81     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
82 kumaneko 2690 mutex_lock(&ccs_policy_lock);
83     list_for_each_entry_rcu(group, &ccs_address_group_list, list) {
84 kumaneko 2540 if (saved_group_name != group->group_name)
85     continue;
86     atomic_inc(&group->users);
87     error = 0;
88     break;
89 kumaneko 719 }
90 kumaneko 2718 if (error && ccs_memory_ok(entry, sizeof(*entry))) {
91 kumaneko 2540 INIT_LIST_HEAD(&entry->address_group_member_list);
92     entry->group_name = saved_group_name;
93     saved_group_name = NULL;
94     atomic_set(&entry->users, 1);
95 kumaneko 2690 list_add_tail_rcu(&entry->list, &ccs_address_group_list);
96 kumaneko 2540 group = entry;
97     entry = NULL;
98     error = 0;
99 kumaneko 719 }
100 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
101 kumaneko 2540 ccs_put_name(saved_group_name);
102     kfree(entry);
103     return !error ? group : NULL;
104 kumaneko 719 }
105    
106 kumaneko 1052 /**
107 kumaneko 2002 * ccs_update_address_group_entry - Update "struct ccs_address_group_entry" list.
108 kumaneko 1052 *
109 kumaneko 1064 * @group_name: The name of address group.
110     * @is_ipv6: True if @min_address and @max_address are IPv6 addresses.
111 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
112     * @max_address: End of IPv4 or IPv6 address range.
113     * @is_delete: True if it is a delete request.
114     *
115     * Returns 0 on success, negative value otherwise.
116     */
117 kumaneko 2002 static int ccs_update_address_group_entry(const char *group_name,
118     const bool is_ipv6,
119     const u16 *min_address,
120     const u16 *max_address,
121     const bool is_delete)
122 kumaneko 111 {
123 kumaneko 2002 struct ccs_address_group_entry *group;
124 kumaneko 2540 struct ccs_address_group_member *entry = NULL;
125 kumaneko 2002 struct ccs_address_group_member *member;
126 kumaneko 1052 const struct in6_addr *saved_min_address = NULL;
127     const struct in6_addr *saved_max_address = NULL;
128 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
129 kumaneko 2399 const u32 min_ipv4_address = ntohl(*(u32 *) min_address);
130     const u32 max_ipv4_address = ntohl(*(u32 *) max_address);
131 kumaneko 2540 group = ccs_get_address_group(group_name);
132     if (!group)
133 kumaneko 1052 return -ENOMEM;
134 kumaneko 2555 if (is_ipv6) {
135     saved_min_address
136     = ccs_get_ipv6_address((struct in6_addr *)
137     min_address);
138     saved_max_address
139     = ccs_get_ipv6_address((struct in6_addr *)
140     max_address);
141     if (!saved_min_address || !saved_max_address)
142     goto out;
143     }
144 kumaneko 2540 if (!is_delete)
145     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
146 kumaneko 2690 mutex_lock(&ccs_policy_lock);
147     list_for_each_entry_rcu(member, &group->address_group_member_list,
148     list) {
149 kumaneko 2540 if (member->is_ipv6 != is_ipv6)
150 kumaneko 1052 continue;
151 kumaneko 2540 if (is_ipv6) {
152     if (member->min.ipv6 != saved_min_address ||
153     member->max.ipv6 != saved_max_address)
154 kumaneko 1052 continue;
155 kumaneko 2540 } else {
156     if (member->min.ipv4 != min_ipv4_address ||
157     member->max.ipv4 != max_ipv4_address)
158     continue;
159 kumaneko 111 }
160 kumaneko 2540 member->is_deleted = is_delete;
161     error = 0;
162 kumaneko 111 break;
163     }
164 kumaneko 2718 if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
165 kumaneko 2540 entry->is_ipv6 = is_ipv6;
166     if (is_ipv6) {
167     entry->min.ipv6 = saved_min_address;
168     saved_min_address = NULL;
169     entry->max.ipv6 = saved_max_address;
170     saved_max_address = NULL;
171     } else {
172     entry->min.ipv4 = min_ipv4_address;
173     entry->max.ipv4 = max_ipv4_address;
174     }
175 kumaneko 2690 list_add_tail_rcu(&entry->list,
176     &group->address_group_member_list);
177 kumaneko 2540 entry = NULL;
178     error = 0;
179 kumaneko 111 }
180 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
181 kumaneko 111 out:
182 kumaneko 2540 ccs_put_ipv6_address(saved_min_address);
183     ccs_put_ipv6_address(saved_max_address);
184     ccs_put_address_group(group);
185 kumaneko 111 return error;
186     }
187    
188 kumaneko 1052 /**
189 kumaneko 2002 * ccs_parse_ip_address - Parse an IP address.
190 kumaneko 1657 *
191     * @address: String to parse.
192     * @min: Pointer to store min address.
193     * @max: Pointer to store max address.
194     *
195     * Returns 2 if @address is an IPv6, 1 if @address is an IPv4, 0 otherwise.
196     */
197 kumaneko 2002 static int ccs_parse_ip_address(char *address, u16 *min, u16 *max)
198 kumaneko 1657 {
199     int count = sscanf(address, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"
200     "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
201     &min[0], &min[1], &min[2], &min[3],
202     &min[4], &min[5], &min[6], &min[7],
203     &max[0], &max[1], &max[2], &max[3],
204     &max[4], &max[5], &max[6], &max[7]);
205     if (count == 8 || count == 16) {
206     u8 i;
207     if (count == 8)
208     memmove(max, min, sizeof(u16) * 8);
209     for (i = 0; i < 8; i++) {
210     min[i] = htons(min[i]);
211     max[i] = htons(max[i]);
212     }
213     return 2;
214     }
215     count = sscanf(address, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
216     &min[0], &min[1], &min[2], &min[3],
217     &max[0], &max[1], &max[2], &max[3]);
218     if (count == 4 || count == 8) {
219 kumaneko 1658 u32 ip = htonl((((u8) min[0]) << 24) + (((u8) min[1]) << 16)
220     + (((u8) min[2]) << 8) + (u8) min[3]);
221     memmove(min, &ip, sizeof(ip));
222     if (count == 8)
223     ip = htonl((((u8) max[0]) << 24) + (((u8) max[1]) << 16)
224     + (((u8) max[2]) << 8) + (u8) max[3]);
225     memmove(max, &ip, sizeof(ip));
226 kumaneko 1657 return 1;
227     }
228     return 0;
229     }
230    
231     /**
232 kumaneko 2002 * ccs_write_address_group_policy - Write "struct ccs_address_group_entry" list.
233 kumaneko 1052 *
234     * @data: String to parse.
235     * @is_delete: True if it is a delete request.
236     *
237     * Returns 0 on success, negative value otherwise.
238     */
239     int ccs_write_address_group_policy(char *data, const bool is_delete)
240 kumaneko 111 {
241 kumaneko 2779 char *w[2];
242 kumaneko 853 bool is_ipv6;
243 kumaneko 1064 u16 min_address[8];
244     u16 max_address[8];
245 kumaneko 2779 if (!ccs_tokenize(data, w, sizeof(w)) || !w[1][0])
246     return -EINVAL;
247     switch (ccs_parse_ip_address(w[1], min_address, max_address)) {
248 kumaneko 1657 case 2:
249 kumaneko 1016 is_ipv6 = true;
250 kumaneko 1657 break;
251     case 1:
252 kumaneko 1016 is_ipv6 = false;
253 kumaneko 1657 break;
254     default:
255     return -EINVAL;
256 kumaneko 111 }
257 kumaneko 2779 return ccs_update_address_group_entry(w[0], is_ipv6, min_address,
258 kumaneko 2002 max_address, is_delete);
259 kumaneko 111 }
260    
261 kumaneko 1052 /**
262 kumaneko 2039 * ccs_address_matches_group - Check whether the given address matches members of the given address group.
263 kumaneko 1052 *
264     * @is_ipv6: True if @address is an IPv6 address.
265     * @address: An IPv4 or IPv6 address.
266 kumaneko 2002 * @group: Pointer to "struct ccs_address_group_entry".
267 kumaneko 1052 *
268     * Returns true if @address matches addresses in @group group, false otherwise.
269 kumaneko 2540 *
270 kumaneko 2828 * Caller holds ccs_read_lock().
271 kumaneko 1052 */
272 kumaneko 2039 static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
273     const struct ccs_address_group_entry *
274     group)
275 kumaneko 111 {
276 kumaneko 2002 struct ccs_address_group_member *member;
277 kumaneko 111 const u32 ip = ntohl(*address);
278 kumaneko 2540 bool matched = false;
279 kumaneko 2828 ccs_check_read_lock();
280 kumaneko 2690 list_for_each_entry_rcu(member, &group->address_group_member_list,
281     list) {
282 kumaneko 1052 if (member->is_deleted)
283     continue;
284 kumaneko 111 if (member->is_ipv6) {
285 kumaneko 1052 if (is_ipv6 &&
286     memcmp(member->min.ipv6, address, 16) <= 0 &&
287 kumaneko 2540 memcmp(address, member->max.ipv6, 16) <= 0) {
288     matched = true;
289     break;
290     }
291 kumaneko 111 } else {
292 kumaneko 1052 if (!is_ipv6 &&
293 kumaneko 2540 member->min.ipv4 <= ip && ip <= member->max.ipv4) {
294     matched = true;
295     break;
296     }
297 kumaneko 111 }
298     }
299 kumaneko 2540 return matched;
300 kumaneko 111 }
301    
302 kumaneko 1052 /**
303 kumaneko 2002 * ccs_read_address_group_policy - Read "struct ccs_address_group_entry" list.
304 kumaneko 1052 *
305     * @head: Pointer to "struct ccs_io_buffer".
306     *
307     * Returns true on success, false otherwise.
308 kumaneko 2690 *
309 kumaneko 2828 * Caller holds ccs_read_lock().
310 kumaneko 1052 */
311     bool ccs_read_address_group_policy(struct ccs_io_buffer *head)
312 kumaneko 111 {
313 kumaneko 2540 struct list_head *gpos;
314     struct list_head *mpos;
315     bool done = true;
316 kumaneko 2828 ccs_check_read_lock();
317 kumaneko 2690 list_for_each_cookie(gpos, head->read_var1, &ccs_address_group_list) {
318 kumaneko 2002 struct ccs_address_group_entry *group;
319 kumaneko 2540 group = list_entry(gpos, struct ccs_address_group_entry, list);
320 kumaneko 2690 list_for_each_cookie(mpos, head->read_var2,
321     &group->address_group_member_list) {
322 kumaneko 708 char buf[128];
323 kumaneko 2002 struct ccs_address_group_member *member;
324 kumaneko 2540 member = list_entry(mpos,
325 kumaneko 2002 struct ccs_address_group_member,
326 kumaneko 1052 list);
327     if (member->is_deleted)
328     continue;
329 kumaneko 1064 if (member->is_ipv6) {
330 kumaneko 1052 const struct in6_addr *min_address
331     = member->min.ipv6;
332     const struct in6_addr *max_address
333     = member->max.ipv6;
334     ccs_print_ipv6(buf, sizeof(buf), min_address);
335 kumaneko 719 if (min_address != max_address) {
336 kumaneko 1052 int len;
337 kumaneko 1795 char *cp = buf + strlen(buf);
338 kumaneko 708 *cp++ = '-';
339 kumaneko 1052 len = strlen(buf);
340     ccs_print_ipv6(cp, sizeof(buf) - len,
341     max_address);
342 kumaneko 111 }
343 kumaneko 708 } else {
344 kumaneko 1052 const u32 min_address = member->min.ipv4;
345     const u32 max_address = member->max.ipv4;
346 kumaneko 708 memset(buf, 0, sizeof(buf));
347 kumaneko 1052 snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u",
348     HIPQUAD(min_address));
349 kumaneko 708 if (min_address != max_address) {
350     const int len = strlen(buf);
351 kumaneko 1052 snprintf(buf + len,
352     sizeof(buf) - 1 - len,
353     "-%u.%u.%u.%u",
354     HIPQUAD(max_address));
355 kumaneko 708 }
356 kumaneko 111 }
357 kumaneko 2540 done = ccs_io_printf(head, KEYWORD_ADDRESS_GROUP
358     "%s %s\n", group->group_name->name,
359     buf);
360     if (!done)
361     break;
362 kumaneko 111 }
363 kumaneko 2540 if (!done)
364     break;
365 kumaneko 111 }
366 kumaneko 2540 return done;
367 kumaneko 111 }
368    
369 kumaneko 719 #if !defined(NIP6)
370 kumaneko 1052 #define NIP6(addr) \
371 kumaneko 1056 ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]), \
372     ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \
373     ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \
374     ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])
375 kumaneko 719 #endif
376    
377 kumaneko 1052 /**
378 kumaneko 1054 * ccs_print_ipv6 - Print an IPv6 address.
379 kumaneko 1052 *
380     * @buffer: Buffer to write to.
381 kumaneko 1064 * @buffer_len: Size of @buffer.
382 kumaneko 1052 * @ip: Pointer to "struct in6_addr".
383     *
384 kumaneko 1064 * Returns nothing.
385 kumaneko 1052 */
386 kumaneko 1064 void ccs_print_ipv6(char *buffer, const int buffer_len,
387     const struct in6_addr *ip)
388 kumaneko 111 {
389     memset(buffer, 0, buffer_len);
390 kumaneko 719 snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
391 kumaneko 111 }
392    
393 kumaneko 1052 /**
394     * ccs_net2keyword - Convert network operation index to network operation name.
395     *
396     * @operation: Type of operation.
397     *
398     * Returns the name of operation.
399     */
400     const char *ccs_net2keyword(const u8 operation)
401 kumaneko 111 {
402     const char *keyword = "unknown";
403     switch (operation) {
404     case NETWORK_ACL_UDP_BIND:
405     keyword = "UDP bind";
406     break;
407     case NETWORK_ACL_UDP_CONNECT:
408     keyword = "UDP connect";
409     break;
410     case NETWORK_ACL_TCP_BIND:
411     keyword = "TCP bind";
412     break;
413     case NETWORK_ACL_TCP_LISTEN:
414     keyword = "TCP listen";
415     break;
416     case NETWORK_ACL_TCP_CONNECT:
417     keyword = "TCP connect";
418     break;
419     case NETWORK_ACL_TCP_ACCEPT:
420     keyword = "TCP accept";
421     break;
422     case NETWORK_ACL_RAW_BIND:
423     keyword = "RAW bind";
424     break;
425     case NETWORK_ACL_RAW_CONNECT:
426     keyword = "RAW connect";
427     break;
428     }
429     return keyword;
430     }
431    
432 kumaneko 1052 /**
433 kumaneko 2002 * ccs_update_network_entry - Update "struct ccs_ip_network_acl_record" list.
434 kumaneko 1052 *
435     * @operation: Type of operation.
436     * @record_type: Type of address.
437 kumaneko 2540 * @group: Name of group. May be NULL.
438 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
439     * @max_address: End of IPv4 or IPv6 address range.
440     * @min_port: Start of port number range.
441     * @max_port: End of port number range.
442 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
443 kumaneko 2576 * @condition: Pointer to "struct ccs_condition". May be NULL.
444 kumaneko 1052 * @is_delete: True if it is a delete request.
445     *
446     * Returns 0 on success, negative value otherwise.
447     */
448 kumaneko 2002 static int ccs_update_network_entry(const u8 operation, const u8 record_type,
449 kumaneko 2863 const char *address_group_name,
450     const char *port_group_name,
451 kumaneko 2002 const u32 *min_address,
452     const u32 *max_address,
453     const u16 min_port, const u16 max_port,
454 kumaneko 2282 struct ccs_domain_info *domain,
455 kumaneko 2576 struct ccs_condition *condition,
456 kumaneko 2002 const bool is_delete)
457 kumaneko 111 {
458 kumaneko 2863 struct ccs_acl_info *ptr;
459     struct ccs_ip_network_acl_record e;
460 kumaneko 2540 struct ccs_ip_network_acl_record *entry = NULL;
461     int error = is_delete ? -ENOENT : -ENOMEM;
462 kumaneko 2863 memset(&e, 0, sizeof(e));
463     e.head.type = TYPE_IP_NETWORK_ACL;
464     e.head.cond = condition;
465 kumaneko 1052 if (!domain)
466     return -EINVAL;
467 kumaneko 2863 if (address_group_name) {
468     e.address.group = ccs_get_address_group(address_group_name);
469     if (!e.address.group)
470 kumaneko 2540 return -ENOMEM;
471     } else if (record_type == IP_RECORD_TYPE_IPv6) {
472 kumaneko 2863 e.address.ipv6.min = ccs_get_ipv6_address((struct in6_addr *)
473     min_address);
474     e.address.ipv6.max = ccs_get_ipv6_address((struct in6_addr *)
475     max_address);
476     if (!e.address.ipv6.min || !e.address.ipv6.max)
477 kumaneko 2540 goto out;
478 kumaneko 2863 } else {
479     /* use host byte order to allow u32 comparison than memcmp().*/
480     e.address.ipv4.min = ntohl(*min_address);
481     e.address.ipv4.max = ntohl(*max_address);
482 kumaneko 2540 }
483 kumaneko 2863 if (port_group_name) {
484     if (!ccs_check_and_save_number(port_group_name,
485     &e.port_is_group, &e.port))
486     goto out;
487     } else {
488     e.port.value.min = min_port;
489     e.port.value.max = max_port;
490     }
491 kumaneko 1052 if (is_delete)
492     goto delete;
493 kumaneko 2540 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
494 kumaneko 2690 mutex_lock(&ccs_policy_lock);
495     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
496 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
497 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_IP_NETWORK_ACL)
498 kumaneko 1052 continue;
499 kumaneko 2544 if (ptr->cond != condition)
500 kumaneko 1052 continue;
501 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
502 kumaneko 2863 if (memcmp(acl, &e, sizeof(e)))
503 kumaneko 1052 continue;
504     error = ccs_add_domain_acl(NULL, ptr);
505 kumaneko 2540 break;
506 kumaneko 1052 }
507 kumaneko 2718 if (error && ccs_memory_ok(entry, sizeof(*entry))) {
508 kumaneko 2863 memmove(entry, &e, sizeof(e));
509     memset(&e, 0, sizeof(e));
510 kumaneko 2540 error = ccs_add_domain_acl(domain, &entry->head);
511     entry = NULL;
512 kumaneko 1052 }
513 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
514 kumaneko 1052 goto out;
515     delete:
516 kumaneko 2690 mutex_lock(&ccs_policy_lock);
517     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
518 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
519 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
520 kumaneko 1052 continue;
521 kumaneko 2544 if (ptr->cond != condition)
522 kumaneko 1052 continue;
523 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
524 kumaneko 2863 if (memcmp(acl, &e, sizeof(e)))
525 kumaneko 1052 continue;
526     error = ccs_del_domain_acl(ptr);
527     break;
528 kumaneko 111 }
529 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
530 kumaneko 1052 out:
531 kumaneko 2863 if (address_group_name)
532     ccs_put_address_group(e.address.group);
533     else if (record_type == IP_RECORD_TYPE_IPv6) {
534     ccs_put_ipv6_address(e.address.ipv6.min);
535     ccs_put_ipv6_address(e.address.ipv6.max);
536     }
537     if (port_group_name)
538     ccs_put_number_group(e.port.group);
539 kumaneko 2540 kfree(entry);
540 kumaneko 111 return error;
541     }
542    
543 kumaneko 1052 /**
544 kumaneko 2702 * ccs_check_network_entry2 - Check permission for network operation.
545 kumaneko 1052 *
546     * @is_ipv6: True if @address is an IPv6 address.
547     * @operation: Type of operation.
548     * @address: An IPv4 or IPv6 address.
549     * @port: Port number.
550     *
551     * Returns 0 on success, negative value otherwise.
552 kumaneko 2690 *
553 kumaneko 2828 * Caller holds ccs_read_lock().
554 kumaneko 1052 */
555 kumaneko 2702 static int ccs_check_network_entry2(const bool is_ipv6, const u8 operation,
556     const u32 *address, const u16 port)
557 kumaneko 111 {
558 kumaneko 1657 struct ccs_request_info r;
559 kumaneko 2002 struct ccs_acl_info *ptr;
560 kumaneko 1052 const char *keyword = ccs_net2keyword(operation);
561 kumaneko 1657 bool is_enforce;
562 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
563     const u32 ip = ntohl(*address);
564 kumaneko 1016 bool found = false;
565 kumaneko 1064 char buf[64];
566 kumaneko 2828 ccs_check_read_lock();
567 kumaneko 1657 if (!ccs_can_sleep())
568 kumaneko 1052 return 0;
569 kumaneko 2282 ccs_init_request_info(&r, NULL, CCS_MAC_FOR_NETWORK);
570 kumaneko 1657 is_enforce = (r.mode == 3);
571 kumaneko 2692 if (!r.mode)
572     return 0;
573 kumaneko 2002 retry:
574 kumaneko 2690 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
575 kumaneko 2002 struct ccs_ip_network_acl_record *acl;
576 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
577 kumaneko 1052 continue;
578 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
579 kumaneko 2863 if (acl->operation_type != operation)
580 kumaneko 1052 continue;
581 kumaneko 2863 if (acl->port_is_group) {
582     if (!ccs_number_matches_group(port, port,
583     acl->port.group))
584     continue;
585     } else {
586     if (port < acl->port.value.min ||
587     acl->port.value.max < port)
588     continue;
589     }
590     if (!ccs_check_condition(&r, ptr))
591     continue;
592 kumaneko 708 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
593 kumaneko 2039 if (!ccs_address_matches_group(is_ipv6, address,
594 kumaneko 2863 acl->address.group))
595 kumaneko 1052 continue;
596 kumaneko 708 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
597 kumaneko 1052 if (is_ipv6 ||
598 kumaneko 2863 ip < acl->address.ipv4.min ||
599     acl->address.ipv4.max < ip)
600 kumaneko 1052 continue;
601 kumaneko 111 } else {
602 kumaneko 1052 if (!is_ipv6 ||
603 kumaneko 2863 memcmp(acl->address.ipv6.min, address, 16) > 0 ||
604     memcmp(address, acl->address.ipv6.max, 16) > 0)
605 kumaneko 1052 continue;
606 kumaneko 111 }
607 kumaneko 2690 r.cond = ptr->cond;
608 kumaneko 1016 found = true;
609 kumaneko 708 break;
610 kumaneko 111 }
611 kumaneko 1064 memset(buf, 0, sizeof(buf));
612     if (is_ipv6)
613     ccs_print_ipv6(buf, sizeof(buf),
614     (const struct in6_addr *) address);
615     else
616     snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
617 kumaneko 2002 ccs_audit_network_log(&r, keyword, buf, port, found);
618 kumaneko 2692 if (found)
619     return 0;
620 kumaneko 1561 if (is_enforce) {
621 kumaneko 2544 int err = ccs_check_supervisor(&r, KEYWORD_ALLOW_NETWORK
622     "%s %s %u\n", keyword, buf,
623     port);
624     if (err == 1)
625 kumaneko 1561 goto retry;
626 kumaneko 2692 return err;
627 kumaneko 2780 } else if (ccs_domain_quota_ok(&r)) {
628 kumaneko 2581 struct ccs_condition *cond = ccs_handler_cond();
629 kumaneko 2002 ccs_update_network_entry(operation, is_ipv6 ?
630     IP_RECORD_TYPE_IPv6 :
631     IP_RECORD_TYPE_IPv4,
632 kumaneko 2863 NULL, NULL, address, address, port,
633     port, r.domain, cond, false);
634 kumaneko 2581 ccs_put_condition(cond);
635     }
636 kumaneko 2692 return 0;
637 kumaneko 111 }
638    
639 kumaneko 1052 /**
640 kumaneko 2702 * ccs_check_network_entry - Check permission for network operation.
641     *
642     * @is_ipv6: True if @address is an IPv6 address.
643     * @operation: Type of operation.
644     * @address: An IPv4 or IPv6 address.
645     * @port: Port number.
646     *
647     * Returns 0 on success, negative value otherwise.
648     */
649     static int ccs_check_network_entry(const bool is_ipv6, const u8 operation,
650     const u32 *address, const u16 port)
651     {
652 kumaneko 2828 const int idx = ccs_read_lock();
653 kumaneko 2702 const int error = ccs_check_network_entry2(is_ipv6, operation,
654     address, port);
655 kumaneko 2828 ccs_read_unlock(idx);
656 kumaneko 2702 return error;
657     }
658    
659     /**
660 kumaneko 2002 * ccs_write_network_policy - Write "struct ccs_ip_network_acl_record" list.
661 kumaneko 1052 *
662     * @data: String to parse.
663 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
664 kumaneko 2576 * @condition: Pointer to "struct ccs_condition". May be NULL.
665 kumaneko 1052 * @is_delete: True if it is a delete request.
666     *
667     * Returns 0 on success, negative value otherwise.
668     */
669 kumaneko 2282 int ccs_write_network_policy(char *data, struct ccs_domain_info *domain,
670 kumaneko 2576 struct ccs_condition *condition,
671 kumaneko 1052 const bool is_delete)
672 kumaneko 111 {
673 kumaneko 2779 char *w[4];
674 kumaneko 1064 u8 sock_type;
675     u8 operation;
676     u8 record_type;
677     u16 min_address[8];
678     u16 max_address[8];
679 kumaneko 2863 const char *address_group_name = NULL;
680     const char *port_group_name = NULL;
681 kumaneko 1064 u16 min_port;
682     u16 max_port;
683 kumaneko 2779 if (!ccs_tokenize(data, w, sizeof(w)) || !w[3][0])
684     return -EINVAL;
685     if (!strcmp(w[0], "TCP"))
686 kumaneko 1052 sock_type = SOCK_STREAM;
687 kumaneko 2779 else if (!strcmp(w[0], "UDP"))
688 kumaneko 1052 sock_type = SOCK_DGRAM;
689 kumaneko 2779 else if (!strcmp(w[0], "RAW"))
690 kumaneko 1052 sock_type = SOCK_RAW;
691     else
692     goto out;
693 kumaneko 2779 if (!strcmp(w[1], "bind"))
694 kumaneko 1052 switch (sock_type) {
695     case SOCK_STREAM:
696     operation = NETWORK_ACL_TCP_BIND;
697     break;
698     case SOCK_DGRAM:
699     operation = NETWORK_ACL_UDP_BIND;
700     break;
701     default:
702     operation = NETWORK_ACL_RAW_BIND;
703     }
704 kumaneko 2779 else if (!strcmp(w[1], "connect"))
705 kumaneko 1052 switch (sock_type) {
706     case SOCK_STREAM:
707     operation = NETWORK_ACL_TCP_CONNECT;
708     break;
709     case SOCK_DGRAM:
710     operation = NETWORK_ACL_UDP_CONNECT;
711     break;
712     default:
713     operation = NETWORK_ACL_RAW_CONNECT;
714     }
715 kumaneko 2779 else if (sock_type == SOCK_STREAM && !strcmp(w[1], "listen"))
716 kumaneko 111 operation = NETWORK_ACL_TCP_LISTEN;
717 kumaneko 2779 else if (sock_type == SOCK_STREAM && !strcmp(w[1], "accept"))
718 kumaneko 111 operation = NETWORK_ACL_TCP_ACCEPT;
719 kumaneko 1052 else
720 kumaneko 111 goto out;
721 kumaneko 2779 switch (ccs_parse_ip_address(w[2], min_address, max_address)) {
722 kumaneko 1657 case 2:
723 kumaneko 111 record_type = IP_RECORD_TYPE_IPv6;
724 kumaneko 1657 break;
725     case 1:
726 kumaneko 111 record_type = IP_RECORD_TYPE_IPv4;
727 kumaneko 1657 break;
728     default:
729 kumaneko 2779 if (w[2][0] != '@')
730 kumaneko 1657 goto out;
731 kumaneko 2863 address_group_name = w[2] + 1;
732 kumaneko 111 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
733 kumaneko 1657 break;
734 kumaneko 111 }
735 kumaneko 2863 switch (sscanf(w[3], "%hu-%hu", &min_port, &max_port)) {
736     case 2:
737     break;
738     case 1:
739 kumaneko 1052 max_port = min_port;
740 kumaneko 2863 break;
741     default:
742     if (w[3][0] != '@')
743     goto out;
744     port_group_name = w[3];
745     break;
746     }
747     return ccs_update_network_entry(operation, record_type,
748     address_group_name, port_group_name,
749 kumaneko 2002 (u32 *) min_address,
750     (u32 *) max_address,
751     min_port, max_port, domain, condition,
752     is_delete);
753 kumaneko 1657 out:
754     return -EINVAL;
755 kumaneko 111 }
756    
757 kumaneko 1052 /**
758     * ccs_check_network_listen_acl - Check permission for listen() operation.
759     *
760     * @is_ipv6: True if @address is an IPv6 address.
761     * @address: An IPv4 or IPv6 address.
762     * @port: Port number.
763     *
764     * Returns 0 on success, negative value otherwise.
765     */
766 kumaneko 2037 static inline int ccs_check_network_listen_acl(const bool is_ipv6,
767     const u8 *address,
768     const u16 port)
769 kumaneko 111 {
770 kumaneko 2002 return ccs_check_network_entry(is_ipv6, NETWORK_ACL_TCP_LISTEN,
771     (const u32 *) address, ntohs(port));
772 kumaneko 111 }
773    
774 kumaneko 1052 /**
775     * ccs_check_network_connect_acl - Check permission for connect() operation.
776     *
777     * @is_ipv6: True if @address is an IPv6 address.
778     * @sock_type: Type of socket. (TCP or UDP or RAW)
779     * @address: An IPv4 or IPv6 address.
780     * @port: Port number.
781     *
782     * Returns 0 on success, negative value otherwise.
783     */
784 kumaneko 2037 static inline int ccs_check_network_connect_acl(const bool is_ipv6,
785     const int sock_type,
786     const u8 *address,
787     const u16 port)
788 kumaneko 111 {
789 kumaneko 1052 u8 operation;
790     switch (sock_type) {
791     case SOCK_STREAM:
792     operation = NETWORK_ACL_TCP_CONNECT;
793     break;
794     case SOCK_DGRAM:
795     operation = NETWORK_ACL_UDP_CONNECT;
796     break;
797     default:
798     operation = NETWORK_ACL_RAW_CONNECT;
799     }
800 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
801     (const u32 *) address, ntohs(port));
802 kumaneko 111 }
803    
804 kumaneko 1052 /**
805     * ccs_check_network_bind_acl - Check permission for bind() operation.
806     *
807     * @is_ipv6: True if @address is an IPv6 address.
808     * @sock_type: Type of socket. (TCP or UDP or RAW)
809     * @address: An IPv4 or IPv6 address.
810     * @port: Port number.
811     *
812     * Returns 0 on success, negative value otherwise.
813     */
814 kumaneko 2037 static int ccs_check_network_bind_acl(const bool is_ipv6, const int sock_type,
815     const u8 *address, const u16 port)
816 kumaneko 111 {
817 kumaneko 1052 u8 operation;
818     switch (sock_type) {
819     case SOCK_STREAM:
820     operation = NETWORK_ACL_TCP_BIND;
821     break;
822     case SOCK_DGRAM:
823     operation = NETWORK_ACL_UDP_BIND;
824     break;
825     default:
826     operation = NETWORK_ACL_RAW_BIND;
827     }
828 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
829     (const u32 *) address, ntohs(port));
830 kumaneko 111 }
831    
832 kumaneko 1052 /**
833     * ccs_check_network_accept_acl - Check permission for accept() operation.
834     *
835     * @is_ipv6: True if @address is an IPv6 address.
836     * @address: An IPv4 or IPv6 address.
837     * @port: Port number.
838     *
839     * Returns 0 on success, negative value otherwise.
840     */
841 kumaneko 2037 static inline int ccs_check_network_accept_acl(const bool is_ipv6,
842     const u8 *address,
843     const u16 port)
844 kumaneko 111 {
845 kumaneko 708 int retval;
846 kumaneko 2282 current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
847 kumaneko 2002 retval = ccs_check_network_entry(is_ipv6, NETWORK_ACL_TCP_ACCEPT,
848     (const u32 *) address, ntohs(port));
849 kumaneko 2282 current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
850 kumaneko 708 return retval;
851 kumaneko 111 }
852    
853 kumaneko 1052 /**
854     * ccs_check_network_sendmsg_acl - Check permission for sendmsg() operation.
855     *
856     * @is_ipv6: True if @address is an IPv6 address.
857     * @sock_type: Type of socket. (UDP or RAW)
858     * @address: An IPv4 or IPv6 address.
859     * @port: Port number.
860     *
861     * Returns 0 on success, negative value otherwise.
862     */
863 kumaneko 2037 static inline int ccs_check_network_sendmsg_acl(const bool is_ipv6,
864     const int sock_type,
865     const u8 *address,
866     const u16 port)
867 kumaneko 111 {
868 kumaneko 1052 u8 operation;
869     if (sock_type == SOCK_DGRAM)
870     operation = NETWORK_ACL_UDP_CONNECT;
871     else
872     operation = NETWORK_ACL_RAW_CONNECT;
873 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
874     (const u32 *) address, ntohs(port));
875 kumaneko 111 }
876    
877 kumaneko 1052 /**
878     * ccs_check_network_recvmsg_acl - Check permission for recvmsg() operation.
879     *
880     * @is_ipv6: True if @address is an IPv6 address.
881     * @sock_type: Type of socket. (UDP or RAW)
882     * @address: An IPv4 or IPv6 address.
883     * @port: Port number.
884     *
885     * Returns 0 on success, negative value otherwise.
886     */
887 kumaneko 2037 static inline int ccs_check_network_recvmsg_acl(const bool is_ipv6,
888     const int sock_type,
889     const u8 *address,
890     const u16 port)
891 kumaneko 111 {
892 kumaneko 708 int retval;
893 kumaneko 1052 const u8 operation
894 kumaneko 1064 = (sock_type == SOCK_DGRAM) ?
895 kumaneko 1052 NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
896 kumaneko 2282 current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
897 kumaneko 2002 retval = ccs_check_network_entry(is_ipv6, operation,
898     (const u32 *) address, ntohs(port));
899 kumaneko 2282 current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
900 kumaneko 708 return retval;
901 kumaneko 111 }
902 kumaneko 2037
903     #define MAX_SOCK_ADDR 128 /* net/socket.c */
904    
905     /* Check permission for creating a socket. */
906     int ccs_socket_create_permission(int family, int type, int protocol)
907     {
908     int error = 0;
909     /* Nothing to do if I am a kernel service. */
910     if (segment_eq(get_fs(), KERNEL_DS))
911     return 0;
912 kumaneko 2282 if (family == PF_PACKET && !ccs_capable(CCS_USE_PACKET_SOCKET))
913 kumaneko 2037 return -EPERM;
914 kumaneko 2282 if (family == PF_ROUTE && !ccs_capable(CCS_USE_ROUTE_SOCKET))
915 kumaneko 2037 return -EPERM;
916     if (family != PF_INET && family != PF_INET6)
917     return 0;
918     switch (type) {
919     case SOCK_STREAM:
920 kumaneko 2282 if (!ccs_capable(CCS_INET_STREAM_SOCKET_CREATE))
921 kumaneko 2037 error = -EPERM;
922     break;
923     case SOCK_DGRAM:
924 kumaneko 2282 if (!ccs_capable(CCS_USE_INET_DGRAM_SOCKET))
925 kumaneko 2037 error = -EPERM;
926     break;
927     case SOCK_RAW:
928 kumaneko 2282 if (!ccs_capable(CCS_USE_INET_RAW_SOCKET))
929 kumaneko 2037 error = -EPERM;
930     break;
931     }
932     return error;
933     }
934    
935     /* Check permission for listening a TCP socket. */
936     int ccs_socket_listen_permission(struct socket *sock)
937     {
938     int error = 0;
939     char addr[MAX_SOCK_ADDR];
940     int addr_len;
941     /* Nothing to do if I am a kernel service. */
942     if (segment_eq(get_fs(), KERNEL_DS))
943     return 0;
944     if (sock->type != SOCK_STREAM)
945     return 0;
946     switch (sock->sk->sk_family) {
947     case PF_INET:
948     case PF_INET6:
949     break;
950     default:
951     return 0;
952     }
953 kumaneko 2282 if (!ccs_capable(CCS_INET_STREAM_SOCKET_LISTEN))
954 kumaneko 2037 return -EPERM;
955     if (sock->ops->getname(sock, (struct sockaddr *) addr, &addr_len, 0))
956     return -EPERM;
957     switch (((struct sockaddr *) addr)->sa_family) {
958     struct sockaddr_in6 *addr6;
959     struct sockaddr_in *addr4;
960     case AF_INET6:
961     addr6 = (struct sockaddr_in6 *) addr;
962     error = ccs_check_network_listen_acl(true,
963     addr6->sin6_addr.s6_addr,
964     addr6->sin6_port);
965     break;
966     case AF_INET:
967     addr4 = (struct sockaddr_in *) addr;
968     error = ccs_check_network_listen_acl(false,
969     (u8 *) &addr4->sin_addr,
970     addr4->sin_port);
971     break;
972     }
973     return error;
974     }
975    
976     /* Check permission for setting the remote IP address/port pair of a socket. */
977     int ccs_socket_connect_permission(struct socket *sock, struct sockaddr *addr,
978     int addr_len)
979     {
980     int error = 0;
981     const unsigned int type = sock->type;
982     /* Nothing to do if I am a kernel service. */
983     if (segment_eq(get_fs(), KERNEL_DS))
984     return 0;
985     switch (type) {
986     case SOCK_STREAM:
987     case SOCK_DGRAM:
988     case SOCK_RAW:
989     break;
990     default:
991     return 0;
992     }
993     switch (addr->sa_family) {
994     struct sockaddr_in6 *addr6;
995     struct sockaddr_in *addr4;
996     u16 port;
997     case AF_INET6:
998     if (addr_len < SIN6_LEN_RFC2133)
999     break;
1000     addr6 = (struct sockaddr_in6 *) addr;
1001     if (type != SOCK_RAW)
1002     port = addr6->sin6_port;
1003     else
1004     port = htons(sock->sk->sk_protocol);
1005     error = ccs_check_network_connect_acl(true, type,
1006     addr6->sin6_addr.s6_addr,
1007     port);
1008     break;
1009     case AF_INET:
1010     if (addr_len < sizeof(struct sockaddr_in))
1011     break;
1012     addr4 = (struct sockaddr_in *) addr;
1013     if (type != SOCK_RAW)
1014     port = addr4->sin_port;
1015     else
1016     port = htons(sock->sk->sk_protocol);
1017     error = ccs_check_network_connect_acl(false, type,
1018     (u8 *) &addr4->sin_addr,
1019     port);
1020     break;
1021     }
1022     if (type != SOCK_STREAM)
1023     return error;
1024     switch (sock->sk->sk_family) {
1025     case PF_INET:
1026     case PF_INET6:
1027 kumaneko 2282 if (!ccs_capable(CCS_INET_STREAM_SOCKET_CONNECT))
1028 kumaneko 2037 error = -EPERM;
1029     break;
1030     }
1031     return error;
1032     }
1033    
1034     /* Check permission for setting the local IP address/port pair of a socket. */
1035     int ccs_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
1036     int addr_len)
1037     {
1038     int error = 0;
1039     const unsigned int type = sock->type;
1040     /* Nothing to do if I am a kernel service. */
1041     if (segment_eq(get_fs(), KERNEL_DS))
1042     return 0;
1043     switch (type) {
1044     case SOCK_STREAM:
1045     case SOCK_DGRAM:
1046     case SOCK_RAW:
1047     break;
1048     default:
1049     return 0;
1050     }
1051     switch (addr->sa_family) {
1052     struct sockaddr_in6 *addr6;
1053     struct sockaddr_in *addr4;
1054     u16 port;
1055     case AF_INET6:
1056     if (addr_len < SIN6_LEN_RFC2133)
1057     break;
1058     addr6 = (struct sockaddr_in6 *) addr;
1059     if (type != SOCK_RAW)
1060     port = addr6->sin6_port;
1061     else
1062     port = htons(sock->sk->sk_protocol);
1063     error = ccs_check_network_bind_acl(true, type,
1064     addr6->sin6_addr.s6_addr,
1065     port);
1066     break;
1067     case AF_INET:
1068     if (addr_len < sizeof(struct sockaddr_in))
1069     break;
1070     addr4 = (struct sockaddr_in *) addr;
1071     if (type != SOCK_RAW)
1072     port = addr4->sin_port;
1073     else
1074     port = htons(sock->sk->sk_protocol);
1075     error = ccs_check_network_bind_acl(false, type,
1076     (u8 *) &addr4->sin_addr,
1077     port);
1078     break;
1079     }
1080     return error;
1081     }
1082    
1083     /*
1084     * Check permission for accepting a TCP socket.
1085     *
1086     * Currently, the LSM hook for this purpose is not provided.
1087     */
1088     int ccs_socket_accept_permission(struct socket *sock, struct sockaddr *addr)
1089     {
1090     int error = 0;
1091     int addr_len;
1092     /* Nothing to do if I am a kernel service. */
1093     if (segment_eq(get_fs(), KERNEL_DS))
1094     return 0;
1095     switch (sock->sk->sk_family) {
1096     case PF_INET:
1097     case PF_INET6:
1098     break;
1099     default:
1100     return 0;
1101     }
1102     error = sock->ops->getname(sock, addr, &addr_len, 2);
1103     if (error)
1104     return error;
1105     switch (addr->sa_family) {
1106     struct sockaddr_in6 *addr6;
1107     struct sockaddr_in *addr4;
1108     case AF_INET6:
1109     addr6 = (struct sockaddr_in6 *) addr;
1110     error = ccs_check_network_accept_acl(true,
1111     addr6->sin6_addr.s6_addr,
1112     addr6->sin6_port);
1113     break;
1114     case AF_INET:
1115     addr4 = (struct sockaddr_in *) addr;
1116     error = ccs_check_network_accept_acl(false,
1117     (u8 *) &addr4->sin_addr,
1118     addr4->sin_port);
1119     break;
1120     }
1121     return error;
1122     }
1123    
1124     /* Check permission for sending a datagram via a UDP or RAW socket. */
1125     int ccs_socket_sendmsg_permission(struct socket *sock, struct sockaddr *addr,
1126     int addr_len)
1127     {
1128     int error = 0;
1129     const int type = sock->type;
1130     /* Nothing to do if I am a kernel service. */
1131     if (segment_eq(get_fs(), KERNEL_DS))
1132     return 0;
1133     if (!addr || (type != SOCK_DGRAM && type != SOCK_RAW))
1134     return 0;
1135     switch (addr->sa_family) {
1136     struct sockaddr_in6 *addr6;
1137     struct sockaddr_in *addr4;
1138     u16 port;
1139     case AF_INET6:
1140     if (addr_len < SIN6_LEN_RFC2133)
1141     break;
1142     addr6 = (struct sockaddr_in6 *) addr;
1143     if (type == SOCK_DGRAM)
1144     port = addr6->sin6_port;
1145     else
1146     port = htons(sock->sk->sk_protocol);
1147     error = ccs_check_network_sendmsg_acl(true, type,
1148     addr6->sin6_addr.s6_addr,
1149     port);
1150     break;
1151     case AF_INET:
1152     if (addr_len < sizeof(struct sockaddr_in))
1153     break;
1154     addr4 = (struct sockaddr_in *) addr;
1155     if (type == SOCK_DGRAM)
1156     port = addr4->sin_port;
1157     else
1158     port = htons(sock->sk->sk_protocol);
1159     error = ccs_check_network_sendmsg_acl(false, type,
1160     (u8 *) &addr4->sin_addr,
1161     port);
1162     break;
1163     }
1164     return error;
1165     }
1166    
1167     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
1168     #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5
1169    
1170     static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
1171     {
1172     return skb->nh.iph;
1173     }
1174    
1175     static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
1176     {
1177     return skb->h.uh;
1178     }
1179    
1180     static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
1181     {
1182     return skb->nh.ipv6h;
1183     }
1184    
1185     #endif
1186     #endif
1187    
1188 kumaneko 2459 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
1189     static void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
1190     unsigned int flags)
1191     {
1192     /* Clear queue. */
1193     if (flags & MSG_PEEK) {
1194     int clear = 0;
1195     spin_lock_irq(&sk->sk_receive_queue.lock);
1196     if (skb == skb_peek(&sk->sk_receive_queue)) {
1197     __skb_unlink(skb, &sk->sk_receive_queue);
1198     clear = 1;
1199     }
1200     spin_unlock_irq(&sk->sk_receive_queue.lock);
1201     if (clear)
1202     kfree_skb(skb);
1203     }
1204 kumaneko 2570 skb_free_datagram(sk, skb);
1205 kumaneko 2459 }
1206     #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
1207     static void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
1208     unsigned int flags)
1209     {
1210     /* Clear queue. */
1211     if (flags & MSG_PEEK) {
1212     int clear = 0;
1213     spin_lock_bh(&sk->sk_receive_queue.lock);
1214     if (skb == skb_peek(&sk->sk_receive_queue)) {
1215     __skb_unlink(skb, &sk->sk_receive_queue);
1216     clear = 1;
1217     }
1218     spin_unlock_bh(&sk->sk_receive_queue.lock);
1219     if (clear)
1220     kfree_skb(skb);
1221     }
1222 kumaneko 2570 skb_free_datagram(sk, skb);
1223 kumaneko 2459 }
1224     #endif
1225    
1226 kumaneko 2037 /*
1227     * Check permission for receiving a datagram via a UDP or RAW socket.
1228     *
1229     * Currently, the LSM hook for this purpose is not provided.
1230     */
1231 kumaneko 2459 int ccs_socket_recvmsg_permission(struct sock *sk, struct sk_buff *skb,
1232     const unsigned int flags)
1233 kumaneko 2037 {
1234     int error = 0;
1235     const unsigned int type = sk->sk_type;
1236 kumaneko 2459 if (type != SOCK_DGRAM && type != SOCK_RAW)
1237 kumaneko 2037 return 0;
1238     /* Nothing to do if I am a kernel service. */
1239     if (segment_eq(get_fs(), KERNEL_DS))
1240     return 0;
1241    
1242     switch (sk->sk_family) {
1243     struct in6_addr sin6;
1244     struct in_addr sin4;
1245     u16 port;
1246     case PF_INET6:
1247     if (type == SOCK_DGRAM) { /* UDP IPv6 */
1248     if (skb->protocol == htons(ETH_P_IP)) {
1249     ipv6_addr_set(&sin6, 0, 0, htonl(0xffff),
1250     ip_hdr(skb)->saddr);
1251     } else {
1252     ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
1253     }
1254     port = udp_hdr(skb)->source;
1255     } else { /* RAW IPv6 */
1256     ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
1257     port = htons(sk->sk_protocol);
1258     }
1259     error = ccs_check_network_recvmsg_acl(true, type,
1260     (u8 *) &sin6, port);
1261     break;
1262     case PF_INET:
1263     if (type == SOCK_DGRAM) { /* UDP IPv4 */
1264     sin4.s_addr = ip_hdr(skb)->saddr;
1265     port = udp_hdr(skb)->source;
1266     } else { /* RAW IPv4 */
1267     sin4.s_addr = ip_hdr(skb)->saddr;
1268     port = htons(sk->sk_protocol);
1269     }
1270     error = ccs_check_network_recvmsg_acl(false, type,
1271     (u8 *) &sin4, port);
1272     break;
1273     }
1274     if (!error)
1275     return 0;
1276     /*
1277     * Remove from queue if MSG_PEEK is used so that
1278     * the head message from unwanted source in receive queue will not
1279     * prevent the caller from picking up next message from wanted source
1280     * when the caller is using MSG_PEEK flag for picking up.
1281     */
1282     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1283 kumaneko 2459 if (type == SOCK_DGRAM)
1284     lock_sock(sk);
1285 kumaneko 2037 #endif
1286 kumaneko 2459 skb_kill_datagram(sk, skb, flags);
1287     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1288     if (type == SOCK_DGRAM)
1289     release_sock(sk);
1290     #endif
1291 kumaneko 2037 /* Hope less harmful than -EPERM. */
1292 kumaneko 2519 return -ENOMEM;
1293 kumaneko 2037 }
1294 kumaneko 2459 EXPORT_SYMBOL(ccs_socket_recvmsg_permission);

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