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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2692 - (hide annotations) (download) (as text)
Wed Jun 24 06:48:30 2009 UTC (14 years, 11 months ago) by kumaneko
Original Path: branches/ccs-patch/fs/tomoyo_network.c
File MIME type: text/x-csrc
File size: 35522 byte(s)


1 kumaneko 111 /*
2     * fs/tomoyo_network.c
3     *
4     * Implementation of the Domain-Based Mandatory Access Control.
5     *
6 kumaneko 2030 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 kumaneko 111 *
8 kumaneko 2690 * Version: 1.6.8 2009/05/28
9 kumaneko 111 *
10     * This file is applicable to both 2.4.30 and 2.6.11 and later.
11     * See README.ccs for ChangeLog.
12     *
13     */
14    
15     #include <linux/ccs_common.h>
16     #include <linux/tomoyo.h>
17 kumaneko 2138 #include <linux/tomoyo_socket.h>
18 kumaneko 111 #include <linux/realpath.h>
19 kumaneko 1084 #include <linux/net.h>
20     #include <linux/inet.h>
21     #include <linux/in.h>
22     #include <linux/in6.h>
23 kumaneko 2037 #include <net/ip.h>
24     #include <net/ipv6.h>
25     #include <net/udp.h>
26 kumaneko 111
27 kumaneko 2037 /* Index numbers for Network Controls. */
28     enum ccs_network_acl_index {
29     NETWORK_ACL_UDP_BIND,
30     NETWORK_ACL_UDP_CONNECT,
31     NETWORK_ACL_TCP_BIND,
32     NETWORK_ACL_TCP_LISTEN,
33     NETWORK_ACL_TCP_CONNECT,
34     NETWORK_ACL_TCP_ACCEPT,
35     NETWORK_ACL_RAW_BIND,
36     NETWORK_ACL_RAW_CONNECT
37     };
38    
39 kumaneko 1052 /**
40 kumaneko 2002 * ccs_audit_network_log - Audit network log.
41 kumaneko 1052 *
42 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
43 kumaneko 1052 * @operation: The name of operation.
44     * @address: An IPv4 or IPv6 address.
45     * @port: Port number.
46     * @is_granted: True if this is a granted log.
47     *
48     * Returns 0 on success, negative value otherwise.
49     */
50 kumaneko 2002 static int ccs_audit_network_log(struct ccs_request_info *r,
51     const char *operation, const char *address,
52     const u16 port, const bool is_granted)
53 kumaneko 111 {
54 kumaneko 1657 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_NETWORK
55     "%s %s %u\n", operation, address, port);
56 kumaneko 111 }
57    
58 kumaneko 2540 /* The list for "struct ccs_address_group_entry". */
59     LIST_HEAD(ccs_address_group_list);
60    
61 kumaneko 1052 /**
62 kumaneko 2540 * ccs_get_address_group - Allocate memory for "struct ccs_address_group_entry".
63 kumaneko 1052 *
64 kumaneko 2540 * @group_name: The name of address group.
65 kumaneko 1052 *
66 kumaneko 2540 * Returns pointer to "struct ccs_address_group_entry" on success,
67     * NULL otherwise.
68 kumaneko 1052 */
69 kumaneko 2540 static struct ccs_address_group_entry *ccs_get_address_group(const char *
70     group_name)
71 kumaneko 719 {
72 kumaneko 2540 struct ccs_address_group_entry *entry = NULL;
73     struct ccs_address_group_entry *group;
74     const struct ccs_path_info *saved_group_name;
75     int error = -ENOMEM;
76 kumaneko 2577 if (!ccs_is_correct_path(group_name, 0, 0, 0) ||
77 kumaneko 2540 !group_name[0])
78 kumaneko 1052 return NULL;
79 kumaneko 2540 saved_group_name = ccs_get_name(group_name);
80     if (!saved_group_name)
81     return NULL;
82     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
83 kumaneko 2690 mutex_lock(&ccs_policy_lock);
84     list_for_each_entry_rcu(group, &ccs_address_group_list, list) {
85 kumaneko 2540 if (saved_group_name != group->group_name)
86     continue;
87     atomic_inc(&group->users);
88     error = 0;
89     break;
90 kumaneko 719 }
91 kumaneko 2540 if (error && ccs_memory_ok(entry)) {
92     INIT_LIST_HEAD(&entry->address_group_member_list);
93     entry->group_name = saved_group_name;
94     saved_group_name = NULL;
95     atomic_set(&entry->users, 1);
96 kumaneko 2690 list_add_tail_rcu(&entry->list, &ccs_address_group_list);
97 kumaneko 2540 group = entry;
98     entry = NULL;
99     error = 0;
100 kumaneko 719 }
101 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
102 kumaneko 2540 ccs_put_name(saved_group_name);
103     kfree(entry);
104     return !error ? group : NULL;
105 kumaneko 719 }
106    
107 kumaneko 1052 /**
108 kumaneko 2002 * ccs_update_address_group_entry - Update "struct ccs_address_group_entry" list.
109 kumaneko 1052 *
110 kumaneko 1064 * @group_name: The name of address group.
111     * @is_ipv6: True if @min_address and @max_address are IPv6 addresses.
112 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
113     * @max_address: End of IPv4 or IPv6 address range.
114     * @is_delete: True if it is a delete request.
115     *
116     * Returns 0 on success, negative value otherwise.
117     */
118 kumaneko 2002 static int ccs_update_address_group_entry(const char *group_name,
119     const bool is_ipv6,
120     const u16 *min_address,
121     const u16 *max_address,
122     const bool is_delete)
123 kumaneko 111 {
124 kumaneko 2002 struct ccs_address_group_entry *group;
125 kumaneko 2540 struct ccs_address_group_member *entry = NULL;
126 kumaneko 2002 struct ccs_address_group_member *member;
127 kumaneko 1052 const struct in6_addr *saved_min_address = NULL;
128     const struct in6_addr *saved_max_address = NULL;
129 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
130 kumaneko 2399 const u32 min_ipv4_address = ntohl(*(u32 *) min_address);
131     const u32 max_ipv4_address = ntohl(*(u32 *) max_address);
132 kumaneko 2540 group = ccs_get_address_group(group_name);
133     if (!group)
134 kumaneko 1052 return -ENOMEM;
135 kumaneko 2555 if (is_ipv6) {
136     saved_min_address
137     = ccs_get_ipv6_address((struct in6_addr *)
138     min_address);
139     saved_max_address
140     = ccs_get_ipv6_address((struct in6_addr *)
141     max_address);
142     if (!saved_min_address || !saved_max_address)
143     goto out;
144     }
145 kumaneko 2540 if (!is_delete)
146     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
147 kumaneko 2690 mutex_lock(&ccs_policy_lock);
148     list_for_each_entry_rcu(member, &group->address_group_member_list,
149     list) {
150 kumaneko 2540 if (member->is_ipv6 != is_ipv6)
151 kumaneko 1052 continue;
152 kumaneko 2540 if (is_ipv6) {
153     if (member->min.ipv6 != saved_min_address ||
154     member->max.ipv6 != saved_max_address)
155 kumaneko 1052 continue;
156 kumaneko 2540 } else {
157     if (member->min.ipv4 != min_ipv4_address ||
158     member->max.ipv4 != max_ipv4_address)
159     continue;
160 kumaneko 111 }
161 kumaneko 2540 member->is_deleted = is_delete;
162     error = 0;
163 kumaneko 111 break;
164     }
165 kumaneko 2540 if (!is_delete && error && ccs_memory_ok(entry)) {
166     entry->is_ipv6 = is_ipv6;
167     if (is_ipv6) {
168     entry->min.ipv6 = saved_min_address;
169     saved_min_address = NULL;
170     entry->max.ipv6 = saved_max_address;
171     saved_max_address = NULL;
172     } else {
173     entry->min.ipv4 = min_ipv4_address;
174     entry->max.ipv4 = max_ipv4_address;
175     }
176 kumaneko 2690 list_add_tail_rcu(&entry->list,
177     &group->address_group_member_list);
178 kumaneko 2540 entry = NULL;
179     error = 0;
180 kumaneko 111 }
181 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
182 kumaneko 111 out:
183 kumaneko 2540 ccs_put_ipv6_address(saved_min_address);
184     ccs_put_ipv6_address(saved_max_address);
185     ccs_put_address_group(group);
186 kumaneko 1064 ccs_update_counter(CCS_UPDATES_COUNTER_EXCEPTION_POLICY);
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 853 bool is_ipv6;
244 kumaneko 1064 u16 min_address[8];
245     u16 max_address[8];
246 kumaneko 111 char *cp = strchr(data, ' ');
247 kumaneko 1052 if (!cp)
248     return -EINVAL;
249 kumaneko 111 *cp++ = '\0';
250 kumaneko 2002 switch (ccs_parse_ip_address(cp, min_address, max_address)) {
251 kumaneko 1657 case 2:
252 kumaneko 1016 is_ipv6 = true;
253 kumaneko 1657 break;
254     case 1:
255 kumaneko 1016 is_ipv6 = false;
256 kumaneko 1657 break;
257     default:
258     return -EINVAL;
259 kumaneko 111 }
260 kumaneko 2002 return ccs_update_address_group_entry(data, is_ipv6, min_address,
261     max_address, is_delete);
262 kumaneko 111 }
263    
264 kumaneko 1052 /**
265 kumaneko 2039 * ccs_address_matches_group - Check whether the given address matches members of the given address group.
266 kumaneko 1052 *
267     * @is_ipv6: True if @address is an IPv6 address.
268     * @address: An IPv4 or IPv6 address.
269 kumaneko 2002 * @group: Pointer to "struct ccs_address_group_entry".
270 kumaneko 1052 *
271     * Returns true if @address matches addresses in @group group, false otherwise.
272 kumaneko 2540 *
273     * Caller holds ccs_policy_lockfor reading.
274 kumaneko 1052 */
275 kumaneko 2039 static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
276     const struct ccs_address_group_entry *
277     group)
278 kumaneko 111 {
279 kumaneko 2002 struct ccs_address_group_member *member;
280 kumaneko 111 const u32 ip = ntohl(*address);
281 kumaneko 2540 bool matched = false;
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     * Caller holds srcu_read_lock(&ccs_ss).
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 2690 list_for_each_cookie(gpos, head->read_var1, &ccs_address_group_list) {
319 kumaneko 2002 struct ccs_address_group_entry *group;
320 kumaneko 2540 group = list_entry(gpos, struct ccs_address_group_entry, list);
321 kumaneko 2690 list_for_each_cookie(mpos, head->read_var2,
322     &group->address_group_member_list) {
323 kumaneko 708 char buf[128];
324 kumaneko 2002 struct ccs_address_group_member *member;
325 kumaneko 2540 member = list_entry(mpos,
326 kumaneko 2002 struct ccs_address_group_member,
327 kumaneko 1052 list);
328     if (member->is_deleted)
329     continue;
330 kumaneko 1064 if (member->is_ipv6) {
331 kumaneko 1052 const struct in6_addr *min_address
332     = member->min.ipv6;
333     const struct in6_addr *max_address
334     = member->max.ipv6;
335     ccs_print_ipv6(buf, sizeof(buf), min_address);
336 kumaneko 719 if (min_address != max_address) {
337 kumaneko 1052 int len;
338 kumaneko 1795 char *cp = buf + strlen(buf);
339 kumaneko 708 *cp++ = '-';
340 kumaneko 1052 len = strlen(buf);
341     ccs_print_ipv6(cp, sizeof(buf) - len,
342     max_address);
343 kumaneko 111 }
344 kumaneko 708 } else {
345 kumaneko 1052 const u32 min_address = member->min.ipv4;
346     const u32 max_address = member->max.ipv4;
347 kumaneko 708 memset(buf, 0, sizeof(buf));
348 kumaneko 1052 snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u",
349     HIPQUAD(min_address));
350 kumaneko 708 if (min_address != max_address) {
351     const int len = strlen(buf);
352 kumaneko 1052 snprintf(buf + len,
353     sizeof(buf) - 1 - len,
354     "-%u.%u.%u.%u",
355     HIPQUAD(max_address));
356 kumaneko 708 }
357 kumaneko 111 }
358 kumaneko 2540 done = ccs_io_printf(head, KEYWORD_ADDRESS_GROUP
359     "%s %s\n", group->group_name->name,
360     buf);
361     if (!done)
362     break;
363 kumaneko 111 }
364 kumaneko 2540 if (!done)
365     break;
366 kumaneko 111 }
367 kumaneko 2540 return done;
368 kumaneko 111 }
369    
370 kumaneko 719 #if !defined(NIP6)
371 kumaneko 1052 #define NIP6(addr) \
372 kumaneko 1056 ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]), \
373     ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \
374     ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \
375     ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])
376 kumaneko 719 #endif
377    
378 kumaneko 1052 /**
379 kumaneko 1054 * ccs_print_ipv6 - Print an IPv6 address.
380 kumaneko 1052 *
381     * @buffer: Buffer to write to.
382 kumaneko 1064 * @buffer_len: Size of @buffer.
383 kumaneko 1052 * @ip: Pointer to "struct in6_addr".
384     *
385 kumaneko 1064 * Returns nothing.
386 kumaneko 1052 */
387 kumaneko 1064 void ccs_print_ipv6(char *buffer, const int buffer_len,
388     const struct in6_addr *ip)
389 kumaneko 111 {
390     memset(buffer, 0, buffer_len);
391 kumaneko 719 snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
392 kumaneko 111 }
393    
394 kumaneko 1052 /**
395     * ccs_net2keyword - Convert network operation index to network operation name.
396     *
397     * @operation: Type of operation.
398     *
399     * Returns the name of operation.
400     */
401     const char *ccs_net2keyword(const u8 operation)
402 kumaneko 111 {
403     const char *keyword = "unknown";
404     switch (operation) {
405     case NETWORK_ACL_UDP_BIND:
406     keyword = "UDP bind";
407     break;
408     case NETWORK_ACL_UDP_CONNECT:
409     keyword = "UDP connect";
410     break;
411     case NETWORK_ACL_TCP_BIND:
412     keyword = "TCP bind";
413     break;
414     case NETWORK_ACL_TCP_LISTEN:
415     keyword = "TCP listen";
416     break;
417     case NETWORK_ACL_TCP_CONNECT:
418     keyword = "TCP connect";
419     break;
420     case NETWORK_ACL_TCP_ACCEPT:
421     keyword = "TCP accept";
422     break;
423     case NETWORK_ACL_RAW_BIND:
424     keyword = "RAW bind";
425     break;
426     case NETWORK_ACL_RAW_CONNECT:
427     keyword = "RAW connect";
428     break;
429     }
430     return keyword;
431     }
432    
433 kumaneko 1052 /**
434 kumaneko 2002 * ccs_update_network_entry - Update "struct ccs_ip_network_acl_record" list.
435 kumaneko 1052 *
436     * @operation: Type of operation.
437     * @record_type: Type of address.
438 kumaneko 2540 * @group: Name of group. May be NULL.
439 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
440     * @max_address: End of IPv4 or IPv6 address range.
441     * @min_port: Start of port number range.
442     * @max_port: End of port number range.
443 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
444 kumaneko 2576 * @condition: Pointer to "struct ccs_condition". May be NULL.
445 kumaneko 1052 * @is_delete: True if it is a delete request.
446     *
447     * Returns 0 on success, negative value otherwise.
448     */
449 kumaneko 2002 static int ccs_update_network_entry(const u8 operation, const u8 record_type,
450 kumaneko 2540 const char *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 2540 struct ccs_ip_network_acl_record *entry = NULL;
459 kumaneko 2002 struct ccs_acl_info *ptr;
460 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
461 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
462     const u32 min_ip = ntohl(*min_address);
463     const u32 max_ip = ntohl(*max_address);
464     const struct in6_addr *saved_min_address = NULL;
465     const struct in6_addr *saved_max_address = NULL;
466 kumaneko 2540 struct ccs_address_group_entry *group = NULL;
467 kumaneko 1052 if (!domain)
468     return -EINVAL;
469 kumaneko 2540 if (group_name) {
470     group = ccs_get_address_group(group_name);
471     if (!group)
472     return -ENOMEM;
473     } else if (record_type == IP_RECORD_TYPE_IPv6) {
474     saved_min_address = ccs_get_ipv6_address((struct in6_addr *)
475     min_address);
476     saved_max_address = ccs_get_ipv6_address((struct in6_addr *)
477     max_address);
478     if (!saved_min_address || !saved_max_address)
479     goto out;
480     }
481 kumaneko 1052 if (is_delete)
482     goto delete;
483 kumaneko 2540 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
484 kumaneko 2690 mutex_lock(&ccs_policy_lock);
485     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
486 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
487 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_IP_NETWORK_ACL)
488 kumaneko 1052 continue;
489 kumaneko 2544 if (ptr->cond != condition)
490 kumaneko 1052 continue;
491 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
492 kumaneko 1052 if (acl->operation_type != operation ||
493     acl->record_type != record_type ||
494     acl->min_port != min_port || max_port != acl->max_port)
495     continue;
496 kumaneko 708 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
497 kumaneko 1052 if (acl->u.group != group)
498     continue;
499 kumaneko 708 } else if (record_type == IP_RECORD_TYPE_IPv4) {
500 kumaneko 1052 if (acl->u.ipv4.min != min_ip ||
501     max_ip != acl->u.ipv4.max)
502     continue;
503     } else if (record_type == IP_RECORD_TYPE_IPv6) {
504     if (acl->u.ipv6.min != saved_min_address ||
505     saved_max_address != acl->u.ipv6.max)
506     continue;
507 kumaneko 708 }
508 kumaneko 1052 error = ccs_add_domain_acl(NULL, ptr);
509 kumaneko 2540 break;
510 kumaneko 1052 }
511 kumaneko 2540 if (error && ccs_memory_ok(entry)) {
512     entry->head.type = TYPE_IP_NETWORK_ACL;
513     entry->head.cond = condition;
514     entry->operation_type = operation;
515     entry->record_type = record_type;
516     if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
517     entry->u.group = group;
518     group = NULL;
519     } else if (record_type == IP_RECORD_TYPE_IPv4) {
520     entry->u.ipv4.min = min_ip;
521     entry->u.ipv4.max = max_ip;
522     } else {
523     entry->u.ipv6.min = saved_min_address;
524     saved_min_address = NULL;
525     entry->u.ipv6.max = saved_max_address;
526     saved_max_address = NULL;
527     }
528     entry->min_port = min_port;
529     entry->max_port = max_port;
530     error = ccs_add_domain_acl(domain, &entry->head);
531     entry = NULL;
532 kumaneko 1052 }
533 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
534 kumaneko 1052 goto out;
535     delete:
536 kumaneko 2690 mutex_lock(&ccs_policy_lock);
537     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
538 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
539 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
540 kumaneko 1052 continue;
541 kumaneko 2544 if (ptr->cond != condition)
542 kumaneko 1052 continue;
543 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
544 kumaneko 1052 if (acl->operation_type != operation ||
545     acl->record_type != record_type ||
546     acl->min_port != min_port || max_port != acl->max_port)
547     continue;
548     if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
549     if (acl->u.group != group)
550     continue;
551     } else if (record_type == IP_RECORD_TYPE_IPv4) {
552     if (acl->u.ipv4.min != min_ip ||
553     max_ip != acl->u.ipv4.max)
554     continue;
555     } else if (record_type == IP_RECORD_TYPE_IPv6) {
556     if (acl->u.ipv6.min != saved_min_address ||
557     saved_max_address != acl->u.ipv6.max)
558     continue;
559 kumaneko 111 }
560 kumaneko 1052 error = ccs_del_domain_acl(ptr);
561     break;
562 kumaneko 111 }
563 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
564 kumaneko 1052 out:
565 kumaneko 2540 ccs_put_ipv6_address(saved_min_address);
566     ccs_put_ipv6_address(saved_max_address);
567     ccs_put_address_group(group);
568     kfree(entry);
569 kumaneko 111 return error;
570     }
571    
572 kumaneko 1052 /**
573 kumaneko 2002 * ccs_check_network_entry - Check permission for network operation.
574 kumaneko 1052 *
575     * @is_ipv6: True if @address is an IPv6 address.
576     * @operation: Type of operation.
577     * @address: An IPv4 or IPv6 address.
578     * @port: Port number.
579     *
580     * Returns 0 on success, negative value otherwise.
581 kumaneko 2690 *
582     * Caller holds srcu_read_lock(&ccs_ss).
583 kumaneko 1052 */
584 kumaneko 2002 static int ccs_check_network_entry(const bool is_ipv6, const u8 operation,
585     const u32 *address, const u16 port)
586 kumaneko 111 {
587 kumaneko 1657 struct ccs_request_info r;
588 kumaneko 2002 struct ccs_acl_info *ptr;
589 kumaneko 1052 const char *keyword = ccs_net2keyword(operation);
590 kumaneko 1657 bool is_enforce;
591 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
592     const u32 ip = ntohl(*address);
593 kumaneko 1016 bool found = false;
594 kumaneko 1064 char buf[64];
595 kumaneko 1657 if (!ccs_can_sleep())
596 kumaneko 1052 return 0;
597 kumaneko 2282 ccs_init_request_info(&r, NULL, CCS_MAC_FOR_NETWORK);
598 kumaneko 1657 is_enforce = (r.mode == 3);
599 kumaneko 2692 if (!r.mode)
600     return 0;
601 kumaneko 2002 retry:
602 kumaneko 2690 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
603 kumaneko 2002 struct ccs_ip_network_acl_record *acl;
604 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
605 kumaneko 1052 continue;
606 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
607 kumaneko 1052 if (acl->operation_type != operation || port < acl->min_port ||
608 kumaneko 1657 acl->max_port < port || !ccs_check_condition(&r, ptr))
609 kumaneko 1052 continue;
610 kumaneko 708 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
611 kumaneko 2039 if (!ccs_address_matches_group(is_ipv6, address,
612     acl->u.group))
613 kumaneko 1052 continue;
614 kumaneko 708 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
615 kumaneko 1052 if (is_ipv6 ||
616     ip < acl->u.ipv4.min || acl->u.ipv4.max < ip)
617     continue;
618 kumaneko 111 } else {
619 kumaneko 1052 if (!is_ipv6 ||
620     memcmp(acl->u.ipv6.min, address, 16) > 0 ||
621     memcmp(address, acl->u.ipv6.max, 16) > 0)
622     continue;
623 kumaneko 111 }
624 kumaneko 2690 r.cond = ptr->cond;
625 kumaneko 1016 found = true;
626 kumaneko 708 break;
627 kumaneko 111 }
628 kumaneko 1064 memset(buf, 0, sizeof(buf));
629     if (is_ipv6)
630     ccs_print_ipv6(buf, sizeof(buf),
631     (const struct in6_addr *) address);
632     else
633     snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
634 kumaneko 2002 ccs_audit_network_log(&r, keyword, buf, port, found);
635 kumaneko 2692 if (found)
636     return 0;
637 kumaneko 2690 if (ccs_verbose_mode(r.domain))
638 kumaneko 1064 printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
639     ccs_get_msg(is_enforce), keyword, buf, port,
640 kumaneko 2690 ccs_get_last_name(r.domain));
641 kumaneko 1561 if (is_enforce) {
642 kumaneko 2544 int err = ccs_check_supervisor(&r, KEYWORD_ALLOW_NETWORK
643     "%s %s %u\n", keyword, buf,
644     port);
645     if (err == 1)
646 kumaneko 1561 goto retry;
647 kumaneko 2692 return err;
648 kumaneko 1561 }
649 kumaneko 2690 if (r.mode == 1 && ccs_domain_quota_ok(r.domain)) {
650 kumaneko 2581 struct ccs_condition *cond = ccs_handler_cond();
651 kumaneko 2002 ccs_update_network_entry(operation, is_ipv6 ?
652     IP_RECORD_TYPE_IPv6 :
653     IP_RECORD_TYPE_IPv4,
654     NULL, address, address, port, port,
655 kumaneko 2690 r.domain, cond, false);
656 kumaneko 2581 ccs_put_condition(cond);
657     }
658 kumaneko 2692 return 0;
659 kumaneko 111 }
660    
661 kumaneko 1052 /**
662 kumaneko 2002 * ccs_write_network_policy - Write "struct ccs_ip_network_acl_record" list.
663 kumaneko 1052 *
664     * @data: String to parse.
665 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
666 kumaneko 2576 * @condition: Pointer to "struct ccs_condition". May be NULL.
667 kumaneko 1052 * @is_delete: True if it is a delete request.
668     *
669     * Returns 0 on success, negative value otherwise.
670     */
671 kumaneko 2282 int ccs_write_network_policy(char *data, struct ccs_domain_info *domain,
672 kumaneko 2576 struct ccs_condition *condition,
673 kumaneko 1052 const bool is_delete)
674 kumaneko 111 {
675 kumaneko 1064 u8 sock_type;
676     u8 operation;
677     u8 record_type;
678     u16 min_address[8];
679     u16 max_address[8];
680 kumaneko 2540 const char *group_name = NULL;
681 kumaneko 1064 u16 min_port;
682     u16 max_port;
683 kumaneko 853 u8 count;
684 kumaneko 1064 char *cp1 = strchr(data, ' ');
685     char *cp2;
686 kumaneko 1052 if (!cp1)
687     goto out;
688     cp1++;
689     if (!strncmp(data, "TCP ", 4))
690     sock_type = SOCK_STREAM;
691     else if (!strncmp(data, "UDP ", 4))
692     sock_type = SOCK_DGRAM;
693     else if (!strncmp(data, "RAW ", 4))
694     sock_type = SOCK_RAW;
695     else
696     goto out;
697     cp2 = strchr(cp1, ' ');
698     if (!cp2)
699     goto out;
700     cp2++;
701     if (!strncmp(cp1, "bind ", 5))
702     switch (sock_type) {
703     case SOCK_STREAM:
704     operation = NETWORK_ACL_TCP_BIND;
705     break;
706     case SOCK_DGRAM:
707     operation = NETWORK_ACL_UDP_BIND;
708     break;
709     default:
710     operation = NETWORK_ACL_RAW_BIND;
711     }
712     else if (!strncmp(cp1, "connect ", 8))
713     switch (sock_type) {
714     case SOCK_STREAM:
715     operation = NETWORK_ACL_TCP_CONNECT;
716     break;
717     case SOCK_DGRAM:
718     operation = NETWORK_ACL_UDP_CONNECT;
719     break;
720     default:
721     operation = NETWORK_ACL_RAW_CONNECT;
722     }
723     else if (sock_type == SOCK_STREAM && !strncmp(cp1, "listen ", 7))
724 kumaneko 111 operation = NETWORK_ACL_TCP_LISTEN;
725 kumaneko 1052 else if (sock_type == SOCK_STREAM && !strncmp(cp1, "accept ", 7))
726 kumaneko 111 operation = NETWORK_ACL_TCP_ACCEPT;
727 kumaneko 1052 else
728 kumaneko 111 goto out;
729 kumaneko 1052 cp1 = strchr(cp2, ' ');
730     if (!cp1)
731     goto out;
732     *cp1++ = '\0';
733 kumaneko 2002 switch (ccs_parse_ip_address(cp2, min_address, max_address)) {
734 kumaneko 1657 case 2:
735 kumaneko 111 record_type = IP_RECORD_TYPE_IPv6;
736 kumaneko 1657 break;
737     case 1:
738 kumaneko 111 record_type = IP_RECORD_TYPE_IPv4;
739 kumaneko 1657 break;
740     default:
741     if (*cp2 != '@')
742     goto out;
743 kumaneko 2540 group_name = cp2 + 1;
744 kumaneko 111 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
745 kumaneko 1657 break;
746 kumaneko 111 }
747 kumaneko 1052 if (strchr(cp1, ' '))
748     goto out;
749     count = sscanf(cp1, "%hu-%hu", &min_port, &max_port);
750     if (count != 1 && count != 2)
751     goto out;
752     if (count == 1)
753     max_port = min_port;
754 kumaneko 2540 return ccs_update_network_entry(operation, record_type, 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