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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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