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

Subversion リポジトリの参照

Contents of /trunk/1.7.x/ccs-patch/security/ccsecurity/internal.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3069 - (show annotations) (download) (as text)
Mon Sep 28 02:07:38 2009 UTC (14 years, 8 months ago) by kumaneko
File MIME type: text/x-chdr
File size: 36916 byte(s)


1 /*
2 * security/ccsecurity/internal.h
3 *
4 * Copyright (C) 2005-2009 NTT DATA CORPORATION
5 *
6 * Version: 1.7.0 2009/09/11
7 *
8 * This file is applicable to both 2.4.30 and 2.6.11 and later.
9 * See README.ccs for ChangeLog.
10 *
11 */
12
13 #ifndef _SECURITY_CCSECURITY_INTERNAL_H
14 #define _SECURITY_CCSECURITY_INTERNAL_H
15
16 #include <linux/string.h>
17 #include <linux/mm.h>
18 #include <linux/utime.h>
19 #include <linux/file.h>
20 #include <linux/smp_lock.h>
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/slab.h>
24 #include <linux/poll.h>
25 #include <linux/binfmts.h>
26 #include <asm/uaccess.h>
27 #include <stdarg.h>
28 #include <linux/delay.h>
29 #include <linux/version.h>
30 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
31 #include <linux/kmod.h>
32 #endif
33 #include <linux/in6.h>
34 #include <linux/ccsecurity.h>
35 #include "compat.h"
36
37 /* Index numbers for Access Controls. */
38 enum ccs_acl_entry_type_index {
39 CCS_TYPE_PATH_ACL,
40 CCS_TYPE_PATH2_ACL,
41 CCS_TYPE_PATH_NUMBER_ACL,
42 CCS_TYPE_PATH_NUMBER3_ACL,
43 CCS_TYPE_ENV_ACL,
44 CCS_TYPE_CAPABILITY_ACL,
45 CCS_TYPE_IP_NETWORK_ACL,
46 CCS_TYPE_SIGNAL_ACL,
47 CCS_TYPE_MOUNT_ACL,
48 CCS_TYPE_UMOUNT_ACL,
49 CCS_TYPE_CHROOT_ACL,
50 CCS_TYPE_PIVOT_ROOT_ACL,
51 CCS_TYPE_EXECUTE_HANDLER,
52 CCS_TYPE_DENIED_EXECUTE_HANDLER
53 };
54
55 /*
56 * CCS_TYPE_READ_WRITE is special. CCS_TYPE_READ_WRITE is automatically set if
57 * both CCS_TYPE_READ and CCS_TYPE_WRITE are set. Both CCS_TYPE_READ and
58 * CCS_TYPE_WRITE are automatically set if CCS_TYPE_READ_WRITE is set.
59 * CCS_TYPE_READ_WRITE is automatically cleared if either CCS_TYPE_READ or
60 * CCS_TYPE_WRITE is cleared. Both CCS_TYPE_READ and CCS_TYPE_WRITE are
61 * automatically cleared if CCS_TYPE_READ_WRITE is cleared.
62 */
63
64 enum ccs_path_acl_index {
65 CCS_TYPE_READ_WRITE,
66 CCS_TYPE_EXECUTE,
67 CCS_TYPE_READ,
68 CCS_TYPE_WRITE,
69 CCS_TYPE_UNLINK,
70 CCS_TYPE_RMDIR,
71 CCS_TYPE_TRUNCATE,
72 CCS_TYPE_SYMLINK,
73 CCS_TYPE_REWRITE,
74 CCS_MAX_PATH_OPERATION
75 };
76
77 enum ccs_path_number3_acl_index {
78 CCS_TYPE_MKBLOCK,
79 CCS_TYPE_MKCHAR,
80 CCS_MAX_PATH_NUMBER3_OPERATION
81 };
82
83 enum ccs_path2_acl_index {
84 CCS_TYPE_LINK,
85 CCS_TYPE_RENAME,
86 CCS_MAX_PATH2_OPERATION
87 };
88
89 enum ccs_path_number_acl_index {
90 CCS_TYPE_CREATE,
91 CCS_TYPE_MKDIR,
92 CCS_TYPE_MKFIFO,
93 CCS_TYPE_MKSOCK,
94 CCS_TYPE_IOCTL,
95 CCS_TYPE_CHMOD,
96 CCS_TYPE_CHOWN,
97 CCS_TYPE_CHGRP,
98 CCS_MAX_PATH_NUMBER_OPERATION
99 };
100
101 enum ccs_network_acl_index {
102 CCS_NETWORK_UDP_BIND, /* UDP's bind() operation. */
103 CCS_NETWORK_UDP_CONNECT, /* UDP's connect()/send()/recv() operation. */
104 CCS_NETWORK_TCP_BIND, /* TCP's bind() operation. */
105 CCS_NETWORK_TCP_LISTEN, /* TCP's listen() operation. */
106 CCS_NETWORK_TCP_CONNECT, /* TCP's connect() operation. */
107 CCS_NETWORK_TCP_ACCEPT, /* TCP's accept() operation. */
108 CCS_NETWORK_RAW_BIND, /* IP's bind() operation. */
109 CCS_NETWORK_RAW_CONNECT, /* IP's connect()/send()/recv() operation. */
110 CCS_MAX_NETWORK_OPERATION
111 };
112
113 enum ccs_ip_address_type {
114 CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP,
115 CCS_IP_ADDRESS_TYPE_IPv4,
116 CCS_IP_ADDRESS_TYPE_IPv6
117 };
118
119 /* Indexes for /proc/ccs/ interfaces. */
120 enum ccs_proc_interface_index {
121 CCS_DOMAINPOLICY,
122 CCS_EXCEPTIONPOLICY,
123 CCS_DOMAIN_STATUS,
124 CCS_PROCESS_STATUS,
125 CCS_MEMINFO,
126 CCS_GRANTLOG,
127 CCS_REJECTLOG,
128 CCS_SELFDOMAIN,
129 CCS_VERSION,
130 CCS_PROFILE,
131 CCS_QUERY,
132 CCS_MANAGER,
133 CCS_EXECUTE_HANDLER
134 };
135
136 enum ccs_mac_index {
137 CCS_MAC_FILE_EXECUTE,
138 CCS_MAC_FILE_OPEN,
139 CCS_MAC_FILE_CREATE,
140 CCS_MAC_FILE_UNLINK,
141 CCS_MAC_FILE_MKDIR,
142 CCS_MAC_FILE_RMDIR,
143 CCS_MAC_FILE_MKFIFO,
144 CCS_MAC_FILE_MKSOCK,
145 CCS_MAC_FILE_TRUNCATE,
146 CCS_MAC_FILE_SYMLINK,
147 CCS_MAC_FILE_REWRITE,
148 CCS_MAC_FILE_MKBLOCK,
149 CCS_MAC_FILE_MKCHAR,
150 CCS_MAC_FILE_LINK,
151 CCS_MAC_FILE_RENAME,
152 CCS_MAC_FILE_CHMOD,
153 CCS_MAC_FILE_CHOWN,
154 CCS_MAC_FILE_CHGRP,
155 CCS_MAC_FILE_IOCTL,
156 CCS_MAC_FILE_CHROOT,
157 CCS_MAC_FILE_MOUNT,
158 CCS_MAC_FILE_UMOUNT,
159 CCS_MAC_FILE_PIVOT_ROOT,
160 CCS_MAC_NETWORK_UDP_BIND,
161 CCS_MAC_NETWORK_UDP_CONNECT,
162 CCS_MAC_NETWORK_TCP_BIND,
163 CCS_MAC_NETWORK_TCP_LISTEN,
164 CCS_MAC_NETWORK_TCP_CONNECT,
165 CCS_MAC_NETWORK_TCP_ACCEPT,
166 CCS_MAC_NETWORK_RAW_BIND,
167 CCS_MAC_NETWORK_RAW_CONNECT,
168 CCS_MAC_ENVIRON,
169 CCS_MAC_SIGNAL,
170 CCS_MAX_MAC_INDEX
171 };
172
173 enum ccs_mac_category_index {
174 CCS_MAC_CATEGORY_FILE,
175 CCS_MAC_CATEGORY_NETWORK,
176 CCS_MAC_CATEGORY_MISC,
177 CCS_MAC_CATEGORY_IPC,
178 CCS_MAC_CATEGORY_CAPABILITY,
179 CCS_MAX_MAC_CATEGORY_INDEX
180 };
181
182 enum ccs_conditions_index {
183 CCS_TASK_UID, /* current_uid() */
184 CCS_TASK_EUID, /* current_euid() */
185 CCS_TASK_SUID, /* current_suid() */
186 CCS_TASK_FSUID, /* current_fsuid() */
187 CCS_TASK_GID, /* current_gid() */
188 CCS_TASK_EGID, /* current_egid() */
189 CCS_TASK_SGID, /* current_sgid() */
190 CCS_TASK_FSGID, /* current_fsgid() */
191 CCS_TASK_PID, /* sys_getpid() */
192 CCS_TASK_PPID, /* sys_getppid() */
193 CCS_EXEC_ARGC, /* "struct linux_binprm *"->argc */
194 CCS_EXEC_ENVC, /* "struct linux_binprm *"->envc */
195 CCS_TASK_STATE_0, /* (u8) (current->ccs_flags >> 24) */
196 CCS_TASK_STATE_1, /* (u8) (current->ccs_flags >> 16) */
197 CCS_TASK_STATE_2, /* (u8) (task->ccs_flags >> 8) */
198 CCS_TYPE_IS_SOCKET, /* S_IFSOCK */
199 CCS_TYPE_IS_SYMLINK, /* S_IFLNK */
200 CCS_TYPE_IS_FILE, /* S_IFREG */
201 CCS_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
202 CCS_TYPE_IS_DIRECTORY, /* S_IFDIR */
203 CCS_TYPE_IS_CHAR_DEV, /* S_IFCHR */
204 CCS_TYPE_IS_FIFO, /* S_IFIFO */
205 CCS_MODE_SETUID, /* S_ISUID */
206 CCS_MODE_SETGID, /* S_ISGID */
207 CCS_MODE_STICKY, /* S_ISVTX */
208 CCS_MODE_OWNER_READ, /* S_IRUSR */
209 CCS_MODE_OWNER_WRITE, /* S_IWUSR */
210 CCS_MODE_OWNER_EXECUTE, /* S_IXUSR */
211 CCS_MODE_GROUP_READ, /* S_IRGRP */
212 CCS_MODE_GROUP_WRITE, /* S_IWGRP */
213 CCS_MODE_GROUP_EXECUTE, /* S_IXGRP */
214 CCS_MODE_OTHERS_READ, /* S_IROTH */
215 CCS_MODE_OTHERS_WRITE, /* S_IWOTH */
216 CCS_MODE_OTHERS_EXECUTE, /* S_IXOTH */
217 CCS_TASK_TYPE, /* ((u8) task->ccs_flags) &
218 CCS_TASK_IS_EXECUTE_HANDLER */
219 CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
220 CCS_EXEC_REALPATH,
221 CCS_SYMLINK_TARGET,
222 CCS_PATH1_UID,
223 CCS_PATH1_GID,
224 CCS_PATH1_INO,
225 CCS_PATH1_MAJOR,
226 CCS_PATH1_MINOR,
227 CCS_PATH1_PERM,
228 CCS_PATH1_TYPE,
229 CCS_PATH1_DEV_MAJOR,
230 CCS_PATH1_DEV_MINOR,
231 CCS_PATH2_UID,
232 CCS_PATH2_GID,
233 CCS_PATH2_INO,
234 CCS_PATH2_MAJOR,
235 CCS_PATH2_MINOR,
236 CCS_PATH2_PERM,
237 CCS_PATH2_TYPE,
238 CCS_PATH2_DEV_MAJOR,
239 CCS_PATH2_DEV_MINOR,
240 CCS_PATH1_PARENT_UID,
241 CCS_PATH1_PARENT_GID,
242 CCS_PATH1_PARENT_INO,
243 CCS_PATH1_PARENT_PERM,
244 CCS_PATH2_PARENT_UID,
245 CCS_PATH2_PARENT_GID,
246 CCS_PATH2_PARENT_INO,
247 CCS_PATH2_PARENT_PERM,
248 CCS_MAX_CONDITION_KEYWORD,
249 CCS_NUMBER_UNION,
250 CCS_NAME_UNION,
251 CCS_ARGV_ENTRY,
252 CCS_ENVP_ENTRY
253 };
254
255 /* Keywords for ACLs. */
256 #define CCS_KEYWORD_ADDRESS_GROUP "address_group "
257 #define CCS_KEYWORD_AGGREGATOR "aggregator "
258 #define CCS_KEYWORD_ALLOW_CAPABILITY "allow_capability "
259 #define CCS_KEYWORD_ALLOW_CHROOT "allow_chroot "
260 #define CCS_KEYWORD_ALLOW_ENV "allow_env "
261 #define CCS_KEYWORD_ALLOW_IOCTL "allow_ioctl "
262 #define CCS_KEYWORD_ALLOW_CHMOD "allow_chmod "
263 #define CCS_KEYWORD_ALLOW_CHOWN "allow_chown "
264 #define CCS_KEYWORD_ALLOW_CHGRP "allow_chgrp "
265 #define CCS_KEYWORD_ALLOW_MOUNT "allow_mount "
266 #define CCS_KEYWORD_ALLOW_NETWORK "allow_network "
267 #define CCS_KEYWORD_ALLOW_PIVOT_ROOT "allow_pivot_root "
268 #define CCS_KEYWORD_ALLOW_READ "allow_read "
269 #define CCS_KEYWORD_ALLOW_SIGNAL "allow_signal "
270 #define CCS_KEYWORD_DELETE "delete "
271 #define CCS_KEYWORD_DENY_AUTOBIND "deny_autobind "
272 #define CCS_KEYWORD_DENY_REWRITE "deny_rewrite "
273 #define CCS_KEYWORD_ALLOW_UNMOUNT "allow_unmount "
274 #define CCS_KEYWORD_FILE_PATTERN "file_pattern "
275 #define CCS_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
276 #define CCS_KEYWORD_KEEP_DOMAIN "keep_domain "
277 #define CCS_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
278 #define CCS_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
279 #define CCS_KEYWORD_PATH_GROUP "path_group "
280 #define CCS_KEYWORD_NUMBER_GROUP "number_group "
281 #define CCS_KEYWORD_SELECT "select "
282 #define CCS_KEYWORD_USE_PROFILE "use_profile "
283 #define CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
284 #define CCS_KEYWORD_IGNORE_GLOBAL_ALLOW_ENV "ignore_global_allow_env"
285 #define CCS_KEYWORD_EXECUTE_HANDLER "execute_handler"
286 #define CCS_KEYWORD_DENIED_EXECUTE_HANDLER "denied_execute_handler"
287
288 /* A domain definition starts with <kernel>. */
289 #define ROOT_NAME "<kernel>"
290 #define ROOT_NAME_LEN (sizeof(ROOT_NAME) - 1)
291
292 /* Value type definition. */
293 #define CCS_VALUE_TYPE_INVALID 0
294 #define CCS_VALUE_TYPE_DECIMAL 1
295 #define CCS_VALUE_TYPE_OCTAL 2
296 #define CCS_VALUE_TYPE_HEXADECIMAL 3
297
298 #define CCS_EXEC_TMPSIZE 4096
299
300 /* Profile number is an integer between 0 and 255. */
301 #define CCS_MAX_PROFILES 256
302
303 #define CCS_CONFIG_DISABLED 0
304 #define CCS_CONFIG_LEARNING 1
305 #define CCS_CONFIG_PERMISSIVE 2
306 #define CCS_CONFIG_ENFORCING 3
307 #define CCS_CONFIG_WANT_REJECT_LOG 64
308 #define CCS_CONFIG_WANT_GRANT_LOG 128
309 #define CCS_CONFIG_USE_DEFAULT 255
310
311 #define CCS_OPEN_FOR_IOCTL_ONLY 8
312 #define CCS_TASK_IS_IN_EXECVE 16
313 #define CCS_DONT_SLEEP_ON_ENFORCE_ERROR 32
314 #define CCS_TASK_IS_EXECUTE_HANDLER 64
315 #define CCS_TASK_IS_POLICY_MANAGER 128
316 /* Highest 24 bits are reserved for task.state[] conditions. */
317
318 struct dentry;
319 struct vfsmount;
320 struct in6_addr;
321 extern asmlinkage long sys_getpid(void);
322 extern asmlinkage long sys_getppid(void);
323
324 /**
325 * list_for_each_cookie - iterate over a list with cookie.
326 * @pos: the &struct list_head to use as a loop cursor.
327 * @cookie: the &struct list_head to use as a cookie.
328 * @head: the head for your list.
329 *
330 * Same with list_for_each_rcu() except that this primitive uses @cookie
331 * so that we can continue iteration.
332 * @cookie must be NULL when iteration starts, and @cookie will become
333 * NULL when iteration finishes.
334 */
335 #define list_for_each_cookie(pos, cookie, head) \
336 for (({ if (!cookie) \
337 cookie = head; }), \
338 pos = rcu_dereference((cookie)->next); \
339 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
340 (cookie) = pos, pos = rcu_dereference(pos->next))
341
342 struct ccs_name_union {
343 const struct ccs_path_info *filename;
344 struct ccs_path_group *group;
345 u8 is_group;
346 };
347
348 struct ccs_number_union {
349 unsigned long values[2];
350 struct ccs_number_group *group;
351 u8 min_type;
352 u8 max_type;
353 u8 is_group;
354 };
355
356 /* Structure for "path_group" directive. */
357 struct ccs_path_group {
358 struct list_head list;
359 const struct ccs_path_info *group_name;
360 struct list_head member_list;
361 atomic_t users;
362 };
363
364 /* Structure for "number_group" directive. */
365 struct ccs_number_group {
366 struct list_head list;
367 const struct ccs_path_info *group_name;
368 struct list_head member_list;
369 atomic_t users;
370 };
371
372 /* Structure for "address_group" directive. */
373 struct ccs_address_group {
374 struct list_head list;
375 const struct ccs_path_info *group_name;
376 struct list_head member_list;
377 atomic_t users;
378 };
379
380 /* Structure for "path_group" directive. */
381 struct ccs_path_group_member {
382 struct list_head list;
383 bool is_deleted;
384 const struct ccs_path_info *member_name;
385 };
386
387 /* Structure for "number_group" directive. */
388 struct ccs_number_group_member {
389 struct list_head list;
390 bool is_deleted;
391 struct ccs_number_union number;
392 };
393
394 /* Structure for "address_group" directive. */
395 struct ccs_address_group_member {
396 struct list_head list;
397 bool is_deleted;
398 bool is_ipv6;
399 union {
400 u32 ipv4; /* Host byte order */
401 const struct in6_addr *ipv6; /* Network byte order */
402 } min, max;
403 };
404
405
406 /* Subset of "struct stat". */
407 struct ccs_mini_stat {
408 uid_t uid;
409 gid_t gid;
410 ino_t ino;
411 mode_t mode;
412 dev_t dev;
413 dev_t rdev;
414 };
415
416 /* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
417 struct ccs_page_dump {
418 struct page *page; /* Previously dumped page. */
419 char *data; /* Contents of "page". Size is PAGE_SIZE. */
420 };
421
422 /* Structure for attribute checks in addition to pathname checks. */
423 struct ccs_obj_info {
424 bool validate_done;
425 bool path1_valid;
426 bool path1_parent_valid;
427 bool path2_valid;
428 bool path2_parent_valid;
429 struct path path1;
430 struct path path2;
431 struct ccs_mini_stat path1_stat;
432 /* I don't handle path2_stat for rename operation. */
433 struct ccs_mini_stat path2_stat;
434 struct ccs_mini_stat path1_parent_stat;
435 struct ccs_mini_stat path2_parent_stat;
436 struct ccs_path_info *symlink_target;
437 unsigned int dev;
438 };
439
440 struct ccs_condition_element {
441 /*
442 * Left hand operand. A "struct ccs_argv_entry" for CCS_ARGV_ENTRY, a
443 * "struct ccs_envp_entry" for CCS_ENVP_ENTRY is attached to the tail
444 * of the array of this struct.
445 */
446 u8 left;
447 /*
448 * Right hand operand. A "struct ccs_number_union" for
449 * CCS_NUMBER_UNION, a "struct ccs_name_union" for CCS_NAME_UNION is
450 * attached to the tail of the array of this struct.
451 */
452 u8 right;
453 /* Equation operator. true if equals or overlaps, false otherwise. */
454 bool equals;
455 };
456
457 /* Structure for " if " and "; set" part. */
458 struct ccs_condition {
459 struct list_head list;
460 atomic_t users;
461 u32 size;
462 u16 condc;
463 u16 numbers_count;
464 u16 names_count;
465 u16 argc;
466 u16 envc;
467 u8 post_state[4];
468 /*
469 * struct ccs_condition_element condition[condc];
470 * struct ccs_number_union values[numbers_count];
471 * struct ccs_name_union names[names_count];
472 * struct ccs_argv_entry argv[argc];
473 * struct ccs_envp_entry envp[envc];
474 */
475 };
476
477 struct ccs_execve_entry;
478
479 /* Structure for request info. */
480 struct ccs_request_info {
481 struct ccs_domain_info *domain;
482 struct ccs_obj_info *obj;
483 struct ccs_execve_entry *ee;
484 struct ccs_condition *cond;
485 u8 retry;
486 u8 profile;
487 u8 mode;
488 u8 type;
489 };
490
491 /* Structure for holding a token. */
492 struct ccs_path_info {
493 const char *name;
494 u32 hash; /* = full_name_hash(name, strlen(name)) */
495 u16 total_len; /* = strlen(name) */
496 u16 const_len; /* = ccs_const_part_length(name) */
497 bool is_dir; /* = ccs_strendswith(name, "/") */
498 bool is_patterned; /* = const_len < total_len */
499 };
500
501 /* Structure for execve() operation. */
502 struct ccs_execve_entry {
503 struct ccs_request_info r;
504 struct ccs_obj_info obj;
505 struct linux_binprm *bprm;
506 struct ccs_domain_info *previous_domain;
507 int reader_idx;
508 /* For execute_handler */
509 const struct ccs_path_info *handler;
510 char *handler_path; /* = kstrdup(handler->name, GFP_KERNEL) */
511 /* For dumping argv[] and envp[]. */
512 struct ccs_page_dump dump;
513 /* For temporary use. */
514 char *tmp; /* Size is CCS_EXEC_TMPSIZE bytes */
515 };
516
517 /* Common header for holding ACL entries. */
518 struct ccs_acl_info {
519 struct list_head list;
520 struct ccs_condition *cond;
521 bool is_deleted;
522 u8 type; /* = one of values in "enum ccs_acl_entry_type_index" */
523 } __attribute__((__packed__));
524
525 /* Structure for domain information. */
526 struct ccs_domain_info {
527 struct list_head list;
528 struct list_head acl_info_list;
529 /* Name of this domain. Never NULL. */
530 const struct ccs_path_info *domainname;
531 u8 profile; /* Profile number to use. */
532 bool is_deleted; /* Delete flag. */
533 bool quota_warned; /* Quota warnning flag. */
534 /* Ignore "allow_read" directive in exception policy. */
535 bool ignore_global_allow_read;
536 /* Ignore "allow_env" directive in exception policy. */
537 bool ignore_global_allow_env;
538 /*
539 * This domain was unable to create a new domain at
540 * ccs_find_next_domain() because the name of the domain to be created
541 * was too long or it could not allocate memory.
542 * More than one process continued execve() without domain transition.
543 */
544 bool domain_transition_failed;
545 };
546
547 /* Structure for "allow_read" keyword. */
548 struct ccs_globally_readable_file_entry {
549 struct list_head list;
550 bool is_deleted;
551 const struct ccs_path_info *filename;
552 };
553
554 /* Structure for "file_pattern" keyword. */
555 struct ccs_pattern_entry {
556 struct list_head list;
557 bool is_deleted;
558 const struct ccs_path_info *pattern;
559 };
560
561 /* Structure for "deny_rewrite" keyword. */
562 struct ccs_no_rewrite_entry {
563 struct list_head list;
564 bool is_deleted;
565 const struct ccs_path_info *pattern;
566 };
567
568 /* Structure for "allow_env" keyword. */
569 struct ccs_globally_usable_env_entry {
570 struct list_head list;
571 bool is_deleted;
572 const struct ccs_path_info *env;
573 };
574
575 /* Structure for "initialize_domain" and "no_initialize_domain" keyword. */
576 struct ccs_domain_initializer_entry {
577 struct list_head list;
578 bool is_deleted;
579 bool is_not; /* True if this entry is "no_initialize_domain". */
580 bool is_last_name; /* True if the domainname is ccs_last_word(). */
581 const struct ccs_path_info *domainname; /* This may be NULL */
582 const struct ccs_path_info *program;
583 };
584
585 /* Structure for "keep_domain" and "no_keep_domain" keyword. */
586 struct ccs_domain_keeper_entry {
587 struct list_head list;
588 bool is_deleted;
589 bool is_not; /* True if this entry is "no_keep_domain". */
590 bool is_last_name; /* True if the domainname is ccs_last_word(). */
591 const struct ccs_path_info *domainname;
592 const struct ccs_path_info *program; /* This may be NULL */
593 };
594
595 /* Structure for "aggregator" keyword. */
596 struct ccs_aggregator_entry {
597 struct list_head list;
598 bool is_deleted;
599 const struct ccs_path_info *original_name;
600 const struct ccs_path_info *aggregated_name;
601 };
602
603 /* Structure for "allow_unmount" keyword. */
604 struct ccs_umount_acl {
605 struct ccs_acl_info head; /* type = CCS_TYPE_UMOUNT_ACL */
606 struct ccs_name_union dir;
607 };
608
609 /* Structure for "allow_pivot_root" keyword. */
610 struct ccs_pivot_root_acl {
611 struct ccs_acl_info head; /* type = CCS_TYPE_PIVOT_ROOT_ACL */
612 struct ccs_name_union old_root;
613 struct ccs_name_union new_root;
614 };
615
616 /* Structure for "allow_mount" keyword. */
617 struct ccs_mount_acl {
618 struct ccs_acl_info head; /* type = CCS_TYPE_MOUNT_ACL */
619 struct ccs_name_union dev_name;
620 struct ccs_name_union dir_name;
621 struct ccs_name_union fs_type;
622 struct ccs_number_union flags;
623 };
624
625 /* Structure for "allow_chroot" keyword. */
626 struct ccs_chroot_acl {
627 struct ccs_acl_info head; /* type = CCS_TYPE_CHROOT_ACL */
628 struct ccs_name_union dir;
629 };
630
631 /* Structure for "deny_autobind" keyword. */
632 struct ccs_reserved_entry {
633 struct list_head list;
634 bool is_deleted; /* Delete flag. */
635 u16 min_port; /* Start of port number range. */
636 u16 max_port; /* End of port number range. */
637 };
638
639 /* Structure for policy manager. */
640 struct ccs_policy_manager_entry {
641 struct list_head list;
642 bool is_deleted; /* True if this entry is deleted. */
643 bool is_domain; /* True if manager is a domainname. */
644 /* A path to program or a domainname. */
645 const struct ccs_path_info *manager;
646 };
647
648 /* Structure for argv[]. */
649 struct ccs_argv_entry {
650 unsigned int index;
651 const struct ccs_path_info *value;
652 bool is_not;
653 };
654
655 /* Structure for envp[]. */
656 struct ccs_envp_entry {
657 const struct ccs_path_info *name;
658 const struct ccs_path_info *value;
659 bool is_not;
660 };
661
662 /*
663 * Structure for "execute_handler" and "denied_execute_handler" directive.
664 * These directives can exist only one entry in a domain.
665 *
666 * If "execute_handler" directive exists and the current process is not
667 * an execute handler, all execve() requests are replaced by execve() requests
668 * of a program specified by "execute_handler" directive.
669 * If the current process is an execute handler,
670 * "execute_handler" and "denied_execute_handler" directives are ignored.
671 * The program specified by "execute_handler" validates execve() parameters
672 * and executes the original execve() requests if appropriate.
673 *
674 * "denied_execute_handler" directive is used only when execve() request was
675 * rejected in enforcing mode (i.e. MAC_FOR_FILE=enforcing).
676 * The program specified by "denied_execute_handler" does whatever it wants
677 * to do (e.g. silently terminate, change firewall settings,
678 * redirect the user to honey pot etc.).
679 */
680 struct ccs_execute_handler_record {
681 struct ccs_acl_info head; /* type = CCS_TYPE_*EXECUTE_HANDLER */
682 const struct ccs_path_info *handler; /* Pointer to single pathname. */
683 };
684
685 /*
686 * Structure for "allow_read/write", "allow_execute", "allow_read",
687 * "allow_write", "allow_unlink", "allow_rmdir", "allow_truncate",
688 * "allow_symlink" and "allow_rewrite" directive.
689 */
690 struct ccs_path_acl {
691 struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
692 u16 perm;
693 struct ccs_name_union name;
694 };
695
696 /* Structure for "allow_mkblock" and "allow_mkchar" directive. */
697 struct ccs_path_number3_acl {
698 struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER3_ACL */
699 u8 perm;
700 struct ccs_name_union name;
701 struct ccs_number_union mode;
702 struct ccs_number_union major;
703 struct ccs_number_union minor;
704 };
705
706 /* Structure for "allow_rename" and "allow_link" directive. */
707 struct ccs_path2_acl {
708 struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
709 u8 perm;
710 struct ccs_name_union name1;
711 struct ccs_name_union name2;
712 };
713
714 /*
715 * Structure for "allow_create", "allow_mkdir", "allow_mkfifo", "allow_mksock",
716 * "allow_ioctl", "allow_chmod", "allow_chown" and "allow_chgrp" directive.
717 */
718 struct ccs_path_number_acl {
719 struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */
720 u8 perm;
721 struct ccs_name_union name;
722 struct ccs_number_union number;
723 };
724
725 /* Structure for "allow_env" directive in domain policy. */
726 struct ccs_env_acl {
727 struct ccs_acl_info head; /* type = CCS_TYPE_ENV_ACL */
728 const struct ccs_path_info *env; /* environment variable */
729 };
730
731 /* Structure for "allow_capability" directive. */
732 struct ccs_capability_acl {
733 struct ccs_acl_info head; /* type = CCS_TYPE_CAPABILITY_ACL */
734 u8 operation;
735 };
736
737 /* Structure for "allow_signal" directive. */
738 struct ccs_signal_acl {
739 struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */
740 u16 sig;
741 /* Pointer to destination pattern. */
742 const struct ccs_path_info *domainname;
743 };
744
745 struct ccs_ipv6addr_entry {
746 struct list_head list;
747 atomic_t users;
748 struct in6_addr addr;
749 };
750
751 /* Structure for "allow_network" directive. */
752 struct ccs_ip_network_acl {
753 struct ccs_acl_info head; /* type = CCS_TYPE_IP_NETWORK_ACL */
754 u16 perm;
755 /*
756 * address_type takes one of the following constants.
757 * CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP
758 * if address points to "address_group" directive.
759 * CCS_IP_ADDRESS_TYPE_IPv4
760 * if address points to an IPv4 address.
761 * CCS_IP_ADDRESS_TYPE_IPv6
762 * if address points to an IPv6 address.
763 */
764 u8 address_type;
765 union {
766 struct {
767 /* Start of IPv4 address range. Host endian. */
768 u32 min;
769 /* End of IPv4 address range. Host endian. */
770 u32 max;
771 } ipv4;
772 struct {
773 /* Start of IPv6 address range. Big endian. */
774 const struct in6_addr *min;
775 /* End of IPv6 address range. Big endian. */
776 const struct in6_addr *max;
777 } ipv6;
778 /* Pointer to address group. */
779 struct ccs_address_group *group;
780 } address;
781 struct ccs_number_union port;
782 };
783
784
785 /* Structure for reading/writing policy via /proc interfaces. */
786 struct ccs_io_buffer {
787 void (*read) (struct ccs_io_buffer *);
788 int (*write) (struct ccs_io_buffer *);
789 int (*poll) (struct file *file, poll_table *wait);
790 /* Exclusive lock for this structure. */
791 struct mutex io_sem;
792 /* Index returned by ccs_read_lock(). */
793 int reader_idx;
794 /* The position currently reading from. */
795 struct list_head *read_var1;
796 /* Extra variables for reading. */
797 struct list_head *read_var2;
798 /* The position currently writing to. */
799 struct ccs_domain_info *write_var1;
800 /* The step for reading. */
801 int read_step;
802 /* Buffer for reading. */
803 char *read_buf;
804 /* EOF flag for reading. */
805 bool read_eof;
806 /* Read domain ACL of specified PID? */
807 bool read_single_domain;
808 /* Read allow_execute entry only? */
809 bool read_execute_only;
810 /* Extra variable for reading. */
811 u8 read_bit;
812 /* Bytes available for reading. */
813 int read_avail;
814 /* Size of read buffer. */
815 int readbuf_size;
816 /* Buffer for writing. */
817 char *write_buf;
818 /* Bytes available for writing. */
819 int write_avail;
820 /* Size of write buffer. */
821 int writebuf_size;
822 /* Type of this interface. */
823 u8 type;
824 };
825
826 struct ccs_preference {
827 #ifdef CONFIG_CCSECURITY_AUDIT
828 unsigned int audit_max_grant_log;
829 unsigned int audit_max_reject_log;
830 #endif
831 unsigned int learning_max_entry;
832 unsigned int enforcing_penalty;
833 bool audit_task_info;
834 bool audit_path_info;
835 bool enforcing_verbose;
836 bool learning_verbose;
837 bool learning_exec_realpath;
838 bool learning_exec_argv0;
839 bool learning_symlink_target;
840 bool permissive_verbose;
841 };
842
843 struct ccs_profile {
844 const struct ccs_path_info *comment;
845 struct ccs_preference *audit;
846 struct ccs_preference *learning;
847 struct ccs_preference *permissive;
848 struct ccs_preference *enforcing;
849 struct ccs_preference preference;
850 u8 default_config;
851 u8 config[CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX
852 + CCS_MAX_MAC_CATEGORY_INDEX];
853 };
854
855 /* Prototype definition. */
856
857 bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
858 const struct ccs_address_group *group);
859 bool ccs_commit_ok(void *ptr, void *data, const unsigned int size);
860 bool ccs_compare_name_union(const struct ccs_path_info *name,
861 const struct ccs_name_union *ptr);
862 bool ccs_compare_number_union(const unsigned long value,
863 const struct ccs_number_union *ptr);
864 bool ccs_condition(struct ccs_request_info *r, const struct ccs_acl_info *acl);
865 bool ccs_domain_quota_ok(struct ccs_request_info *r);
866 bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
867 struct ccs_page_dump *dump);
868 bool ccs_get_audit(const u8 profile, const u8 index, const bool is_granted);
869 bool ccs_io_printf(struct ccs_io_buffer *head, const char *fmt, ...)
870 __attribute__ ((format(printf, 2, 3)));
871 bool ccs_is_correct_domain(const unsigned char *domainname);
872 bool ccs_is_correct_path(const char *filename, const s8 start_type,
873 const s8 pattern_type, const s8 end_type);
874 bool ccs_is_domain_def(const unsigned char *buffer);
875 bool ccs_memory_ok(const void *ptr, const unsigned int size);
876 bool ccs_number_matches_group(const unsigned long min, const unsigned long max,
877 const struct ccs_number_group *group);
878 bool ccs_parse_name_union(const char *filename, struct ccs_name_union *ptr);
879 bool ccs_parse_number_union(char *data, struct ccs_number_union *num);
880 bool ccs_path_matches_group(const struct ccs_path_info *pathname,
881 const struct ccs_path_group *group,
882 const bool may_use_pattern);
883 bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
884 const struct ccs_path_info *pattern);
885 bool ccs_print_number_union(struct ccs_io_buffer *head,
886 const struct ccs_number_union *ptr);
887 bool ccs_read_address_group_policy(struct ccs_io_buffer *head);
888 bool ccs_read_aggregator_policy(struct ccs_io_buffer *head);
889 bool ccs_read_domain_initializer_policy(struct ccs_io_buffer *head);
890 bool ccs_read_domain_keeper_policy(struct ccs_io_buffer *head);
891 bool ccs_read_file_pattern(struct ccs_io_buffer *head);
892 bool ccs_read_globally_readable_policy(struct ccs_io_buffer *head);
893 bool ccs_read_globally_usable_env_policy(struct ccs_io_buffer *head);
894 bool ccs_read_no_rewrite_policy(struct ccs_io_buffer *head);
895 bool ccs_read_number_group_policy(struct ccs_io_buffer *head);
896 bool ccs_read_path_group_policy(struct ccs_io_buffer *head);
897 bool ccs_read_reserved_port_policy(struct ccs_io_buffer *head);
898 bool ccs_str_starts(char **src, const char *find);
899 bool ccs_tokenize(char *buffer, char *w[], size_t size);
900 char *ccs_encode(const char *str);
901 char *ccs_init_audit_log(int *len, struct ccs_request_info *r);
902 char *ccs_realpath_from_path(struct path *path);
903 const char *ccs_cap2keyword(const u8 operation);
904 const char *ccs_file_pattern(const struct ccs_path_info *filename);
905 const char *ccs_get_exe(void);
906 const char *ccs_last_word(const char *name);
907 const char *ccs_net2keyword(const u8 operation);
908 const char *ccs_path22keyword(const u8 operation);
909 const char *ccs_path2keyword(const u8 operation);
910 const char *ccs_path_number2keyword(const u8 operation);
911 const char *ccs_path_number32keyword(const u8 operation);
912 const struct ccs_path_info *ccs_get_name(const char *name);
913 const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr);
914 int ccs_close_control(struct file *file);
915 int ccs_delete_domain(char *data);
916 int ccs_env_perm(struct ccs_request_info *r, const char *env);
917 int ccs_exec_perm(struct ccs_request_info *r,
918 const struct ccs_path_info *filename);
919 int ccs_get_mode(const u8 profile, const u8 index);
920 int ccs_get_path(const char *pathname, struct path *path);
921 int ccs_init_request_info(struct ccs_request_info *r,
922 struct ccs_domain_info *domain, const u8 index);
923 int ccs_open_control(const u8 type, struct file *file);
924 int ccs_parse_ip_address(char *address, u16 *min, u16 *max);
925 int ccs_poll_control(struct file *file, poll_table *wait);
926 int ccs_poll_grant_log(struct file *file, poll_table *wait);
927 int ccs_poll_reject_log(struct file *file, poll_table *wait);
928 int ccs_read_control(struct file *file, char __user *buffer,
929 const int buffer_len);
930 int ccs_read_lock(void);
931 int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
932 __attribute__ ((format(printf, 2, 3)));
933 int ccs_symlink_path(const char *pathname, struct ccs_path_info *name);
934 int ccs_write_address_group_policy(char *data, const bool is_delete);
935 int ccs_write_aggregator_policy(char *data, const bool is_delete);
936 int ccs_write_audit_log(const bool is_granted, struct ccs_request_info *r,
937 const char *fmt, ...)
938 __attribute__ ((format(printf, 3, 4)));
939 int ccs_write_capability_policy(char *data, struct ccs_domain_info *domain,
940 struct ccs_condition *condition,
941 const bool is_delete);
942 int ccs_write_chroot_policy(char *data, struct ccs_domain_info *domain,
943 struct ccs_condition *condition,
944 const bool is_delete);
945 int ccs_write_control(struct file *file, const char __user *buffer,
946 const int buffer_len);
947 int ccs_write_domain_initializer_policy(char *data, const bool is_not,
948 const bool is_delete);
949 int ccs_write_domain_keeper_policy(char *data, const bool is_not,
950 const bool is_delete);
951 int ccs_write_env_policy(char *data, struct ccs_domain_info *domain,
952 struct ccs_condition *condition,
953 const bool is_delete);
954 int ccs_write_file_policy(char *data, struct ccs_domain_info *domain,
955 struct ccs_condition *condition,
956 const bool is_delete);
957 int ccs_write_globally_readable_policy(char *data, const bool is_delete);
958 int ccs_write_globally_usable_env_policy(char *data, const bool is_delete);
959 int ccs_write_memory_quota(struct ccs_io_buffer *head);
960 int ccs_write_mount_policy(char *data, struct ccs_domain_info *domain,
961 struct ccs_condition *condition,
962 const bool is_delete);
963 int ccs_write_network_policy(char *data, struct ccs_domain_info *domain,
964 struct ccs_condition *condition,
965 const bool is_delete);
966 int ccs_write_no_rewrite_policy(char *data, const bool is_delete);
967 int ccs_write_number_group_policy(char *data, const bool is_delete);
968 int ccs_write_path_group_policy(char *data, const bool is_delete);
969 int ccs_write_pattern_policy(char *data, const bool is_delete);
970 int ccs_write_pivot_root_policy(char *data, struct ccs_domain_info *domain,
971 struct ccs_condition *condition,
972 const bool is_delete);
973 int ccs_write_reserved_port_policy(char *data, const bool is_delete);
974 int ccs_write_signal_policy(char *data, struct ccs_domain_info *domain,
975 struct ccs_condition *condition,
976 const bool is_delete);
977 int ccs_write_umount_policy(char *data, struct ccs_domain_info *domain,
978 struct ccs_condition *condition,
979 const bool is_delete);
980 struct ccs_address_group *ccs_get_address_group(const char *group_name);
981 struct ccs_condition *ccs_get_condition(char * const condition);
982 struct ccs_domain_info *ccs_find_domain(const char *domainname);
983 struct ccs_domain_info *ccs_find_or_assign_new_domain(const char *domainname,
984 const u8 profile);
985 struct ccs_number_group *ccs_get_number_group(const char *group_name);
986 struct ccs_path_group *ccs_get_path_group(const char *group_name);
987 struct ccs_profile *ccs_profile(const u8 profile);
988 u8 ccs_parse_ulong(unsigned long *result, char **str);
989 void ccs_check_profile(void);
990 void ccs_fill_path_info(struct ccs_path_info *ptr);
991 void ccs_get_attributes(struct ccs_obj_info *obj);
992 void ccs_load_policy(const char *filename);
993 void ccs_memory_free(const void *ptr, size_t size);
994 void ccs_normalize_line(unsigned char *buffer);
995 void ccs_print_ipv6(char *buffer, const int buffer_len,
996 const struct in6_addr *ip);
997 void ccs_print_ulong(char *buffer, const int buffer_len,
998 const unsigned long value, const u8 type);
999 void ccs_put_address_group(struct ccs_address_group *group);
1000 void ccs_put_condition(struct ccs_condition *cond);
1001 void ccs_put_ipv6_address(const struct in6_addr *addr);
1002 void ccs_put_name(const struct ccs_path_info *name);
1003 void ccs_put_name_union(struct ccs_name_union *ptr);
1004 void ccs_put_number_group(struct ccs_number_group *group);
1005 void ccs_put_number_union(struct ccs_number_union *ptr);
1006 void ccs_put_path_group(struct ccs_path_group *group);
1007 void ccs_read_grant_log(struct ccs_io_buffer *head);
1008 void ccs_read_memory_counter(struct ccs_io_buffer *head);
1009 void ccs_read_reject_log(struct ccs_io_buffer *head);
1010 void ccs_read_unlock(const int idx);
1011 void ccs_run_gc(void);
1012 void ccs_warn_log(struct ccs_request_info *r, const char *fmt, ...)
1013 __attribute__ ((format(printf, 2, 3)));
1014 void ccs_warn_oom(const char *function);
1015
1016 /* strcmp() for "struct ccs_path_info" structure. */
1017 static inline bool ccs_pathcmp(const struct ccs_path_info *a,
1018 const struct ccs_path_info *b)
1019 {
1020 return a->hash != b->hash || strcmp(a->name, b->name);
1021 }
1022
1023 static inline int ccs_memcmp(void *a, void *b, const u8 offset, const u8 size)
1024 {
1025 return memcmp(((char *) a) + offset, ((char *) b) + offset,
1026 size - offset);
1027 }
1028
1029 extern struct mutex ccs_policy_lock;
1030 extern struct list_head ccs_domain_list;
1031 extern struct list_head ccs_address_group_list;
1032 extern struct list_head ccs_globally_readable_list;
1033 extern struct list_head ccs_path_group_list;
1034 extern struct list_head ccs_number_group_list;
1035 extern struct list_head ccs_pattern_list;
1036 extern struct list_head ccs_no_rewrite_list;
1037 extern struct list_head ccs_globally_usable_env_list;
1038 extern struct list_head ccs_domain_initializer_list;
1039 extern struct list_head ccs_domain_keeper_list;
1040 extern struct list_head ccs_aggregator_list;
1041 extern struct list_head ccs_reservedport_list;
1042 extern struct list_head ccs_policy_manager_list;
1043
1044 extern bool ccs_policy_loaded;
1045 extern struct ccs_domain_info ccs_kernel_domain;
1046
1047 extern const char *ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD];
1048
1049 extern unsigned int ccs_audit_log_memory_size;
1050 extern unsigned int ccs_quota_for_audit_log;
1051 extern unsigned int ccs_query_memory_size;
1052 extern unsigned int ccs_quota_for_query;
1053
1054 #include <linux/dcache.h>
1055 extern spinlock_t vfsmount_lock;
1056
1057 #ifdef D_PATH_DISCONNECT
1058
1059 static inline void ccs_realpath_lock(void)
1060 {
1061 spin_lock(&vfsmount_lock);
1062 spin_lock(&dcache_lock);
1063 }
1064 static inline void ccs_realpath_unlock(void)
1065 {
1066 spin_unlock(&dcache_lock);
1067 spin_unlock(&vfsmount_lock);
1068 }
1069
1070 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1071
1072 static inline void ccs_realpath_lock(void)
1073 {
1074 spin_lock(&dcache_lock);
1075 spin_lock(&vfsmount_lock);
1076 }
1077 static inline void ccs_realpath_unlock(void)
1078 {
1079 spin_unlock(&vfsmount_lock);
1080 spin_unlock(&dcache_lock);
1081 }
1082
1083 #else
1084
1085 static inline void ccs_realpath_lock(void)
1086 {
1087 spin_lock(&dcache_lock);
1088 }
1089 static inline void ccs_realpath_unlock(void)
1090 {
1091 spin_unlock(&dcache_lock);
1092 }
1093
1094 #endif
1095
1096 static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
1097 {
1098 return task->ccs_domain_info ?
1099 task->ccs_domain_info : &ccs_kernel_domain;
1100 }
1101
1102 static inline struct ccs_domain_info *ccs_current_domain(void)
1103 {
1104 struct task_struct *task = current;
1105 if (!task->ccs_domain_info)
1106 task->ccs_domain_info = &ccs_kernel_domain;
1107 return task->ccs_domain_info;
1108 }
1109
1110 static inline void ccs_add_domain_acl(struct ccs_domain_info *domain,
1111 struct ccs_acl_info *acl)
1112 {
1113 if (acl->cond)
1114 atomic_inc(&acl->cond->users);
1115 list_add_tail_rcu(&acl->list, &domain->acl_info_list);
1116 }
1117
1118 #if defined(CONFIG_SLOB)
1119 static inline int ccs_round2(size_t size)
1120 {
1121 return size;
1122 }
1123 #else
1124 static inline int ccs_round2(size_t size)
1125 {
1126 #if PAGE_SIZE == 4096
1127 size_t bsize = 32;
1128 #else
1129 size_t bsize = 64;
1130 #endif
1131 if (!size)
1132 return 0;
1133 while (size > bsize)
1134 bsize <<= 1;
1135 return bsize;
1136 }
1137 #endif
1138
1139 #endif

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