1 |
/* |
2 |
* security/ccsecurity/internal.h |
3 |
* |
4 |
* Copyright (C) 2005-2011 NTT DATA CORPORATION |
5 |
* |
6 |
* Version: 1.8.0+ 2011/03/05 |
7 |
*/ |
8 |
|
9 |
#ifndef _SECURITY_CCSECURITY_INTERNAL_H |
10 |
#define _SECURITY_CCSECURITY_INTERNAL_H |
11 |
|
12 |
#include <linux/version.h> |
13 |
#include <linux/types.h> |
14 |
#include <linux/kernel.h> |
15 |
#include <linux/string.h> |
16 |
#include <linux/mm.h> |
17 |
#include <linux/utime.h> |
18 |
#include <linux/file.h> |
19 |
#include <linux/smp_lock.h> |
20 |
#include <linux/module.h> |
21 |
#include <linux/init.h> |
22 |
#include <linux/slab.h> |
23 |
#include <linux/highmem.h> |
24 |
#include <linux/poll.h> |
25 |
#include <linux/binfmts.h> |
26 |
#include <linux/delay.h> |
27 |
#include <linux/sched.h> |
28 |
#include <linux/dcache.h> |
29 |
#include <linux/mount.h> |
30 |
#include <linux/net.h> |
31 |
#include <linux/inet.h> |
32 |
#include <linux/in.h> |
33 |
#include <linux/in6.h> |
34 |
#include <linux/un.h> |
35 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) |
36 |
#include <linux/fs.h> |
37 |
#endif |
38 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) |
39 |
#include <linux/namei.h> |
40 |
#endif |
41 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) |
42 |
#include <linux/fs_struct.h> |
43 |
#endif |
44 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) |
45 |
#include <linux/namespace.h> |
46 |
#endif |
47 |
#include <linux/proc_fs.h> |
48 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR) |
49 |
#include <linux/hash.h> |
50 |
#endif |
51 |
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL)) |
52 |
#include <linux/sysctl.h> |
53 |
#endif |
54 |
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6) |
55 |
#include <linux/kthread.h> |
56 |
#endif |
57 |
#include <stdarg.h> |
58 |
#include <asm/uaccess.h> |
59 |
#include <net/sock.h> |
60 |
#include <net/af_unix.h> |
61 |
#include <net/ip.h> |
62 |
#include <net/ipv6.h> |
63 |
#include <net/udp.h> |
64 |
|
65 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) |
66 |
#define sk_family family |
67 |
#define sk_protocol protocol |
68 |
#define sk_type type |
69 |
#endif |
70 |
|
71 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) |
72 |
|
73 |
/* Structure for holding "struct vfsmount *" and "struct dentry *". */ |
74 |
struct path { |
75 |
struct vfsmount *mnt; |
76 |
struct dentry *dentry; |
77 |
}; |
78 |
|
79 |
#endif |
80 |
|
81 |
#ifndef bool |
82 |
#define bool _Bool |
83 |
#endif |
84 |
#ifndef false |
85 |
#define false 0 |
86 |
#endif |
87 |
#ifndef true |
88 |
#define true 1 |
89 |
#endif |
90 |
|
91 |
#ifndef __user |
92 |
#define __user |
93 |
#endif |
94 |
|
95 |
#ifndef current_uid |
96 |
#define current_uid() (current->uid) |
97 |
#endif |
98 |
#ifndef current_gid |
99 |
#define current_gid() (current->gid) |
100 |
#endif |
101 |
#ifndef current_euid |
102 |
#define current_euid() (current->euid) |
103 |
#endif |
104 |
#ifndef current_egid |
105 |
#define current_egid() (current->egid) |
106 |
#endif |
107 |
#ifndef current_suid |
108 |
#define current_suid() (current->suid) |
109 |
#endif |
110 |
#ifndef current_sgid |
111 |
#define current_sgid() (current->sgid) |
112 |
#endif |
113 |
#ifndef current_fsuid |
114 |
#define current_fsuid() (current->fsuid) |
115 |
#endif |
116 |
#ifndef current_fsgid |
117 |
#define current_fsgid() (current->fsgid) |
118 |
#endif |
119 |
|
120 |
#ifndef DEFINE_SPINLOCK |
121 |
#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED |
122 |
#endif |
123 |
|
124 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) |
125 |
#define mutex semaphore |
126 |
#define mutex_init(mutex) init_MUTEX(mutex) |
127 |
#define mutex_unlock(mutex) up(mutex) |
128 |
#define mutex_lock(mutex) down(mutex) |
129 |
#define mutex_lock_interruptible(mutex) down_interruptible(mutex) |
130 |
#define mutex_trylock(mutex) (!down_trylock(mutex)) |
131 |
#define DEFINE_MUTEX(mutexname) DECLARE_MUTEX(mutexname) |
132 |
#endif |
133 |
|
134 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) |
135 |
#define MS_UNBINDABLE (1<<17) /* change to unbindable */ |
136 |
#define MS_PRIVATE (1<<18) /* change to private */ |
137 |
#define MS_SLAVE (1<<19) /* change to slave */ |
138 |
#define MS_SHARED (1<<20) /* change to shared */ |
139 |
#endif |
140 |
|
141 |
#ifndef container_of |
142 |
#define container_of(ptr, type, member) ({ \ |
143 |
const typeof(((type *)0)->member) *__mptr = (ptr); \ |
144 |
(type *)((char *)__mptr - offsetof(type, member)); }) |
145 |
#endif |
146 |
|
147 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) |
148 |
#define smp_read_barrier_depends smp_rmb |
149 |
#endif |
150 |
|
151 |
#ifndef ACCESS_ONCE |
152 |
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) |
153 |
#endif |
154 |
|
155 |
#ifndef rcu_dereference |
156 |
#define rcu_dereference(p) ({ \ |
157 |
typeof(p) _________p1 = ACCESS_ONCE(p); \ |
158 |
smp_read_barrier_depends(); /* see RCU */ \ |
159 |
(_________p1); \ |
160 |
}) |
161 |
#endif |
162 |
|
163 |
#ifndef rcu_assign_pointer |
164 |
#define rcu_assign_pointer(p, v) \ |
165 |
({ \ |
166 |
if (!__builtin_constant_p(v) || \ |
167 |
((v) != NULL)) \ |
168 |
smp_wmb(); /* see RCU */ \ |
169 |
(p) = (v); \ |
170 |
}) |
171 |
#endif |
172 |
|
173 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) |
174 |
|
175 |
/** |
176 |
* kzalloc() - Allocate memory. The memory is set to zero. |
177 |
* |
178 |
* @size: Size to allocate. |
179 |
* @flags: GFP flags. |
180 |
* |
181 |
* Returns pointer to allocated memory on success, NULL otherwise. |
182 |
* |
183 |
* This is for compatibility with older kernels. |
184 |
* |
185 |
* Since several distributions backported kzalloc(), I define it as a macro |
186 |
* rather than an inlined function in order to avoid multiple definition error. |
187 |
*/ |
188 |
#define kzalloc(size, flags) ({ \ |
189 |
void *ret = kmalloc((size), (flags)); \ |
190 |
if (ret) \ |
191 |
memset(ret, 0, (size)); \ |
192 |
ret; }) |
193 |
|
194 |
#endif |
195 |
|
196 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) |
197 |
|
198 |
/** |
199 |
* path_put - Drop reference on "struct path". |
200 |
* |
201 |
* @path: Pointer to "struct path". |
202 |
* |
203 |
* Returns nothing. |
204 |
* |
205 |
* This is for compatibility with older kernels. |
206 |
*/ |
207 |
static inline void path_put(struct path *path) |
208 |
{ |
209 |
dput(path->dentry); |
210 |
mntput(path->mnt); |
211 |
} |
212 |
|
213 |
#endif |
214 |
|
215 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) |
216 |
|
217 |
/** |
218 |
* __list_add_rcu - Insert a new entry between two known consecutive entries. |
219 |
* |
220 |
* @new: Pointer to "struct list_head". |
221 |
* @prev: Pointer to "struct list_head". |
222 |
* @next: Pointer to "struct list_head". |
223 |
* |
224 |
* Returns nothing. |
225 |
* |
226 |
* This is for compatibility with older kernels. |
227 |
*/ |
228 |
static inline void __list_add_rcu(struct list_head *new, |
229 |
struct list_head *prev, |
230 |
struct list_head *next) |
231 |
{ |
232 |
new->next = next; |
233 |
new->prev = prev; |
234 |
rcu_assign_pointer(prev->next, new); |
235 |
next->prev = new; |
236 |
} |
237 |
|
238 |
/** |
239 |
* list_add_tail_rcu - Add a new entry to rcu-protected list. |
240 |
* |
241 |
* @new: Pointer to "struct list_head". |
242 |
* @head: Pointer to "struct list_head". |
243 |
* |
244 |
* Returns nothing. |
245 |
* |
246 |
* This is for compatibility with older kernels. |
247 |
*/ |
248 |
static inline void list_add_tail_rcu(struct list_head *new, |
249 |
struct list_head *head) |
250 |
{ |
251 |
__list_add_rcu(new, head->prev, head); |
252 |
} |
253 |
|
254 |
/** |
255 |
* list_add_rcu - Add a new entry to rcu-protected list. |
256 |
* |
257 |
* @new: Pointer to "struct list_head". |
258 |
* @head: Pointer to "struct list_head". |
259 |
* |
260 |
* Returns nothing. |
261 |
* |
262 |
* This is for compatibility with older kernels. |
263 |
*/ |
264 |
static inline void list_add_rcu(struct list_head *new, struct list_head *head) |
265 |
{ |
266 |
__list_add_rcu(new, head, head->next); |
267 |
} |
268 |
|
269 |
#endif |
270 |
|
271 |
#ifndef srcu_dereference |
272 |
|
273 |
/** |
274 |
* srcu_dereference - Fetch SRCU-protected pointer with checking. |
275 |
* |
276 |
* @p: The pointer to read, prior to dereferencing. |
277 |
* @ss: Pointer to "struct srcu_struct". |
278 |
* |
279 |
* Returns @p. |
280 |
* |
281 |
* This is for compatibility with older kernels. |
282 |
*/ |
283 |
#define srcu_dereference(p, ss) rcu_dereference(p) |
284 |
|
285 |
#endif |
286 |
|
287 |
#ifndef list_for_each_entry_srcu |
288 |
|
289 |
/** |
290 |
* list_for_each_entry_srcu - Iterate over rcu list of given type. |
291 |
* |
292 |
* @pos: The type * to use as a loop cursor. |
293 |
* @head: The head for your list. |
294 |
* @member: The name of the list_struct within the struct. |
295 |
* @ss: Pointer to "struct srcu_struct". |
296 |
* |
297 |
* As of 2.6.36, this macro is not provided because only TOMOYO wants it. |
298 |
*/ |
299 |
#define list_for_each_entry_srcu(pos, head, member, ss) \ |
300 |
for (pos = list_entry(srcu_dereference((head)->next, ss), \ |
301 |
typeof(*pos), member); \ |
302 |
prefetch(pos->member.next), &pos->member != (head); \ |
303 |
pos = list_entry(srcu_dereference(pos->member.next, ss), \ |
304 |
typeof(*pos), member)) |
305 |
|
306 |
#endif |
307 |
|
308 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 30) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9)) |
309 |
|
310 |
#ifndef ssleep |
311 |
|
312 |
/** |
313 |
* ssleep - Sleep for specified seconds. |
314 |
* |
315 |
* @secs: Seconds to sleep. |
316 |
* |
317 |
* Returns nothing. |
318 |
* |
319 |
* This is for compatibility with older kernels. |
320 |
* |
321 |
* Since several distributions backported ssleep(), I define it as a macro |
322 |
* rather than an inlined function in order to avoid multiple definition error. |
323 |
*/ |
324 |
#define ssleep(secs) { \ |
325 |
set_current_state(TASK_UNINTERRUPTIBLE); \ |
326 |
schedule_timeout((HZ * secs) + 1); \ |
327 |
} |
328 |
|
329 |
#endif |
330 |
|
331 |
#endif |
332 |
|
333 |
/* |
334 |
* TOMOYO specific part start. |
335 |
*/ |
336 |
|
337 |
#include <linux/ccsecurity.h> |
338 |
|
339 |
/* Enumeration definition for internal use. */ |
340 |
|
341 |
/* Index numbers for Access Controls. */ |
342 |
enum ccs_acl_entry_type_index { |
343 |
CCS_TYPE_PATH_ACL, |
344 |
CCS_TYPE_PATH2_ACL, |
345 |
CCS_TYPE_PATH_NUMBER_ACL, |
346 |
CCS_TYPE_MKDEV_ACL, |
347 |
CCS_TYPE_MOUNT_ACL, |
348 |
CCS_TYPE_ENV_ACL, |
349 |
CCS_TYPE_CAPABILITY_ACL, |
350 |
CCS_TYPE_INET_ACL, |
351 |
CCS_TYPE_UNIX_ACL, |
352 |
CCS_TYPE_SIGNAL_ACL, |
353 |
CCS_TYPE_AUTO_EXECUTE_HANDLER, |
354 |
CCS_TYPE_DENIED_EXECUTE_HANDLER, |
355 |
CCS_TYPE_AUTO_TASK_ACL, |
356 |
CCS_TYPE_MANUAL_TASK_ACL, |
357 |
}; |
358 |
|
359 |
/* Index numbers for "struct ccs_condition". */ |
360 |
enum ccs_conditions_index { |
361 |
CCS_TASK_UID, /* current_uid() */ |
362 |
CCS_TASK_EUID, /* current_euid() */ |
363 |
CCS_TASK_SUID, /* current_suid() */ |
364 |
CCS_TASK_FSUID, /* current_fsuid() */ |
365 |
CCS_TASK_GID, /* current_gid() */ |
366 |
CCS_TASK_EGID, /* current_egid() */ |
367 |
CCS_TASK_SGID, /* current_sgid() */ |
368 |
CCS_TASK_FSGID, /* current_fsgid() */ |
369 |
CCS_TASK_PID, /* sys_getpid() */ |
370 |
CCS_TASK_PPID, /* sys_getppid() */ |
371 |
CCS_EXEC_ARGC, /* "struct linux_binprm *"->argc */ |
372 |
CCS_EXEC_ENVC, /* "struct linux_binprm *"->envc */ |
373 |
CCS_TYPE_IS_SOCKET, /* S_IFSOCK */ |
374 |
CCS_TYPE_IS_SYMLINK, /* S_IFLNK */ |
375 |
CCS_TYPE_IS_FILE, /* S_IFREG */ |
376 |
CCS_TYPE_IS_BLOCK_DEV, /* S_IFBLK */ |
377 |
CCS_TYPE_IS_DIRECTORY, /* S_IFDIR */ |
378 |
CCS_TYPE_IS_CHAR_DEV, /* S_IFCHR */ |
379 |
CCS_TYPE_IS_FIFO, /* S_IFIFO */ |
380 |
CCS_MODE_SETUID, /* S_ISUID */ |
381 |
CCS_MODE_SETGID, /* S_ISGID */ |
382 |
CCS_MODE_STICKY, /* S_ISVTX */ |
383 |
CCS_MODE_OWNER_READ, /* S_IRUSR */ |
384 |
CCS_MODE_OWNER_WRITE, /* S_IWUSR */ |
385 |
CCS_MODE_OWNER_EXECUTE, /* S_IXUSR */ |
386 |
CCS_MODE_GROUP_READ, /* S_IRGRP */ |
387 |
CCS_MODE_GROUP_WRITE, /* S_IWGRP */ |
388 |
CCS_MODE_GROUP_EXECUTE, /* S_IXGRP */ |
389 |
CCS_MODE_OTHERS_READ, /* S_IROTH */ |
390 |
CCS_MODE_OTHERS_WRITE, /* S_IWOTH */ |
391 |
CCS_MODE_OTHERS_EXECUTE, /* S_IXOTH */ |
392 |
CCS_TASK_TYPE, /* ((u8) task->ccs_flags) & |
393 |
CCS_TASK_IS_EXECUTE_HANDLER */ |
394 |
CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */ |
395 |
CCS_EXEC_REALPATH, |
396 |
CCS_SYMLINK_TARGET, |
397 |
CCS_PATH1_UID, |
398 |
CCS_PATH1_GID, |
399 |
CCS_PATH1_INO, |
400 |
CCS_PATH1_MAJOR, |
401 |
CCS_PATH1_MINOR, |
402 |
CCS_PATH1_PERM, |
403 |
CCS_PATH1_TYPE, |
404 |
CCS_PATH1_DEV_MAJOR, |
405 |
CCS_PATH1_DEV_MINOR, |
406 |
CCS_PATH2_UID, |
407 |
CCS_PATH2_GID, |
408 |
CCS_PATH2_INO, |
409 |
CCS_PATH2_MAJOR, |
410 |
CCS_PATH2_MINOR, |
411 |
CCS_PATH2_PERM, |
412 |
CCS_PATH2_TYPE, |
413 |
CCS_PATH2_DEV_MAJOR, |
414 |
CCS_PATH2_DEV_MINOR, |
415 |
CCS_PATH1_PARENT_UID, |
416 |
CCS_PATH1_PARENT_GID, |
417 |
CCS_PATH1_PARENT_INO, |
418 |
CCS_PATH1_PARENT_PERM, |
419 |
CCS_PATH2_PARENT_UID, |
420 |
CCS_PATH2_PARENT_GID, |
421 |
CCS_PATH2_PARENT_INO, |
422 |
CCS_PATH2_PARENT_PERM, |
423 |
CCS_MAX_CONDITION_KEYWORD, |
424 |
CCS_NUMBER_UNION, |
425 |
CCS_NAME_UNION, |
426 |
CCS_ARGV_ENTRY, |
427 |
CCS_ENVP_ENTRY, |
428 |
}; |
429 |
|
430 |
/* Index numbers for domain's attributes. */ |
431 |
enum ccs_domain_info_flags_index { |
432 |
/* Quota warnning flag. */ |
433 |
CCS_DIF_QUOTA_WARNED, |
434 |
/* |
435 |
* This domain was unable to create a new domain at |
436 |
* ccs_find_next_domain() because the name of the domain to be created |
437 |
* was too long or it could not allocate memory. |
438 |
* More than one process continued execve() without domain transition. |
439 |
*/ |
440 |
CCS_DIF_TRANSITION_FAILED, |
441 |
CCS_MAX_DOMAIN_INFO_FLAGS |
442 |
}; |
443 |
|
444 |
/* Index numbers for audit type. */ |
445 |
enum ccs_grant_log { |
446 |
/* Follow profile's configuration. */ |
447 |
CCS_GRANTLOG_AUTO, |
448 |
/* Do not generate grant log. */ |
449 |
CCS_GRANTLOG_NO, |
450 |
/* Generate grant_log. */ |
451 |
CCS_GRANTLOG_YES, |
452 |
}; |
453 |
|
454 |
/* Index numbers for group entries. */ |
455 |
enum ccs_group_id { |
456 |
CCS_PATH_GROUP, |
457 |
CCS_NUMBER_GROUP, |
458 |
CCS_ADDRESS_GROUP, |
459 |
CCS_MAX_GROUP |
460 |
}; |
461 |
|
462 |
/* Index numbers for type of IP address. */ |
463 |
enum ccs_ip_address_type { |
464 |
CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP, |
465 |
CCS_IP_ADDRESS_TYPE_IPv4, |
466 |
CCS_IP_ADDRESS_TYPE_IPv6, |
467 |
}; |
468 |
|
469 |
/* Index numbers for category of functionality. */ |
470 |
enum ccs_mac_category_index { |
471 |
CCS_MAC_CATEGORY_FILE, |
472 |
CCS_MAC_CATEGORY_NETWORK, |
473 |
CCS_MAC_CATEGORY_MISC, |
474 |
CCS_MAC_CATEGORY_IPC, |
475 |
CCS_MAC_CATEGORY_CAPABILITY, |
476 |
CCS_MAX_MAC_CATEGORY_INDEX |
477 |
}; |
478 |
|
479 |
/* Index numbers for functionality. */ |
480 |
enum ccs_mac_index { |
481 |
CCS_MAC_FILE_EXECUTE, |
482 |
CCS_MAC_FILE_OPEN, |
483 |
CCS_MAC_FILE_CREATE, |
484 |
CCS_MAC_FILE_UNLINK, |
485 |
CCS_MAC_FILE_GETATTR, |
486 |
CCS_MAC_FILE_MKDIR, |
487 |
CCS_MAC_FILE_RMDIR, |
488 |
CCS_MAC_FILE_MKFIFO, |
489 |
CCS_MAC_FILE_MKSOCK, |
490 |
CCS_MAC_FILE_TRUNCATE, |
491 |
CCS_MAC_FILE_SYMLINK, |
492 |
CCS_MAC_FILE_MKBLOCK, |
493 |
CCS_MAC_FILE_MKCHAR, |
494 |
CCS_MAC_FILE_LINK, |
495 |
CCS_MAC_FILE_RENAME, |
496 |
CCS_MAC_FILE_CHMOD, |
497 |
CCS_MAC_FILE_CHOWN, |
498 |
CCS_MAC_FILE_CHGRP, |
499 |
CCS_MAC_FILE_IOCTL, |
500 |
CCS_MAC_FILE_CHROOT, |
501 |
CCS_MAC_FILE_MOUNT, |
502 |
CCS_MAC_FILE_UMOUNT, |
503 |
CCS_MAC_FILE_PIVOT_ROOT, |
504 |
CCS_MAC_NETWORK_INET_STREAM_BIND, |
505 |
CCS_MAC_NETWORK_INET_STREAM_LISTEN, |
506 |
CCS_MAC_NETWORK_INET_STREAM_CONNECT, |
507 |
CCS_MAC_NETWORK_INET_STREAM_ACCEPT, |
508 |
CCS_MAC_NETWORK_INET_DGRAM_BIND, |
509 |
CCS_MAC_NETWORK_INET_DGRAM_SEND, |
510 |
CCS_MAC_NETWORK_INET_DGRAM_RECV, |
511 |
CCS_MAC_NETWORK_INET_RAW_BIND, |
512 |
CCS_MAC_NETWORK_INET_RAW_SEND, |
513 |
CCS_MAC_NETWORK_INET_RAW_RECV, |
514 |
CCS_MAC_NETWORK_UNIX_STREAM_BIND, |
515 |
CCS_MAC_NETWORK_UNIX_STREAM_LISTEN, |
516 |
CCS_MAC_NETWORK_UNIX_STREAM_CONNECT, |
517 |
CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT, |
518 |
CCS_MAC_NETWORK_UNIX_DGRAM_BIND, |
519 |
CCS_MAC_NETWORK_UNIX_DGRAM_SEND, |
520 |
CCS_MAC_NETWORK_UNIX_DGRAM_RECV, |
521 |
CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND, |
522 |
CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN, |
523 |
CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT, |
524 |
CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT, |
525 |
CCS_MAC_ENVIRON, |
526 |
CCS_MAC_SIGNAL, |
527 |
CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET, |
528 |
CCS_MAC_CAPABILITY_USE_PACKET_SOCKET, |
529 |
CCS_MAC_CAPABILITY_SYS_REBOOT, |
530 |
CCS_MAC_CAPABILITY_SYS_VHANGUP, |
531 |
CCS_MAC_CAPABILITY_SYS_SETTIME, |
532 |
CCS_MAC_CAPABILITY_SYS_NICE, |
533 |
CCS_MAC_CAPABILITY_SYS_SETHOSTNAME, |
534 |
CCS_MAC_CAPABILITY_USE_KERNEL_MODULE, |
535 |
CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD, |
536 |
CCS_MAC_CAPABILITY_SYS_PTRACE, |
537 |
CCS_MAX_MAC_INDEX |
538 |
}; |
539 |
|
540 |
/* Index numbers for /proc/ccs/meminfo interface. */ |
541 |
enum ccs_memory_stat_type { |
542 |
CCS_MEMORY_POLICY, |
543 |
CCS_MEMORY_AUDIT, |
544 |
CCS_MEMORY_QUERY, |
545 |
CCS_MAX_MEMORY_STAT |
546 |
}; |
547 |
|
548 |
/* Index numbers for access controls with one pathname and three numbers. */ |
549 |
enum ccs_mkdev_acl_index { |
550 |
CCS_TYPE_MKBLOCK, |
551 |
CCS_TYPE_MKCHAR, |
552 |
CCS_MAX_MKDEV_OPERATION |
553 |
}; |
554 |
|
555 |
/* Index numbers for operation mode. */ |
556 |
enum ccs_mode_value { |
557 |
CCS_CONFIG_DISABLED, |
558 |
CCS_CONFIG_LEARNING, |
559 |
CCS_CONFIG_PERMISSIVE, |
560 |
CCS_CONFIG_ENFORCING, |
561 |
CCS_CONFIG_MAX_MODE, |
562 |
CCS_CONFIG_WANT_REJECT_LOG = 64, |
563 |
CCS_CONFIG_WANT_GRANT_LOG = 128, |
564 |
CCS_CONFIG_USE_DEFAULT = 255, |
565 |
}; |
566 |
|
567 |
/* Index numbers for socket operations. */ |
568 |
enum ccs_network_acl_index { |
569 |
CCS_NETWORK_BIND, /* bind() operation. */ |
570 |
CCS_NETWORK_LISTEN, /* listen() operation. */ |
571 |
CCS_NETWORK_CONNECT, /* connect() operation. */ |
572 |
CCS_NETWORK_ACCEPT, /* accept() operation. */ |
573 |
CCS_NETWORK_SEND, /* send() operation. */ |
574 |
CCS_NETWORK_RECV, /* recv() operation. */ |
575 |
CCS_MAX_NETWORK_OPERATION |
576 |
}; |
577 |
|
578 |
/* Index numbers for access controls with two pathnames. */ |
579 |
enum ccs_path2_acl_index { |
580 |
CCS_TYPE_LINK, |
581 |
CCS_TYPE_RENAME, |
582 |
CCS_TYPE_PIVOT_ROOT, |
583 |
CCS_MAX_PATH2_OPERATION |
584 |
}; |
585 |
|
586 |
/* Index numbers for access controls with one pathname. */ |
587 |
enum ccs_path_acl_index { |
588 |
CCS_TYPE_EXECUTE, |
589 |
CCS_TYPE_READ, |
590 |
CCS_TYPE_WRITE, |
591 |
CCS_TYPE_APPEND, |
592 |
CCS_TYPE_UNLINK, |
593 |
CCS_TYPE_GETATTR, |
594 |
CCS_TYPE_RMDIR, |
595 |
CCS_TYPE_TRUNCATE, |
596 |
CCS_TYPE_SYMLINK, |
597 |
CCS_TYPE_CHROOT, |
598 |
CCS_TYPE_UMOUNT, |
599 |
CCS_MAX_PATH_OPERATION |
600 |
}; |
601 |
|
602 |
/* Index numbers for access controls with one pathname and one number. */ |
603 |
enum ccs_path_number_acl_index { |
604 |
CCS_TYPE_CREATE, |
605 |
CCS_TYPE_MKDIR, |
606 |
CCS_TYPE_MKFIFO, |
607 |
CCS_TYPE_MKSOCK, |
608 |
CCS_TYPE_IOCTL, |
609 |
CCS_TYPE_CHMOD, |
610 |
CCS_TYPE_CHOWN, |
611 |
CCS_TYPE_CHGRP, |
612 |
CCS_MAX_PATH_NUMBER_OPERATION |
613 |
}; |
614 |
|
615 |
/* Index numbers for stat(). */ |
616 |
enum ccs_path_stat_index { |
617 |
/* Do not change this order. */ |
618 |
CCS_PATH1, |
619 |
CCS_PATH1_PARENT, |
620 |
CCS_PATH2, |
621 |
CCS_PATH2_PARENT, |
622 |
CCS_MAX_PATH_STAT |
623 |
}; |
624 |
|
625 |
/* Index numbers for entry type. */ |
626 |
enum ccs_policy_id { |
627 |
CCS_ID_RESERVEDPORT, |
628 |
CCS_ID_GROUP, |
629 |
CCS_ID_ADDRESS_GROUP, |
630 |
CCS_ID_PATH_GROUP, |
631 |
CCS_ID_NUMBER_GROUP, |
632 |
CCS_ID_AGGREGATOR, |
633 |
CCS_ID_TRANSITION_CONTROL, |
634 |
CCS_ID_MANAGER, |
635 |
CCS_ID_IPV6_ADDRESS, |
636 |
CCS_ID_CONDITION, |
637 |
CCS_ID_NAME, |
638 |
CCS_ID_ACL, |
639 |
CCS_ID_DOMAIN, |
640 |
CCS_MAX_POLICY |
641 |
}; |
642 |
|
643 |
/* Index numbers for /proc/ccs/stat interface. */ |
644 |
enum ccs_policy_stat_type { |
645 |
/* Do not change this order. */ |
646 |
CCS_STAT_POLICY_UPDATES, |
647 |
CCS_STAT_POLICY_LEARNING, /* == CCS_CONFIG_LEARNING */ |
648 |
CCS_STAT_POLICY_PERMISSIVE, /* == CCS_CONFIG_PERMISSIVE */ |
649 |
CCS_STAT_POLICY_ENFORCING, /* == CCS_CONFIG_ENFORCING */ |
650 |
CCS_MAX_POLICY_STAT |
651 |
}; |
652 |
|
653 |
/* Index numbers for profile's PREFERENCE values. */ |
654 |
enum ccs_pref_index { |
655 |
CCS_PREF_MAX_AUDIT_LOG, |
656 |
CCS_PREF_MAX_LEARNING_ENTRY, |
657 |
CCS_PREF_ENFORCING_PENALTY, |
658 |
CCS_MAX_PREF |
659 |
}; |
660 |
|
661 |
/* Index numbers for /proc/ccs/ interfaces. */ |
662 |
enum ccs_proc_interface_index { |
663 |
CCS_DOMAINPOLICY, |
664 |
CCS_EXCEPTIONPOLICY, |
665 |
CCS_DOMAIN_STATUS, |
666 |
CCS_PROCESS_STATUS, |
667 |
CCS_MEMINFO, |
668 |
CCS_STAT, |
669 |
CCS_AUDIT, |
670 |
CCS_VERSION, |
671 |
CCS_PROFILE, |
672 |
CCS_QUERY, |
673 |
CCS_MANAGER, |
674 |
CCS_EXECUTE_HANDLER, |
675 |
}; |
676 |
|
677 |
/* Index numbers for shared entries. */ |
678 |
enum ccs_shared_acl_id { |
679 |
CCS_CONDITION_LIST, |
680 |
CCS_IPV6ADDRESS_LIST, |
681 |
CCS_MAX_LIST |
682 |
}; |
683 |
|
684 |
/* Index numbers for special mount operations. */ |
685 |
enum ccs_special_mount { |
686 |
CCS_MOUNT_BIND, /* mount --bind /source /dest */ |
687 |
CCS_MOUNT_MOVE, /* mount --move /old /new */ |
688 |
CCS_MOUNT_REMOUNT, /* mount -o remount /dir */ |
689 |
CCS_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */ |
690 |
CCS_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */ |
691 |
CCS_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */ |
692 |
CCS_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */ |
693 |
CCS_MAX_SPECIAL_MOUNT |
694 |
}; |
695 |
|
696 |
/* Index numbers for domain transition control keywords. */ |
697 |
enum ccs_transition_type { |
698 |
/* Do not change this order, */ |
699 |
CCS_TRANSITION_CONTROL_NO_INITIALIZE, |
700 |
CCS_TRANSITION_CONTROL_INITIALIZE, |
701 |
CCS_TRANSITION_CONTROL_NO_KEEP, |
702 |
CCS_TRANSITION_CONTROL_KEEP, |
703 |
CCS_MAX_TRANSITION_TYPE |
704 |
}; |
705 |
|
706 |
/* Index numbers for type of numeric values. */ |
707 |
enum ccs_value_type { |
708 |
CCS_VALUE_TYPE_INVALID, |
709 |
CCS_VALUE_TYPE_DECIMAL, |
710 |
CCS_VALUE_TYPE_OCTAL, |
711 |
CCS_VALUE_TYPE_HEXADECIMAL, |
712 |
}; |
713 |
|
714 |
/* Constants definition for internal use. */ |
715 |
|
716 |
/* |
717 |
* TOMOYO uses this hash only when appending a string into the string table. |
718 |
* Frequency of appending strings is very low. So we don't need large (e.g. |
719 |
* 64k) hash size. 256 will be sufficient. |
720 |
*/ |
721 |
#define CCS_HASH_BITS 8 |
722 |
#define CCS_MAX_HASH (1u << CCS_HASH_BITS) |
723 |
|
724 |
/* |
725 |
* TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET. |
726 |
* Therefore, we don't need SOCK_MAX. |
727 |
*/ |
728 |
#define CCS_SOCK_MAX 6 |
729 |
|
730 |
/* A domain definition starts with <kernel>. */ |
731 |
#define CCS_ROOT_NAME "<kernel>" |
732 |
#define CCS_ROOT_NAME_LEN (sizeof(CCS_ROOT_NAME) - 1) |
733 |
|
734 |
/* Size of temporary buffer for execve() operation. */ |
735 |
#define CCS_EXEC_TMPSIZE 4096 |
736 |
|
737 |
/* Profile number is an integer between 0 and 255. */ |
738 |
#define CCS_MAX_PROFILES 256 |
739 |
|
740 |
/* Group number is an integer between 0 and 255. */ |
741 |
#define CCS_MAX_ACL_GROUPS 256 |
742 |
|
743 |
/* Current thread is doing open(O_RDONLY | O_TRUNC) ? */ |
744 |
#define CCS_OPEN_FOR_READ_TRUNCATE 1 |
745 |
/* Current thread is doing open(3) ? */ |
746 |
#define CCS_OPEN_FOR_IOCTL_ONLY 2 |
747 |
/* Current thread is doing do_execve() ? */ |
748 |
#define CCS_TASK_IS_IN_EXECVE 4 |
749 |
/* Current thread is running as an execute handler program? */ |
750 |
#define CCS_TASK_IS_EXECUTE_HANDLER 8 |
751 |
/* Current thread is allowed to modify policy via /proc/ccs/ interface? */ |
752 |
#define CCS_TASK_IS_MANAGER 16 |
753 |
|
754 |
/* |
755 |
* Retry this request. Returned by ccs_supervisor() if policy violation has |
756 |
* occurred in enforcing mode and the userspace daemon decided to retry. |
757 |
* |
758 |
* We must choose a positive value in order to distinguish "granted" (which is |
759 |
* 0) and "rejected" (which is a negative value) and "retry". |
760 |
*/ |
761 |
#define CCS_RETRY_REQUEST 1 |
762 |
|
763 |
/* Ignore gfp flags which are not supported. */ |
764 |
#ifndef __GFP_HIGHIO |
765 |
#define __GFP_HIGHIO 0 |
766 |
#endif |
767 |
#ifndef __GFP_NOWARN |
768 |
#define __GFP_NOWARN 0 |
769 |
#endif |
770 |
#ifndef __GFP_NORETRY |
771 |
#define __GFP_NORETRY 0 |
772 |
#endif |
773 |
#ifndef __GFP_NOMEMALLOC |
774 |
#define __GFP_NOMEMALLOC 0 |
775 |
#endif |
776 |
|
777 |
/* The gfp flags used by TOMOYO. */ |
778 |
#define CCS_GFP_FLAGS (__GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_NOWARN | \ |
779 |
__GFP_NORETRY | __GFP_NOMEMALLOC) |
780 |
|
781 |
/* Size of read buffer for /proc/ccs/ interface. */ |
782 |
#define CCS_MAX_IO_READ_QUEUE 32 |
783 |
|
784 |
/* Structure definition for internal use. */ |
785 |
|
786 |
/* Common header for holding ACL entries. */ |
787 |
struct ccs_acl_head { |
788 |
struct list_head list; |
789 |
bool is_deleted; |
790 |
} __attribute__((__packed__)); |
791 |
|
792 |
/* Common header for shared entries. */ |
793 |
struct ccs_shared_acl_head { |
794 |
struct list_head list; |
795 |
atomic_t users; |
796 |
} __attribute__((__packed__)); |
797 |
|
798 |
/* Common header for individual entries. */ |
799 |
struct ccs_acl_info { |
800 |
struct list_head list; |
801 |
struct ccs_condition *cond; /* Maybe NULL. */ |
802 |
bool is_deleted; |
803 |
u8 type; /* = one of values in "enum ccs_acl_entry_type_index" */ |
804 |
} __attribute__((__packed__)); |
805 |
|
806 |
/* Structure for holding a word. */ |
807 |
struct ccs_name_union { |
808 |
/* Either @filename or @group is NULL. */ |
809 |
const struct ccs_path_info *filename; |
810 |
struct ccs_group *group; |
811 |
/* True if @group != NULL, false if @filename != NULL. */ |
812 |
u8 is_group; |
813 |
}; |
814 |
|
815 |
/* Structure for holding a number. */ |
816 |
struct ccs_number_union { |
817 |
unsigned long values[2]; |
818 |
struct ccs_group *group; /* Maybe NULL. */ |
819 |
/* One of values in "enum ccs_value_type". */ |
820 |
u8 value_type[2]; |
821 |
/* True if @group != NULL, false otherwise. */ |
822 |
u8 is_group; |
823 |
}; |
824 |
|
825 |
/* Structure for "path_group"/"number_group"/"address_group" directive. */ |
826 |
struct ccs_group { |
827 |
struct ccs_shared_acl_head head; |
828 |
/* Name of group (without leading '@'). */ |
829 |
const struct ccs_path_info *group_name; |
830 |
/* |
831 |
* List of "struct ccs_path_group" or "struct ccs_number_group" or |
832 |
* "struct ccs_address_group". |
833 |
*/ |
834 |
struct list_head member_list; |
835 |
}; |
836 |
|
837 |
/* Structure for "path_group" directive. */ |
838 |
struct ccs_path_group { |
839 |
struct ccs_acl_head head; |
840 |
const struct ccs_path_info *member_name; |
841 |
}; |
842 |
|
843 |
/* Structure for "number_group" directive. */ |
844 |
struct ccs_number_group { |
845 |
struct ccs_acl_head head; |
846 |
struct ccs_number_union number; |
847 |
}; |
848 |
|
849 |
/* Structure for "address_group" directive. */ |
850 |
struct ccs_address_group { |
851 |
struct ccs_acl_head head; |
852 |
bool is_ipv6; /* True if IPv6 address, false if IPv4 address. */ |
853 |
union { |
854 |
u32 ipv4; /* Host byte order */ |
855 |
const struct in6_addr *ipv6; /* Network byte order */ |
856 |
} min, max; |
857 |
}; |
858 |
|
859 |
/* Subset of "struct stat". Used by conditional ACL and audit logs. */ |
860 |
struct ccs_mini_stat { |
861 |
uid_t uid; |
862 |
gid_t gid; |
863 |
ino_t ino; |
864 |
mode_t mode; |
865 |
dev_t dev; |
866 |
dev_t rdev; |
867 |
}; |
868 |
|
869 |
/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */ |
870 |
struct ccs_page_dump { |
871 |
struct page *page; /* Previously dumped page. */ |
872 |
char *data; /* Contents of "page". Size is PAGE_SIZE. */ |
873 |
}; |
874 |
|
875 |
/* Structure for attribute checks in addition to pathname checks. */ |
876 |
struct ccs_obj_info { |
877 |
/* True if ccs_get_attributes() was already called, false otherwise. */ |
878 |
bool validate_done; |
879 |
/* True if @stat[] is valid. */ |
880 |
bool stat_valid[CCS_MAX_PATH_STAT]; |
881 |
/* First pathname. Initialized with { NULL, NULL } if no path. */ |
882 |
struct path path1; |
883 |
/* Second pathname. Initialized with { NULL, NULL } if no path. */ |
884 |
struct path path2; |
885 |
/* |
886 |
* Information on @path1, @path1's parent directory, @path2, @path2's |
887 |
* parent directory. |
888 |
*/ |
889 |
struct ccs_mini_stat stat[CCS_MAX_PATH_STAT]; |
890 |
/* |
891 |
* Content of symbolic link to be created. NULL for operations other |
892 |
* than symlink(). |
893 |
*/ |
894 |
struct ccs_path_info *symlink_target; |
895 |
}; |
896 |
|
897 |
/* Structure for entries which follows "struct ccs_condition". */ |
898 |
struct ccs_condition_element { |
899 |
/* |
900 |
* Left hand operand. A "struct ccs_argv" for CCS_ARGV_ENTRY, a |
901 |
* "struct ccs_envp" for CCS_ENVP_ENTRY is attached to the tail |
902 |
* of the array of this struct. |
903 |
*/ |
904 |
u8 left; |
905 |
/* |
906 |
* Right hand operand. A "struct ccs_number_union" for |
907 |
* CCS_NUMBER_UNION, a "struct ccs_name_union" for CCS_NAME_UNION is |
908 |
* attached to the tail of the array of this struct. |
909 |
*/ |
910 |
u8 right; |
911 |
/* Equation operator. True if equals or overlaps, false otherwise. */ |
912 |
bool equals; |
913 |
}; |
914 |
|
915 |
/* Structure for optional arguments. */ |
916 |
struct ccs_condition { |
917 |
struct ccs_shared_acl_head head; |
918 |
u32 size; /* Memory size allocated for this entry. */ |
919 |
u16 condc; /* Number of conditions in this struct. */ |
920 |
u16 numbers_count; /* Number of "struct ccs_number_union values". */ |
921 |
u16 names_count; /* Number of "struct ccs_name_union names". */ |
922 |
u16 argc; /* Number of "struct ccs_argv". */ |
923 |
u16 envc; /* Number of "struct ccs_envp". */ |
924 |
u8 grant_log; /* One of values in "enum ccs_grant_log". */ |
925 |
const struct ccs_path_info *transit; /* Maybe NULL. */ |
926 |
/* |
927 |
* struct ccs_condition_element condition[condc]; |
928 |
* struct ccs_number_union values[numbers_count]; |
929 |
* struct ccs_name_union names[names_count]; |
930 |
* struct ccs_argv argv[argc]; |
931 |
* struct ccs_envp envp[envc]; |
932 |
*/ |
933 |
}; |
934 |
|
935 |
struct ccs_execve; |
936 |
|
937 |
/* Structure for request info. */ |
938 |
struct ccs_request_info { |
939 |
/* |
940 |
* For holding parameters specific to operations which deal files. |
941 |
* NULL if not dealing files. |
942 |
*/ |
943 |
struct ccs_obj_info *obj; |
944 |
/* |
945 |
* For holding parameters specific to execve() request. |
946 |
* NULL if not dealing do_execve(). |
947 |
*/ |
948 |
struct ccs_execve *ee; |
949 |
/* |
950 |
* For holding parameters. |
951 |
* Pointers in this union are not NULL except path->matched_path. |
952 |
*/ |
953 |
union { |
954 |
struct { |
955 |
const struct ccs_path_info *filename; |
956 |
/* |
957 |
* For using wildcards at ccs_find_next_domain(). |
958 |
* |
959 |
* The matched_acl cannot be used because it may refer |
960 |
* a "struct ccs_path_acl" with ->is_group == true. |
961 |
* We want to use exact "struct ccs_path_info" rather |
962 |
* than "struct ccs_path_acl". |
963 |
*/ |
964 |
const struct ccs_path_info *matched_path; |
965 |
/* One of values in "enum ccs_path_acl_index". */ |
966 |
u8 operation; |
967 |
} path; |
968 |
struct { |
969 |
const struct ccs_path_info *filename1; |
970 |
const struct ccs_path_info *filename2; |
971 |
/* One of values in "enum ccs_path2_acl_index". */ |
972 |
u8 operation; |
973 |
} path2; |
974 |
struct { |
975 |
const struct ccs_path_info *filename; |
976 |
unsigned int mode; |
977 |
unsigned int major; |
978 |
unsigned int minor; |
979 |
/* One of values in "enum ccs_mkdev_acl_index". */ |
980 |
u8 operation; |
981 |
} mkdev; |
982 |
struct { |
983 |
const struct ccs_path_info *filename; |
984 |
unsigned long number; |
985 |
/* |
986 |
* One of values in "enum ccs_path_number_acl_index". |
987 |
*/ |
988 |
u8 operation; |
989 |
} path_number; |
990 |
struct { |
991 |
const u32 *address; |
992 |
u32 ip; |
993 |
u16 port; |
994 |
/* One of values smaller than CCS_SOCK_MAX. */ |
995 |
u8 protocol; |
996 |
/* One of values in "enum ccs_network_acl_index". */ |
997 |
u8 operation; |
998 |
bool is_ipv6; |
999 |
} inet_network; |
1000 |
struct { |
1001 |
const struct ccs_path_info *address; |
1002 |
/* One of values smaller than CCS_SOCK_MAX. */ |
1003 |
u8 protocol; |
1004 |
/* One of values in "enum ccs_network_acl_index". */ |
1005 |
u8 operation; |
1006 |
} unix_network; |
1007 |
struct { |
1008 |
const struct ccs_path_info *name; |
1009 |
} environ; |
1010 |
struct { |
1011 |
/* One of values in "enum ccs_capability_acl_index". */ |
1012 |
u8 operation; |
1013 |
} capability; |
1014 |
struct { |
1015 |
const char *dest_pattern; |
1016 |
int sig; |
1017 |
} signal; |
1018 |
struct { |
1019 |
const struct ccs_path_info *type; |
1020 |
const struct ccs_path_info *dir; |
1021 |
const struct ccs_path_info *dev; |
1022 |
unsigned long flags; |
1023 |
int need_dev; |
1024 |
} mount; |
1025 |
struct { |
1026 |
const struct ccs_path_info *domainname; |
1027 |
} task; |
1028 |
} param; |
1029 |
u8 param_type; /* One of values in "enum ccs_acl_entry_type_index". */ |
1030 |
bool granted; /* True if granted, false otherwise. */ |
1031 |
/* True if current thread should not be carried sleep penalty. */ |
1032 |
bool dont_sleep_on_enforce_error; |
1033 |
/* |
1034 |
* For updating current->ccs_domain_info at ccs_update_task_domain(). |
1035 |
* Initialized to NULL at ccs_init_request_info(). |
1036 |
* Matching "struct ccs_acl_info" is copied if access request was |
1037 |
* granted. Re-initialized to NULL at ccs_update_task_domain(). |
1038 |
*/ |
1039 |
struct ccs_acl_info *matched_acl; |
1040 |
/* |
1041 |
* For counting number of retries made for this request. |
1042 |
* This counter is incremented whenever ccs_supervisor() returned |
1043 |
* CCS_RETRY_REQUEST. |
1044 |
*/ |
1045 |
u8 retry; |
1046 |
/* |
1047 |
* For holding profile number used for this request. |
1048 |
* One of values between 0 and CCS_MAX_PROFILES - 1. |
1049 |
*/ |
1050 |
u8 profile; |
1051 |
/* |
1052 |
* For holding operation mode used for this request. |
1053 |
* One of CCS_CONFIG_DISABLED, CCS_CONFIG_LEARNING, |
1054 |
* CCS_CONFIG_PERMISSIVE, CCS_CONFIG_ENFORCING. |
1055 |
*/ |
1056 |
u8 mode; |
1057 |
/* |
1058 |
* For holding operation index used for this request. |
1059 |
* Used by ccs_init_request_info() / ccs_get_mode() / |
1060 |
* ccs_write_log(). One of values in "enum ccs_mac_index". |
1061 |
*/ |
1062 |
u8 type; |
1063 |
}; |
1064 |
|
1065 |
/* Structure for holding a token. */ |
1066 |
struct ccs_path_info { |
1067 |
const char *name; |
1068 |
u32 hash; /* = full_name_hash(name, strlen(name)) */ |
1069 |
u16 total_len; /* = strlen(name) */ |
1070 |
u16 const_len; /* = ccs_const_part_length(name) */ |
1071 |
bool is_dir; /* = ccs_strendswith(name, "/") */ |
1072 |
bool is_patterned; /* = const_len < total_len */ |
1073 |
}; |
1074 |
|
1075 |
/* Structure for execve() operation. */ |
1076 |
struct ccs_execve { |
1077 |
struct ccs_request_info r; |
1078 |
struct ccs_obj_info obj; |
1079 |
struct linux_binprm *bprm; |
1080 |
struct ccs_domain_info *previous_domain; |
1081 |
int reader_idx; |
1082 |
/* For execute_handler */ |
1083 |
const struct ccs_path_info *handler; |
1084 |
char *handler_path; /* = kstrdup(handler->name, CCS_GFP_FLAGS) */ |
1085 |
/* For dumping argv[] and envp[]. */ |
1086 |
struct ccs_page_dump dump; |
1087 |
/* For temporary use. */ |
1088 |
char *tmp; /* Size is CCS_EXEC_TMPSIZE bytes */ |
1089 |
}; |
1090 |
|
1091 |
/* Structure for domain information. */ |
1092 |
struct ccs_domain_info { |
1093 |
struct list_head list; |
1094 |
struct list_head acl_info_list[2]; |
1095 |
/* Name of this domain. Never NULL. */ |
1096 |
const struct ccs_path_info *domainname; |
1097 |
u8 profile; /* Profile number to use. */ |
1098 |
u8 group; |
1099 |
bool is_deleted; /* Delete flag. */ |
1100 |
bool flags[CCS_MAX_DOMAIN_INFO_FLAGS]; |
1101 |
}; |
1102 |
|
1103 |
/* |
1104 |
* Structure for "initialize_domain"/"no_initialize_domain" and |
1105 |
* "keep_domain"/"no_keep_domain" keyword. |
1106 |
*/ |
1107 |
struct ccs_transition_control { |
1108 |
struct ccs_acl_head head; |
1109 |
u8 type; /* = one of values in "enum ccs_transition_type" */ |
1110 |
bool is_last_name; /* True if the domainname is ccs_last_word(). */ |
1111 |
const struct ccs_path_info *domainname; |
1112 |
const struct ccs_path_info *program; |
1113 |
}; |
1114 |
|
1115 |
/* Structure for "aggregator" keyword. */ |
1116 |
struct ccs_aggregator { |
1117 |
struct ccs_acl_head head; |
1118 |
const struct ccs_path_info *original_name; |
1119 |
const struct ccs_path_info *aggregated_name; |
1120 |
}; |
1121 |
|
1122 |
/* Structure for "deny_autobind" keyword. */ |
1123 |
struct ccs_reserved { |
1124 |
struct ccs_acl_head head; |
1125 |
u16 min_port; /* Start of port number range. */ |
1126 |
u16 max_port; /* End of port number range. */ |
1127 |
}; |
1128 |
|
1129 |
/* Structure for policy manager. */ |
1130 |
struct ccs_manager { |
1131 |
struct ccs_acl_head head; |
1132 |
bool is_domain; /* True if manager is a domainname. */ |
1133 |
/* A path to program or a domainname. */ |
1134 |
const struct ccs_path_info *manager; |
1135 |
}; |
1136 |
|
1137 |
/* Structure for argv[]. */ |
1138 |
struct ccs_argv { |
1139 |
unsigned int index; |
1140 |
const struct ccs_path_info *value; |
1141 |
bool is_not; |
1142 |
}; |
1143 |
|
1144 |
/* Structure for envp[]. */ |
1145 |
struct ccs_envp { |
1146 |
const struct ccs_path_info *name; |
1147 |
const struct ccs_path_info *value; |
1148 |
bool is_not; |
1149 |
}; |
1150 |
|
1151 |
/* |
1152 |
* Structure for "task auto_execute_handler" and "task denied_execute_handler" |
1153 |
* directive. |
1154 |
* |
1155 |
* If "task auto_execute_handler" directive exists and the current process is |
1156 |
* not an execute handler, all execve() requests are replaced by execve() |
1157 |
* requests of a program specified by "task auto_execute_handler" directive. |
1158 |
* If the current process is an execute handler, "task auto_execute_handler" |
1159 |
* and "task denied_execute_handler" directives are ignored. |
1160 |
* The program specified by "task execute_handler" validates execve() |
1161 |
* parameters and executes the original execve() requests if appropriate. |
1162 |
* |
1163 |
* "task denied_execute_handler" directive is used only when execve() request |
1164 |
* was rejected in enforcing mode (i.e. CONFIG::file::execute={ mode=enforcing |
1165 |
* }). The program specified by "task denied_execute_handler" does whatever it |
1166 |
* wants to do (e.g. silently terminate, change firewall settings, redirect the |
1167 |
* user to honey pot etc.). |
1168 |
*/ |
1169 |
struct ccs_handler_acl { |
1170 |
struct ccs_acl_info head; /* type = CCS_TYPE_*_EXECUTE_HANDLER */ |
1171 |
const struct ccs_path_info *handler; /* Pointer to single pathname. */ |
1172 |
}; |
1173 |
|
1174 |
/* |
1175 |
* Structure for "task auto_domain_transition" and |
1176 |
* "task manual_domain_transition" directive. |
1177 |
*/ |
1178 |
struct ccs_task_acl { |
1179 |
struct ccs_acl_info head; /* type = CCS_TYPE_*_TASK_ACL */ |
1180 |
/* Pointer to domainname. */ |
1181 |
const struct ccs_path_info *domainname; |
1182 |
}; |
1183 |
|
1184 |
/* |
1185 |
* Structure for "file execute", "file read", "file write", "file append", |
1186 |
* "file unlink", "file getattr", "file rmdir", "file truncate", |
1187 |
* "file symlink", "file chroot" and "file unmount" directive. |
1188 |
*/ |
1189 |
struct ccs_path_acl { |
1190 |
struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */ |
1191 |
u16 perm; /* Bitmask of values in "enum ccs_path_acl_index". */ |
1192 |
struct ccs_name_union name; |
1193 |
}; |
1194 |
|
1195 |
/* |
1196 |
* Structure for "file rename", "file link" and "file pivot_root" directive. |
1197 |
*/ |
1198 |
struct ccs_path2_acl { |
1199 |
struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */ |
1200 |
u8 perm; /* Bitmask of values in "enum ccs_path2_acl_index". */ |
1201 |
struct ccs_name_union name1; |
1202 |
struct ccs_name_union name2; |
1203 |
}; |
1204 |
|
1205 |
/* |
1206 |
* Structure for "file create", "file mkdir", "file mkfifo", "file mksock", |
1207 |
* "file ioctl", "file chmod", "file chown" and "file chgrp" directive. |
1208 |
*/ |
1209 |
struct ccs_path_number_acl { |
1210 |
struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */ |
1211 |
u8 perm; /* Bitmask of values in "enum ccs_path_number_acl_index". */ |
1212 |
struct ccs_name_union name; |
1213 |
struct ccs_number_union number; |
1214 |
}; |
1215 |
|
1216 |
/* Structure for "file mkblock" and "file mkchar" directive. */ |
1217 |
struct ccs_mkdev_acl { |
1218 |
struct ccs_acl_info head; /* type = CCS_TYPE_MKDEV_ACL */ |
1219 |
u8 perm; /* Bitmask of values in "enum ccs_mkdev_acl_index". */ |
1220 |
struct ccs_name_union name; |
1221 |
struct ccs_number_union mode; |
1222 |
struct ccs_number_union major; |
1223 |
struct ccs_number_union minor; |
1224 |
}; |
1225 |
|
1226 |
/* Structure for "file mount" directive. */ |
1227 |
struct ccs_mount_acl { |
1228 |
struct ccs_acl_info head; /* type = CCS_TYPE_MOUNT_ACL */ |
1229 |
struct ccs_name_union dev_name; |
1230 |
struct ccs_name_union dir_name; |
1231 |
struct ccs_name_union fs_type; |
1232 |
struct ccs_number_union flags; |
1233 |
}; |
1234 |
|
1235 |
/* Structure for "misc env" directive in domain policy. */ |
1236 |
struct ccs_env_acl { |
1237 |
struct ccs_acl_info head; /* type = CCS_TYPE_ENV_ACL */ |
1238 |
const struct ccs_path_info *env; /* environment variable */ |
1239 |
}; |
1240 |
|
1241 |
/* Structure for "capability" directive. */ |
1242 |
struct ccs_capability_acl { |
1243 |
struct ccs_acl_info head; /* type = CCS_TYPE_CAPABILITY_ACL */ |
1244 |
u8 operation; /* one of values in "enum ccs_capability_acl_index". */ |
1245 |
}; |
1246 |
|
1247 |
/* Structure for "ipc signal" directive. */ |
1248 |
struct ccs_signal_acl { |
1249 |
struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */ |
1250 |
u16 sig; |
1251 |
/* Pointer to destination pattern. */ |
1252 |
const struct ccs_path_info *domainname; |
1253 |
}; |
1254 |
|
1255 |
/* Structure for holding an IPv6 address. */ |
1256 |
struct ccs_ipv6addr { |
1257 |
struct ccs_shared_acl_head head; |
1258 |
struct in6_addr addr; |
1259 |
}; |
1260 |
|
1261 |
/* Structure for "network inet" directive. */ |
1262 |
struct ccs_inet_acl { |
1263 |
struct ccs_acl_info head; /* type = CCS_TYPE_INET_ACL */ |
1264 |
u8 protocol; |
1265 |
u8 perm; /* Bitmask of values in "enum ccs_network_acl_index" */ |
1266 |
/* |
1267 |
* address_type takes one of the following constants. |
1268 |
* CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP |
1269 |
* if @address points to "address_group" directive. |
1270 |
* CCS_IP_ADDRESS_TYPE_IPv4 |
1271 |
* if @address points to an IPv4 address. |
1272 |
* CCS_IP_ADDRESS_TYPE_IPv6 |
1273 |
* if @address points to an IPv6 address. |
1274 |
*/ |
1275 |
u8 address_type; |
1276 |
union { |
1277 |
struct { |
1278 |
/* Start of IPv4 address range. Host endian. */ |
1279 |
u32 min; |
1280 |
/* End of IPv4 address range. Host endian. */ |
1281 |
u32 max; |
1282 |
} ipv4; |
1283 |
struct { |
1284 |
/* Start of IPv6 address range. Big endian. */ |
1285 |
const struct in6_addr *min; |
1286 |
/* End of IPv6 address range. Big endian. */ |
1287 |
const struct in6_addr *max; |
1288 |
} ipv6; |
1289 |
/* Pointer to address group. */ |
1290 |
struct ccs_group *group; |
1291 |
} address; |
1292 |
struct ccs_number_union port; |
1293 |
}; |
1294 |
|
1295 |
/* Structure for "network unix" directive. */ |
1296 |
struct ccs_unix_acl { |
1297 |
struct ccs_acl_info head; /* type = CCS_TYPE_UNIX_ACL */ |
1298 |
u8 protocol; |
1299 |
u8 perm; /* Bitmask of values in "enum ccs_network_acl_index" */ |
1300 |
struct ccs_name_union name; |
1301 |
}; |
1302 |
|
1303 |
/* Structure for holding string data. */ |
1304 |
struct ccs_name { |
1305 |
struct ccs_shared_acl_head head; |
1306 |
int size; /* Memory size allocated for this entry. */ |
1307 |
struct ccs_path_info entry; |
1308 |
}; |
1309 |
|
1310 |
/* Structure for holding a line from /proc/ccs/ interface. */ |
1311 |
struct ccs_acl_param { |
1312 |
char *data; |
1313 |
struct ccs_domain_info *domain; |
1314 |
bool is_delete; |
1315 |
}; |
1316 |
|
1317 |
/* Structure for reading/writing policy via /proc/ccs/ interfaces. */ |
1318 |
struct ccs_io_buffer { |
1319 |
void (*read) (struct ccs_io_buffer *); |
1320 |
int (*write) (struct ccs_io_buffer *); |
1321 |
int (*poll) (struct file *file, poll_table *wait); |
1322 |
/* Exclusive lock for this structure. */ |
1323 |
struct mutex io_sem; |
1324 |
char __user *read_user_buf; |
1325 |
size_t read_user_buf_avail; |
1326 |
struct { |
1327 |
struct list_head *domain; |
1328 |
struct list_head *group; |
1329 |
struct list_head *acl; |
1330 |
size_t avail; |
1331 |
unsigned int step; |
1332 |
unsigned int query_index; |
1333 |
u16 index; |
1334 |
u16 cond_index; |
1335 |
u8 acl_group_index; |
1336 |
u8 cond_step; |
1337 |
u8 bit; |
1338 |
u8 w_pos; |
1339 |
bool eof; |
1340 |
bool print_this_domain_only; |
1341 |
bool print_transition_related_only; |
1342 |
bool print_cond_part; |
1343 |
const char *w[CCS_MAX_IO_READ_QUEUE]; |
1344 |
} r; |
1345 |
struct { |
1346 |
struct ccs_domain_info *domain; |
1347 |
size_t avail; |
1348 |
} w; |
1349 |
/* Buffer for reading. */ |
1350 |
char *read_buf; |
1351 |
/* Size of read buffer. */ |
1352 |
size_t readbuf_size; |
1353 |
/* Buffer for writing. */ |
1354 |
char *write_buf; |
1355 |
/* Size of write buffer. */ |
1356 |
size_t writebuf_size; |
1357 |
/* Type of interface. */ |
1358 |
enum ccs_proc_interface_index type; |
1359 |
/* Users counter protected by ccs_io_buffer_list_lock. */ |
1360 |
u8 users; |
1361 |
/* List for telling GC not to kfree() elements. */ |
1362 |
struct list_head list; |
1363 |
}; |
1364 |
|
1365 |
/* Structure for /proc/ccs/profile interface. */ |
1366 |
struct ccs_profile { |
1367 |
const struct ccs_path_info *comment; |
1368 |
u8 default_config; |
1369 |
u8 config[CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX]; |
1370 |
unsigned int pref[CCS_MAX_PREF]; |
1371 |
}; |
1372 |
|
1373 |
/* Structure for representing YYYY/MM/DD hh/mm/ss. */ |
1374 |
struct ccs_time { |
1375 |
u16 year; |
1376 |
u8 month; |
1377 |
u8 day; |
1378 |
u8 hour; |
1379 |
u8 min; |
1380 |
u8 sec; |
1381 |
}; |
1382 |
|
1383 |
/* Prototype definition for "struct ccsecurity_operations". */ |
1384 |
|
1385 |
void __init ccs_capability_init(void); |
1386 |
void __init ccs_domain_init(void); |
1387 |
void __init ccs_file_init(void); |
1388 |
void __init ccs_mm_init(void); |
1389 |
void __init ccs_mount_init(void); |
1390 |
void __init ccs_network_init(void); |
1391 |
void __init ccs_policy_io_init(void); |
1392 |
void __init ccs_signal_init(void); |
1393 |
|
1394 |
/* Prototype definition for internal use. */ |
1395 |
|
1396 |
bool ccs_address_matches_group(const bool is_ipv6, const u32 *address, |
1397 |
const struct ccs_group *group); |
1398 |
bool ccs_compare_number_union(const unsigned long value, |
1399 |
const struct ccs_number_union *ptr); |
1400 |
bool ccs_condition(struct ccs_request_info *r, |
1401 |
const struct ccs_condition *cond); |
1402 |
bool ccs_correct_domain(const unsigned char *domainname); |
1403 |
bool ccs_correct_path(const char *filename); |
1404 |
bool ccs_correct_word(const char *string); |
1405 |
bool ccs_domain_def(const unsigned char *buffer); |
1406 |
bool ccs_domain_quota_ok(struct ccs_request_info *r); |
1407 |
bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos, |
1408 |
struct ccs_page_dump *dump); |
1409 |
bool ccs_memory_ok(const void *ptr, const unsigned int size); |
1410 |
bool ccs_number_matches_group(const unsigned long min, const unsigned long max, |
1411 |
const struct ccs_group *group); |
1412 |
bool ccs_parse_name_union(const char *filename, struct ccs_name_union *ptr); |
1413 |
bool ccs_parse_number_union(char *data, struct ccs_number_union *num); |
1414 |
bool ccs_path_matches_pattern(const struct ccs_path_info *filename, |
1415 |
const struct ccs_path_info *pattern); |
1416 |
bool ccs_permstr(const char *string, const char *keyword); |
1417 |
bool ccs_str_starts(char **src, const char *find); |
1418 |
bool ccs_tokenize(char *buffer, char *w[], size_t size); |
1419 |
char *ccs_encode(const char *str); |
1420 |
char *ccs_encode2(const char *str, int str_len); |
1421 |
char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt, |
1422 |
va_list args); |
1423 |
char *ccs_read_token(struct ccs_acl_param *param); |
1424 |
char *ccs_realpath_from_path(struct path *path); |
1425 |
const char *ccs_yesno(const unsigned int value); |
1426 |
const char *ccs_get_exe(void); |
1427 |
const struct ccs_path_info *ccs_compare_name_union |
1428 |
(const struct ccs_path_info *name, const struct ccs_name_union *ptr); |
1429 |
const struct ccs_path_info *ccs_get_domainname(struct ccs_acl_param *param); |
1430 |
const struct ccs_path_info *ccs_get_name(const char *name); |
1431 |
const struct ccs_path_info *ccs_path_matches_group |
1432 |
(const struct ccs_path_info *pathname, const struct ccs_group *group); |
1433 |
const struct in6_addr *ccs_get_ipv6_address(const struct in6_addr *addr); |
1434 |
int ccs_close_control(struct file *file); |
1435 |
int ccs_delete_domain(char *data); |
1436 |
int ccs_env_perm(struct ccs_request_info *r, const char *env); |
1437 |
int ccs_get_path(const char *pathname, struct path *path); |
1438 |
int ccs_init_request_info(struct ccs_request_info *r, const u8 index); |
1439 |
int ccs_open_control(const u8 type, struct file *file); |
1440 |
int ccs_parse_ip_address(char *address, u16 *min, u16 *max); |
1441 |
int ccs_path_permission(struct ccs_request_info *r, u8 operation, |
1442 |
const struct ccs_path_info *filename); |
1443 |
int ccs_poll_control(struct file *file, poll_table *wait); |
1444 |
int ccs_poll_log(struct file *file, poll_table *wait); |
1445 |
int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...) |
1446 |
__attribute__ ((format(printf, 2, 3))); |
1447 |
int ccs_symlink_path(const char *pathname, struct ccs_path_info *name); |
1448 |
int ccs_update_domain(struct ccs_acl_info *new_entry, const int size, |
1449 |
struct ccs_acl_param *param, |
1450 |
bool (*check_duplicate) (const struct ccs_acl_info *, |
1451 |
const struct ccs_acl_info *), |
1452 |
bool (*merge_duplicate) (struct ccs_acl_info *, |
1453 |
struct ccs_acl_info *, |
1454 |
const bool)); |
1455 |
int ccs_update_policy(struct ccs_acl_head *new_entry, const int size, |
1456 |
bool is_delete, struct list_head *list, |
1457 |
bool (*check_duplicate) (const struct ccs_acl_head *, |
1458 |
const struct ccs_acl_head *)); |
1459 |
int ccs_write_aggregator(char *data, const bool is_delete); |
1460 |
int ccs_write_capability(struct ccs_acl_param *param); |
1461 |
int ccs_write_file(struct ccs_acl_param *param); |
1462 |
int ccs_write_group(char *data, const bool is_delete, const u8 type); |
1463 |
int ccs_write_inet_network(struct ccs_acl_param *param); |
1464 |
int ccs_write_ipc(struct ccs_acl_param *param); |
1465 |
int ccs_write_misc(struct ccs_acl_param *param); |
1466 |
int ccs_write_reserved_port(char *data, const bool is_delete); |
1467 |
int ccs_write_transition_control(char *data, const bool is_delete, |
1468 |
const u8 type); |
1469 |
int ccs_write_unix_network(struct ccs_acl_param *param); |
1470 |
ssize_t ccs_read_control(struct file *file, char __user *buffer, |
1471 |
const size_t buffer_len); |
1472 |
ssize_t ccs_write_control(struct file *file, const char __user *buffer, |
1473 |
const size_t buffer_len); |
1474 |
struct ccs_condition *ccs_get_condition(char *condition); |
1475 |
struct ccs_domain_info *ccs_assign_domain(const char *domainname, |
1476 |
const u8 profile, const u8 group, |
1477 |
const bool transit); |
1478 |
struct ccs_domain_info *ccs_find_domain(const char *domainname); |
1479 |
struct ccs_group *ccs_get_group(const char *group_name, const u8 idx); |
1480 |
struct ccs_profile *ccs_profile(const u8 profile); |
1481 |
u8 ccs_get_config(const u8 profile, const u8 index); |
1482 |
u8 ccs_parse_ulong(unsigned long *result, char **str); |
1483 |
void *ccs_commit_ok(void *data, const unsigned int size); |
1484 |
void ccs_check_acl(struct ccs_request_info *r, |
1485 |
bool (*check_entry) (struct ccs_request_info *, |
1486 |
const struct ccs_acl_info *)); |
1487 |
void ccs_convert_time(time_t time, struct ccs_time *p); |
1488 |
void ccs_del_condition(struct list_head *element); |
1489 |
void ccs_fill_path_info(struct ccs_path_info *ptr); |
1490 |
void ccs_get_attributes(struct ccs_obj_info *obj); |
1491 |
void ccs_memory_free(const void *ptr, size_t size); |
1492 |
void ccs_normalize_line(unsigned char *buffer); |
1493 |
void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register); |
1494 |
void ccs_print_ipv4(char *buffer, const int buffer_len, const u32 min_ip, |
1495 |
const u32 max_ip); |
1496 |
void ccs_print_ipv6(char *buffer, const int buffer_len, |
1497 |
const struct in6_addr *min_ip, |
1498 |
const struct in6_addr *max_ip); |
1499 |
void ccs_print_ulong(char *buffer, const int buffer_len, |
1500 |
const unsigned long value, const u8 type); |
1501 |
void ccs_put_name_union(struct ccs_name_union *ptr); |
1502 |
void ccs_put_number_union(struct ccs_number_union *ptr); |
1503 |
void ccs_read_log(struct ccs_io_buffer *head); |
1504 |
void ccs_transition_failed(const char *domainname); |
1505 |
void ccs_update_stat(const u8 index); |
1506 |
void ccs_warn_oom(const char *function); |
1507 |
void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...) |
1508 |
__attribute__ ((format(printf, 2, 3))); |
1509 |
void ccs_write_log2(struct ccs_request_info *r, int len, const char *fmt, |
1510 |
va_list args); |
1511 |
#ifdef CONFIG_CCSECURITY_USE_BUILTIN_POLICY |
1512 |
void __init ccs_load_builtin_policy(void); |
1513 |
#endif |
1514 |
|
1515 |
/* Variable definition for internal use. */ |
1516 |
|
1517 |
extern bool ccs_policy_loaded; |
1518 |
extern const char * const ccs_condition_keyword[CCS_MAX_CONDITION_KEYWORD]; |
1519 |
extern const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS]; |
1520 |
extern const char * const ccs_mac_keywords[CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX]; |
1521 |
extern const char * const ccs_mode[CCS_CONFIG_MAX_MODE]; |
1522 |
extern const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION]; |
1523 |
extern const char * const ccs_proto_keyword[CCS_SOCK_MAX]; |
1524 |
extern const char * const ccs_socket_keyword[CCS_MAX_NETWORK_OPERATION]; |
1525 |
extern const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX]; |
1526 |
extern const u8 ccs_index2category[CCS_MAX_MAC_INDEX]; |
1527 |
extern const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION]; |
1528 |
extern const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION]; |
1529 |
extern const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION]; |
1530 |
extern struct ccs_domain_info ccs_acl_group[CCS_MAX_ACL_GROUPS]; |
1531 |
extern struct ccs_domain_info ccs_kernel_domain; |
1532 |
extern struct list_head ccs_domain_list; |
1533 |
extern struct list_head ccs_group_list[CCS_MAX_GROUP]; |
1534 |
extern struct list_head ccs_name_list[CCS_MAX_HASH]; |
1535 |
extern struct list_head ccs_policy_list[CCS_MAX_POLICY]; |
1536 |
extern struct list_head ccs_shared_list[CCS_MAX_LIST]; |
1537 |
extern struct mutex ccs_policy_lock; |
1538 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) |
1539 |
extern struct srcu_struct ccs_ss; |
1540 |
#endif |
1541 |
extern unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT]; |
1542 |
extern unsigned int ccs_memory_used[CCS_MAX_MEMORY_STAT]; |
1543 |
|
1544 |
/* Inlined functions for internal use. */ |
1545 |
|
1546 |
/** |
1547 |
* ccs_pathcmp - strcmp() for "struct ccs_path_info" structure. |
1548 |
* |
1549 |
* @a: Pointer to "struct ccs_path_info". |
1550 |
* @b: Pointer to "struct ccs_path_info". |
1551 |
* |
1552 |
* Returns true if @a == @b, false otherwise. |
1553 |
*/ |
1554 |
static inline bool ccs_pathcmp(const struct ccs_path_info *a, |
1555 |
const struct ccs_path_info *b) |
1556 |
{ |
1557 |
return a->hash != b->hash || strcmp(a->name, b->name); |
1558 |
} |
1559 |
|
1560 |
/** |
1561 |
* ccs_same_name_union - Check for duplicated "struct ccs_name_union" entry. |
1562 |
* |
1563 |
* @a: Pointer to "struct ccs_name_union". |
1564 |
* @b: Pointer to "struct ccs_name_union". |
1565 |
* |
1566 |
* Returns true if @a == @b, false otherwise. |
1567 |
*/ |
1568 |
static inline bool ccs_same_name_union(const struct ccs_name_union *a, |
1569 |
const struct ccs_name_union *b) |
1570 |
{ |
1571 |
return a->filename == b->filename && a->group == b->group && |
1572 |
a->is_group == b->is_group; |
1573 |
} |
1574 |
|
1575 |
/** |
1576 |
* ccs_same_number_union - Check for duplicated "struct ccs_number_union" entry. |
1577 |
* |
1578 |
* @a: Pointer to "struct ccs_number_union". |
1579 |
* @b: Pointer to "struct ccs_number_union". |
1580 |
* |
1581 |
* Returns true if @a == @b, false otherwise. |
1582 |
*/ |
1583 |
static inline bool ccs_same_number_union(const struct ccs_number_union *a, |
1584 |
const struct ccs_number_union *b) |
1585 |
{ |
1586 |
return a->values[0] == b->values[0] && a->values[1] == b->values[1] |
1587 |
&& a->group == b->group && |
1588 |
a->value_type[0] == b->value_type[0] && |
1589 |
a->value_type[1] == b->value_type[1] && |
1590 |
a->is_group == b->is_group; |
1591 |
} |
1592 |
|
1593 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) |
1594 |
|
1595 |
/** |
1596 |
* ccs_read_lock - Take lock for protecting policy. |
1597 |
* |
1598 |
* Returns index number for ccs_read_unlock(). |
1599 |
*/ |
1600 |
static inline int ccs_read_lock(void) |
1601 |
{ |
1602 |
return srcu_read_lock(&ccs_ss); |
1603 |
} |
1604 |
|
1605 |
/** |
1606 |
* ccs_read_unlock - Release lock for protecting policy. |
1607 |
* |
1608 |
* @idx: Index number returned by ccs_read_lock(). |
1609 |
* |
1610 |
* Returns nothing. |
1611 |
*/ |
1612 |
static inline void ccs_read_unlock(const int idx) |
1613 |
{ |
1614 |
srcu_read_unlock(&ccs_ss, idx); |
1615 |
} |
1616 |
|
1617 |
#else |
1618 |
|
1619 |
int ccs_lock(void); |
1620 |
void ccs_unlock(const int idx); |
1621 |
|
1622 |
/** |
1623 |
* ccs_read_lock - Take lock for protecting policy. |
1624 |
* |
1625 |
* Returns index number for ccs_read_unlock(). |
1626 |
*/ |
1627 |
static inline int ccs_read_lock(void) |
1628 |
{ |
1629 |
return ccs_lock(); |
1630 |
} |
1631 |
|
1632 |
/** |
1633 |
* ccs_read_unlock - Release lock for protecting policy. |
1634 |
* |
1635 |
* @idx: Index number returned by ccs_read_lock(). |
1636 |
* |
1637 |
* Returns nothing. |
1638 |
*/ |
1639 |
static inline void ccs_read_unlock(const int idx) |
1640 |
{ |
1641 |
ccs_unlock(idx); |
1642 |
} |
1643 |
|
1644 |
#endif |
1645 |
|
1646 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) |
1647 |
|
1648 |
/** |
1649 |
* ccs_tasklist_lock - Take lock for reading list of "struct task_struct". |
1650 |
* |
1651 |
* Returns nothing. |
1652 |
*/ |
1653 |
static inline void ccs_tasklist_lock(void) |
1654 |
{ |
1655 |
rcu_read_lock(); |
1656 |
} |
1657 |
|
1658 |
/** |
1659 |
* ccs_tasklist_unlock - Release lock for reading list of "struct task_struct". |
1660 |
* |
1661 |
* Returns nothing. |
1662 |
*/ |
1663 |
static inline void ccs_tasklist_unlock(void) |
1664 |
{ |
1665 |
rcu_read_unlock(); |
1666 |
} |
1667 |
|
1668 |
#else |
1669 |
|
1670 |
/** |
1671 |
* ccs_tasklist_lock - Take lock for reading list of "struct task_struct". |
1672 |
* |
1673 |
* Returns nothing. |
1674 |
*/ |
1675 |
static inline void ccs_tasklist_lock(void) |
1676 |
{ |
1677 |
read_lock(&tasklist_lock); |
1678 |
} |
1679 |
|
1680 |
/** |
1681 |
* ccs_tasklist_unlock - Release lock for reading list of "struct task_struct". |
1682 |
* |
1683 |
* Returns nothing. |
1684 |
*/ |
1685 |
static inline void ccs_tasklist_unlock(void) |
1686 |
{ |
1687 |
read_unlock(&tasklist_lock); |
1688 |
} |
1689 |
|
1690 |
#endif |
1691 |
|
1692 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
1693 |
|
1694 |
/** |
1695 |
* ccs_sys_getppid - Copy of getppid(). |
1696 |
* |
1697 |
* Returns parent process's PID. |
1698 |
* |
1699 |
* Alpha does not have getppid() defined. To be able to build this module on |
1700 |
* Alpha, I have to copy getppid() from kernel/timer.c. |
1701 |
*/ |
1702 |
static inline pid_t ccs_sys_getppid(void) |
1703 |
{ |
1704 |
pid_t pid; |
1705 |
rcu_read_lock(); |
1706 |
pid = task_tgid_vnr(current->real_parent); |
1707 |
rcu_read_unlock(); |
1708 |
return pid; |
1709 |
} |
1710 |
|
1711 |
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) |
1712 |
|
1713 |
/** |
1714 |
* ccs_sys_getppid - Copy of getppid(). |
1715 |
* |
1716 |
* Returns parent process's PID. |
1717 |
* |
1718 |
* This function was rewritten to use RCU in 2.6.16.34. However, distributors |
1719 |
* which use earlier kernels (e.g. 2.6.8/2.6.9) did not backport the bugfix. |
1720 |
* Therefore, I'm using code for 2.6.16.34 for earlier kernels. |
1721 |
*/ |
1722 |
static inline pid_t ccs_sys_getppid(void) |
1723 |
{ |
1724 |
pid_t pid; |
1725 |
rcu_read_lock(); |
1726 |
#if (defined(RHEL_MAJOR) && RHEL_MAJOR == 5) || (defined(AX_MAJOR) && AX_MAJOR == 3) |
1727 |
pid = rcu_dereference(current->parent)->tgid; |
1728 |
#else |
1729 |
pid = rcu_dereference(current->real_parent)->tgid; |
1730 |
#endif |
1731 |
rcu_read_unlock(); |
1732 |
return pid; |
1733 |
} |
1734 |
|
1735 |
#else |
1736 |
|
1737 |
/** |
1738 |
* ccs_sys_getppid - Copy of getppid(). |
1739 |
* |
1740 |
* Returns parent process's PID. |
1741 |
* |
1742 |
* I can't use code for 2.6.16.34 for 2.4 kernels because 2.4 kernels does not |
1743 |
* have RCU. Therefore, I'm using pessimistic lock (i.e. tasklist_lock |
1744 |
* spinlock). |
1745 |
*/ |
1746 |
static inline pid_t ccs_sys_getppid(void) |
1747 |
{ |
1748 |
pid_t pid; |
1749 |
read_lock(&tasklist_lock); |
1750 |
#ifdef TASK_DEAD |
1751 |
pid = current->group_leader->real_parent->tgid; |
1752 |
#else |
1753 |
pid = current->p_opptr->pid; |
1754 |
#endif |
1755 |
read_unlock(&tasklist_lock); |
1756 |
return pid; |
1757 |
} |
1758 |
|
1759 |
#endif |
1760 |
|
1761 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
1762 |
|
1763 |
/** |
1764 |
* ccs_sys_getpid - Copy of getpid(). |
1765 |
* |
1766 |
* Returns current thread's PID. |
1767 |
* |
1768 |
* Alpha does not have getpid() defined. To be able to build this module on |
1769 |
* Alpha, I have to copy getpid() from kernel/timer.c. |
1770 |
*/ |
1771 |
static inline pid_t ccs_sys_getpid(void) |
1772 |
{ |
1773 |
return task_tgid_vnr(current); |
1774 |
} |
1775 |
|
1776 |
#else |
1777 |
|
1778 |
/** |
1779 |
* ccs_sys_getpid - Copy of getpid(). |
1780 |
* |
1781 |
* Returns current thread's PID. |
1782 |
*/ |
1783 |
static inline pid_t ccs_sys_getpid(void) |
1784 |
{ |
1785 |
return current->tgid; |
1786 |
} |
1787 |
|
1788 |
#endif |
1789 |
|
1790 |
/** |
1791 |
* ccs_get_mode - Get mode for specified functionality. |
1792 |
* |
1793 |
* @profile: Profile number. |
1794 |
* @index: Functionality number. |
1795 |
* |
1796 |
* Returns mode. |
1797 |
*/ |
1798 |
static inline u8 ccs_get_mode(const u8 profile, const u8 index) |
1799 |
{ |
1800 |
return ccs_get_config(profile, index) & (CCS_CONFIG_MAX_MODE - 1); |
1801 |
} |
1802 |
|
1803 |
#if defined(CONFIG_SLOB) |
1804 |
|
1805 |
/** |
1806 |
* ccs_round2 - Round up to power of 2 for calculating memory usage. |
1807 |
* |
1808 |
* @size: Size to be rounded up. |
1809 |
* |
1810 |
* Returns @size. |
1811 |
* |
1812 |
* Since SLOB does not round up, this function simply returns @size. |
1813 |
*/ |
1814 |
static inline int ccs_round2(size_t size) |
1815 |
{ |
1816 |
return size; |
1817 |
} |
1818 |
|
1819 |
#else |
1820 |
|
1821 |
/** |
1822 |
* ccs_round2 - Round up to power of 2 for calculating memory usage. |
1823 |
* |
1824 |
* @size: Size to be rounded up. |
1825 |
* |
1826 |
* Returns rounded size. |
1827 |
* |
1828 |
* Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of |
1829 |
* (e.g.) 128 bytes. |
1830 |
*/ |
1831 |
static inline int ccs_round2(size_t size) |
1832 |
{ |
1833 |
#if PAGE_SIZE == 4096 |
1834 |
size_t bsize = 32; |
1835 |
#else |
1836 |
size_t bsize = 64; |
1837 |
#endif |
1838 |
if (!size) |
1839 |
return 0; |
1840 |
while (size > bsize) |
1841 |
bsize <<= 1; |
1842 |
return bsize; |
1843 |
} |
1844 |
|
1845 |
#endif |
1846 |
|
1847 |
/** |
1848 |
* ccs_put_condition - Drop reference on "struct ccs_condition". |
1849 |
* |
1850 |
* @cond: Pointer to "struct ccs_condition". Maybe NULL. |
1851 |
* |
1852 |
* Returns nothing. |
1853 |
*/ |
1854 |
static inline void ccs_put_condition(struct ccs_condition *cond) |
1855 |
{ |
1856 |
if (cond) |
1857 |
atomic_dec(&cond->head.users); |
1858 |
} |
1859 |
|
1860 |
/** |
1861 |
* ccs_put_group - Drop reference on "struct ccs_group". |
1862 |
* |
1863 |
* @group: Pointer to "struct ccs_group". Maybe NULL. |
1864 |
* |
1865 |
* Returns nothing. |
1866 |
*/ |
1867 |
static inline void ccs_put_group(struct ccs_group *group) |
1868 |
{ |
1869 |
if (group) |
1870 |
atomic_dec(&group->head.users); |
1871 |
} |
1872 |
|
1873 |
/** |
1874 |
* ccs_put_ipv6_address - Drop reference on "struct ccs_ipv6addr". |
1875 |
* |
1876 |
* @addr: Pointer to "struct in6_addr". Maybe NULL. |
1877 |
* |
1878 |
* Returns nothing. |
1879 |
*/ |
1880 |
static inline void ccs_put_ipv6_address(const struct in6_addr *addr) |
1881 |
{ |
1882 |
if (addr) |
1883 |
atomic_dec(&container_of(addr, struct ccs_ipv6addr, |
1884 |
addr)->head.users); |
1885 |
} |
1886 |
|
1887 |
/** |
1888 |
* ccs_put_name - Drop reference on "struct ccs_name". |
1889 |
* |
1890 |
* @name: Pointer to "struct ccs_path_info". Maybe NULL. |
1891 |
* |
1892 |
* Returns nothing. |
1893 |
*/ |
1894 |
static inline void ccs_put_name(const struct ccs_path_info *name) |
1895 |
{ |
1896 |
if (name) |
1897 |
atomic_dec(&container_of(name, struct ccs_name, entry)-> |
1898 |
head.users); |
1899 |
} |
1900 |
|
1901 |
/* For importing variables and functions. */ |
1902 |
extern const struct ccsecurity_exports ccsecurity_exports; |
1903 |
|
1904 |
#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY |
1905 |
|
1906 |
/* |
1907 |
* Structure for holding "struct ccs_domain_info *" and "struct ccs_execve *" |
1908 |
* and "u32 ccs_flags" for each "struct task_struct". |
1909 |
* |
1910 |
* "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct" |
1911 |
* are maintained outside that "struct task_struct". Therefore, ccs_security |
1912 |
* != task_struct . This keeps KABI for distributor's prebuilt kernels but |
1913 |
* entails slow access. |
1914 |
* |
1915 |
* Memory for this structure is allocated when current thread tries to access |
1916 |
* it. Therefore, if memory allocation failed, current thread will be killed by |
1917 |
* SIGKILL. Note that if current->pid == 1, sending SIGKILL won't work. |
1918 |
*/ |
1919 |
struct ccs_security { |
1920 |
struct list_head list; |
1921 |
const struct task_struct *task; |
1922 |
struct ccs_domain_info *ccs_domain_info; |
1923 |
u32 ccs_flags; |
1924 |
struct rcu_head rcu; |
1925 |
}; |
1926 |
|
1927 |
#define CCS_TASK_SECURITY_HASH_BITS 12 |
1928 |
#define CCS_MAX_TASK_SECURITY_HASH (1u << CCS_TASK_SECURITY_HASH_BITS) |
1929 |
extern struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH]; |
1930 |
|
1931 |
struct ccs_security *ccs_find_task_security(const struct task_struct *task); |
1932 |
|
1933 |
/** |
1934 |
* ccs_current_security - Get "struct ccs_security" for current thread. |
1935 |
* |
1936 |
* Returns pointer to "struct ccs_security" for current thread. |
1937 |
*/ |
1938 |
static inline struct ccs_security *ccs_current_security(void) |
1939 |
{ |
1940 |
return ccs_find_task_security(current); |
1941 |
} |
1942 |
|
1943 |
/** |
1944 |
* ccs_task_domain - Get "struct ccs_domain_info" for specified thread. |
1945 |
* |
1946 |
* @task: Pointer to "struct task_struct". |
1947 |
* |
1948 |
* Returns pointer to "struct ccs_security" for specified thread. |
1949 |
*/ |
1950 |
static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task) |
1951 |
{ |
1952 |
struct ccs_domain_info *domain; |
1953 |
rcu_read_lock(); |
1954 |
domain = ccs_find_task_security(task)->ccs_domain_info; |
1955 |
rcu_read_unlock(); |
1956 |
return domain; |
1957 |
} |
1958 |
|
1959 |
/** |
1960 |
* ccs_current_domain - Get "struct ccs_domain_info" for current thread. |
1961 |
* |
1962 |
* Returns pointer to "struct ccs_domain_info" for current thread. |
1963 |
*/ |
1964 |
static inline struct ccs_domain_info *ccs_current_domain(void) |
1965 |
{ |
1966 |
return ccs_find_task_security(current)->ccs_domain_info; |
1967 |
} |
1968 |
|
1969 |
/** |
1970 |
* ccs_task_flags - Get flags for specified thread. |
1971 |
* |
1972 |
* @task: Pointer to "struct task_struct". |
1973 |
* |
1974 |
* Returns flags for specified thread. |
1975 |
*/ |
1976 |
static inline u32 ccs_task_flags(struct task_struct *task) |
1977 |
{ |
1978 |
u32 ccs_flags; |
1979 |
rcu_read_lock(); |
1980 |
ccs_flags = ccs_find_task_security(task)->ccs_flags; |
1981 |
rcu_read_unlock(); |
1982 |
return ccs_flags; |
1983 |
} |
1984 |
|
1985 |
/** |
1986 |
* ccs_current_flags - Get flags for current thread. |
1987 |
* |
1988 |
* Returns flags for current thread. |
1989 |
*/ |
1990 |
static inline u32 ccs_current_flags(void) |
1991 |
{ |
1992 |
return ccs_find_task_security(current)->ccs_flags; |
1993 |
} |
1994 |
|
1995 |
#else |
1996 |
|
1997 |
/* |
1998 |
* "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct" |
1999 |
* are maintained inside that "struct task_struct". Therefore, ccs_security == |
2000 |
* task_struct . This allows fast access but breaks KABI checks for |
2001 |
* distributor's prebuilt kernels due to changes in "struct task_struct". |
2002 |
*/ |
2003 |
#define ccs_security task_struct |
2004 |
|
2005 |
/** |
2006 |
* ccs_find_task_security - Find "struct ccs_security" for given task. |
2007 |
* |
2008 |
* @task: Pointer to "struct task_struct". |
2009 |
* |
2010 |
* Returns pointer to "struct ccs_security". |
2011 |
*/ |
2012 |
static inline struct ccs_security *ccs_find_task_security(struct task_struct * |
2013 |
task) |
2014 |
{ |
2015 |
return task; |
2016 |
} |
2017 |
|
2018 |
/** |
2019 |
* ccs_current_security - Get "struct ccs_security" for current thread. |
2020 |
* |
2021 |
* Returns pointer to "struct ccs_security" for current thread. |
2022 |
*/ |
2023 |
static inline struct ccs_security *ccs_current_security(void) |
2024 |
{ |
2025 |
return ccs_find_task_security(current); |
2026 |
} |
2027 |
|
2028 |
/** |
2029 |
* ccs_task_domain - Get "struct ccs_domain_info" for specified thread. |
2030 |
* |
2031 |
* @task: Pointer to "struct task_struct". |
2032 |
* |
2033 |
* Returns pointer to "struct ccs_security" for specified thread. |
2034 |
*/ |
2035 |
static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task) |
2036 |
{ |
2037 |
struct ccs_domain_info *domain = task->ccs_domain_info; |
2038 |
return domain ? domain : &ccs_kernel_domain; |
2039 |
} |
2040 |
|
2041 |
/** |
2042 |
* ccs_current_domain - Get "struct ccs_domain_info" for current thread. |
2043 |
* |
2044 |
* Returns pointer to "struct ccs_domain_info" for current thread. |
2045 |
* |
2046 |
* If current thread does not belong to a domain (which is true for initial |
2047 |
* init_task in order to hide ccs_kernel_domain from this module), current |
2048 |
* thread enters into ccs_kernel_domain. |
2049 |
*/ |
2050 |
static inline struct ccs_domain_info *ccs_current_domain(void) |
2051 |
{ |
2052 |
struct task_struct *task = current; |
2053 |
if (!task->ccs_domain_info) |
2054 |
task->ccs_domain_info = &ccs_kernel_domain; |
2055 |
return task->ccs_domain_info; |
2056 |
} |
2057 |
|
2058 |
/** |
2059 |
* ccs_task_flags - Get flags for specified thread. |
2060 |
* |
2061 |
* @task: Pointer to "struct task_struct". |
2062 |
* |
2063 |
* Returns flags for specified thread. |
2064 |
*/ |
2065 |
static inline u32 ccs_task_flags(struct task_struct *task) |
2066 |
{ |
2067 |
return ccs_find_task_security(task)->ccs_flags; |
2068 |
} |
2069 |
|
2070 |
/** |
2071 |
* ccs_current_flags - Get flags for current thread. |
2072 |
* |
2073 |
* Returns flags for current thread. |
2074 |
*/ |
2075 |
static inline u32 ccs_current_flags(void) |
2076 |
{ |
2077 |
return ccs_find_task_security(current)->ccs_flags; |
2078 |
} |
2079 |
|
2080 |
#endif |
2081 |
|
2082 |
#endif |