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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 719 - (show annotations) (download) (as text)
Wed Nov 21 04:01:53 2007 UTC (16 years, 6 months ago) by kumaneko
Original Path: trunk/1.5.x/ccs-patch/fs/tomoyo_network.c
File MIME type: text/x-csrc
File size: 20705 byte(s)


1 /*
2 * fs/tomoyo_network.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2007 NTT DATA CORPORATION
7 *
8 * Version: 1.5.2-pre 2007/11/19
9 *
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 /***** TOMOYO Linux start. *****/
15
16 #include <linux/ccs_common.h>
17 #include <linux/tomoyo.h>
18 #include <linux/realpath.h>
19 #include <net/ip.h>
20
21 /************************* VARIABLES *************************/
22
23 extern struct mutex domain_acl_lock;
24
25 /************************* AUDIT FUNCTIONS *************************/
26
27 static int AuditNetworkLog(const bool is_ipv6, const char *operation, const u32 *address, const u16 port, const bool is_granted)
28 {
29 char *buf;
30 int len = 256;
31 if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
32 if ((buf = InitAuditLog(&len)) == NULL) return -ENOMEM;
33 snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_NETWORK "%s ", operation);
34 if (is_ipv6) {
35 print_ipv6(buf + strlen(buf), len - strlen(buf), (const struct in6_addr *) address);
36 } else {
37 u32 ip = *address;
38 snprintf(buf + strlen(buf), len - strlen(buf) - 1, "%u.%u.%u.%u", NIPQUAD(ip));
39 }
40 snprintf(buf + strlen(buf), len - strlen(buf) - 1, " %u\n", port);
41 return WriteAuditLog(buf, is_granted);
42 }
43
44 /************************* UTILITY FUNCTIONS *************************/
45
46 /* Keep the given IPv6 address on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned address. */
47 static const struct in6_addr *SaveIPv6Address(const struct in6_addr *addr)
48 {
49 static const int block_size = 16;
50 struct addr_list {
51 struct in6_addr addr[block_size];
52 struct addr_list *next;
53 u32 in_use_count;
54 };
55 static struct addr_list *list = NULL;
56 struct addr_list *ptr;
57 static DEFINE_MUTEX(lock);
58 int i = block_size;
59 if (!addr) return NULL;
60 mutex_lock(&lock);
61 for (ptr = list; ptr; ptr = ptr->next) {
62 for (i = 0; i < ptr->in_use_count; i++) {
63 if (memcmp(&ptr->addr[i], addr, sizeof(*addr)) == 0) goto ok;
64 }
65 if (i < block_size) break;
66 }
67 if (i == block_size && (ptr = alloc_element(sizeof(*ptr))) != NULL) {
68 struct addr_list *p = list;
69 if (p) {
70 while (p->next) p = p->next;
71 p->next = ptr;
72 } else {
73 list = ptr;
74 }
75 i = 0;
76 }
77 if (ptr) ptr->addr[ptr->in_use_count++] = *addr;
78 ok:
79 mutex_unlock(&lock);
80 return ptr ? &ptr->addr[i] : NULL;
81 }
82
83 /************************* ADDRESS GROUP HANDLER *************************/
84
85 static LIST_HEAD(address_group_list);
86
87 static int AddAddressGroupEntry(const char *group_name, const bool is_ipv6, const u16 *min_address, const u16 *max_address, const bool is_delete)
88 {
89 static DEFINE_MUTEX(lock);
90 struct address_group_entry *new_group, *group;
91 struct address_group_member *new_member, *member;
92 const struct path_info *saved_group_name;
93 const struct in6_addr *saved_min_address = NULL, *saved_max_address = NULL;
94 int error = -ENOMEM;
95 bool found = 0;
96 if (!IsCorrectPath(group_name, 0, 0, 0, __FUNCTION__) || !group_name[0]) return -EINVAL;
97 if ((saved_group_name = SaveName(group_name)) == NULL) return -ENOMEM;
98 if (is_ipv6) {
99 if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL
100 || (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address))) return -ENOMEM;
101 }
102 mutex_lock(&lock);
103 list_for_each_entry(group, &address_group_list, list) {
104 if (saved_group_name != group->group_name) continue;
105 list_for_each_entry(member, &group->address_group_member_list, list) {
106 if (member->is_ipv6 != is_ipv6) continue;
107 if (is_ipv6) {
108 if (member->min.ipv6 != saved_min_address || member->max.ipv6 != saved_max_address) continue;
109 } else {
110 if (member->min.ipv4 != * (u32 *) min_address || member->max.ipv4 != * (u32 *) max_address) continue;
111 }
112 member->is_deleted = is_delete;
113 error = 0;
114 goto out;
115 }
116 found = 1;
117 break;
118 }
119 if (is_delete) {
120 error = -ENOENT;
121 goto out;
122 }
123 if (!found) {
124 if ((new_group = alloc_element(sizeof(*new_group))) == NULL) goto out;
125 INIT_LIST_HEAD(&new_group->address_group_member_list);
126 new_group->group_name = saved_group_name;
127 list_add_tail_mb(&new_group->list, &address_group_list);
128 group = new_group;
129 }
130 if ((new_member = alloc_element(sizeof(*new_member))) == NULL) goto out;
131 new_member->is_ipv6 = is_ipv6;
132 if (is_ipv6) {
133 new_member->min.ipv6 = saved_min_address;
134 new_member->max.ipv6 = saved_max_address;
135 } else {
136 new_member->min.ipv4 = * (u32 *) min_address;
137 new_member->max.ipv4 = * (u32 *) max_address;
138 }
139 list_add_tail_mb(&new_member->list, &group->address_group_member_list);
140 error = 0;
141 out:
142 mutex_unlock(&lock);
143 return error;
144 }
145
146 int AddAddressGroupPolicy(char *data, const bool is_delete)
147 {
148 int count, is_ipv6;
149 u16 min_address[8], max_address[8];
150 char *cp = strchr(data, ' ');
151 if (!cp) return -EINVAL;
152 *cp++ = '\0';
153 if ((count = sscanf(cp, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
154 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
155 &min_address[4], &min_address[5], &min_address[6], &min_address[7],
156 &max_address[0], &max_address[1], &max_address[2], &max_address[3],
157 &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {
158 int i;
159 for (i = 0; i < 8; i++) {
160 min_address[i] = htons(min_address[i]);
161 max_address[i] = htons(max_address[i]);
162 }
163 if (count == 8) memmove(max_address, min_address, sizeof(min_address));
164 is_ipv6 = 1;
165 } else if ((count = sscanf(cp, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
166 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
167 &max_address[0], &max_address[1], &max_address[2], &max_address[3])) == 4 || count == 8) {
168 u32 ip = ((((u8) min_address[0]) << 24) + (((u8) min_address[1]) << 16) + (((u8) min_address[2]) << 8) + (u8) min_address[3]);
169 * (u32 *) min_address = ip;
170 if (count == 8) ip = ((((u8) max_address[0]) << 24) + (((u8) max_address[1]) << 16) + (((u8) max_address[2]) << 8) + (u8) max_address[3]);
171 * (u32 *) max_address = ip;
172 is_ipv6 = 0;
173 } else {
174 return -EINVAL;
175 }
176 return AddAddressGroupEntry(data, is_ipv6, min_address, max_address, is_delete);
177 }
178
179 static struct address_group_entry *FindOrAssignNewAddressGroup(const char *group_name)
180 {
181 int i;
182 struct address_group_entry *group;
183 for (i = 0; i <= 1; i++) {
184 list_for_each_entry(group, &address_group_list, list) {
185 if (strcmp(group_name, group->group_name->name) == 0) return group;
186 }
187 if (i == 0) {
188 const u16 dummy[2] = { 0, 0 };
189 AddAddressGroupEntry(group_name, 0, dummy, dummy, 0);
190 AddAddressGroupEntry(group_name, 0, dummy, dummy, 1);
191 }
192 }
193 return NULL;
194 }
195
196 static int AddressMatchesToGroup(const bool is_ipv6, const u32 *address, const struct address_group_entry *group)
197 {
198 struct address_group_member *member;
199 const u32 ip = ntohl(*address);
200 list_for_each_entry(member, &group->address_group_member_list, list) {
201 if (member->is_deleted) continue;
202 if (member->is_ipv6) {
203 if (is_ipv6 && memcmp(member->min.ipv6, address, 16) <= 0 && memcmp(address, member->max.ipv6, 16) <= 0) return 1;
204 } else {
205 if (!is_ipv6 && member->min.ipv4 <= ip && ip <= member->max.ipv4) return 1;
206 }
207 }
208 return 0;
209 }
210
211 int ReadAddressGroupPolicy(struct io_buffer *head)
212 {
213 struct list_head *gpos;
214 struct list_head *mpos;
215 list_for_each_cookie(gpos, head->read_var1, &address_group_list) {
216 struct address_group_entry *group;
217 group = list_entry(gpos, struct address_group_entry, list);
218 list_for_each_cookie(mpos, head->read_var2, &group->address_group_member_list) {
219 char buf[128];
220 struct address_group_member *member;
221 member = list_entry(mpos, struct address_group_member, list);
222 if (member->is_deleted) continue;
223 if (member->is_ipv6) {
224 const struct in6_addr *min_address = member->min.ipv6, *max_address = member->max.ipv6;
225 print_ipv6(buf, sizeof(buf), min_address);
226 if (min_address != max_address) {
227 char *cp = strchr(buf, '\0');
228 *cp++ = '-';
229 print_ipv6(cp, sizeof(buf) - strlen(buf), max_address);
230 }
231 } else {
232 const u32 min_address = member->min.ipv4, max_address = member->max.ipv4;
233 memset(buf, 0, sizeof(buf));
234 snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(min_address));
235 if (min_address != max_address) {
236 const int len = strlen(buf);
237 snprintf(buf + len, sizeof(buf) - 1 - len, "-%u.%u.%u.%u", HIPQUAD(max_address));
238 }
239 }
240 if (io_printf(head, KEYWORD_ADDRESS_GROUP "%s %s\n", group->group_name->name, buf)) return -ENOMEM;
241 }
242 }
243 return 0;
244 }
245
246 /************************* NETWORK NETWORK ACL HANDLER *************************/
247
248 #if !defined(NIP6)
249 #define NIP6(addr) \
250 ntohs((addr).s6_addr16[0]), \
251 ntohs((addr).s6_addr16[1]), \
252 ntohs((addr).s6_addr16[2]), \
253 ntohs((addr).s6_addr16[3]), \
254 ntohs((addr).s6_addr16[4]), \
255 ntohs((addr).s6_addr16[5]), \
256 ntohs((addr).s6_addr16[6]), \
257 ntohs((addr).s6_addr16[7])
258 #endif
259
260 char *print_ipv6(char *buffer, const int buffer_len, const struct in6_addr *ip)
261 {
262 memset(buffer, 0, buffer_len);
263 snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
264 return buffer;
265 }
266
267 const char *network2keyword(const unsigned int operation)
268 {
269 const char *keyword = "unknown";
270 switch (operation) {
271 case NETWORK_ACL_UDP_BIND:
272 keyword = "UDP bind";
273 break;
274 case NETWORK_ACL_UDP_CONNECT:
275 keyword = "UDP connect";
276 break;
277 case NETWORK_ACL_TCP_BIND:
278 keyword = "TCP bind";
279 break;
280 case NETWORK_ACL_TCP_LISTEN:
281 keyword = "TCP listen";
282 break;
283 case NETWORK_ACL_TCP_CONNECT:
284 keyword = "TCP connect";
285 break;
286 case NETWORK_ACL_TCP_ACCEPT:
287 keyword = "TCP accept";
288 break;
289 case NETWORK_ACL_RAW_BIND:
290 keyword = "RAW bind";
291 break;
292 case NETWORK_ACL_RAW_CONNECT:
293 keyword = "RAW connect";
294 break;
295 }
296 return keyword;
297 }
298
299 static int AddNetworkEntry(const u8 operation, const u8 record_type, const struct address_group_entry *group, const u32 *min_address, const u32 *max_address, const u16 min_port, const u16 max_port, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
300 {
301 struct acl_info *ptr;
302 struct ip_network_acl_record *acl;
303 int error = -ENOMEM;
304 const u32 min_ip = ntohl(*min_address), max_ip = ntohl(*max_address); /* using host byte order to allow u32 comparison than memcmp().*/
305 const struct in6_addr *saved_min_address = NULL, *saved_max_address = NULL;
306 if (!domain) return -EINVAL;
307 if (record_type == IP_RECORD_TYPE_IPv6) {
308 if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL
309 || (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address))) return -ENOMEM;
310 }
311 mutex_lock(&domain_acl_lock);
312 if (!is_delete) {
313 list_for_each_entry(ptr, &domain->acl_info_list, list) {
314 acl = container_of(ptr, struct ip_network_acl_record, head);
315 if (ptr->type == TYPE_IP_NETWORK_ACL && acl->operation_type == operation && acl->record_type == record_type && ptr->cond == condition && acl->min_port == min_port && max_port == acl->max_port) {
316 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
317 if (acl->u.group == group) {
318 ptr->is_deleted = 0;
319 /* Found. Nothing to do. */
320 error = 0;
321 goto out;
322 }
323 } else if (record_type == IP_RECORD_TYPE_IPv4) {
324 if (acl->u.ipv4.min == min_ip && max_ip == acl->u.ipv4.max) {
325 ptr->is_deleted = 0;
326 /* Found. Nothing to do. */
327 error = 0;
328 goto out;
329 }
330 } else if (record_type == IP_RECORD_TYPE_IPv6) {
331 if (acl->u.ipv6.min == saved_min_address && saved_max_address == acl->u.ipv6.max) {
332 ptr->is_deleted = 0;
333 /* Found. Nothing to do. */
334 error = 0;
335 goto out;
336 }
337 }
338 }
339 }
340 /* Not found. Append it to the tail. */
341 if ((acl = alloc_element(sizeof(*acl))) == NULL) goto out;
342 acl->head.type = TYPE_IP_NETWORK_ACL;
343 acl->operation_type = operation;
344 acl->record_type = record_type;
345 acl->head.cond = condition;
346 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
347 acl->u.group = group;
348 } else if (record_type == IP_RECORD_TYPE_IPv4) {
349 acl->u.ipv4.min = min_ip;
350 acl->u.ipv4.max = max_ip;
351 } else {
352 acl->u.ipv6.min = saved_min_address;
353 acl->u.ipv6.max = saved_max_address;
354 }
355 acl->min_port = min_port;
356 acl->max_port = max_port;
357 error = AddDomainACL(domain, &acl->head);
358 } else {
359 error = -ENOENT;
360 list_for_each_entry(ptr, &domain->acl_info_list, list) {
361 acl = container_of(ptr, struct ip_network_acl_record, head);
362 if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || acl->record_type != record_type || ptr->cond != condition || acl->min_port != min_port || acl->max_port != max_port) continue;
363 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
364 if (acl->u.group != group) continue;
365 } else if (record_type == IP_RECORD_TYPE_IPv4) {
366 if (acl->u.ipv4.min != min_ip || max_ip != acl->u.ipv4.max) continue;
367 } else if (record_type == IP_RECORD_TYPE_IPv6) {
368 if (acl->u.ipv6.min != saved_min_address || saved_max_address != acl->u.ipv6.max) continue;
369 }
370 error = DelDomainACL(ptr);
371 break;
372 }
373 }
374 out: ;
375 mutex_unlock(&domain_acl_lock);
376 return error;
377 }
378
379 static int CheckNetworkEntry(const bool is_ipv6, const int operation, const u32 *address, const u16 port)
380 {
381 struct domain_info * const domain = current->domain_info;
382 struct acl_info *ptr;
383 const char *keyword = network2keyword(operation);
384 const bool is_enforce = CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_NETWORK);
385 const u32 ip = ntohl(*address); /* using host byte order to allow u32 comparison than memcmp().*/
386 bool found = 0;
387 if (!CheckCCSFlags(CCS_TOMOYO_MAC_FOR_NETWORK)) return 0;
388 list_for_each_entry(ptr, &domain->acl_info_list, list) {
389 struct ip_network_acl_record *acl;
390 acl = container_of(ptr, struct ip_network_acl_record, head);
391 if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || port < acl->min_port || acl->max_port < port || CheckCondition(ptr->cond, NULL)) continue;
392 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
393 if (!AddressMatchesToGroup(is_ipv6, address, acl->u.group)) continue;
394 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
395 if (is_ipv6 || ip < acl->u.ipv4.min || acl->u.ipv4.max < ip) continue;
396 } else {
397 if (!is_ipv6 || memcmp(acl->u.ipv6.min, address, 16) > 0 || memcmp(address, acl->u.ipv6.max, 16) > 0) continue;
398 }
399 found = 1;
400 break;
401
402 }
403 AuditNetworkLog(is_ipv6, keyword, address, port, found);
404 if (found) return 0;
405 if (TomoyoVerboseMode()) {
406 if (is_ipv6) {
407 char buf[64];
408 print_ipv6(buf, sizeof(buf), (const struct in6_addr *) address);
409 printk("TOMOYO-%s: %s to %s %u denied for %s\n", GetMSG(is_enforce), keyword, buf, port, GetLastName(domain));
410 } else {
411 printk("TOMOYO-%s: %s to %u.%u.%u.%u %u denied for %s\n", GetMSG(is_enforce), keyword, HIPQUAD(ip), port, GetLastName(domain));
412 }
413 }
414 AuditNetworkLog(is_ipv6, keyword, address, port, 0);
415 if (is_enforce) {
416 if (is_ipv6) {
417 char buf[64];
418 print_ipv6(buf, sizeof(buf), (const struct in6_addr *) address);
419 return CheckSupervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s %s %u\n", domain->domainname->name, keyword, buf, port);
420 }
421 return CheckSupervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s %u.%u.%u.%u %u\n", domain->domainname->name, keyword, HIPQUAD(ip), port);
422 }
423 if (CheckCCSAccept(CCS_TOMOYO_MAC_FOR_NETWORK, domain)) AddNetworkEntry(operation, is_ipv6 ? IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4, NULL, address, address, port, port, domain, NULL, 0);
424 return 0;
425 }
426
427 int AddNetworkPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
428 {
429 u8 sock_type, operation, record_type;
430 u16 min_address[8], max_address[8];
431 struct address_group_entry *group = NULL;
432 u16 min_port, max_port;
433 int count;
434 char *cp1 = NULL, *cp2 = NULL;
435 if ((cp1 = strchr(data, ' ')) == NULL) goto out; cp1++;
436 if (strncmp(data, "TCP ", 4) == 0) sock_type = SOCK_STREAM;
437 else if (strncmp(data, "UDP ", 4) == 0) sock_type = SOCK_DGRAM;
438 else if (strncmp(data, "RAW ", 4) == 0) sock_type = SOCK_RAW;
439 else goto out;
440 if ((cp2 = strchr(cp1, ' ')) == NULL) goto out; cp2++;
441 if (strncmp(cp1, "bind ", 5) == 0) {
442 operation = (sock_type == SOCK_STREAM) ? NETWORK_ACL_TCP_BIND : (sock_type == SOCK_DGRAM) ? NETWORK_ACL_UDP_BIND : NETWORK_ACL_RAW_BIND;
443 } else if (strncmp(cp1, "connect ", 8) == 0) {
444 operation = (sock_type == SOCK_STREAM) ? NETWORK_ACL_TCP_CONNECT : (sock_type == SOCK_DGRAM) ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
445 } else if (sock_type == SOCK_STREAM && strncmp(cp1, "listen ", 7) == 0) {
446 operation = NETWORK_ACL_TCP_LISTEN;
447 } else if (sock_type == SOCK_STREAM && strncmp(cp1, "accept ", 7) == 0) {
448 operation = NETWORK_ACL_TCP_ACCEPT;
449 } else {
450 goto out;
451 }
452 if ((cp1 = strchr(cp2, ' ')) == NULL) goto out; *cp1++ = '\0';
453 if ((count = sscanf(cp2, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
454 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
455 &min_address[4], &min_address[5], &min_address[6], &min_address[7],
456 &max_address[0], &max_address[1], &max_address[2], &max_address[3],
457 &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {
458 int i;
459 for (i = 0; i < 8; i++) {
460 min_address[i] = htons(min_address[i]);
461 max_address[i] = htons(max_address[i]);
462 }
463 if (count == 8) memmove(max_address, min_address, sizeof(min_address));
464 record_type = IP_RECORD_TYPE_IPv6;
465 } else if ((count = sscanf(cp2, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
466 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
467 &max_address[0], &max_address[1], &max_address[2], &max_address[3])) == 4 || count == 8) {
468 u32 ip = htonl((((u8) min_address[0]) << 24) + (((u8) min_address[1]) << 16) + (((u8) min_address[2]) << 8) + (u8) min_address[3]);
469 * (u32 *) min_address = ip;
470 if (count == 8) ip = htonl((((u8) max_address[0]) << 24) + (((u8) max_address[1]) << 16) + (((u8) max_address[2]) << 8) + (u8) max_address[3]);
471 * (u32 *) max_address = ip;
472 record_type = IP_RECORD_TYPE_IPv4;
473 } else if (*cp2 == '@') {
474 if ((group = FindOrAssignNewAddressGroup(cp2 + 1)) == NULL) return -ENOMEM;
475 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
476 } else {
477 goto out;
478 }
479 if (strchr(cp1, ' ')) goto out;
480 if ((count = sscanf(cp1, "%hu-%hu", &min_port, &max_port)) == 1 || count == 2) {
481 if (count == 1) max_port = min_port;
482 return AddNetworkEntry(operation, record_type, group, (u32 *) min_address, (u32 *) max_address, min_port, max_port, domain, condition, is_delete);
483 }
484 out: ;
485 return -EINVAL;
486 }
487
488 int CheckNetworkListenACL(const _Bool is_ipv6, const u8 *address, const u16 port)
489 {
490 return CheckNetworkEntry(is_ipv6, NETWORK_ACL_TCP_LISTEN, (const u32 *) address, ntohs(port));
491 }
492 EXPORT_SYMBOL(CheckNetworkListenACL);
493
494 int CheckNetworkConnectACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
495 {
496 return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_CONNECT : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT), (const u32 *) address, ntohs(port));
497 }
498 EXPORT_SYMBOL(CheckNetworkConnectACL);
499
500 int CheckNetworkBindACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
501 {
502 return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_BIND : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_BIND : NETWORK_ACL_RAW_BIND), (const u32 *) address, ntohs(port));
503 }
504 EXPORT_SYMBOL(CheckNetworkBindACL);
505
506 int CheckNetworkAcceptACL(const _Bool is_ipv6, const u8 *address, const u16 port)
507 {
508 int retval;
509 current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
510 retval = CheckNetworkEntry(is_ipv6, NETWORK_ACL_TCP_ACCEPT, (const u32 *) address, ntohs(port));
511 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
512 return retval;
513 }
514 EXPORT_SYMBOL(CheckNetworkAcceptACL);
515
516 int CheckNetworkSendMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
517 {
518 return CheckNetworkEntry(is_ipv6, sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT, (const u32 *) address, ntohs(port));
519 }
520 EXPORT_SYMBOL(CheckNetworkSendMsgACL);
521
522 int CheckNetworkRecvMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
523 {
524 int retval;
525 current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
526 retval = CheckNetworkEntry(is_ipv6, sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT, (const u32 *) address, ntohs(port));
527 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
528 return retval;
529 }
530 EXPORT_SYMBOL(CheckNetworkRecvMsgACL);
531
532 /***** TOMOYO Linux end. *****/

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