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

Subversion リポジトリの参照

Annotation of /branches/ccs-patch/security/ccsecurity/network.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2870 - (hide annotations) (download) (as text)
Sat Aug 8 03:09:07 2009 UTC (14 years, 9 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 35368 byte(s)


1 kumaneko 111 /*
2 kumaneko 2864 * security/ccsecurity/network.c
3 kumaneko 111 *
4 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 kumaneko 111 *
6 kumaneko 2869 * Version: 1.7.0-pre 2009/08/08
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 kumaneko 2870 return -EINVAL;
247 kumaneko 2779 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 2865 static const u8 offset = offsetof(struct ccs_ip_network_acl_record,
459     head.cond);
460 kumaneko 2863 struct ccs_acl_info *ptr;
461     struct ccs_ip_network_acl_record e;
462 kumaneko 2540 struct ccs_ip_network_acl_record *entry = NULL;
463     int error = is_delete ? -ENOENT : -ENOMEM;
464 kumaneko 2863 memset(&e, 0, sizeof(e));
465     e.head.type = TYPE_IP_NETWORK_ACL;
466     e.head.cond = condition;
467 kumaneko 2865 e.operation_type = operation;
468     e.record_type = record_type;
469 kumaneko 1052 if (!domain)
470     return -EINVAL;
471 kumaneko 2863 if (address_group_name) {
472     e.address.group = ccs_get_address_group(address_group_name);
473     if (!e.address.group)
474 kumaneko 2540 return -ENOMEM;
475     } else if (record_type == IP_RECORD_TYPE_IPv6) {
476 kumaneko 2863 e.address.ipv6.min = ccs_get_ipv6_address((struct in6_addr *)
477     min_address);
478     e.address.ipv6.max = ccs_get_ipv6_address((struct in6_addr *)
479     max_address);
480     if (!e.address.ipv6.min || !e.address.ipv6.max)
481 kumaneko 2540 goto out;
482 kumaneko 2863 } else {
483     /* use host byte order to allow u32 comparison than memcmp().*/
484     e.address.ipv4.min = ntohl(*min_address);
485     e.address.ipv4.max = ntohl(*max_address);
486 kumaneko 2540 }
487 kumaneko 2863 if (port_group_name) {
488     if (!ccs_check_and_save_number(port_group_name,
489     &e.port_is_group, &e.port))
490     goto out;
491     } else {
492     e.port.value.min = min_port;
493     e.port.value.max = max_port;
494     }
495 kumaneko 1052 if (is_delete)
496     goto delete;
497 kumaneko 2540 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
498 kumaneko 2690 mutex_lock(&ccs_policy_lock);
499     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
500 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
501 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_IP_NETWORK_ACL)
502 kumaneko 1052 continue;
503 kumaneko 2865 //if (ptr->cond != condition)
504     //continue;
505 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
506 kumaneko 2865 if (memcmp(((char *) acl) + offset, ((char *) &e) + offset,
507     sizeof(e) - offset))
508 kumaneko 1052 continue;
509     error = ccs_add_domain_acl(NULL, ptr);
510 kumaneko 2540 break;
511 kumaneko 1052 }
512 kumaneko 2718 if (error && ccs_memory_ok(entry, sizeof(*entry))) {
513 kumaneko 2863 memmove(entry, &e, sizeof(e));
514     memset(&e, 0, sizeof(e));
515 kumaneko 2540 error = ccs_add_domain_acl(domain, &entry->head);
516     entry = NULL;
517 kumaneko 1052 }
518 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
519 kumaneko 1052 goto out;
520     delete:
521 kumaneko 2690 mutex_lock(&ccs_policy_lock);
522     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
523 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
524 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
525 kumaneko 1052 continue;
526 kumaneko 2865 //if (ptr->cond != condition)
527     //continue;
528 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
529 kumaneko 2865 if (memcmp(((char *) acl) + offset, ((char *) &e) + offset,
530     sizeof(e) - offset))
531 kumaneko 1052 continue;
532     error = ccs_del_domain_acl(ptr);
533     break;
534 kumaneko 111 }
535 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
536 kumaneko 1052 out:
537 kumaneko 2863 if (address_group_name)
538     ccs_put_address_group(e.address.group);
539     else if (record_type == IP_RECORD_TYPE_IPv6) {
540     ccs_put_ipv6_address(e.address.ipv6.min);
541     ccs_put_ipv6_address(e.address.ipv6.max);
542     }
543     if (port_group_name)
544     ccs_put_number_group(e.port.group);
545 kumaneko 2540 kfree(entry);
546 kumaneko 111 return error;
547     }
548    
549 kumaneko 1052 /**
550 kumaneko 2702 * ccs_check_network_entry2 - Check permission for network operation.
551 kumaneko 1052 *
552     * @is_ipv6: True if @address is an IPv6 address.
553     * @operation: Type of operation.
554     * @address: An IPv4 or IPv6 address.
555     * @port: Port number.
556     *
557     * Returns 0 on success, negative value otherwise.
558 kumaneko 2690 *
559 kumaneko 2828 * Caller holds ccs_read_lock().
560 kumaneko 1052 */
561 kumaneko 2702 static int ccs_check_network_entry2(const bool is_ipv6, const u8 operation,
562     const u32 *address, const u16 port)
563 kumaneko 111 {
564 kumaneko 1657 struct ccs_request_info r;
565 kumaneko 2002 struct ccs_acl_info *ptr;
566 kumaneko 1052 const char *keyword = ccs_net2keyword(operation);
567 kumaneko 1657 bool is_enforce;
568 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
569     const u32 ip = ntohl(*address);
570 kumaneko 1016 bool found = false;
571 kumaneko 1064 char buf[64];
572 kumaneko 2828 ccs_check_read_lock();
573 kumaneko 1657 if (!ccs_can_sleep())
574 kumaneko 1052 return 0;
575 kumaneko 2282 ccs_init_request_info(&r, NULL, CCS_MAC_FOR_NETWORK);
576 kumaneko 1657 is_enforce = (r.mode == 3);
577 kumaneko 2692 if (!r.mode)
578     return 0;
579 kumaneko 2002 retry:
580 kumaneko 2690 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
581 kumaneko 2002 struct ccs_ip_network_acl_record *acl;
582 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
583 kumaneko 1052 continue;
584 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
585 kumaneko 2863 if (acl->operation_type != operation)
586 kumaneko 1052 continue;
587 kumaneko 2863 if (acl->port_is_group) {
588     if (!ccs_number_matches_group(port, port,
589     acl->port.group))
590     continue;
591     } else {
592     if (port < acl->port.value.min ||
593     acl->port.value.max < port)
594     continue;
595     }
596     if (!ccs_check_condition(&r, ptr))
597     continue;
598 kumaneko 708 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
599 kumaneko 2039 if (!ccs_address_matches_group(is_ipv6, address,
600 kumaneko 2863 acl->address.group))
601 kumaneko 1052 continue;
602 kumaneko 708 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
603 kumaneko 1052 if (is_ipv6 ||
604 kumaneko 2863 ip < acl->address.ipv4.min ||
605     acl->address.ipv4.max < ip)
606 kumaneko 1052 continue;
607 kumaneko 111 } else {
608 kumaneko 1052 if (!is_ipv6 ||
609 kumaneko 2863 memcmp(acl->address.ipv6.min, address, 16) > 0 ||
610     memcmp(address, acl->address.ipv6.max, 16) > 0)
611 kumaneko 1052 continue;
612 kumaneko 111 }
613 kumaneko 2690 r.cond = ptr->cond;
614 kumaneko 1016 found = true;
615 kumaneko 708 break;
616 kumaneko 111 }
617 kumaneko 1064 memset(buf, 0, sizeof(buf));
618     if (is_ipv6)
619     ccs_print_ipv6(buf, sizeof(buf),
620     (const struct in6_addr *) address);
621     else
622     snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
623 kumaneko 2002 ccs_audit_network_log(&r, keyword, buf, port, found);
624 kumaneko 2692 if (found)
625     return 0;
626 kumaneko 1561 if (is_enforce) {
627 kumaneko 2544 int err = ccs_check_supervisor(&r, KEYWORD_ALLOW_NETWORK
628     "%s %s %u\n", keyword, buf,
629     port);
630     if (err == 1)
631 kumaneko 1561 goto retry;
632 kumaneko 2692 return err;
633 kumaneko 2780 } else if (ccs_domain_quota_ok(&r)) {
634 kumaneko 2581 struct ccs_condition *cond = ccs_handler_cond();
635 kumaneko 2002 ccs_update_network_entry(operation, is_ipv6 ?
636     IP_RECORD_TYPE_IPv6 :
637     IP_RECORD_TYPE_IPv4,
638 kumaneko 2863 NULL, NULL, address, address, port,
639     port, r.domain, cond, false);
640 kumaneko 2581 ccs_put_condition(cond);
641     }
642 kumaneko 2692 return 0;
643 kumaneko 111 }
644    
645 kumaneko 1052 /**
646 kumaneko 2702 * ccs_check_network_entry - Check permission for network operation.
647     *
648     * @is_ipv6: True if @address is an IPv6 address.
649     * @operation: Type of operation.
650     * @address: An IPv4 or IPv6 address.
651     * @port: Port number.
652     *
653     * Returns 0 on success, negative value otherwise.
654     */
655     static int ccs_check_network_entry(const bool is_ipv6, const u8 operation,
656     const u32 *address, const u16 port)
657     {
658 kumaneko 2828 const int idx = ccs_read_lock();
659 kumaneko 2702 const int error = ccs_check_network_entry2(is_ipv6, operation,
660     address, port);
661 kumaneko 2828 ccs_read_unlock(idx);
662 kumaneko 2702 return error;
663     }
664    
665     /**
666 kumaneko 2002 * ccs_write_network_policy - Write "struct ccs_ip_network_acl_record" list.
667 kumaneko 1052 *
668     * @data: String to parse.
669 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
670 kumaneko 2576 * @condition: Pointer to "struct ccs_condition". May be NULL.
671 kumaneko 1052 * @is_delete: True if it is a delete request.
672     *
673     * Returns 0 on success, negative value otherwise.
674     */
675 kumaneko 2282 int ccs_write_network_policy(char *data, struct ccs_domain_info *domain,
676 kumaneko 2576 struct ccs_condition *condition,
677 kumaneko 1052 const bool is_delete)
678 kumaneko 111 {
679 kumaneko 2779 char *w[4];
680 kumaneko 1064 u8 sock_type;
681     u8 operation;
682     u8 record_type;
683     u16 min_address[8];
684     u16 max_address[8];
685 kumaneko 2863 const char *address_group_name = NULL;
686     const char *port_group_name = NULL;
687 kumaneko 1064 u16 min_port;
688     u16 max_port;
689 kumaneko 2779 if (!ccs_tokenize(data, w, sizeof(w)) || !w[3][0])
690 kumaneko 2870 return -EINVAL;
691 kumaneko 2779 if (!strcmp(w[0], "TCP"))
692 kumaneko 1052 sock_type = SOCK_STREAM;
693 kumaneko 2779 else if (!strcmp(w[0], "UDP"))
694 kumaneko 1052 sock_type = SOCK_DGRAM;
695 kumaneko 2779 else if (!strcmp(w[0], "RAW"))
696 kumaneko 1052 sock_type = SOCK_RAW;
697     else
698     goto out;
699 kumaneko 2779 if (!strcmp(w[1], "bind"))
700 kumaneko 1052 switch (sock_type) {
701     case SOCK_STREAM:
702     operation = NETWORK_ACL_TCP_BIND;
703     break;
704     case SOCK_DGRAM:
705     operation = NETWORK_ACL_UDP_BIND;
706     break;
707     default:
708     operation = NETWORK_ACL_RAW_BIND;
709     }
710 kumaneko 2779 else if (!strcmp(w[1], "connect"))
711 kumaneko 1052 switch (sock_type) {
712     case SOCK_STREAM:
713     operation = NETWORK_ACL_TCP_CONNECT;
714     break;
715     case SOCK_DGRAM:
716     operation = NETWORK_ACL_UDP_CONNECT;
717     break;
718     default:
719     operation = NETWORK_ACL_RAW_CONNECT;
720     }
721 kumaneko 2779 else if (sock_type == SOCK_STREAM && !strcmp(w[1], "listen"))
722 kumaneko 111 operation = NETWORK_ACL_TCP_LISTEN;
723 kumaneko 2779 else if (sock_type == SOCK_STREAM && !strcmp(w[1], "accept"))
724 kumaneko 111 operation = NETWORK_ACL_TCP_ACCEPT;
725 kumaneko 1052 else
726 kumaneko 111 goto out;
727 kumaneko 2779 switch (ccs_parse_ip_address(w[2], min_address, max_address)) {
728 kumaneko 1657 case 2:
729 kumaneko 111 record_type = IP_RECORD_TYPE_IPv6;
730 kumaneko 1657 break;
731     case 1:
732 kumaneko 111 record_type = IP_RECORD_TYPE_IPv4;
733 kumaneko 1657 break;
734     default:
735 kumaneko 2779 if (w[2][0] != '@')
736 kumaneko 1657 goto out;
737 kumaneko 2863 address_group_name = w[2] + 1;
738 kumaneko 111 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
739 kumaneko 1657 break;
740 kumaneko 111 }
741 kumaneko 2863 switch (sscanf(w[3], "%hu-%hu", &min_port, &max_port)) {
742     case 2:
743     break;
744     case 1:
745 kumaneko 1052 max_port = min_port;
746 kumaneko 2863 break;
747     default:
748     if (w[3][0] != '@')
749     goto out;
750     port_group_name = w[3];
751     break;
752     }
753     return ccs_update_network_entry(operation, record_type,
754     address_group_name, port_group_name,
755 kumaneko 2002 (u32 *) min_address,
756     (u32 *) max_address,
757     min_port, max_port, domain, condition,
758     is_delete);
759 kumaneko 1657 out:
760     return -EINVAL;
761 kumaneko 111 }
762    
763 kumaneko 1052 /**
764     * ccs_check_network_listen_acl - Check permission for listen() operation.
765     *
766     * @is_ipv6: True if @address is an IPv6 address.
767     * @address: An IPv4 or IPv6 address.
768     * @port: Port number.
769     *
770     * Returns 0 on success, negative value otherwise.
771     */
772 kumaneko 2037 static inline int ccs_check_network_listen_acl(const bool is_ipv6,
773     const u8 *address,
774     const u16 port)
775 kumaneko 111 {
776 kumaneko 2002 return ccs_check_network_entry(is_ipv6, NETWORK_ACL_TCP_LISTEN,
777     (const u32 *) address, ntohs(port));
778 kumaneko 111 }
779    
780 kumaneko 1052 /**
781     * ccs_check_network_connect_acl - Check permission for connect() operation.
782     *
783     * @is_ipv6: True if @address is an IPv6 address.
784     * @sock_type: Type of socket. (TCP or UDP or RAW)
785     * @address: An IPv4 or IPv6 address.
786     * @port: Port number.
787     *
788     * Returns 0 on success, negative value otherwise.
789     */
790 kumaneko 2037 static inline int ccs_check_network_connect_acl(const bool is_ipv6,
791     const int sock_type,
792     const u8 *address,
793     const u16 port)
794 kumaneko 111 {
795 kumaneko 1052 u8 operation;
796     switch (sock_type) {
797     case SOCK_STREAM:
798     operation = NETWORK_ACL_TCP_CONNECT;
799     break;
800     case SOCK_DGRAM:
801     operation = NETWORK_ACL_UDP_CONNECT;
802     break;
803     default:
804     operation = NETWORK_ACL_RAW_CONNECT;
805     }
806 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
807     (const u32 *) address, ntohs(port));
808 kumaneko 111 }
809    
810 kumaneko 1052 /**
811     * ccs_check_network_bind_acl - Check permission for bind() operation.
812     *
813     * @is_ipv6: True if @address is an IPv6 address.
814     * @sock_type: Type of socket. (TCP or UDP or RAW)
815     * @address: An IPv4 or IPv6 address.
816     * @port: Port number.
817     *
818     * Returns 0 on success, negative value otherwise.
819     */
820 kumaneko 2037 static int ccs_check_network_bind_acl(const bool is_ipv6, const int sock_type,
821     const u8 *address, const u16 port)
822 kumaneko 111 {
823 kumaneko 1052 u8 operation;
824     switch (sock_type) {
825     case SOCK_STREAM:
826     operation = NETWORK_ACL_TCP_BIND;
827     break;
828     case SOCK_DGRAM:
829     operation = NETWORK_ACL_UDP_BIND;
830     break;
831     default:
832     operation = NETWORK_ACL_RAW_BIND;
833     }
834 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
835     (const u32 *) address, ntohs(port));
836 kumaneko 111 }
837    
838 kumaneko 1052 /**
839     * ccs_check_network_accept_acl - Check permission for accept() operation.
840     *
841     * @is_ipv6: True if @address is an IPv6 address.
842     * @address: An IPv4 or IPv6 address.
843     * @port: Port number.
844     *
845     * Returns 0 on success, negative value otherwise.
846     */
847 kumaneko 2037 static inline int ccs_check_network_accept_acl(const bool is_ipv6,
848     const u8 *address,
849     const u16 port)
850 kumaneko 111 {
851 kumaneko 708 int retval;
852 kumaneko 2282 current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
853 kumaneko 2002 retval = ccs_check_network_entry(is_ipv6, NETWORK_ACL_TCP_ACCEPT,
854     (const u32 *) address, ntohs(port));
855 kumaneko 2282 current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
856 kumaneko 708 return retval;
857 kumaneko 111 }
858    
859 kumaneko 1052 /**
860     * ccs_check_network_sendmsg_acl - Check permission for sendmsg() operation.
861     *
862     * @is_ipv6: True if @address is an IPv6 address.
863     * @sock_type: Type of socket. (UDP or RAW)
864     * @address: An IPv4 or IPv6 address.
865     * @port: Port number.
866     *
867     * Returns 0 on success, negative value otherwise.
868     */
869 kumaneko 2037 static inline int ccs_check_network_sendmsg_acl(const bool is_ipv6,
870     const int sock_type,
871     const u8 *address,
872     const u16 port)
873 kumaneko 111 {
874 kumaneko 1052 u8 operation;
875     if (sock_type == SOCK_DGRAM)
876     operation = NETWORK_ACL_UDP_CONNECT;
877     else
878     operation = NETWORK_ACL_RAW_CONNECT;
879 kumaneko 2002 return ccs_check_network_entry(is_ipv6, operation,
880     (const u32 *) address, ntohs(port));
881 kumaneko 111 }
882    
883 kumaneko 1052 /**
884     * ccs_check_network_recvmsg_acl - Check permission for recvmsg() operation.
885     *
886     * @is_ipv6: True if @address is an IPv6 address.
887     * @sock_type: Type of socket. (UDP or RAW)
888     * @address: An IPv4 or IPv6 address.
889     * @port: Port number.
890     *
891     * Returns 0 on success, negative value otherwise.
892     */
893 kumaneko 2037 static inline int ccs_check_network_recvmsg_acl(const bool is_ipv6,
894     const int sock_type,
895     const u8 *address,
896     const u16 port)
897 kumaneko 111 {
898 kumaneko 708 int retval;
899 kumaneko 1052 const u8 operation
900 kumaneko 1064 = (sock_type == SOCK_DGRAM) ?
901 kumaneko 1052 NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
902 kumaneko 2282 current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
903 kumaneko 2002 retval = ccs_check_network_entry(is_ipv6, operation,
904     (const u32 *) address, ntohs(port));
905 kumaneko 2282 current->ccs_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
906 kumaneko 708 return retval;
907 kumaneko 111 }
908 kumaneko 2037
909     #define MAX_SOCK_ADDR 128 /* net/socket.c */
910    
911     /* Check permission for creating a socket. */
912     int ccs_socket_create_permission(int family, int type, int protocol)
913     {
914     int error = 0;
915     /* Nothing to do if I am a kernel service. */
916     if (segment_eq(get_fs(), KERNEL_DS))
917     return 0;
918 kumaneko 2282 if (family == PF_PACKET && !ccs_capable(CCS_USE_PACKET_SOCKET))
919 kumaneko 2037 return -EPERM;
920 kumaneko 2282 if (family == PF_ROUTE && !ccs_capable(CCS_USE_ROUTE_SOCKET))
921 kumaneko 2037 return -EPERM;
922     if (family != PF_INET && family != PF_INET6)
923     return 0;
924     switch (type) {
925     case SOCK_STREAM:
926 kumaneko 2282 if (!ccs_capable(CCS_INET_STREAM_SOCKET_CREATE))
927 kumaneko 2037 error = -EPERM;
928     break;
929     case SOCK_DGRAM:
930 kumaneko 2282 if (!ccs_capable(CCS_USE_INET_DGRAM_SOCKET))
931 kumaneko 2037 error = -EPERM;
932     break;
933     case SOCK_RAW:
934 kumaneko 2282 if (!ccs_capable(CCS_USE_INET_RAW_SOCKET))
935 kumaneko 2037 error = -EPERM;
936     break;
937     }
938     return error;
939     }
940    
941     /* Check permission for listening a TCP socket. */
942     int ccs_socket_listen_permission(struct socket *sock)
943     {
944     int error = 0;
945     char addr[MAX_SOCK_ADDR];
946     int addr_len;
947     /* Nothing to do if I am a kernel service. */
948     if (segment_eq(get_fs(), KERNEL_DS))
949     return 0;
950     if (sock->type != SOCK_STREAM)
951     return 0;
952     switch (sock->sk->sk_family) {
953     case PF_INET:
954     case PF_INET6:
955     break;
956     default:
957     return 0;
958     }
959 kumaneko 2282 if (!ccs_capable(CCS_INET_STREAM_SOCKET_LISTEN))
960 kumaneko 2037 return -EPERM;
961     if (sock->ops->getname(sock, (struct sockaddr *) addr, &addr_len, 0))
962     return -EPERM;
963     switch (((struct sockaddr *) addr)->sa_family) {
964     struct sockaddr_in6 *addr6;
965     struct sockaddr_in *addr4;
966     case AF_INET6:
967     addr6 = (struct sockaddr_in6 *) addr;
968     error = ccs_check_network_listen_acl(true,
969     addr6->sin6_addr.s6_addr,
970     addr6->sin6_port);
971     break;
972     case AF_INET:
973     addr4 = (struct sockaddr_in *) addr;
974     error = ccs_check_network_listen_acl(false,
975     (u8 *) &addr4->sin_addr,
976     addr4->sin_port);
977     break;
978     }
979     return error;
980     }
981    
982     /* Check permission for setting the remote IP address/port pair of a socket. */
983     int ccs_socket_connect_permission(struct socket *sock, struct sockaddr *addr,
984     int addr_len)
985     {
986     int error = 0;
987     const unsigned int type = sock->type;
988     /* Nothing to do if I am a kernel service. */
989     if (segment_eq(get_fs(), KERNEL_DS))
990     return 0;
991     switch (type) {
992     case SOCK_STREAM:
993     case SOCK_DGRAM:
994     case SOCK_RAW:
995     break;
996     default:
997     return 0;
998     }
999     switch (addr->sa_family) {
1000     struct sockaddr_in6 *addr6;
1001     struct sockaddr_in *addr4;
1002     u16 port;
1003     case AF_INET6:
1004     if (addr_len < SIN6_LEN_RFC2133)
1005     break;
1006     addr6 = (struct sockaddr_in6 *) addr;
1007     if (type != SOCK_RAW)
1008     port = addr6->sin6_port;
1009     else
1010     port = htons(sock->sk->sk_protocol);
1011     error = ccs_check_network_connect_acl(true, type,
1012     addr6->sin6_addr.s6_addr,
1013     port);
1014     break;
1015     case AF_INET:
1016     if (addr_len < sizeof(struct sockaddr_in))
1017     break;
1018     addr4 = (struct sockaddr_in *) addr;
1019     if (type != SOCK_RAW)
1020     port = addr4->sin_port;
1021     else
1022     port = htons(sock->sk->sk_protocol);
1023     error = ccs_check_network_connect_acl(false, type,
1024     (u8 *) &addr4->sin_addr,
1025     port);
1026     break;
1027     }
1028     if (type != SOCK_STREAM)
1029     return error;
1030     switch (sock->sk->sk_family) {
1031     case PF_INET:
1032     case PF_INET6:
1033 kumaneko 2282 if (!ccs_capable(CCS_INET_STREAM_SOCKET_CONNECT))
1034 kumaneko 2037 error = -EPERM;
1035     break;
1036     }
1037     return error;
1038     }
1039    
1040     /* Check permission for setting the local IP address/port pair of a socket. */
1041     int ccs_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
1042     int addr_len)
1043     {
1044     int error = 0;
1045     const unsigned int type = sock->type;
1046     /* Nothing to do if I am a kernel service. */
1047     if (segment_eq(get_fs(), KERNEL_DS))
1048     return 0;
1049     switch (type) {
1050     case SOCK_STREAM:
1051     case SOCK_DGRAM:
1052     case SOCK_RAW:
1053     break;
1054     default:
1055     return 0;
1056     }
1057     switch (addr->sa_family) {
1058     struct sockaddr_in6 *addr6;
1059     struct sockaddr_in *addr4;
1060     u16 port;
1061     case AF_INET6:
1062     if (addr_len < SIN6_LEN_RFC2133)
1063     break;
1064     addr6 = (struct sockaddr_in6 *) addr;
1065     if (type != SOCK_RAW)
1066     port = addr6->sin6_port;
1067     else
1068     port = htons(sock->sk->sk_protocol);
1069     error = ccs_check_network_bind_acl(true, type,
1070     addr6->sin6_addr.s6_addr,
1071     port);
1072     break;
1073     case AF_INET:
1074     if (addr_len < sizeof(struct sockaddr_in))
1075     break;
1076     addr4 = (struct sockaddr_in *) addr;
1077     if (type != SOCK_RAW)
1078     port = addr4->sin_port;
1079     else
1080     port = htons(sock->sk->sk_protocol);
1081     error = ccs_check_network_bind_acl(false, type,
1082     (u8 *) &addr4->sin_addr,
1083     port);
1084     break;
1085     }
1086     return error;
1087     }
1088    
1089     /*
1090     * Check permission for accepting a TCP socket.
1091     *
1092     * Currently, the LSM hook for this purpose is not provided.
1093     */
1094     int ccs_socket_accept_permission(struct socket *sock, struct sockaddr *addr)
1095     {
1096     int error = 0;
1097     int addr_len;
1098     /* Nothing to do if I am a kernel service. */
1099     if (segment_eq(get_fs(), KERNEL_DS))
1100     return 0;
1101     switch (sock->sk->sk_family) {
1102     case PF_INET:
1103     case PF_INET6:
1104     break;
1105     default:
1106     return 0;
1107     }
1108     error = sock->ops->getname(sock, addr, &addr_len, 2);
1109     if (error)
1110     return error;
1111     switch (addr->sa_family) {
1112     struct sockaddr_in6 *addr6;
1113     struct sockaddr_in *addr4;
1114     case AF_INET6:
1115     addr6 = (struct sockaddr_in6 *) addr;
1116     error = ccs_check_network_accept_acl(true,
1117     addr6->sin6_addr.s6_addr,
1118     addr6->sin6_port);
1119     break;
1120     case AF_INET:
1121     addr4 = (struct sockaddr_in *) addr;
1122     error = ccs_check_network_accept_acl(false,
1123     (u8 *) &addr4->sin_addr,
1124     addr4->sin_port);
1125     break;
1126     }
1127     return error;
1128     }
1129    
1130     /* Check permission for sending a datagram via a UDP or RAW socket. */
1131     int ccs_socket_sendmsg_permission(struct socket *sock, struct sockaddr *addr,
1132     int addr_len)
1133     {
1134     int error = 0;
1135     const int type = sock->type;
1136     /* Nothing to do if I am a kernel service. */
1137     if (segment_eq(get_fs(), KERNEL_DS))
1138     return 0;
1139     if (!addr || (type != SOCK_DGRAM && type != SOCK_RAW))
1140     return 0;
1141     switch (addr->sa_family) {
1142     struct sockaddr_in6 *addr6;
1143     struct sockaddr_in *addr4;
1144     u16 port;
1145     case AF_INET6:
1146     if (addr_len < SIN6_LEN_RFC2133)
1147     break;
1148     addr6 = (struct sockaddr_in6 *) addr;
1149     if (type == SOCK_DGRAM)
1150     port = addr6->sin6_port;
1151     else
1152     port = htons(sock->sk->sk_protocol);
1153     error = ccs_check_network_sendmsg_acl(true, type,
1154     addr6->sin6_addr.s6_addr,
1155     port);
1156     break;
1157     case AF_INET:
1158     if (addr_len < sizeof(struct sockaddr_in))
1159     break;
1160     addr4 = (struct sockaddr_in *) addr;
1161     if (type == SOCK_DGRAM)
1162     port = addr4->sin_port;
1163     else
1164     port = htons(sock->sk->sk_protocol);
1165     error = ccs_check_network_sendmsg_acl(false, type,
1166     (u8 *) &addr4->sin_addr,
1167     port);
1168     break;
1169     }
1170     return error;
1171     }
1172    
1173     #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
1174     #if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5
1175    
1176     static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
1177     {
1178     return skb->nh.iph;
1179     }
1180    
1181     static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
1182     {
1183     return skb->h.uh;
1184     }
1185    
1186     static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
1187     {
1188     return skb->nh.ipv6h;
1189     }
1190    
1191     #endif
1192     #endif
1193    
1194 kumaneko 2459 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
1195     static void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
1196     unsigned int flags)
1197     {
1198     /* Clear queue. */
1199     if (flags & MSG_PEEK) {
1200     int clear = 0;
1201     spin_lock_irq(&sk->sk_receive_queue.lock);
1202     if (skb == skb_peek(&sk->sk_receive_queue)) {
1203     __skb_unlink(skb, &sk->sk_receive_queue);
1204     clear = 1;
1205     }
1206     spin_unlock_irq(&sk->sk_receive_queue.lock);
1207     if (clear)
1208     kfree_skb(skb);
1209     }
1210 kumaneko 2570 skb_free_datagram(sk, skb);
1211 kumaneko 2459 }
1212     #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
1213     static void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
1214     unsigned int flags)
1215     {
1216     /* Clear queue. */
1217     if (flags & MSG_PEEK) {
1218     int clear = 0;
1219     spin_lock_bh(&sk->sk_receive_queue.lock);
1220     if (skb == skb_peek(&sk->sk_receive_queue)) {
1221     __skb_unlink(skb, &sk->sk_receive_queue);
1222     clear = 1;
1223     }
1224     spin_unlock_bh(&sk->sk_receive_queue.lock);
1225     if (clear)
1226     kfree_skb(skb);
1227     }
1228 kumaneko 2570 skb_free_datagram(sk, skb);
1229 kumaneko 2459 }
1230     #endif
1231    
1232 kumaneko 2037 /*
1233     * Check permission for receiving a datagram via a UDP or RAW socket.
1234     *
1235     * Currently, the LSM hook for this purpose is not provided.
1236     */
1237 kumaneko 2459 int ccs_socket_recvmsg_permission(struct sock *sk, struct sk_buff *skb,
1238     const unsigned int flags)
1239 kumaneko 2037 {
1240     int error = 0;
1241     const unsigned int type = sk->sk_type;
1242 kumaneko 2459 if (type != SOCK_DGRAM && type != SOCK_RAW)
1243 kumaneko 2037 return 0;
1244     /* Nothing to do if I am a kernel service. */
1245     if (segment_eq(get_fs(), KERNEL_DS))
1246     return 0;
1247    
1248     switch (sk->sk_family) {
1249     struct in6_addr sin6;
1250     struct in_addr sin4;
1251     u16 port;
1252     case PF_INET6:
1253     if (type == SOCK_DGRAM) { /* UDP IPv6 */
1254     if (skb->protocol == htons(ETH_P_IP)) {
1255     ipv6_addr_set(&sin6, 0, 0, htonl(0xffff),
1256     ip_hdr(skb)->saddr);
1257     } else {
1258     ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
1259     }
1260     port = udp_hdr(skb)->source;
1261     } else { /* RAW IPv6 */
1262     ipv6_addr_copy(&sin6, &ipv6_hdr(skb)->saddr);
1263     port = htons(sk->sk_protocol);
1264     }
1265     error = ccs_check_network_recvmsg_acl(true, type,
1266     (u8 *) &sin6, port);
1267     break;
1268     case PF_INET:
1269     if (type == SOCK_DGRAM) { /* UDP IPv4 */
1270     sin4.s_addr = ip_hdr(skb)->saddr;
1271     port = udp_hdr(skb)->source;
1272     } else { /* RAW IPv4 */
1273     sin4.s_addr = ip_hdr(skb)->saddr;
1274     port = htons(sk->sk_protocol);
1275     }
1276     error = ccs_check_network_recvmsg_acl(false, type,
1277     (u8 *) &sin4, port);
1278     break;
1279     }
1280     if (!error)
1281     return 0;
1282     /*
1283     * Remove from queue if MSG_PEEK is used so that
1284     * the head message from unwanted source in receive queue will not
1285     * prevent the caller from picking up next message from wanted source
1286     * when the caller is using MSG_PEEK flag for picking up.
1287     */
1288     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1289 kumaneko 2459 if (type == SOCK_DGRAM)
1290     lock_sock(sk);
1291 kumaneko 2037 #endif
1292 kumaneko 2459 skb_kill_datagram(sk, skb, flags);
1293     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1294     if (type == SOCK_DGRAM)
1295     release_sock(sk);
1296     #endif
1297 kumaneko 2037 /* Hope less harmful than -EPERM. */
1298 kumaneko 2519 return -ENOMEM;
1299 kumaneko 2037 }
1300 kumaneko 2459 EXPORT_SYMBOL(ccs_socket_recvmsg_permission);

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