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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2779 - (hide annotations) (download) (as text)
Sun Jul 19 07:00:09 2009 UTC (14 years, 10 months ago) by kumaneko
Original Path: branches/ccs-patch/fs/tomoyo_network.c
File MIME type: text/x-csrc
File size: 35944 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 2727 * Version: 1.7.0-pre 2009/07/03
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 kumaneko 1084 #include <linux/net.h>
16     #include <linux/inet.h>
17     #include <linux/in.h>
18     #include <linux/in6.h>
19 kumaneko 2037 #include <net/ip.h>
20     #include <net/ipv6.h>
21     #include <net/udp.h>
22 kumaneko 2763 #include <linux/ccs_common.h>
23     #include <linux/tomoyo.h>
24     #include <linux/tomoyo_socket.h>
25 kumaneko 111
26 kumaneko 2037 /* Index numbers for Network Controls. */
27     enum ccs_network_acl_index {
28     NETWORK_ACL_UDP_BIND,
29     NETWORK_ACL_UDP_CONNECT,
30     NETWORK_ACL_TCP_BIND,
31     NETWORK_ACL_TCP_LISTEN,
32     NETWORK_ACL_TCP_CONNECT,
33     NETWORK_ACL_TCP_ACCEPT,
34     NETWORK_ACL_RAW_BIND,
35     NETWORK_ACL_RAW_CONNECT
36     };
37    
38 kumaneko 1052 /**
39 kumaneko 2002 * ccs_audit_network_log - Audit network log.
40 kumaneko 1052 *
41 kumaneko 1657 * @r: Pointer to "struct ccs_request_info".
42 kumaneko 1052 * @operation: The name of operation.
43     * @address: An IPv4 or IPv6 address.
44     * @port: Port number.
45     * @is_granted: True if this is a granted log.
46     *
47     * Returns 0 on success, negative value otherwise.
48     */
49 kumaneko 2002 static int ccs_audit_network_log(struct ccs_request_info *r,
50     const char *operation, const char *address,
51     const u16 port, const bool is_granted)
52 kumaneko 111 {
53 kumaneko 1657 return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_NETWORK
54     "%s %s %u\n", operation, address, port);
55 kumaneko 111 }
56    
57 kumaneko 2540 /* The list for "struct ccs_address_group_entry". */
58     LIST_HEAD(ccs_address_group_list);
59    
60 kumaneko 1052 /**
61 kumaneko 2540 * ccs_get_address_group - Allocate memory for "struct ccs_address_group_entry".
62 kumaneko 1052 *
63 kumaneko 2540 * @group_name: The name of address group.
64 kumaneko 1052 *
65 kumaneko 2540 * Returns pointer to "struct ccs_address_group_entry" on success,
66     * NULL otherwise.
67 kumaneko 1052 */
68 kumaneko 2540 static struct ccs_address_group_entry *ccs_get_address_group(const char *
69     group_name)
70 kumaneko 719 {
71 kumaneko 2540 struct ccs_address_group_entry *entry = NULL;
72     struct ccs_address_group_entry *group;
73     const struct ccs_path_info *saved_group_name;
74     int error = -ENOMEM;
75 kumaneko 2577 if (!ccs_is_correct_path(group_name, 0, 0, 0) ||
76 kumaneko 2540 !group_name[0])
77 kumaneko 1052 return NULL;
78 kumaneko 2540 saved_group_name = ccs_get_name(group_name);
79     if (!saved_group_name)
80     return NULL;
81     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
82 kumaneko 2690 mutex_lock(&ccs_policy_lock);
83     list_for_each_entry_rcu(group, &ccs_address_group_list, list) {
84 kumaneko 2540 if (saved_group_name != group->group_name)
85     continue;
86     atomic_inc(&group->users);
87     error = 0;
88     break;
89 kumaneko 719 }
90 kumaneko 2718 if (error && ccs_memory_ok(entry, sizeof(*entry))) {
91 kumaneko 2540 INIT_LIST_HEAD(&entry->address_group_member_list);
92     entry->group_name = saved_group_name;
93     saved_group_name = NULL;
94     atomic_set(&entry->users, 1);
95 kumaneko 2690 list_add_tail_rcu(&entry->list, &ccs_address_group_list);
96 kumaneko 2540 group = entry;
97     entry = NULL;
98     error = 0;
99 kumaneko 719 }
100 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
101 kumaneko 2540 ccs_put_name(saved_group_name);
102     kfree(entry);
103     return !error ? group : NULL;
104 kumaneko 719 }
105    
106 kumaneko 1052 /**
107 kumaneko 2002 * ccs_update_address_group_entry - Update "struct ccs_address_group_entry" list.
108 kumaneko 1052 *
109 kumaneko 1064 * @group_name: The name of address group.
110     * @is_ipv6: True if @min_address and @max_address are IPv6 addresses.
111 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
112     * @max_address: End of IPv4 or IPv6 address range.
113     * @is_delete: True if it is a delete request.
114     *
115     * Returns 0 on success, negative value otherwise.
116     */
117 kumaneko 2002 static int ccs_update_address_group_entry(const char *group_name,
118     const bool is_ipv6,
119     const u16 *min_address,
120     const u16 *max_address,
121     const bool is_delete)
122 kumaneko 111 {
123 kumaneko 2002 struct ccs_address_group_entry *group;
124 kumaneko 2540 struct ccs_address_group_member *entry = NULL;
125 kumaneko 2002 struct ccs_address_group_member *member;
126 kumaneko 1052 const struct in6_addr *saved_min_address = NULL;
127     const struct in6_addr *saved_max_address = NULL;
128 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
129 kumaneko 2399 const u32 min_ipv4_address = ntohl(*(u32 *) min_address);
130     const u32 max_ipv4_address = ntohl(*(u32 *) max_address);
131 kumaneko 2540 group = ccs_get_address_group(group_name);
132     if (!group)
133 kumaneko 1052 return -ENOMEM;
134 kumaneko 2555 if (is_ipv6) {
135     saved_min_address
136     = ccs_get_ipv6_address((struct in6_addr *)
137     min_address);
138     saved_max_address
139     = ccs_get_ipv6_address((struct in6_addr *)
140     max_address);
141     if (!saved_min_address || !saved_max_address)
142     goto out;
143     }
144 kumaneko 2540 if (!is_delete)
145     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
146 kumaneko 2690 mutex_lock(&ccs_policy_lock);
147     list_for_each_entry_rcu(member, &group->address_group_member_list,
148     list) {
149 kumaneko 2540 if (member->is_ipv6 != is_ipv6)
150 kumaneko 1052 continue;
151 kumaneko 2540 if (is_ipv6) {
152     if (member->min.ipv6 != saved_min_address ||
153     member->max.ipv6 != saved_max_address)
154 kumaneko 1052 continue;
155 kumaneko 2540 } else {
156     if (member->min.ipv4 != min_ipv4_address ||
157     member->max.ipv4 != max_ipv4_address)
158     continue;
159 kumaneko 111 }
160 kumaneko 2540 member->is_deleted = is_delete;
161     error = 0;
162 kumaneko 111 break;
163     }
164 kumaneko 2718 if (!is_delete && error && ccs_memory_ok(entry, sizeof(*entry))) {
165 kumaneko 2540 entry->is_ipv6 = is_ipv6;
166     if (is_ipv6) {
167     entry->min.ipv6 = saved_min_address;
168     saved_min_address = NULL;
169     entry->max.ipv6 = saved_max_address;
170     saved_max_address = NULL;
171     } else {
172     entry->min.ipv4 = min_ipv4_address;
173     entry->max.ipv4 = max_ipv4_address;
174     }
175 kumaneko 2690 list_add_tail_rcu(&entry->list,
176     &group->address_group_member_list);
177 kumaneko 2540 entry = NULL;
178     error = 0;
179 kumaneko 111 }
180 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
181 kumaneko 111 out:
182 kumaneko 2540 ccs_put_ipv6_address(saved_min_address);
183     ccs_put_ipv6_address(saved_max_address);
184     ccs_put_address_group(group);
185 kumaneko 111 return error;
186     }
187    
188 kumaneko 1052 /**
189 kumaneko 2002 * ccs_parse_ip_address - Parse an IP address.
190 kumaneko 1657 *
191     * @address: String to parse.
192     * @min: Pointer to store min address.
193     * @max: Pointer to store max address.
194     *
195     * Returns 2 if @address is an IPv6, 1 if @address is an IPv4, 0 otherwise.
196     */
197 kumaneko 2002 static int ccs_parse_ip_address(char *address, u16 *min, u16 *max)
198 kumaneko 1657 {
199     int count = sscanf(address, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"
200     "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
201     &min[0], &min[1], &min[2], &min[3],
202     &min[4], &min[5], &min[6], &min[7],
203     &max[0], &max[1], &max[2], &max[3],
204     &max[4], &max[5], &max[6], &max[7]);
205     if (count == 8 || count == 16) {
206     u8 i;
207     if (count == 8)
208     memmove(max, min, sizeof(u16) * 8);
209     for (i = 0; i < 8; i++) {
210     min[i] = htons(min[i]);
211     max[i] = htons(max[i]);
212     }
213     return 2;
214     }
215     count = sscanf(address, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
216     &min[0], &min[1], &min[2], &min[3],
217     &max[0], &max[1], &max[2], &max[3]);
218     if (count == 4 || count == 8) {
219 kumaneko 1658 u32 ip = htonl((((u8) min[0]) << 24) + (((u8) min[1]) << 16)
220     + (((u8) min[2]) << 8) + (u8) min[3]);
221     memmove(min, &ip, sizeof(ip));
222     if (count == 8)
223     ip = htonl((((u8) max[0]) << 24) + (((u8) max[1]) << 16)
224     + (((u8) max[2]) << 8) + (u8) max[3]);
225     memmove(max, &ip, sizeof(ip));
226 kumaneko 1657 return 1;
227     }
228     return 0;
229     }
230    
231     /**
232 kumaneko 2002 * ccs_write_address_group_policy - Write "struct ccs_address_group_entry" list.
233 kumaneko 1052 *
234     * @data: String to parse.
235     * @is_delete: True if it is a delete request.
236     *
237     * Returns 0 on success, negative value otherwise.
238     */
239     int ccs_write_address_group_policy(char *data, const bool is_delete)
240 kumaneko 111 {
241 kumaneko 2779 char *w[2];
242 kumaneko 853 bool is_ipv6;
243 kumaneko 1064 u16 min_address[8];
244     u16 max_address[8];
245 kumaneko 2779 if (!ccs_tokenize(data, w, sizeof(w)) || !w[1][0])
246     return -EINVAL;
247     switch (ccs_parse_ip_address(w[1], min_address, max_address)) {
248 kumaneko 1657 case 2:
249 kumaneko 1016 is_ipv6 = true;
250 kumaneko 1657 break;
251     case 1:
252 kumaneko 1016 is_ipv6 = false;
253 kumaneko 1657 break;
254     default:
255     return -EINVAL;
256 kumaneko 111 }
257 kumaneko 2779 return ccs_update_address_group_entry(w[0], is_ipv6, min_address,
258 kumaneko 2002 max_address, is_delete);
259 kumaneko 111 }
260    
261 kumaneko 1052 /**
262 kumaneko 2039 * ccs_address_matches_group - Check whether the given address matches members of the given address group.
263 kumaneko 1052 *
264     * @is_ipv6: True if @address is an IPv6 address.
265     * @address: An IPv4 or IPv6 address.
266 kumaneko 2002 * @group: Pointer to "struct ccs_address_group_entry".
267 kumaneko 1052 *
268     * Returns true if @address matches addresses in @group group, false otherwise.
269 kumaneko 2540 *
270 kumaneko 2702 * Caller holds srcu_read_lock(&ccs_ss).
271 kumaneko 1052 */
272 kumaneko 2039 static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
273     const struct ccs_address_group_entry *
274     group)
275 kumaneko 111 {
276 kumaneko 2002 struct ccs_address_group_member *member;
277 kumaneko 111 const u32 ip = ntohl(*address);
278 kumaneko 2540 bool matched = false;
279 kumaneko 2690 list_for_each_entry_rcu(member, &group->address_group_member_list,
280     list) {
281 kumaneko 1052 if (member->is_deleted)
282     continue;
283 kumaneko 111 if (member->is_ipv6) {
284 kumaneko 1052 if (is_ipv6 &&
285     memcmp(member->min.ipv6, address, 16) <= 0 &&
286 kumaneko 2540 memcmp(address, member->max.ipv6, 16) <= 0) {
287     matched = true;
288     break;
289     }
290 kumaneko 111 } else {
291 kumaneko 1052 if (!is_ipv6 &&
292 kumaneko 2540 member->min.ipv4 <= ip && ip <= member->max.ipv4) {
293     matched = true;
294     break;
295     }
296 kumaneko 111 }
297     }
298 kumaneko 2540 return matched;
299 kumaneko 111 }
300    
301 kumaneko 1052 /**
302 kumaneko 2002 * ccs_read_address_group_policy - Read "struct ccs_address_group_entry" list.
303 kumaneko 1052 *
304     * @head: Pointer to "struct ccs_io_buffer".
305     *
306     * Returns true on success, false otherwise.
307 kumaneko 2690 *
308     * Caller holds srcu_read_lock(&ccs_ss).
309 kumaneko 1052 */
310     bool ccs_read_address_group_policy(struct ccs_io_buffer *head)
311 kumaneko 111 {
312 kumaneko 2540 struct list_head *gpos;
313     struct list_head *mpos;
314     bool done = true;
315 kumaneko 2690 list_for_each_cookie(gpos, head->read_var1, &ccs_address_group_list) {
316 kumaneko 2002 struct ccs_address_group_entry *group;
317 kumaneko 2540 group = list_entry(gpos, struct ccs_address_group_entry, list);
318 kumaneko 2690 list_for_each_cookie(mpos, head->read_var2,
319     &group->address_group_member_list) {
320 kumaneko 708 char buf[128];
321 kumaneko 2002 struct ccs_address_group_member *member;
322 kumaneko 2540 member = list_entry(mpos,
323 kumaneko 2002 struct ccs_address_group_member,
324 kumaneko 1052 list);
325     if (member->is_deleted)
326     continue;
327 kumaneko 1064 if (member->is_ipv6) {
328 kumaneko 1052 const struct in6_addr *min_address
329     = member->min.ipv6;
330     const struct in6_addr *max_address
331     = member->max.ipv6;
332     ccs_print_ipv6(buf, sizeof(buf), min_address);
333 kumaneko 719 if (min_address != max_address) {
334 kumaneko 1052 int len;
335 kumaneko 1795 char *cp = buf + strlen(buf);
336 kumaneko 708 *cp++ = '-';
337 kumaneko 1052 len = strlen(buf);
338     ccs_print_ipv6(cp, sizeof(buf) - len,
339     max_address);
340 kumaneko 111 }
341 kumaneko 708 } else {
342 kumaneko 1052 const u32 min_address = member->min.ipv4;
343     const u32 max_address = member->max.ipv4;
344 kumaneko 708 memset(buf, 0, sizeof(buf));
345 kumaneko 1052 snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u",
346     HIPQUAD(min_address));
347 kumaneko 708 if (min_address != max_address) {
348     const int len = strlen(buf);
349 kumaneko 1052 snprintf(buf + len,
350     sizeof(buf) - 1 - len,
351     "-%u.%u.%u.%u",
352     HIPQUAD(max_address));
353 kumaneko 708 }
354 kumaneko 111 }
355 kumaneko 2540 done = ccs_io_printf(head, KEYWORD_ADDRESS_GROUP
356     "%s %s\n", group->group_name->name,
357     buf);
358     if (!done)
359     break;
360 kumaneko 111 }
361 kumaneko 2540 if (!done)
362     break;
363 kumaneko 111 }
364 kumaneko 2540 return done;
365 kumaneko 111 }
366    
367 kumaneko 719 #if !defined(NIP6)
368 kumaneko 1052 #define NIP6(addr) \
369 kumaneko 1056 ntohs((addr).s6_addr16[0]), ntohs((addr).s6_addr16[1]), \
370     ntohs((addr).s6_addr16[2]), ntohs((addr).s6_addr16[3]), \
371     ntohs((addr).s6_addr16[4]), ntohs((addr).s6_addr16[5]), \
372     ntohs((addr).s6_addr16[6]), ntohs((addr).s6_addr16[7])
373 kumaneko 719 #endif
374    
375 kumaneko 1052 /**
376 kumaneko 1054 * ccs_print_ipv6 - Print an IPv6 address.
377 kumaneko 1052 *
378     * @buffer: Buffer to write to.
379 kumaneko 1064 * @buffer_len: Size of @buffer.
380 kumaneko 1052 * @ip: Pointer to "struct in6_addr".
381     *
382 kumaneko 1064 * Returns nothing.
383 kumaneko 1052 */
384 kumaneko 1064 void ccs_print_ipv6(char *buffer, const int buffer_len,
385     const struct in6_addr *ip)
386 kumaneko 111 {
387     memset(buffer, 0, buffer_len);
388 kumaneko 719 snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
389 kumaneko 111 }
390    
391 kumaneko 1052 /**
392     * ccs_net2keyword - Convert network operation index to network operation name.
393     *
394     * @operation: Type of operation.
395     *
396     * Returns the name of operation.
397     */
398     const char *ccs_net2keyword(const u8 operation)
399 kumaneko 111 {
400     const char *keyword = "unknown";
401     switch (operation) {
402     case NETWORK_ACL_UDP_BIND:
403     keyword = "UDP bind";
404     break;
405     case NETWORK_ACL_UDP_CONNECT:
406     keyword = "UDP connect";
407     break;
408     case NETWORK_ACL_TCP_BIND:
409     keyword = "TCP bind";
410     break;
411     case NETWORK_ACL_TCP_LISTEN:
412     keyword = "TCP listen";
413     break;
414     case NETWORK_ACL_TCP_CONNECT:
415     keyword = "TCP connect";
416     break;
417     case NETWORK_ACL_TCP_ACCEPT:
418     keyword = "TCP accept";
419     break;
420     case NETWORK_ACL_RAW_BIND:
421     keyword = "RAW bind";
422     break;
423     case NETWORK_ACL_RAW_CONNECT:
424     keyword = "RAW connect";
425     break;
426     }
427     return keyword;
428     }
429    
430 kumaneko 1052 /**
431 kumaneko 2002 * ccs_update_network_entry - Update "struct ccs_ip_network_acl_record" list.
432 kumaneko 1052 *
433     * @operation: Type of operation.
434     * @record_type: Type of address.
435 kumaneko 2540 * @group: Name of group. May be NULL.
436 kumaneko 1052 * @min_address: Start of IPv4 or IPv6 address range.
437     * @max_address: End of IPv4 or IPv6 address range.
438     * @min_port: Start of port number range.
439     * @max_port: End of port number range.
440 kumaneko 2282 * @domain: Pointer to "struct ccs_domain_info".
441 kumaneko 2576 * @condition: Pointer to "struct ccs_condition". May be NULL.
442 kumaneko 1052 * @is_delete: True if it is a delete request.
443     *
444     * Returns 0 on success, negative value otherwise.
445     */
446 kumaneko 2002 static int ccs_update_network_entry(const u8 operation, const u8 record_type,
447 kumaneko 2540 const char *group_name,
448 kumaneko 2002 const u32 *min_address,
449     const u32 *max_address,
450     const u16 min_port, const u16 max_port,
451 kumaneko 2282 struct ccs_domain_info *domain,
452 kumaneko 2576 struct ccs_condition *condition,
453 kumaneko 2002 const bool is_delete)
454 kumaneko 111 {
455 kumaneko 2540 struct ccs_ip_network_acl_record *entry = NULL;
456 kumaneko 2002 struct ccs_acl_info *ptr;
457 kumaneko 2540 int error = is_delete ? -ENOENT : -ENOMEM;
458 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
459     const u32 min_ip = ntohl(*min_address);
460     const u32 max_ip = ntohl(*max_address);
461     const struct in6_addr *saved_min_address = NULL;
462     const struct in6_addr *saved_max_address = NULL;
463 kumaneko 2540 struct ccs_address_group_entry *group = NULL;
464 kumaneko 1052 if (!domain)
465     return -EINVAL;
466 kumaneko 2540 if (group_name) {
467     group = ccs_get_address_group(group_name);
468     if (!group)
469     return -ENOMEM;
470     } else if (record_type == IP_RECORD_TYPE_IPv6) {
471     saved_min_address = ccs_get_ipv6_address((struct in6_addr *)
472     min_address);
473     saved_max_address = ccs_get_ipv6_address((struct in6_addr *)
474     max_address);
475     if (!saved_min_address || !saved_max_address)
476     goto out;
477     }
478 kumaneko 1052 if (is_delete)
479     goto delete;
480 kumaneko 2540 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
481 kumaneko 2690 mutex_lock(&ccs_policy_lock);
482     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
483 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
484 kumaneko 1064 if (ccs_acl_type1(ptr) != TYPE_IP_NETWORK_ACL)
485 kumaneko 1052 continue;
486 kumaneko 2544 if (ptr->cond != condition)
487 kumaneko 1052 continue;
488 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
489 kumaneko 1052 if (acl->operation_type != operation ||
490     acl->record_type != record_type ||
491     acl->min_port != min_port || max_port != acl->max_port)
492     continue;
493 kumaneko 708 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
494 kumaneko 1052 if (acl->u.group != group)
495     continue;
496 kumaneko 708 } else if (record_type == IP_RECORD_TYPE_IPv4) {
497 kumaneko 1052 if (acl->u.ipv4.min != min_ip ||
498     max_ip != acl->u.ipv4.max)
499     continue;
500     } else if (record_type == IP_RECORD_TYPE_IPv6) {
501     if (acl->u.ipv6.min != saved_min_address ||
502     saved_max_address != acl->u.ipv6.max)
503     continue;
504 kumaneko 708 }
505 kumaneko 1052 error = ccs_add_domain_acl(NULL, ptr);
506 kumaneko 2540 break;
507 kumaneko 1052 }
508 kumaneko 2718 if (error && ccs_memory_ok(entry, sizeof(*entry))) {
509 kumaneko 2540 entry->head.type = TYPE_IP_NETWORK_ACL;
510     entry->head.cond = condition;
511     entry->operation_type = operation;
512     entry->record_type = record_type;
513     if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
514     entry->u.group = group;
515     group = NULL;
516     } else if (record_type == IP_RECORD_TYPE_IPv4) {
517     entry->u.ipv4.min = min_ip;
518     entry->u.ipv4.max = max_ip;
519     } else {
520     entry->u.ipv6.min = saved_min_address;
521     saved_min_address = NULL;
522     entry->u.ipv6.max = saved_max_address;
523     saved_max_address = NULL;
524     }
525     entry->min_port = min_port;
526     entry->max_port = max_port;
527     error = ccs_add_domain_acl(domain, &entry->head);
528     entry = NULL;
529 kumaneko 1052 }
530 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
531 kumaneko 1052 goto out;
532     delete:
533 kumaneko 2690 mutex_lock(&ccs_policy_lock);
534     list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
535 kumaneko 2540 struct ccs_ip_network_acl_record *acl;
536 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
537 kumaneko 1052 continue;
538 kumaneko 2544 if (ptr->cond != condition)
539 kumaneko 1052 continue;
540 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
541 kumaneko 1052 if (acl->operation_type != operation ||
542     acl->record_type != record_type ||
543     acl->min_port != min_port || max_port != acl->max_port)
544     continue;
545     if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
546     if (acl->u.group != group)
547     continue;
548     } else if (record_type == IP_RECORD_TYPE_IPv4) {
549     if (acl->u.ipv4.min != min_ip ||
550     max_ip != acl->u.ipv4.max)
551     continue;
552     } else if (record_type == IP_RECORD_TYPE_IPv6) {
553     if (acl->u.ipv6.min != saved_min_address ||
554     saved_max_address != acl->u.ipv6.max)
555     continue;
556 kumaneko 111 }
557 kumaneko 1052 error = ccs_del_domain_acl(ptr);
558     break;
559 kumaneko 111 }
560 kumaneko 2690 mutex_unlock(&ccs_policy_lock);
561 kumaneko 1052 out:
562 kumaneko 2540 ccs_put_ipv6_address(saved_min_address);
563     ccs_put_ipv6_address(saved_max_address);
564     ccs_put_address_group(group);
565     kfree(entry);
566 kumaneko 111 return error;
567     }
568    
569 kumaneko 1052 /**
570 kumaneko 2702 * ccs_check_network_entry2 - Check permission for network operation.
571 kumaneko 1052 *
572     * @is_ipv6: True if @address is an IPv6 address.
573     * @operation: Type of operation.
574     * @address: An IPv4 or IPv6 address.
575     * @port: Port number.
576     *
577     * Returns 0 on success, negative value otherwise.
578 kumaneko 2690 *
579     * Caller holds srcu_read_lock(&ccs_ss).
580 kumaneko 1052 */
581 kumaneko 2702 static int ccs_check_network_entry2(const bool is_ipv6, const u8 operation,
582     const u32 *address, const u16 port)
583 kumaneko 111 {
584 kumaneko 1657 struct ccs_request_info r;
585 kumaneko 2002 struct ccs_acl_info *ptr;
586 kumaneko 1052 const char *keyword = ccs_net2keyword(operation);
587 kumaneko 1657 bool is_enforce;
588 kumaneko 1052 /* using host byte order to allow u32 comparison than memcmp().*/
589     const u32 ip = ntohl(*address);
590 kumaneko 1016 bool found = false;
591 kumaneko 1064 char buf[64];
592 kumaneko 1657 if (!ccs_can_sleep())
593 kumaneko 1052 return 0;
594 kumaneko 2282 ccs_init_request_info(&r, NULL, CCS_MAC_FOR_NETWORK);
595 kumaneko 1657 is_enforce = (r.mode == 3);
596 kumaneko 2692 if (!r.mode)
597     return 0;
598 kumaneko 2002 retry:
599 kumaneko 2690 list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {
600 kumaneko 2002 struct ccs_ip_network_acl_record *acl;
601 kumaneko 1064 if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
602 kumaneko 1052 continue;
603 kumaneko 2002 acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
604 kumaneko 1052 if (acl->operation_type != operation || port < acl->min_port ||
605 kumaneko 1657 acl->max_port < port || !ccs_check_condition(&r, ptr))
606 kumaneko 1052 continue;
607 kumaneko 708 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
608 kumaneko 2039 if (!ccs_address_matches_group(is_ipv6, address,
609     acl->u.group))
610 kumaneko 1052 continue;
611 kumaneko 708 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
612 kumaneko 1052 if (is_ipv6 ||
613     ip < acl->u.ipv4.min || acl->u.ipv4.max < ip)
614     continue;
615 kumaneko 111 } else {
616 kumaneko 1052 if (!is_ipv6 ||
617     memcmp(acl->u.ipv6.min, address, 16) > 0 ||
618     memcmp(address, acl->u.ipv6.max, 16) > 0)
619     continue;
620 kumaneko 111 }
621 kumaneko 2690 r.cond = ptr->cond;
622 kumaneko 1016 found = true;
623 kumaneko 708 break;
624 kumaneko 111 }
625 kumaneko 1064 memset(buf, 0, sizeof(buf));
626     if (is_ipv6)
627     ccs_print_ipv6(buf, sizeof(buf),
628     (const struct in6_addr *) address);
629     else
630     snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
631 kumaneko 2002 ccs_audit_network_log(&r, keyword, buf, port, found);
632 kumaneko 2692 if (found)
633     return 0;
634 kumaneko 2690 if (ccs_verbose_mode(r.domain))
635 kumaneko 1064 printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
636     ccs_get_msg(is_enforce), keyword, buf, port,
637 kumaneko 2690 ccs_get_last_name(r.domain));
638 kumaneko 1561 if (is_enforce) {
639 kumaneko 2544 int err = ccs_check_supervisor(&r, KEYWORD_ALLOW_NETWORK
640     "%s %s %u\n", keyword, buf,
641     port);
642     if (err == 1)
643 kumaneko 1561 goto retry;
644 kumaneko 2692 return err;
645 kumaneko 1561 }
646 kumaneko 2690 if (r.mode == 1 && ccs_domain_quota_ok(r.domain)) {
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     const int idx = srcu_read_lock(&ccs_ss);
672     const int error = ccs_check_network_entry2(is_ipv6, operation,
673     address, port);
674     srcu_read_unlock(&ccs_ss, idx);
675     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