• R/O
  • SSH
  • HTTPS

akari: 提交


Commit MetaInfo

修订版672 (tree)
时间2021-04-01 19:17:40
作者kumaneko

Log Message

1.0.47

更改概述

差异

--- tags/patches/1.0.47/README (nonexistent)
+++ tags/patches/1.0.47/README (revision 672)
@@ -0,0 +1,383 @@
1+Notes for AKARI project
2+
3+AKARI is Access Keeping And Regulating Instrument for Linux 2.6 and later
4+kernels.
5+
6+You can use AKARI for analyzing your system's behavior (i.e. reports which
7+application accesses which resources like strace command does) and optionally
8+restricting your system's behavior (i.e. controls which application can
9+access which resources like TOMOYO/AppArmor does).
10+
11+AKARI is forked from TOMOYO 1.8 and made as a LKM (loadable kernel module)
12+so that you don't need to replace your kernels installed in your system.
13+
14+This patch is released under the GPLv2.
15+
16+Project URL: https://akari.osdn.jp/
17+
18+ChangeLog:
19+
20+Version 1.0 2010/10/10 First release.
21+
22+Version 1.0.1 2010/10/18 Minor update release.
23+
24+ Synchronize with TOMOYO revision 4069.
25+
26+ Fix off-by-two in ccs_check_unix_address().
27+
28+ Implement post accept() LSM hook.
29+
30+Version 1.0.2 2010/10/25 Minor update release.
31+
32+ Synchronize with TOMOYO revision 4090.
33+
34+ Add getattr() and readdir() checks.
35+
36+ Use "YYYY/MM/DD hh:mm:ss" format for /proc/ccs/ interface.
37+
38+ Do not automatically add / for umount().
39+
40+Version 1.0.3 2010/11/01 Minor update release.
41+
42+ Synchronize with TOMOYO revision 4104.
43+
44+ Fix pathname handling in ccs_unix_entry().
45+
46+Version 1.0.4 2010/11/11 Minor update release.
47+
48+ Synchronize with TOMOYO 1.8.0 release.
49+
50+ Add sysctl() check for 2.6.21 to 2.6.32 kernels.
51+
52+ Fix double new_decode_dev() bug for mknod().
53+
54+ Fix keyword typo.
55+
56+ Fix build failure on some kernels.
57+
58+ Changed pathname prefix priority.
59+
60+ Use hash table for faster scan.
61+
62+ Updated function comments.
63+
64+Version 1.0.5 2010/11/22 Minor update release.
65+
66+ Make ccs_domain_info/ccs_flags inheritable for 2.6.29 and later kernels.
67+
68+Version 1.0.6 2010/12/31 Minor update release.
69+
70+ Synchronize with TOMOYO revision 4280.
71+
72+ Use same interface for audit logs.
73+
74+ Split ccs_null_security into ccs_default_security and ccs_oom_security.
75+
76+Version 1.0.7 2011/01/21 Minor update release.
77+
78+ Synchronize with TOMOYO revision 4400.
79+
80+ Use filesystem name for unnamed devices when vfsmount is missing.
81+
82+Version 1.0.8 2011/02/07 Minor update release.
83+
84+ Synchronize with TOMOYO revision 4545.
85+
86+ Fix infinite loop bug when reading /proc/ccs/audit or /proc/ccs/query .
87+
88+Version 1.0.9 2011/02/14 Minor update release.
89+
90+ Fix missing permission check for interpreters in 2.6.30 and later kernels.
91+
92+Version 1.0.10 2011/02/15 Minor update release.
93+
94+ Fix missing permission check for interpreters in 2.6.23 and earlier kernels.
95+
96+ Fix wrong execute permission check and domain transition in 2.6.28 and earlier kernels.
97+
98+Version 1.0.11 2010/04/01 Minor update release.
99+
100+ Synchronize with TOMOYO 1.8.1 release.
101+
102+ Run garbage collector without waiting for /proc/ccs/ users.
103+
104+ Support built-in policy configuration.
105+
106+ Remove /proc/ccs/meminfo interface.
107+
108+ Pack policy when printing via /proc/ccs/ interface.
109+
110+ Fix conditional policy parsing.
111+
112+ Serialize updating profile's comment line.
113+
114+Version 1.0.12 2011/04/11 Minor update release.
115+
116+ Synchronize with TOMOYO revision 4874.
117+
118+ Fix fcntl(F_SETFL, O_APPEND) handling.
119+
120+Version 1.0.13 2011/05/05 Minor update release.
121+
122+ Synchronize with TOMOYO revision 4963.
123+
124+ Fix wrong profile number in audit logs for "misc env" permission.
125+
126+Version 1.0.14 2011/05/11 Minor update release.
127+
128+ Synchronize with TOMOYO revision 4978.
129+
130+ Fix wrong domainname validation.
131+
132+Version 1.0.15 2011/06/20 Minor update release.
133+
134+ Synchronize with TOMOYO 1.8.2 release.
135+
136+ Add policy namespace support.
137+
138+Version 1.0.16 2011/07/07 Minor update release.
139+
140+ Synchronize with TOMOYO revision 5235.
141+
142+ Remove /proc/ccs/.domain_status interface.
143+
144+Version 1.0.17 2011/07/13 Minor update release.
145+
146+ Synchronize with TOMOYO revision 5266.
147+
148+ Fix /proc/ccs/stat parser.
149+
150+ Accept "::" notation for IPv6 address.
151+
152+Version 1.0.18 2011/09/03 Minor update release.
153+
154+ Synchronize with TOMOYO revision 5401.
155+
156+ Avoid race when retrying "file execute" permission check.
157+
158+ Remove unneeded daemonize().
159+
160+ Fix load failure with !CONFIG_SMP && !CONFIG_DEBUG_SPINLOCK kernels.
161+
162+Version 1.0.19 2011/09/15 Minor update release.
163+
164+ Use akari/config.h for choosing build options.
165+
166+ Fix build error on CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER=y case.
167+
168+ Use lookup_mnt() rather than __put_namespace(). (2.6.0 to 2.6.2 kernels)
169+
170+ Fix unbalanced spin_lock()/spin_unlock() pair in lsm_pin().
171+ (2.6.15 to 2.6.35 kernels)
172+
173+ Fix "struct task_struct" leaks of tasks created before loading akari.ko .
174+ (2.6.28 and earlier kernels)
175+
176+ Use "struct task_struct"->pids[PIDTYPE_PID].pid instead of
177+ "struct task_struct" for associating with per "struct task_struct" variables
178+ (i.e. "struct ccs_security") in order to reduce amount of dead memory
179+ waiting for garbage collection. (2.6.29 and later kernels)
180+
181+ Add akari_test.ko for checking whether akari.ko seems to work or not.
182+
183+ Add SH and ARM architectures support. (Needs more testing.)
184+
185+Version 1.0.20 2011/09/29 Minor update release.
186+
187+ Synchronize with TOMOYO 1.8.3 release.
188+
189+ Allow specifying domain transition preference.
190+
191+ Simplify garbage collector.
192+
193+Version 1.0.21 2011/10/25 Minor update release.
194+
195+ Synchronize with TOMOYO revision 5569.
196+
197+ Fix incomplete read after seek.
198+
199+ Use query id for reaching target process's domain policy.
200+
201+ Fix quota counting.
202+
203+Version 1.0.22 2011/11/11 Minor update release.
204+
205+ Synchronize with TOMOYO revision 5625.
206+
207+ Optimize for object's size.
208+
209+Version 1.0.23 2011/11/18 Minor update release.
210+
211+ Synchronize with TOMOYO revision 5646.
212+
213+ Fix kernel config mapping error.
214+
215+Version 1.0.24 2011/12/13 Minor update release.
216+
217+ Synchronize with TOMOYO revision 5711.
218+
219+ Follow __d_path() behavior change. (Only 2.6.36 and later)
220+
221+Version 1.0.25 2012/02/29 Minor update release.
222+
223+ Synchronize with TOMOYO revision 5893.
224+
225+ Follow UMH_WAIT_PROC constant renumbering.
226+
227+ Fix mount flags checking order.
228+
229+Version 1.0.26 2012/04/01 Minor update release.
230+
231+ Synchronize with TOMOYO revision 5973.
232+
233+ Return appropriate value to poll().
234+
235+Version 1.0.27 2012/05/05 Minor update release.
236+
237+ Synchronize with TOMOYO revision 6035.
238+
239+ Readd RHEL_MINOR/AX_MINOR checks.
240+
241+ Accept manager programs which do not start with / .
242+
243+Version 1.0.28 2012/10/20 Security update release.
244+
245+ Fix kernel panic caused by double kfree() bug when "struct ccs_execve"
246+ pointer was by error duplicated at __ccs_alloc_task_security().
247+ This bug affects only 2.6.28 and earlier kernels.
248+
249+Version 1.0.29 2012/11/04 Minor update release.
250+
251+ Use dummy pointer as needed in order to make sure that security_bprm_free()
252+ (which is used for making the caller of do_execve() return to previous
253+ domain when do_execve() failed after domain transition) is always called.
254+ Without this fix, domain transition history on 2.6.28 and earlier kernels
255+ becomes inaccurate.
256+
257+Version 1.0.30 2013/02/14 Minor update release.
258+
259+ Commit a2a8474c "exec: do not sleep in TASK_TRACED under ->cred_guard_mutex"
260+ moved "current->in_execve = 1;" from before prepare_bprm_creds() to after
261+ prepare_bprm_creds(). It turned out that, as an unexpected bonus, we can use
262+ security_prepare_creds() as a hook for emulating security_bprm_free() hook.
263+
264+ I updated the logic for security_bprm_free() emulation, and now AKARI should
265+ be able to coexist with other AKARI-like LKM-based LSM implementations (e.g.
266+ CaitSith) on all kernel versions other than 2.6.29 and 2.6.30.
267+
268+Version 1.0.31 2015/01/12 Minor update release.
269+
270+ Synchronize with TOMOYO revision 6373.
271+
272+ Fix missing chmod(-1) check in Linux 3.1 and later kernels.
273+
274+ Fix potentially using bogus attributes when stat() fails.
275+
276+Version 1.0.32 2015/04/08 Minor update release.
277+
278+ Synchronize with TOMOYO revision 6388.
279+
280+ Fix incorrect readdir() permission check.
281+
282+Version 1.0.33 2015/04/21 Minor update release.
283+
284+ Synchronize with TOMOYO revision 6407.
285+
286+ Fix incorrect retry request check.
287+
288+Version 1.0.34 2015/05/05 Minor update release.
289+
290+ Synchronize with TOMOYO 1.8.4 release.
291+
292+ Support multiple use_group entries.
293+
294+Version 1.0.35 2015/11/11 Minor update release.
295+
296+ Synchronize with TOMOYO 1.8.5 release.
297+
298+ Use memory allocation flags used by TOMOYO 2.x.
299+
300+ Limit wildcard recursion depth.
301+
302+Version 1.0.36 2017/02/20 Minor update release.
303+
304+ Synchronize with TOMOYO revision 6553.
305+
306+ The bug fixed in TOMOYO's GC does not affect AKARI because
307+ AKARI always uses CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY.
308+
309+Version 1.0.37 2017/09/17 Minor update release.
310+
311+ Use smp_rmb() when waiting for hook readiness.
312+
313+Version 1.0.38 2018/04/01 Minor update release.
314+
315+ Synchronize with TOMOYO revision 6638.
316+
317+ Due to incorrect probe_kernel_write() usage, previously registered LSM
318+ hook (if any) was by error overwritten by this hook. This bug affects
319+ only 4.12 and later kernels.
320+
321+Version 1.0.39 2019/08/20 Minor update release.
322+
323+ Synchronize with TOMOYO 1.8.6 release.
324+
325+ Change pathname calculation for read-only filesystems.
326+
327+ Reject move_mount() system call for now.
328+
329+ Don't check open/getattr permission on sockets.
330+
331+Version 1.0.40 2019/12/25 Minor update release.
332+
333+ Synchronize with TOMOYO revision 6758.
334+
335+ Don't use nifty names on sockets.
336+
337+Version 1.0.41 2020/04/13 Minor update release.
338+
339+ Synchronize with TOMOYO revision 6785.
340+
341+ Fix wrong put_page() usage in ccs_dump_page().
342+
343+Version 1.0.42 2020/05/05 Minor update release.
344+
345+ Synchronize with TOMOYO 1.8.7 release.
346+
347+ Loosen domainname validation and pathname validation.
348+
349+Version 1.0.43 2020/08/08 Minor update release.
350+
351+ Synchronize with TOMOYO revision 6816.
352+
353+ Fix domain transition preference.
354+
355+Version 1.0.44 2020/08/20 Minor update release.
356+
357+ Synchronize with TOMOYO revision 6821.
358+
359+ Fix ccs_realpath() fallback.
360+
361+ Fix wrong ccs_search_binary_handler() mapping.
362+
363+Version 1.0.45 2020/11/11 Minor update release.
364+
365+ Synchronize with TOMOYO 1.8.8 release.
366+
367+ Fix LSM hook detection on ARM64.
368+
369+Version 1.0.46 2020/11/12 Minor update release.
370+
371+ Since ccsecurity_exports.load_policy is initialized to NULL in AKARI,
372+ calling ccsecurity_exports.load_policy() before ccs_permission_init() is
373+ called (changed in revision 654) caused kernel panic as soon as loading
374+ akari.ko module. Since AKARI directly calls ccs_load_policy(), there is
375+ no need to use ccsecurity_exports.load_policy().
376+
377+Version 1.0.47 2021/04/01 Minor update release.
378+
379+ Synchronize with TOMOYO 1.8.9 release.
380+
381+ Skip permission checks for fileless execution requests.
382+
383+ Fix ccs_kernel_service().
--- tags/patches/1.0.47/ccsecurity.h (nonexistent)
+++ tags/patches/1.0.47/ccsecurity.h (revision 672)
@@ -0,0 +1,973 @@
1+/*
2+ * include/linux/ccsecurity.h
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#ifndef _LINUX_CCSECURITY_H
10+#define _LINUX_CCSECURITY_H
11+
12+#include <linux/version.h>
13+
14+#ifndef __user
15+#define __user
16+#endif
17+
18+struct nameidata;
19+struct path;
20+struct dentry;
21+struct vfsmount;
22+struct linux_binprm;
23+struct pt_regs;
24+struct file;
25+struct ctl_table;
26+struct socket;
27+struct sockaddr;
28+struct sock;
29+struct sk_buff;
30+struct msghdr;
31+struct pid_namespace;
32+struct ccs_execve;
33+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
34+/*
35+ * Don't depend on prototype definition, for exec_binprm() is a static function
36+ * which is implicitly inlined by compiler.
37+ */
38+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
39+int search_binary_handler(struct linux_binprm *bprm);
40+#else
41+int search_binary_handler(struct linux_binprm *bprm, struct pt_regs *regs);
42+#endif
43+
44+#ifdef CONFIG_CCSECURITY
45+
46+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
47+/* Obtain prototype of __d_path(). */
48+#include <linux/dcache.h>
49+#endif
50+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
51+/* Obtain definition of kuid_t and kgid_t. */
52+#include <linux/uidgid.h>
53+#endif
54+
55+/* For exporting variables and functions. */
56+struct ccsecurity_exports {
57+ void (*load_policy) (const char *filename);
58+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
59+ char * (*d_absolute_path) (const struct path *, char *, int);
60+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
61+ typeof(__d_path) (*__d_path);
62+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
63+ spinlock_t *vfsmount_lock;
64+#endif
65+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
66+ struct task_struct * (*find_task_by_vpid) (pid_t nr);
67+ struct task_struct * (*find_task_by_pid_ns) (pid_t nr,
68+ struct pid_namespace *ns);
69+#endif
70+};
71+
72+/* For doing access control. */
73+struct ccsecurity_operations {
74+ void (*check_profile) (void);
75+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
76+ int (*chroot_permission) (const struct path *path);
77+ int (*pivot_root_permission) (const struct path *old_path,
78+ const struct path *new_path);
79+ int (*mount_permission) (const char *dev_name, const struct path *path,
80+ const char *type, unsigned long flags,
81+ void *data_page);
82+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
83+ int (*move_mount_permission) (const struct path *from_path,
84+ const struct path *to_path);
85+#endif
86+#else
87+ int (*chroot_permission) (struct nameidata *nd);
88+ int (*pivot_root_permission) (struct nameidata *old_nd,
89+ struct nameidata *new_nd);
90+ int (*mount_permission) (const char *dev_name, struct nameidata *nd,
91+ const char *type, unsigned long flags,
92+ void *data_page);
93+#endif
94+ int (*umount_permission) (struct vfsmount *mnt, int flags);
95+ _Bool (*lport_reserved) (const u16 port);
96+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
97+ void (*save_open_mode) (int mode);
98+ void (*clear_open_mode) (void);
99+ int (*open_permission) (struct dentry *dentry, struct vfsmount *mnt,
100+ const int flag);
101+#else
102+ int (*open_permission) (struct file *file);
103+#endif
104+ int (*ptrace_permission) (long request, long pid);
105+ int (*ioctl_permission) (struct file *filp, unsigned int cmd,
106+ unsigned long arg);
107+ int (*parse_table) (int __user *name, int nlen, void __user *oldval,
108+ void __user *newval, struct ctl_table *table);
109+ _Bool (*capable) (const u8 operation);
110+ int (*mknod_permission) (struct dentry *dentry, struct vfsmount *mnt,
111+ unsigned int mode, unsigned int dev);
112+ int (*mkdir_permission) (struct dentry *dentry, struct vfsmount *mnt,
113+ unsigned int mode);
114+ int (*rmdir_permission) (struct dentry *dentry, struct vfsmount *mnt);
115+ int (*unlink_permission) (struct dentry *dentry, struct vfsmount *mnt);
116+ int (*symlink_permission) (struct dentry *dentry, struct vfsmount *mnt,
117+ const char *from);
118+ int (*truncate_permission) (struct dentry *dentry,
119+ struct vfsmount *mnt);
120+ int (*rename_permission) (struct dentry *old_dentry,
121+ struct dentry *new_dentry,
122+ struct vfsmount *mnt);
123+ int (*link_permission) (struct dentry *old_dentry,
124+ struct dentry *new_dentry,
125+ struct vfsmount *mnt);
126+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
127+ int (*open_exec_permission) (struct dentry *dentry,
128+ struct vfsmount *mnt);
129+ int (*uselib_permission) (struct dentry *dentry, struct vfsmount *mnt);
130+#endif
131+ int (*fcntl_permission) (struct file *file, unsigned int cmd,
132+ unsigned long arg);
133+ int (*kill_permission) (pid_t pid, int sig);
134+ int (*tgkill_permission) (pid_t tgid, pid_t pid, int sig);
135+ int (*tkill_permission) (pid_t pid, int sig);
136+ int (*socket_create_permission) (int family, int type, int protocol);
137+ int (*socket_listen_permission) (struct socket *sock);
138+ int (*socket_connect_permission) (struct socket *sock,
139+ struct sockaddr *addr, int addr_len);
140+ int (*socket_bind_permission) (struct socket *sock,
141+ struct sockaddr *addr, int addr_len);
142+ int (*socket_post_accept_permission) (struct socket *sock,
143+ struct socket *newsock);
144+ int (*socket_sendmsg_permission) (struct socket *sock,
145+ struct msghdr *msg, int size);
146+ int (*socket_post_recvmsg_permission) (struct sock *sk,
147+ struct sk_buff *skb, int flags);
148+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
149+ int (*chown_permission) (struct dentry *dentry, struct vfsmount *mnt,
150+ kuid_t user, kgid_t group);
151+#else
152+ int (*chown_permission) (struct dentry *dentry, struct vfsmount *mnt,
153+ uid_t user, gid_t group);
154+#endif
155+ int (*chmod_permission) (struct dentry *dentry, struct vfsmount *mnt,
156+ mode_t mode);
157+ int (*getattr_permission) (struct vfsmount *mnt,
158+ struct dentry *dentry);
159+ int (*sigqueue_permission) (pid_t pid, int sig);
160+ int (*tgsigqueue_permission) (pid_t tgid, pid_t pid, int sig);
161+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
162+ int (*start_execve) (struct linux_binprm *bprm, struct ccs_execve **eep);
163+ void (*finish_execve) (int retval, struct ccs_execve *ep);
164+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
165+ int (*search_binary_handler) (struct linux_binprm *bprm);
166+#else
167+ int (*search_binary_handler) (struct linux_binprm *bprm,
168+ struct pt_regs *regs);
169+#endif
170+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
171+ int (*alloc_task_security) (const struct task_struct *task);
172+ void (*free_task_security) (const struct task_struct *task);
173+#endif
174+ _Bool disabled;
175+};
176+
177+extern struct ccsecurity_operations ccsecurity_ops;
178+
179+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
180+
181+static inline int ccs_chroot_permission(const struct path *path)
182+{
183+ int (*func) (const struct path *) = ccsecurity_ops.chroot_permission;
184+ return func ? func(path) : 0;
185+}
186+
187+static inline int ccs_pivot_root_permission(const struct path *old_path,
188+ const struct path *new_path)
189+{
190+ int (*func) (const struct path *, const struct path *)
191+ = ccsecurity_ops.pivot_root_permission;
192+ return func ? func(old_path, new_path) : 0;
193+}
194+
195+static inline int ccs_mount_permission(const char *dev_name,
196+ const struct path *path,
197+ const char *type, unsigned long flags,
198+ void *data_page)
199+{
200+ int (*func) (const char *, const struct path *, const char *,
201+ unsigned long, void *) = ccsecurity_ops.mount_permission;
202+ return func ? func(dev_name, path, type, flags, data_page) : 0;
203+}
204+
205+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
206+static inline int ccs_move_mount_permission(const struct path *from_path,
207+ const struct path *to_path)
208+{
209+ int (*func) (const struct path *, const struct path *) =
210+ ccsecurity_ops.move_mount_permission;
211+ return func ? func(from_path, to_path) : 0;
212+}
213+#endif
214+
215+#else
216+
217+static inline int ccs_chroot_permission(struct nameidata *nd)
218+{
219+ int (*func) (struct nameidata *) = ccsecurity_ops.chroot_permission;
220+ return func ? func(nd) : 0;
221+}
222+
223+static inline int ccs_pivot_root_permission(struct nameidata *old_nd,
224+ struct nameidata *new_nd)
225+{
226+ int (*func) (struct nameidata *, struct nameidata *)
227+ = ccsecurity_ops.pivot_root_permission;
228+ return func ? func(old_nd, new_nd) : 0;
229+}
230+
231+static inline int ccs_mount_permission(const char *dev_name,
232+ struct nameidata *nd, const char *type,
233+ unsigned long flags, void *data_page)
234+{
235+ int (*func) (const char *, struct nameidata *, const char *,
236+ unsigned long, void *) = ccsecurity_ops.mount_permission;
237+ return func ? func(dev_name, nd, type, flags, data_page) : 0;
238+}
239+
240+#endif
241+
242+static inline int ccs_umount_permission(struct vfsmount *mnt, int flags)
243+{
244+ int (*func) (struct vfsmount *, int)
245+ = ccsecurity_ops.umount_permission;
246+ return func ? func(mnt, flags) : 0;
247+}
248+
249+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
250+
251+static inline void ccs_save_open_mode(int mode)
252+{
253+ void (*func) (int) = ccsecurity_ops.save_open_mode;
254+ if (func)
255+ func(mode);
256+}
257+
258+static inline void ccs_clear_open_mode(void)
259+{
260+ void (*func) (void) = ccsecurity_ops.clear_open_mode;
261+ if (func)
262+ func();
263+}
264+
265+static inline int ccs_open_permission(struct dentry *dentry,
266+ struct vfsmount *mnt, const int flag)
267+{
268+ int (*func) (struct dentry *, struct vfsmount *, const int)
269+ = ccsecurity_ops.open_permission;
270+ return func ? func(dentry, mnt, flag) : 0;
271+}
272+
273+#else
274+
275+static inline int ccs_open_permission(struct file *filp)
276+{
277+ int (*func) (struct file *) = ccsecurity_ops.open_permission;
278+ return func ? func(filp) : 0;
279+}
280+
281+#endif
282+
283+static inline int ccs_fcntl_permission(struct file *file, unsigned int cmd,
284+ unsigned long arg)
285+{
286+ int (*func) (struct file *, unsigned int, unsigned long)
287+ = ccsecurity_ops.fcntl_permission;
288+ return func ? func(file, cmd, arg) : 0;
289+}
290+
291+static inline int ccs_ioctl_permission(struct file *filp, unsigned int cmd,
292+ unsigned long arg)
293+{
294+ int (*func) (struct file *, unsigned int, unsigned long)
295+ = ccsecurity_ops.ioctl_permission;
296+ return func ? func(filp, cmd, arg) : 0;
297+}
298+
299+static inline int ccs_parse_table(int __user *name, int nlen,
300+ void __user *oldval, void __user *newval,
301+ struct ctl_table *table)
302+{
303+ int (*func) (int __user *, int, void __user *, void __user *,
304+ struct ctl_table *) = ccsecurity_ops.parse_table;
305+ return func ? func(name, nlen, oldval, newval, table) : 0;
306+}
307+
308+static inline int ccs_mknod_permission(struct dentry *dentry,
309+ struct vfsmount *mnt, unsigned int mode,
310+ unsigned int dev)
311+{
312+ int (*func) (struct dentry *, struct vfsmount *, unsigned int,
313+ unsigned int) = ccsecurity_ops.mknod_permission;
314+ return func ? func(dentry, mnt, mode, dev) : 0;
315+}
316+
317+static inline int ccs_mkdir_permission(struct dentry *dentry,
318+ struct vfsmount *mnt, unsigned int mode)
319+{
320+ int (*func) (struct dentry *, struct vfsmount *, unsigned int)
321+ = ccsecurity_ops.mkdir_permission;
322+ return func ? func(dentry, mnt, mode) : 0;
323+}
324+
325+static inline int ccs_rmdir_permission(struct dentry *dentry,
326+ struct vfsmount *mnt)
327+{
328+ int (*func) (struct dentry *, struct vfsmount *)
329+ = ccsecurity_ops.rmdir_permission;
330+ return func ? func(dentry, mnt) : 0;
331+}
332+
333+static inline int ccs_unlink_permission(struct dentry *dentry,
334+ struct vfsmount *mnt)
335+{
336+ int (*func) (struct dentry *, struct vfsmount *)
337+ = ccsecurity_ops.unlink_permission;
338+ return func ? func(dentry, mnt) : 0;
339+}
340+
341+static inline int ccs_symlink_permission(struct dentry *dentry,
342+ struct vfsmount *mnt,
343+ const char *from)
344+{
345+ int (*func) (struct dentry *, struct vfsmount *, const char *)
346+ = ccsecurity_ops.symlink_permission;
347+ return func ? func(dentry, mnt, from) : 0;
348+}
349+
350+static inline int ccs_truncate_permission(struct dentry *dentry,
351+ struct vfsmount *mnt)
352+{
353+ int (*func) (struct dentry *, struct vfsmount *)
354+ = ccsecurity_ops.truncate_permission;
355+ return func ? func(dentry, mnt) : 0;
356+}
357+
358+static inline int ccs_rename_permission(struct dentry *old_dentry,
359+ struct dentry *new_dentry,
360+ struct vfsmount *mnt)
361+{
362+ int (*func) (struct dentry *, struct dentry *, struct vfsmount *)
363+ = ccsecurity_ops.rename_permission;
364+ return func ? func(old_dentry, new_dentry, mnt) : 0;
365+}
366+
367+static inline int ccs_link_permission(struct dentry *old_dentry,
368+ struct dentry *new_dentry,
369+ struct vfsmount *mnt)
370+{
371+ int (*func) (struct dentry *, struct dentry *, struct vfsmount *)
372+ = ccsecurity_ops.link_permission;
373+ return func ? func(old_dentry, new_dentry, mnt) : 0;
374+}
375+
376+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
377+
378+static inline int ccs_open_exec_permission(struct dentry *dentry,
379+ struct vfsmount *mnt)
380+{
381+ int (*func) (struct dentry *, struct vfsmount *)
382+ = ccsecurity_ops.open_exec_permission;
383+ return func ? func(dentry, mnt) : 0;
384+}
385+
386+static inline int ccs_uselib_permission(struct dentry *dentry,
387+ struct vfsmount *mnt)
388+{
389+ int (*func) (struct dentry *, struct vfsmount *)
390+ = ccsecurity_ops.uselib_permission;
391+ return func ? func(dentry, mnt) : 0;
392+}
393+
394+#endif
395+
396+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
397+
398+static inline int ccs_chown_permission(struct dentry *dentry,
399+ struct vfsmount *mnt, kuid_t user,
400+ kgid_t group)
401+{
402+ int (*func) (struct dentry *, struct vfsmount *, kuid_t, kgid_t)
403+ = ccsecurity_ops.chown_permission;
404+ return func ? func(dentry, mnt, user, group) : 0;
405+}
406+
407+#else
408+
409+static inline int ccs_chown_permission(struct dentry *dentry,
410+ struct vfsmount *mnt, uid_t user,
411+ gid_t group)
412+{
413+ int (*func) (struct dentry *, struct vfsmount *, uid_t, gid_t)
414+ = ccsecurity_ops.chown_permission;
415+ return func ? func(dentry, mnt, user, group) : 0;
416+}
417+
418+#endif
419+
420+static inline int ccs_chmod_permission(struct dentry *dentry,
421+ struct vfsmount *mnt, mode_t mode)
422+{
423+ int (*func) (struct dentry *, struct vfsmount *, mode_t)
424+ = ccsecurity_ops.chmod_permission;
425+ return func ? func(dentry, mnt, mode) : 0;
426+}
427+
428+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
429+
430+/* Define as a macro here, for exec_binprm() is a static function. */
431+#define ccs_exec_binprm(bprm) \
432+({ \
433+ struct ccs_execve *ee = NULL; \
434+ void (*func) (int, struct ccs_execve *); \
435+ int retval = ccsecurity_ops.start_execve(bprm, &ee); \
436+ if (!retval) \
437+ retval = exec_binprm(bprm); \
438+ func = ccsecurity_ops.finish_execve; \
439+ if (func) \
440+ func(retval, ee); \
441+ retval; \
442+})
443+
444+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
445+
446+static inline int ccs_search_binary_handler(struct linux_binprm *bprm)
447+{
448+ return ccsecurity_ops.search_binary_handler(bprm);
449+}
450+
451+#else
452+
453+static inline int ccs_search_binary_handler(struct linux_binprm *bprm,
454+ struct pt_regs *regs)
455+{
456+ return ccsecurity_ops.search_binary_handler(bprm, regs);
457+}
458+
459+#endif
460+
461+#else
462+
463+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
464+
465+static inline int ccs_chroot_permission(const struct path *path)
466+{
467+ return 0;
468+}
469+
470+static inline int ccs_pivot_root_permission(const struct path *old_path,
471+ const struct path *new_path)
472+{
473+ return 0;
474+}
475+
476+static inline int ccs_mount_permission(const char *dev_name,
477+ const struct path *path,
478+ const char *type, unsigned long flags,
479+ void *data_page)
480+{
481+ return 0;
482+}
483+
484+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
485+static inline int ccs_move_mount_permission(const struct path *from_path,
486+ const struct path *to_path)
487+{
488+ return 0;
489+}
490+#endif
491+
492+#else
493+
494+static inline int ccs_chroot_permission(struct nameidata *nd)
495+{
496+ return 0;
497+}
498+
499+static inline int ccs_pivot_root_permission(struct nameidata *old_nd,
500+ struct nameidata *new_nd)
501+{
502+ return 0;
503+}
504+
505+static inline int ccs_mount_permission(const char *dev_name,
506+ struct nameidata *nd, const char *type,
507+ unsigned long flags, void *data_page)
508+{
509+ return 0;
510+}
511+
512+#endif
513+
514+static inline int ccs_umount_permission(struct vfsmount *mnt, int flags)
515+{
516+ return 0;
517+}
518+
519+static inline void ccs_save_open_mode(int mode)
520+{
521+}
522+
523+static inline void ccs_clear_open_mode(void)
524+{
525+}
526+
527+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
528+
529+static inline int ccs_open_permission(struct dentry *dentry,
530+ struct vfsmount *mnt, const int flag)
531+{
532+ return 0;
533+}
534+
535+#else
536+
537+static inline int ccs_open_permission(struct file *filp)
538+{
539+ return 0;
540+}
541+
542+#endif
543+
544+static inline int ccs_ioctl_permission(struct file *filp, unsigned int cmd,
545+ unsigned long arg)
546+{
547+ return 0;
548+}
549+
550+static inline int ccs_parse_table(int __user *name, int nlen,
551+ void __user *oldval, void __user *newval,
552+ struct ctl_table *table)
553+{
554+ return 0;
555+}
556+
557+static inline int ccs_mknod_permission(struct dentry *dentry,
558+ struct vfsmount *mnt, unsigned int mode,
559+ unsigned int dev)
560+{
561+ return 0;
562+}
563+
564+static inline int ccs_mkdir_permission(struct dentry *dentry,
565+ struct vfsmount *mnt, unsigned int mode)
566+{
567+ return 0;
568+}
569+
570+static inline int ccs_rmdir_permission(struct dentry *dentry,
571+ struct vfsmount *mnt)
572+{
573+ return 0;
574+}
575+
576+static inline int ccs_unlink_permission(struct dentry *dentry,
577+ struct vfsmount *mnt)
578+{
579+ return 0;
580+}
581+
582+static inline int ccs_symlink_permission(struct dentry *dentry,
583+ struct vfsmount *mnt,
584+ const char *from)
585+{
586+ return 0;
587+}
588+
589+static inline int ccs_truncate_permission(struct dentry *dentry,
590+ struct vfsmount *mnt)
591+{
592+ return 0;
593+}
594+
595+static inline int ccs_rename_permission(struct dentry *old_dentry,
596+ struct dentry *new_dentry,
597+ struct vfsmount *mnt)
598+{
599+ return 0;
600+}
601+
602+static inline int ccs_link_permission(struct dentry *old_dentry,
603+ struct dentry *new_dentry,
604+ struct vfsmount *mnt)
605+{
606+ return 0;
607+}
608+
609+static inline int ccs_open_exec_permission(struct dentry *dentry,
610+ struct vfsmount *mnt)
611+{
612+ return 0;
613+}
614+
615+static inline int ccs_uselib_permission(struct dentry *dentry,
616+ struct vfsmount *mnt)
617+{
618+ return 0;
619+}
620+
621+static inline int ccs_fcntl_permission(struct file *file, unsigned int cmd,
622+ unsigned long arg)
623+{
624+ return 0;
625+}
626+
627+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
628+
629+static inline int ccs_chown_permission(struct dentry *dentry,
630+ struct vfsmount *mnt, kuid_t user,
631+ kgid_t group)
632+{
633+ return 0;
634+}
635+
636+#else
637+
638+static inline int ccs_chown_permission(struct dentry *dentry,
639+ struct vfsmount *mnt, uid_t user,
640+ gid_t group)
641+{
642+ return 0;
643+}
644+
645+#endif
646+
647+static inline int ccs_chmod_permission(struct dentry *dentry,
648+ struct vfsmount *mnt, mode_t mode)
649+{
650+ return 0;
651+}
652+
653+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
654+
655+/* Define as a macro here, for exec_binprm() is a static function. */
656+#define ccs_exec_binprm(bprm) exec_binprm(bprm)
657+
658+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
659+
660+static inline int ccs_search_binary_handler(struct linux_binprm *bprm)
661+{
662+ return search_binary_handler(bprm);
663+}
664+
665+#else
666+
667+static inline int ccs_search_binary_handler(struct linux_binprm *bprm,
668+ struct pt_regs *regs)
669+{
670+ return search_binary_handler(bprm, regs);
671+}
672+
673+#endif
674+
675+#endif
676+
677+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
678+
679+static inline int ccs_alloc_task_security(const struct task_struct *task)
680+{
681+ int (*func) (const struct task_struct *)
682+ = ccsecurity_ops.alloc_task_security;
683+ return func ? func(task) : 0;
684+}
685+
686+static inline void ccs_free_task_security(const struct task_struct *task)
687+{
688+ void (*func) (const struct task_struct *)
689+ = ccsecurity_ops.free_task_security;
690+ if (func)
691+ func(task);
692+}
693+
694+#else
695+
696+static inline int ccs_alloc_task_security(const struct task_struct *task)
697+{
698+ return 0;
699+}
700+
701+static inline void ccs_free_task_security(const struct task_struct *task)
702+{
703+}
704+
705+#endif
706+
707+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
708+
709+static inline int ccs_getattr_permission(struct vfsmount *mnt,
710+ struct dentry *dentry)
711+{
712+ int (*func) (struct vfsmount *, struct dentry *)
713+ = ccsecurity_ops.getattr_permission;
714+ return func ? func(mnt, dentry) : 0;
715+}
716+
717+#else
718+
719+static inline int ccs_getattr_permission(struct vfsmount *mnt,
720+ struct dentry *dentry)
721+{
722+ return 0;
723+}
724+
725+#endif
726+
727+#ifdef CONFIG_CCSECURITY_NETWORK
728+
729+static inline int ccs_socket_listen_permission(struct socket *sock)
730+{
731+ int (*func) (struct socket *)
732+ = ccsecurity_ops.socket_listen_permission;
733+ return func ? func(sock) : 0;
734+}
735+
736+static inline int ccs_socket_connect_permission(struct socket *sock,
737+ struct sockaddr *addr,
738+ int addr_len)
739+{
740+ int (*func) (struct socket *, struct sockaddr *, int)
741+ = ccsecurity_ops.socket_connect_permission;
742+ return func ? func(sock, addr, addr_len) : 0;
743+}
744+
745+static inline int ccs_socket_bind_permission(struct socket *sock,
746+ struct sockaddr *addr,
747+ int addr_len)
748+{
749+ int (*func) (struct socket *, struct sockaddr *, int)
750+ = ccsecurity_ops.socket_bind_permission;
751+ return func ? func(sock, addr, addr_len) : 0;
752+}
753+
754+static inline int ccs_socket_post_accept_permission(struct socket *sock,
755+ struct socket *newsock)
756+{
757+ int (*func) (struct socket *, struct socket *)
758+ = ccsecurity_ops.socket_post_accept_permission;
759+ return func ? func(sock, newsock) : 0;
760+}
761+
762+static inline int ccs_socket_sendmsg_permission(struct socket *sock,
763+ struct msghdr *msg,
764+ int size)
765+{
766+ int (*func) (struct socket *, struct msghdr *, int)
767+ = ccsecurity_ops.socket_sendmsg_permission;
768+ return func ? func(sock, msg, size) : 0;
769+}
770+
771+#else
772+
773+static inline int ccs_socket_listen_permission(struct socket *sock)
774+{
775+ return 0;
776+}
777+
778+static inline int ccs_socket_connect_permission(struct socket *sock,
779+ struct sockaddr *addr,
780+ int addr_len)
781+{
782+ return 0;
783+}
784+
785+static inline int ccs_socket_bind_permission(struct socket *sock,
786+ struct sockaddr *addr,
787+ int addr_len)
788+{
789+ return 0;
790+}
791+
792+static inline int ccs_socket_post_accept_permission(struct socket *sock,
793+ struct socket *newsock)
794+{
795+ return 0;
796+}
797+
798+static inline int ccs_socket_sendmsg_permission(struct socket *sock,
799+ struct msghdr *msg,
800+ int size)
801+{
802+ return 0;
803+}
804+
805+#endif
806+
807+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
808+
809+static inline int ccs_socket_post_recvmsg_permission(struct sock *sk,
810+ struct sk_buff *skb,
811+ int flags)
812+{
813+ int (*func) (struct sock *, struct sk_buff *, int)
814+ = ccsecurity_ops.socket_post_recvmsg_permission;
815+ return func ? func(sk, skb, flags) : 0;
816+}
817+
818+#else
819+
820+static inline int ccs_socket_post_recvmsg_permission(struct sock *sk,
821+ struct sk_buff *skb,
822+ int flags)
823+{
824+ return 0;
825+}
826+
827+#endif
828+
829+#ifdef CONFIG_CCSECURITY_PORTRESERVE
830+
831+static inline _Bool ccs_lport_reserved(const u16 port)
832+{
833+ _Bool (*func) (const u16) = ccsecurity_ops.lport_reserved;
834+ return func ? func(port) : 0;
835+}
836+
837+#else
838+
839+static inline _Bool ccs_lport_reserved(const u16 port)
840+{
841+ return 0;
842+}
843+
844+#endif
845+
846+#ifdef CONFIG_CCSECURITY_CAPABILITY
847+
848+static inline _Bool ccs_capable(const u8 operation)
849+{
850+ _Bool (*func) (const u8) = ccsecurity_ops.capable;
851+ return func ? func(operation) : 1;
852+}
853+
854+static inline int ccs_socket_create_permission(int family, int type,
855+ int protocol)
856+{
857+ int (*func) (int, int, int) = ccsecurity_ops.socket_create_permission;
858+ return func ? func(family, type, protocol) : 0;
859+}
860+
861+static inline int ccs_ptrace_permission(long request, long pid)
862+{
863+ int (*func) (long, long) = ccsecurity_ops.ptrace_permission;
864+ return func ? func(request, pid) : 0;
865+}
866+
867+#else
868+
869+static inline _Bool ccs_capable(const u8 operation)
870+{
871+ return 1;
872+}
873+
874+static inline int ccs_socket_create_permission(int family, int type,
875+ int protocol)
876+{
877+ return 0;
878+}
879+
880+static inline int ccs_ptrace_permission(long request, long pid)
881+{
882+ return 0;
883+}
884+
885+#endif
886+
887+#ifdef CONFIG_CCSECURITY_IPC
888+
889+static inline int ccs_kill_permission(pid_t pid, int sig)
890+{
891+ int (*func) (pid_t, int) = ccsecurity_ops.kill_permission;
892+ return func ? func(pid, sig) : 0;
893+}
894+
895+static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
896+{
897+ int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgkill_permission;
898+ return func ? func(tgid, pid, sig) : 0;
899+}
900+
901+static inline int ccs_tkill_permission(pid_t pid, int sig)
902+{
903+ int (*func) (pid_t, int) = ccsecurity_ops.tkill_permission;
904+ return func ? func(pid, sig) : 0;
905+}
906+
907+static inline int ccs_sigqueue_permission(pid_t pid, int sig)
908+{
909+ int (*func) (pid_t, int) = ccsecurity_ops.sigqueue_permission;
910+ return func ? func(pid, sig) : 0;
911+}
912+
913+static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
914+{
915+ int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgsigqueue_permission;
916+ return func ? func(tgid, pid, sig) : 0;
917+}
918+
919+#else
920+
921+static inline int ccs_kill_permission(pid_t pid, int sig)
922+{
923+ return 0;
924+}
925+
926+static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
927+{
928+ return 0;
929+}
930+
931+static inline int ccs_tkill_permission(pid_t pid, int sig)
932+{
933+ return 0;
934+}
935+
936+static inline int ccs_sigqueue_permission(pid_t pid, int sig)
937+{
938+ return 0;
939+}
940+
941+static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
942+{
943+ return 0;
944+}
945+
946+#endif
947+
948+/* Index numbers for Capability Controls. */
949+enum ccs_capability_acl_index {
950+ /* socket(PF_ROUTE, *, *) */
951+ CCS_USE_ROUTE_SOCKET,
952+ /* socket(PF_PACKET, *, *) */
953+ CCS_USE_PACKET_SOCKET,
954+ /* sys_reboot() */
955+ CCS_SYS_REBOOT,
956+ /* sys_vhangup() */
957+ CCS_SYS_VHANGUP,
958+ /* do_settimeofday(), sys_adjtimex() */
959+ CCS_SYS_SETTIME,
960+ /* sys_nice(), sys_setpriority() */
961+ CCS_SYS_NICE,
962+ /* sys_sethostname(), sys_setdomainname() */
963+ CCS_SYS_SETHOSTNAME,
964+ /* sys_create_module(), sys_init_module(), sys_delete_module() */
965+ CCS_USE_KERNEL_MODULE,
966+ /* sys_kexec_load() */
967+ CCS_SYS_KEXEC_LOAD,
968+ /* sys_ptrace() */
969+ CCS_SYS_PTRACE,
970+ CCS_MAX_CAPABILITY_INDEX
971+};
972+
973+#endif
--- tags/patches/1.0.47/gc.c (nonexistent)
+++ tags/patches/1.0.47/gc.c (revision 672)
@@ -0,0 +1,1054 @@
1+/*
2+ * security/ccsecurity/gc.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#include "internal.h"
10+
11+/***** SECTION1: Constants definition *****/
12+
13+/* For compatibility with older kernels. */
14+#ifndef for_each_process
15+#define for_each_process for_each_task
16+#endif
17+
18+/* The list for "struct ccs_io_buffer". */
19+static LIST_HEAD(ccs_io_buffer_list);
20+/* Lock for protecting ccs_io_buffer_list. */
21+static DEFINE_SPINLOCK(ccs_io_buffer_list_lock);
22+
23+/***** SECTION2: Structure definition *****/
24+
25+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
26+
27+/*
28+ * Lock for syscall users.
29+ *
30+ * This lock is used for protecting single SRCU section for 2.6.18 and
31+ * earlier kernels because they don't have SRCU support.
32+ */
33+struct ccs_lock_struct {
34+ int counter_idx; /* Currently active index (0 or 1). */
35+ int counter[2]; /* Current users. Protected by ccs_counter_lock. */
36+};
37+
38+#endif
39+
40+/***** SECTION3: Prototype definition section *****/
41+
42+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
43+int ccs_lock(void);
44+#endif
45+void ccs_del_acl(struct list_head *element);
46+void ccs_del_condition(struct list_head *element);
47+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register);
48+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
49+void ccs_unlock(const int idx);
50+#endif
51+
52+static bool ccs_domain_used_by_task(struct ccs_domain_info *domain);
53+static bool ccs_name_used_by_io_buffer(const char *string, const size_t size);
54+static bool ccs_struct_used_by_io_buffer(const struct list_head *element);
55+static int ccs_gc_thread(void *unused);
56+static void ccs_collect_acl(struct list_head *list);
57+static void ccs_collect_entry(void);
58+static void ccs_collect_member(const enum ccs_policy_id id,
59+ struct list_head *member_list);
60+static void ccs_memory_free(const void *ptr, const enum ccs_policy_id type);
61+static void ccs_put_name_union(struct ccs_name_union *ptr);
62+static void ccs_put_number_union(struct ccs_number_union *ptr);
63+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
64+static void ccs_synchronize_counter(void);
65+#endif
66+static void ccs_try_to_gc(const enum ccs_policy_id type,
67+ struct list_head *element);
68+
69+/***** SECTION4: Standalone functions section *****/
70+
71+/***** SECTION5: Variables definition section *****/
72+
73+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
74+
75+/*
76+ * Lock for syscall users.
77+ *
78+ * This lock is held for only protecting single SRCU section.
79+ */
80+struct srcu_struct ccs_ss;
81+
82+#else
83+
84+static struct ccs_lock_struct ccs_counter;
85+/* Lock for protecting ccs_counter. */
86+static DEFINE_SPINLOCK(ccs_counter_lock);
87+
88+#endif
89+
90+/***** SECTION6: Dependent functions section *****/
91+
92+/**
93+ * ccs_memory_free - Free memory for elements.
94+ *
95+ * @ptr: Pointer to allocated memory.
96+ * @type: One of values in "enum ccs_policy_id".
97+ *
98+ * Returns nothing.
99+ *
100+ * Caller holds ccs_policy_lock mutex.
101+ */
102+static void ccs_memory_free(const void *ptr, const enum ccs_policy_id type)
103+{
104+ /* Size of an element. */
105+ static const u8 e[CCS_MAX_POLICY] = {
106+#ifdef CONFIG_CCSECURITY_PORTRESERVE
107+ [CCS_ID_RESERVEDPORT] = sizeof(struct ccs_reserved),
108+#endif
109+ [CCS_ID_GROUP] = sizeof(struct ccs_group),
110+#ifdef CONFIG_CCSECURITY_NETWORK
111+ [CCS_ID_ADDRESS_GROUP] = sizeof(struct ccs_address_group),
112+#endif
113+ [CCS_ID_PATH_GROUP] = sizeof(struct ccs_path_group),
114+ [CCS_ID_NUMBER_GROUP] = sizeof(struct ccs_number_group),
115+ [CCS_ID_AGGREGATOR] = sizeof(struct ccs_aggregator),
116+ [CCS_ID_TRANSITION_CONTROL]
117+ = sizeof(struct ccs_transition_control),
118+ [CCS_ID_MANAGER] = sizeof(struct ccs_manager),
119+ /* [CCS_ID_CONDITION] = "struct ccs_condition"->size, */
120+ /* [CCS_ID_NAME] = "struct ccs_name"->size, */
121+ /* [CCS_ID_ACL] = a["struct ccs_acl_info"->type], */
122+ [CCS_ID_DOMAIN] = sizeof(struct ccs_domain_info),
123+ };
124+ /* Size of a domain ACL element. */
125+ static const u8 a[] = {
126+ [CCS_TYPE_PATH_ACL] = sizeof(struct ccs_path_acl),
127+ [CCS_TYPE_PATH2_ACL] = sizeof(struct ccs_path2_acl),
128+ [CCS_TYPE_PATH_NUMBER_ACL]
129+ = sizeof(struct ccs_path_number_acl),
130+ [CCS_TYPE_MKDEV_ACL] = sizeof(struct ccs_mkdev_acl),
131+ [CCS_TYPE_MOUNT_ACL] = sizeof(struct ccs_mount_acl),
132+#ifdef CONFIG_CCSECURITY_NETWORK
133+ [CCS_TYPE_INET_ACL] = sizeof(struct ccs_inet_acl),
134+ [CCS_TYPE_UNIX_ACL] = sizeof(struct ccs_unix_acl),
135+#endif
136+#ifdef CONFIG_CCSECURITY_MISC
137+ [CCS_TYPE_ENV_ACL] = sizeof(struct ccs_env_acl),
138+#endif
139+#ifdef CONFIG_CCSECURITY_CAPABILITY
140+ [CCS_TYPE_CAPABILITY_ACL] = sizeof(struct ccs_capability_acl),
141+#endif
142+#ifdef CONFIG_CCSECURITY_IPC
143+ [CCS_TYPE_SIGNAL_ACL] = sizeof(struct ccs_signal_acl),
144+#endif
145+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
146+ [CCS_TYPE_AUTO_EXECUTE_HANDLER]
147+ = sizeof(struct ccs_handler_acl),
148+ [CCS_TYPE_DENIED_EXECUTE_HANDLER]
149+ = sizeof(struct ccs_handler_acl),
150+#endif
151+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
152+ [CCS_TYPE_AUTO_TASK_ACL] = sizeof(struct ccs_task_acl),
153+ [CCS_TYPE_MANUAL_TASK_ACL] = sizeof(struct ccs_task_acl),
154+#endif
155+ };
156+ size_t size;
157+ if (type == CCS_ID_ACL)
158+ size = a[container_of(ptr, typeof(struct ccs_acl_info),
159+ list)->type];
160+ else if (type == CCS_ID_NAME)
161+ size = container_of(ptr, typeof(struct ccs_name),
162+ head.list)->size;
163+ else if (type == CCS_ID_CONDITION)
164+ size = container_of(ptr, typeof(struct ccs_condition),
165+ head.list)->size;
166+ else
167+ size = e[type];
168+ ccs_memory_used[CCS_MEMORY_POLICY] -= ccs_round2(size);
169+ kfree(ptr);
170+}
171+
172+/**
173+ * ccs_put_name_union - Drop reference on "struct ccs_name_union".
174+ *
175+ * @ptr: Pointer to "struct ccs_name_union".
176+ *
177+ * Returns nothing.
178+ */
179+static void ccs_put_name_union(struct ccs_name_union *ptr)
180+{
181+ ccs_put_group(ptr->group);
182+ ccs_put_name(ptr->filename);
183+}
184+
185+/**
186+ * ccs_put_number_union - Drop reference on "struct ccs_number_union".
187+ *
188+ * @ptr: Pointer to "struct ccs_number_union".
189+ *
190+ * Returns nothing.
191+ */
192+static void ccs_put_number_union(struct ccs_number_union *ptr)
193+{
194+ ccs_put_group(ptr->group);
195+}
196+
197+/**
198+ * ccs_struct_used_by_io_buffer - Check whether the list element is used by /proc/ccs/ users or not.
199+ *
200+ * @element: Pointer to "struct list_head".
201+ *
202+ * Returns true if @element is used by /proc/ccs/ users, false otherwise.
203+ */
204+static bool ccs_struct_used_by_io_buffer(const struct list_head *element)
205+{
206+ struct ccs_io_buffer *head;
207+ bool in_use = false;
208+ spin_lock(&ccs_io_buffer_list_lock);
209+ list_for_each_entry(head, &ccs_io_buffer_list, list) {
210+ head->users++;
211+ spin_unlock(&ccs_io_buffer_list_lock);
212+ mutex_lock(&head->io_sem);
213+ if (head->r.domain == element || head->r.group == element ||
214+ head->r.acl == element || &head->w.domain->list == element)
215+ in_use = true;
216+ mutex_unlock(&head->io_sem);
217+ spin_lock(&ccs_io_buffer_list_lock);
218+ head->users--;
219+ if (in_use)
220+ break;
221+ }
222+ spin_unlock(&ccs_io_buffer_list_lock);
223+ return in_use;
224+}
225+
226+/**
227+ * ccs_name_used_by_io_buffer - Check whether the string is used by /proc/ccs/ users or not.
228+ *
229+ * @string: String to check.
230+ * @size: Memory allocated for @string .
231+ *
232+ * Returns true if @string is used by /proc/ccs/ users, false otherwise.
233+ */
234+static bool ccs_name_used_by_io_buffer(const char *string, const size_t size)
235+{
236+ struct ccs_io_buffer *head;
237+ bool in_use = false;
238+ spin_lock(&ccs_io_buffer_list_lock);
239+ list_for_each_entry(head, &ccs_io_buffer_list, list) {
240+ int i;
241+ head->users++;
242+ spin_unlock(&ccs_io_buffer_list_lock);
243+ mutex_lock(&head->io_sem);
244+ for (i = 0; i < CCS_MAX_IO_READ_QUEUE; i++) {
245+ const char *w = head->r.w[i];
246+ if (w < string || w > string + size)
247+ continue;
248+ in_use = true;
249+ break;
250+ }
251+ mutex_unlock(&head->io_sem);
252+ spin_lock(&ccs_io_buffer_list_lock);
253+ head->users--;
254+ if (in_use)
255+ break;
256+ }
257+ spin_unlock(&ccs_io_buffer_list_lock);
258+ return in_use;
259+}
260+
261+/**
262+ * ccs_del_transition_control - Delete members in "struct ccs_transition_control".
263+ *
264+ * @element: Pointer to "struct list_head".
265+ *
266+ * Returns nothing.
267+ */
268+static inline void ccs_del_transition_control(struct list_head *element)
269+{
270+ struct ccs_transition_control *ptr =
271+ container_of(element, typeof(*ptr), head.list);
272+ ccs_put_name(ptr->domainname);
273+ ccs_put_name(ptr->program);
274+}
275+
276+/**
277+ * ccs_del_aggregator - Delete members in "struct ccs_aggregator".
278+ *
279+ * @element: Pointer to "struct list_head".
280+ *
281+ * Returns nothing.
282+ */
283+static inline void ccs_del_aggregator(struct list_head *element)
284+{
285+ struct ccs_aggregator *ptr =
286+ container_of(element, typeof(*ptr), head.list);
287+ ccs_put_name(ptr->original_name);
288+ ccs_put_name(ptr->aggregated_name);
289+}
290+
291+/**
292+ * ccs_del_manager - Delete members in "struct ccs_manager".
293+ *
294+ * @element: Pointer to "struct list_head".
295+ *
296+ * Returns nothing.
297+ */
298+static inline void ccs_del_manager(struct list_head *element)
299+{
300+ struct ccs_manager *ptr =
301+ container_of(element, typeof(*ptr), head.list);
302+ ccs_put_name(ptr->manager);
303+}
304+
305+/**
306+ * ccs_domain_used_by_task - Check whether the given pointer is referenced by a task.
307+ *
308+ * @domain: Pointer to "struct ccs_domain_info".
309+ *
310+ * Returns true if @domain is in use, false otherwise.
311+ */
312+static bool ccs_domain_used_by_task(struct ccs_domain_info *domain)
313+{
314+ bool in_use = false;
315+ /*
316+ * Don't delete this domain if somebody is doing execve().
317+ *
318+ * Since ccs_finish_execve() first reverts ccs_domain_info and then
319+ * updates ccs_flags, we need smp_rmb() to make sure that GC first
320+ * checks ccs_flags and then checks ccs_domain_info.
321+ */
322+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
323+ int idx;
324+ rcu_read_lock();
325+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
326+ struct ccs_security *ptr;
327+ struct list_head *list = &ccs_task_security_list[idx];
328+ list_for_each_entry_rcu(ptr, list, list) {
329+ if (!(ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
330+ smp_rmb(); /* Avoid out of order execution. */
331+ if (ptr->ccs_domain_info != domain)
332+ continue;
333+ }
334+ in_use = true;
335+ goto out;
336+ }
337+ }
338+ in_use = ccs_used_by_cred(domain);
339+out:
340+ rcu_read_unlock();
341+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) || defined(for_each_process_thread)
342+ struct task_struct *g;
343+ struct task_struct *t;
344+ rcu_read_lock();
345+ for_each_process_thread(g, t) {
346+ if (!(t->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
347+ smp_rmb(); /* Avoid out of order execution. */
348+ if (t->ccs_domain_info != domain)
349+ continue;
350+ }
351+ in_use = true;
352+ goto out;
353+ }
354+out:
355+ rcu_read_unlock();
356+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
357+ struct task_struct *g;
358+ struct task_struct *t;
359+ rcu_read_lock();
360+ read_lock(&tasklist_lock);
361+ do_each_thread(g, t) {
362+ if (!(t->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
363+ smp_rmb(); /* Avoid out of order execution. */
364+ if (t->ccs_domain_info != domain)
365+ continue;
366+ }
367+ in_use = true;
368+ goto out;
369+ } while_each_thread(g, t);
370+out:
371+ read_unlock(&tasklist_lock);
372+ rcu_read_unlock();
373+#else
374+ struct task_struct *p;
375+ read_lock(&tasklist_lock);
376+ for_each_process(p) {
377+ if (!(p->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
378+ smp_rmb(); /* Avoid out of order execution. */
379+ if (p->ccs_domain_info != domain)
380+ continue;
381+ }
382+ in_use = true;
383+ break;
384+ }
385+ read_unlock(&tasklist_lock);
386+#endif
387+ return in_use;
388+}
389+
390+/**
391+ * ccs_del_acl - Delete members in "struct ccs_acl_info".
392+ *
393+ * @element: Pointer to "struct list_head".
394+ *
395+ * Returns nothing.
396+ */
397+void ccs_del_acl(struct list_head *element)
398+{
399+ struct ccs_acl_info *acl = container_of(element, typeof(*acl), list);
400+ ccs_put_condition(acl->cond);
401+ switch (acl->type) {
402+ case CCS_TYPE_PATH_ACL:
403+ {
404+ struct ccs_path_acl *entry =
405+ container_of(acl, typeof(*entry), head);
406+ ccs_put_name_union(&entry->name);
407+ }
408+ break;
409+ case CCS_TYPE_PATH2_ACL:
410+ {
411+ struct ccs_path2_acl *entry =
412+ container_of(acl, typeof(*entry), head);
413+ ccs_put_name_union(&entry->name1);
414+ ccs_put_name_union(&entry->name2);
415+ }
416+ break;
417+ case CCS_TYPE_PATH_NUMBER_ACL:
418+ {
419+ struct ccs_path_number_acl *entry =
420+ container_of(acl, typeof(*entry), head);
421+ ccs_put_name_union(&entry->name);
422+ ccs_put_number_union(&entry->number);
423+ }
424+ break;
425+ case CCS_TYPE_MKDEV_ACL:
426+ {
427+ struct ccs_mkdev_acl *entry =
428+ container_of(acl, typeof(*entry), head);
429+ ccs_put_name_union(&entry->name);
430+ ccs_put_number_union(&entry->mode);
431+ ccs_put_number_union(&entry->major);
432+ ccs_put_number_union(&entry->minor);
433+ }
434+ break;
435+ case CCS_TYPE_MOUNT_ACL:
436+ {
437+ struct ccs_mount_acl *entry =
438+ container_of(acl, typeof(*entry), head);
439+ ccs_put_name_union(&entry->dev_name);
440+ ccs_put_name_union(&entry->dir_name);
441+ ccs_put_name_union(&entry->fs_type);
442+ ccs_put_number_union(&entry->flags);
443+ }
444+ break;
445+#ifdef CONFIG_CCSECURITY_NETWORK
446+ case CCS_TYPE_INET_ACL:
447+ {
448+ struct ccs_inet_acl *entry =
449+ container_of(acl, typeof(*entry), head);
450+ ccs_put_group(entry->address.group);
451+ ccs_put_number_union(&entry->port);
452+ }
453+ break;
454+ case CCS_TYPE_UNIX_ACL:
455+ {
456+ struct ccs_unix_acl *entry =
457+ container_of(acl, typeof(*entry), head);
458+ ccs_put_name_union(&entry->name);
459+ }
460+ break;
461+#endif
462+#ifdef CONFIG_CCSECURITY_MISC
463+ case CCS_TYPE_ENV_ACL:
464+ {
465+ struct ccs_env_acl *entry =
466+ container_of(acl, typeof(*entry), head);
467+ ccs_put_name(entry->env);
468+ }
469+ break;
470+#endif
471+#ifdef CONFIG_CCSECURITY_CAPABILITY
472+ case CCS_TYPE_CAPABILITY_ACL:
473+ {
474+ /* Nothing to do. */
475+ }
476+ break;
477+#endif
478+#ifdef CONFIG_CCSECURITY_IPC
479+ case CCS_TYPE_SIGNAL_ACL:
480+ {
481+ struct ccs_signal_acl *entry =
482+ container_of(acl, typeof(*entry), head);
483+ ccs_put_number_union(&entry->sig);
484+ ccs_put_name(entry->domainname);
485+ }
486+ break;
487+#endif
488+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
489+ case CCS_TYPE_AUTO_EXECUTE_HANDLER:
490+ case CCS_TYPE_DENIED_EXECUTE_HANDLER:
491+ {
492+ struct ccs_handler_acl *entry =
493+ container_of(acl, typeof(*entry), head);
494+ ccs_put_name(entry->handler);
495+ }
496+ break;
497+#endif
498+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
499+ case CCS_TYPE_AUTO_TASK_ACL:
500+ case CCS_TYPE_MANUAL_TASK_ACL:
501+ {
502+ struct ccs_task_acl *entry =
503+ container_of(acl, typeof(*entry), head);
504+ ccs_put_name(entry->domainname);
505+ }
506+ break;
507+#endif
508+ }
509+}
510+
511+/**
512+ * ccs_del_domain - Delete members in "struct ccs_domain_info".
513+ *
514+ * @element: Pointer to "struct list_head".
515+ *
516+ * Returns nothing.
517+ *
518+ * Caller holds ccs_policy_lock mutex.
519+ */
520+static inline void ccs_del_domain(struct list_head *element)
521+{
522+ struct ccs_domain_info *domain =
523+ container_of(element, typeof(*domain), list);
524+ struct ccs_acl_info *acl;
525+ struct ccs_acl_info *tmp;
526+ /*
527+ * Since this domain is referenced from neither "struct ccs_io_buffer"
528+ * nor "struct task_struct", we can delete elements without checking
529+ * for is_deleted flag.
530+ */
531+ list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
532+ ccs_del_acl(&acl->list);
533+ ccs_memory_free(acl, CCS_ID_ACL);
534+ }
535+ ccs_put_name(domain->domainname);
536+}
537+
538+/**
539+ * ccs_del_path_group - Delete members in "struct ccs_path_group".
540+ *
541+ * @element: Pointer to "struct list_head".
542+ *
543+ * Returns nothing.
544+ */
545+static inline void ccs_del_path_group(struct list_head *element)
546+{
547+ struct ccs_path_group *member =
548+ container_of(element, typeof(*member), head.list);
549+ ccs_put_name(member->member_name);
550+}
551+
552+/**
553+ * ccs_del_group - Delete "struct ccs_group".
554+ *
555+ * @element: Pointer to "struct list_head".
556+ *
557+ * Returns nothing.
558+ */
559+static inline void ccs_del_group(struct list_head *element)
560+{
561+ struct ccs_group *group =
562+ container_of(element, typeof(*group), head.list);
563+ ccs_put_name(group->group_name);
564+}
565+
566+/**
567+ * ccs_del_address_group - Delete members in "struct ccs_address_group".
568+ *
569+ * @element: Pointer to "struct list_head".
570+ *
571+ * Returns nothing.
572+ */
573+static inline void ccs_del_address_group(struct list_head *element)
574+{
575+ /* Nothing to do. */
576+}
577+
578+/**
579+ * ccs_del_number_group - Delete members in "struct ccs_number_group".
580+ *
581+ * @element: Pointer to "struct list_head".
582+ *
583+ * Returns nothing.
584+ */
585+static inline void ccs_del_number_group(struct list_head *element)
586+{
587+ /* Nothing to do. */
588+}
589+
590+/**
591+ * ccs_del_reservedport - Delete members in "struct ccs_reserved".
592+ *
593+ * @element: Pointer to "struct list_head".
594+ *
595+ * Returns nothing.
596+ */
597+static inline void ccs_del_reservedport(struct list_head *element)
598+{
599+ /* Nothing to do. */
600+}
601+
602+/**
603+ * ccs_del_condition - Delete members in "struct ccs_condition".
604+ *
605+ * @element: Pointer to "struct list_head".
606+ *
607+ * Returns nothing.
608+ */
609+void ccs_del_condition(struct list_head *element)
610+{
611+ struct ccs_condition *cond = container_of(element, typeof(*cond),
612+ head.list);
613+ const u16 condc = cond->condc;
614+ const u16 numbers_count = cond->numbers_count;
615+ const u16 names_count = cond->names_count;
616+ const u16 argc = cond->argc;
617+ const u16 envc = cond->envc;
618+ unsigned int i;
619+ const struct ccs_condition_element *condp
620+ = (const struct ccs_condition_element *) (cond + 1);
621+ struct ccs_number_union *numbers_p
622+ = (struct ccs_number_union *) (condp + condc);
623+ struct ccs_name_union *names_p
624+ = (struct ccs_name_union *) (numbers_p + numbers_count);
625+ const struct ccs_argv *argv
626+ = (const struct ccs_argv *) (names_p + names_count);
627+ const struct ccs_envp *envp
628+ = (const struct ccs_envp *) (argv + argc);
629+ for (i = 0; i < numbers_count; i++)
630+ ccs_put_number_union(numbers_p++);
631+ for (i = 0; i < names_count; i++)
632+ ccs_put_name_union(names_p++);
633+ for (i = 0; i < argc; argv++, i++)
634+ ccs_put_name(argv->value);
635+ for (i = 0; i < envc; envp++, i++) {
636+ ccs_put_name(envp->name);
637+ ccs_put_name(envp->value);
638+ }
639+ ccs_put_name(cond->transit);
640+}
641+
642+/**
643+ * ccs_del_name - Delete members in "struct ccs_name".
644+ *
645+ * @element: Pointer to "struct list_head".
646+ *
647+ * Returns nothing.
648+ */
649+static inline void ccs_del_name(struct list_head *element)
650+{
651+ /* Nothing to do. */
652+}
653+
654+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
655+
656+/**
657+ * ccs_lock - Alternative for srcu_read_lock().
658+ *
659+ * Returns index number which has to be passed to ccs_unlock().
660+ */
661+int ccs_lock(void)
662+{
663+ int idx;
664+ spin_lock(&ccs_counter_lock);
665+ idx = ccs_counter.counter_idx;
666+ ccs_counter.counter[idx]++;
667+ spin_unlock(&ccs_counter_lock);
668+ return idx;
669+}
670+
671+/**
672+ * ccs_unlock - Alternative for srcu_read_unlock().
673+ *
674+ * @idx: Index number returned by ccs_lock().
675+ *
676+ * Returns nothing.
677+ */
678+void ccs_unlock(const int idx)
679+{
680+ spin_lock(&ccs_counter_lock);
681+ ccs_counter.counter[idx]--;
682+ spin_unlock(&ccs_counter_lock);
683+}
684+
685+/**
686+ * ccs_synchronize_counter - Alternative for synchronize_srcu().
687+ *
688+ * Returns nothing.
689+ */
690+static void ccs_synchronize_counter(void)
691+{
692+ int idx;
693+ int v;
694+ /*
695+ * Change currently active counter's index. Make it visible to other
696+ * threads by doing it with ccs_counter_lock held.
697+ * This function is called by garbage collector thread, and the garbage
698+ * collector thread is exclusive. Therefore, it is guaranteed that
699+ * SRCU grace period has expired when returning from this function.
700+ */
701+ spin_lock(&ccs_counter_lock);
702+ idx = ccs_counter.counter_idx;
703+ ccs_counter.counter_idx ^= 1;
704+ v = ccs_counter.counter[idx];
705+ spin_unlock(&ccs_counter_lock);
706+ /* Wait for previously active counter to become 0. */
707+ while (v) {
708+ ssleep(1);
709+ spin_lock(&ccs_counter_lock);
710+ v = ccs_counter.counter[idx];
711+ spin_unlock(&ccs_counter_lock);
712+ }
713+}
714+
715+#endif
716+
717+/**
718+ * ccs_try_to_gc - Try to kfree() an entry.
719+ *
720+ * @type: One of values in "enum ccs_policy_id".
721+ * @element: Pointer to "struct list_head".
722+ *
723+ * Returns nothing.
724+ *
725+ * Caller holds ccs_policy_lock mutex.
726+ */
727+static void ccs_try_to_gc(const enum ccs_policy_id type,
728+ struct list_head *element)
729+{
730+ /*
731+ * __list_del_entry() guarantees that the list element became no longer
732+ * reachable from the list which the element was originally on (e.g.
733+ * ccs_domain_list). Also, synchronize_srcu() guarantees that the list
734+ * element became no longer referenced by syscall users.
735+ */
736+ __list_del_entry(element);
737+ mutex_unlock(&ccs_policy_lock);
738+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
739+ synchronize_srcu(&ccs_ss);
740+#else
741+ ccs_synchronize_counter();
742+#endif
743+ /*
744+ * However, there are two users which may still be using the list
745+ * element. We need to defer until both users forget this element.
746+ *
747+ * Don't kfree() until "struct ccs_io_buffer"->r.{domain,group,acl} and
748+ * "struct ccs_io_buffer"->w.domain forget this element.
749+ */
750+ if (ccs_struct_used_by_io_buffer(element))
751+ goto reinject;
752+ switch (type) {
753+ case CCS_ID_TRANSITION_CONTROL:
754+ ccs_del_transition_control(element);
755+ break;
756+ case CCS_ID_MANAGER:
757+ ccs_del_manager(element);
758+ break;
759+ case CCS_ID_AGGREGATOR:
760+ ccs_del_aggregator(element);
761+ break;
762+ case CCS_ID_GROUP:
763+ ccs_del_group(element);
764+ break;
765+ case CCS_ID_PATH_GROUP:
766+ ccs_del_path_group(element);
767+ break;
768+#ifdef CONFIG_CCSECURITY_NETWORK
769+ case CCS_ID_ADDRESS_GROUP:
770+ ccs_del_address_group(element);
771+ break;
772+#endif
773+ case CCS_ID_NUMBER_GROUP:
774+ ccs_del_number_group(element);
775+ break;
776+#ifdef CONFIG_CCSECURITY_PORTRESERVE
777+ case CCS_ID_RESERVEDPORT:
778+ ccs_del_reservedport(element);
779+ break;
780+#endif
781+ case CCS_ID_CONDITION:
782+ ccs_del_condition(element);
783+ break;
784+ case CCS_ID_NAME:
785+ /*
786+ * Don't kfree() until all "struct ccs_io_buffer"->r.w[] forget
787+ * this element.
788+ */
789+ if (ccs_name_used_by_io_buffer
790+ (container_of(element, typeof(struct ccs_name),
791+ head.list)->entry.name,
792+ container_of(element, typeof(struct ccs_name),
793+ head.list)->size))
794+ goto reinject;
795+ ccs_del_name(element);
796+ break;
797+ case CCS_ID_ACL:
798+ ccs_del_acl(element);
799+ break;
800+ case CCS_ID_DOMAIN:
801+ /*
802+ * Don't kfree() until all "struct task_struct" forget this
803+ * element.
804+ */
805+ if (ccs_domain_used_by_task
806+ (container_of(element, typeof(struct ccs_domain_info),
807+ list)))
808+ goto reinject;
809+ break;
810+ case CCS_MAX_POLICY:
811+ break;
812+ }
813+ mutex_lock(&ccs_policy_lock);
814+ if (type == CCS_ID_DOMAIN)
815+ ccs_del_domain(element);
816+ ccs_memory_free(element, type);
817+ return;
818+reinject:
819+ /*
820+ * We can safely reinject this element here because
821+ * (1) Appending list elements and removing list elements are protected
822+ * by ccs_policy_lock mutex.
823+ * (2) Only this function removes list elements and this function is
824+ * exclusively executed by ccs_gc_mutex mutex.
825+ * are true.
826+ */
827+ mutex_lock(&ccs_policy_lock);
828+ list_add_rcu(element, element->prev);
829+}
830+
831+/**
832+ * ccs_collect_member - Delete elements with "struct ccs_acl_head".
833+ *
834+ * @id: One of values in "enum ccs_policy_id".
835+ * @member_list: Pointer to "struct list_head".
836+ *
837+ * Returns nothing.
838+ *
839+ * Caller holds ccs_policy_lock mutex.
840+ */
841+static void ccs_collect_member(const enum ccs_policy_id id,
842+ struct list_head *member_list)
843+{
844+ struct ccs_acl_head *member;
845+ struct ccs_acl_head *tmp;
846+ list_for_each_entry_safe(member, tmp, member_list, list) {
847+ if (!member->is_deleted)
848+ continue;
849+ member->is_deleted = CCS_GC_IN_PROGRESS;
850+ ccs_try_to_gc(id, &member->list);
851+ }
852+}
853+
854+/**
855+ * ccs_collect_acl - Delete elements in "struct ccs_domain_info".
856+ *
857+ * @list: Pointer to "struct list_head".
858+ *
859+ * Returns nothing.
860+ *
861+ * Caller holds ccs_policy_lock mutex.
862+ */
863+static void ccs_collect_acl(struct list_head *list)
864+{
865+ struct ccs_acl_info *acl;
866+ struct ccs_acl_info *tmp;
867+ list_for_each_entry_safe(acl, tmp, list, list) {
868+ if (!acl->is_deleted)
869+ continue;
870+ acl->is_deleted = CCS_GC_IN_PROGRESS;
871+ ccs_try_to_gc(CCS_ID_ACL, &acl->list);
872+ }
873+}
874+
875+/**
876+ * ccs_collect_entry - Try to kfree() deleted elements.
877+ *
878+ * Returns nothing.
879+ */
880+static void ccs_collect_entry(void)
881+{
882+ int i;
883+ enum ccs_policy_id id;
884+ struct ccs_policy_namespace *ns;
885+ mutex_lock(&ccs_policy_lock);
886+ {
887+ struct ccs_domain_info *domain;
888+ struct ccs_domain_info *tmp;
889+ list_for_each_entry_safe(domain, tmp, &ccs_domain_list, list) {
890+ ccs_collect_acl(&domain->acl_info_list);
891+ if (!domain->is_deleted ||
892+ ccs_domain_used_by_task(domain))
893+ continue;
894+ ccs_try_to_gc(CCS_ID_DOMAIN, &domain->list);
895+ }
896+ }
897+ list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
898+ for (id = 0; id < CCS_MAX_POLICY; id++)
899+ ccs_collect_member(id, &ns->policy_list[id]);
900+ for (i = 0; i < CCS_MAX_ACL_GROUPS; i++)
901+ ccs_collect_acl(&ns->acl_group[i]);
902+ }
903+ {
904+ struct ccs_shared_acl_head *ptr;
905+ struct ccs_shared_acl_head *tmp;
906+ list_for_each_entry_safe(ptr, tmp, &ccs_condition_list, list) {
907+ if (atomic_read(&ptr->users) > 0)
908+ continue;
909+ atomic_set(&ptr->users, CCS_GC_IN_PROGRESS);
910+ ccs_try_to_gc(CCS_ID_CONDITION, &ptr->list);
911+ }
912+ }
913+ list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
914+ for (i = 0; i < CCS_MAX_GROUP; i++) {
915+ struct list_head *list = &ns->group_list[i];
916+ struct ccs_group *group;
917+ struct ccs_group *tmp;
918+ switch (i) {
919+ case 0:
920+ id = CCS_ID_PATH_GROUP;
921+ break;
922+ case 1:
923+ id = CCS_ID_NUMBER_GROUP;
924+ break;
925+ default:
926+#ifdef CONFIG_CCSECURITY_NETWORK
927+ id = CCS_ID_ADDRESS_GROUP;
928+#else
929+ continue;
930+#endif
931+ break;
932+ }
933+ list_for_each_entry_safe(group, tmp, list, head.list) {
934+ ccs_collect_member(id, &group->member_list);
935+ if (!list_empty(&group->member_list) ||
936+ atomic_read(&group->head.users) > 0)
937+ continue;
938+ atomic_set(&group->head.users,
939+ CCS_GC_IN_PROGRESS);
940+ ccs_try_to_gc(CCS_ID_GROUP, &group->head.list);
941+ }
942+ }
943+ }
944+ for (i = 0; i < CCS_MAX_HASH; i++) {
945+ struct list_head *list = &ccs_name_list[i];
946+ struct ccs_shared_acl_head *ptr;
947+ struct ccs_shared_acl_head *tmp;
948+ list_for_each_entry_safe(ptr, tmp, list, list) {
949+ if (atomic_read(&ptr->users) > 0)
950+ continue;
951+ atomic_set(&ptr->users, CCS_GC_IN_PROGRESS);
952+ ccs_try_to_gc(CCS_ID_NAME, &ptr->list);
953+ }
954+ }
955+ mutex_unlock(&ccs_policy_lock);
956+}
957+
958+/**
959+ * ccs_gc_thread - Garbage collector thread function.
960+ *
961+ * @unused: Unused.
962+ *
963+ * Returns 0.
964+ */
965+static int ccs_gc_thread(void *unused)
966+{
967+ /* Garbage collector thread is exclusive. */
968+ static DEFINE_MUTEX(ccs_gc_mutex);
969+ if (!mutex_trylock(&ccs_gc_mutex))
970+ goto out;
971+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
972+ /* daemonize() not needed. */
973+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
974+ daemonize("GC for CCS");
975+#else
976+ daemonize();
977+ reparent_to_init();
978+#if defined(TASK_DEAD)
979+ {
980+ struct task_struct *task = current;
981+ spin_lock_irq(&task->sighand->siglock);
982+ siginitsetinv(&task->blocked, 0);
983+ recalc_sigpending();
984+ spin_unlock_irq(&task->sighand->siglock);
985+ }
986+#else
987+ {
988+ struct task_struct *task = current;
989+ spin_lock_irq(&task->sigmask_lock);
990+ siginitsetinv(&task->blocked, 0);
991+ recalc_sigpending(task);
992+ spin_unlock_irq(&task->sigmask_lock);
993+ }
994+#endif
995+ snprintf(current->comm, sizeof(current->comm) - 1, "GC for CCS");
996+#endif
997+ ccs_collect_entry();
998+ {
999+ struct ccs_io_buffer *head;
1000+ struct ccs_io_buffer *tmp;
1001+ spin_lock(&ccs_io_buffer_list_lock);
1002+ list_for_each_entry_safe(head, tmp, &ccs_io_buffer_list,
1003+ list) {
1004+ if (head->users)
1005+ continue;
1006+ list_del(&head->list);
1007+ kfree(head->read_buf);
1008+ kfree(head->write_buf);
1009+ kfree(head);
1010+ }
1011+ spin_unlock(&ccs_io_buffer_list_lock);
1012+ }
1013+ mutex_unlock(&ccs_gc_mutex);
1014+out:
1015+ /* This acts as do_exit(0). */
1016+ return 0;
1017+}
1018+
1019+/**
1020+ * ccs_notify_gc - Register/unregister /proc/ccs/ users.
1021+ *
1022+ * @head: Pointer to "struct ccs_io_buffer".
1023+ * @is_register: True if register, false if unregister.
1024+ *
1025+ * Returns nothing.
1026+ */
1027+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register)
1028+{
1029+ bool is_write = false;
1030+ spin_lock(&ccs_io_buffer_list_lock);
1031+ if (is_register) {
1032+ head->users = 1;
1033+ list_add(&head->list, &ccs_io_buffer_list);
1034+ } else {
1035+ is_write = head->write_buf != NULL;
1036+ if (!--head->users) {
1037+ list_del(&head->list);
1038+ kfree(head->read_buf);
1039+ kfree(head->write_buf);
1040+ kfree(head);
1041+ }
1042+ }
1043+ spin_unlock(&ccs_io_buffer_list_lock);
1044+ if (is_write) {
1045+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
1046+ struct task_struct *task = kthread_create(ccs_gc_thread, NULL,
1047+ "GC for CCS");
1048+ if (!IS_ERR(task))
1049+ wake_up_process(task);
1050+#else
1051+ kernel_thread(ccs_gc_thread, NULL, 0);
1052+#endif
1053+ }
1054+}
--- tags/patches/1.0.47/internal.h (nonexistent)
+++ tags/patches/1.0.47/internal.h (revision 672)
@@ -0,0 +1,2168 @@
1+/*
2+ * security/ccsecurity/internal.h
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
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+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
20+#include <linux/smp_lock.h>
21+#endif
22+#include <linux/module.h>
23+#include <linux/init.h>
24+#include <linux/slab.h>
25+#include <linux/highmem.h>
26+#include <linux/poll.h>
27+#include <linux/binfmts.h>
28+#include <linux/delay.h>
29+#include <linux/sched.h>
30+#include <linux/dcache.h>
31+#include <linux/mount.h>
32+#include <linux/net.h>
33+#include <linux/inet.h>
34+#include <linux/in.h>
35+#include <linux/in6.h>
36+#include <linux/un.h>
37+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
38+#include <linux/fs.h>
39+#endif
40+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
41+#include <linux/namei.h>
42+#endif
43+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
44+#include <linux/fs_struct.h>
45+#endif
46+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
47+#include <linux/namespace.h>
48+#endif
49+#include <linux/proc_fs.h>
50+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
51+#include <linux/hash.h>
52+#endif
53+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
54+#include <linux/sysctl.h>
55+#endif
56+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
57+#include <linux/kthread.h>
58+#endif
59+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
60+#include <linux/magic.h>
61+#endif
62+#include <stdarg.h>
63+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
64+#include <linux/uaccess.h>
65+#else
66+#include <asm/uaccess.h>
67+#endif
68+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
69+#include <linux/sched/signal.h>
70+#endif
71+#include <net/sock.h>
72+#include <net/af_unix.h>
73+#include <net/ip.h>
74+#include <net/ipv6.h>
75+#include <net/udp.h>
76+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
77+#include <uapi/linux/mount.h>
78+#endif
79+
80+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
81+#define sk_family family
82+#define sk_protocol protocol
83+#define sk_type type
84+#endif
85+
86+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
87+
88+/* Structure for holding "struct vfsmount *" and "struct dentry *". */
89+struct path {
90+ struct vfsmount *mnt;
91+ struct dentry *dentry;
92+};
93+
94+#endif
95+
96+#ifndef __printf
97+#define __printf(a,b) __attribute__((format(printf,a,b)))
98+#endif
99+#ifndef __packed
100+#define __packed __attribute__((__packed__))
101+#endif
102+#ifndef bool
103+#define bool _Bool
104+#endif
105+#ifndef false
106+#define false 0
107+#endif
108+#ifndef true
109+#define true 1
110+#endif
111+
112+#ifndef __user
113+#define __user
114+#endif
115+
116+#ifndef current_uid
117+#define current_uid() (current->uid)
118+#endif
119+#ifndef current_gid
120+#define current_gid() (current->gid)
121+#endif
122+#ifndef current_euid
123+#define current_euid() (current->euid)
124+#endif
125+#ifndef current_egid
126+#define current_egid() (current->egid)
127+#endif
128+#ifndef current_suid
129+#define current_suid() (current->suid)
130+#endif
131+#ifndef current_sgid
132+#define current_sgid() (current->sgid)
133+#endif
134+#ifndef current_fsuid
135+#define current_fsuid() (current->fsuid)
136+#endif
137+#ifndef current_fsgid
138+#define current_fsgid() (current->fsgid)
139+#endif
140+
141+#ifndef DEFINE_SPINLOCK
142+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
143+#endif
144+
145+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
146+#define mutex semaphore
147+#define mutex_init(mutex) init_MUTEX(mutex)
148+#define mutex_unlock(mutex) up(mutex)
149+#define mutex_lock(mutex) down(mutex)
150+#define mutex_lock_interruptible(mutex) down_interruptible(mutex)
151+#define mutex_trylock(mutex) (!down_trylock(mutex))
152+#define DEFINE_MUTEX(mutexname) DECLARE_MUTEX(mutexname)
153+#endif
154+
155+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
156+#define MS_UNBINDABLE (1<<17) /* change to unbindable */
157+#define MS_PRIVATE (1<<18) /* change to private */
158+#define MS_SLAVE (1<<19) /* change to slave */
159+#define MS_SHARED (1<<20) /* change to shared */
160+#endif
161+
162+#ifndef container_of
163+#define container_of(ptr, type, member) ({ \
164+ const typeof(((type *)0)->member) *__mptr = (ptr); \
165+ (type *)((char *)__mptr - offsetof(type, member)); })
166+#endif
167+
168+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
169+#define smp_read_barrier_depends smp_rmb
170+#endif
171+
172+#ifndef ACCESS_ONCE
173+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
174+#endif
175+
176+#ifndef rcu_dereference
177+#define rcu_dereference(p) ({ \
178+ typeof(p) _________p1 = ACCESS_ONCE(p); \
179+ smp_read_barrier_depends(); /* see RCU */ \
180+ (_________p1); \
181+ })
182+#endif
183+
184+#ifndef rcu_assign_pointer
185+#define rcu_assign_pointer(p, v) \
186+ ({ \
187+ if (!__builtin_constant_p(v) || \
188+ ((v) != NULL)) \
189+ smp_wmb(); /* see RCU */ \
190+ (p) = (v); \
191+ })
192+#endif
193+
194+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
195+#define f_vfsmnt f_path.mnt
196+#endif
197+
198+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
199+
200+/**
201+ * kzalloc() - Allocate memory. The memory is set to zero.
202+ *
203+ * @size: Size to allocate.
204+ * @flags: GFP flags.
205+ *
206+ * Returns pointer to allocated memory on success, NULL otherwise.
207+ *
208+ * This is for compatibility with older kernels.
209+ *
210+ * Since several distributions backported kzalloc(), I define it as a macro
211+ * rather than an inlined function in order to avoid multiple definition error.
212+ */
213+#define kzalloc(size, flags) ({ \
214+ void *ret = kmalloc((size), (flags)); \
215+ if (ret) \
216+ memset(ret, 0, (size)); \
217+ ret; })
218+
219+#endif
220+
221+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
222+
223+/**
224+ * path_put - Drop reference on "struct path".
225+ *
226+ * @path: Pointer to "struct path".
227+ *
228+ * Returns nothing.
229+ *
230+ * This is for compatibility with older kernels.
231+ */
232+static inline void path_put(struct path *path)
233+{
234+ dput(path->dentry);
235+ mntput(path->mnt);
236+}
237+
238+#endif
239+
240+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
241+
242+/**
243+ * __list_add_rcu - Insert a new entry between two known consecutive entries.
244+ *
245+ * @new: Pointer to "struct list_head".
246+ * @prev: Pointer to "struct list_head".
247+ * @next: Pointer to "struct list_head".
248+ *
249+ * Returns nothing.
250+ *
251+ * This is for compatibility with older kernels.
252+ */
253+static inline void __list_add_rcu(struct list_head *new,
254+ struct list_head *prev,
255+ struct list_head *next)
256+{
257+ new->next = next;
258+ new->prev = prev;
259+ rcu_assign_pointer(prev->next, new);
260+ next->prev = new;
261+}
262+
263+/**
264+ * list_add_tail_rcu - Add a new entry to rcu-protected list.
265+ *
266+ * @new: Pointer to "struct list_head".
267+ * @head: Pointer to "struct list_head".
268+ *
269+ * Returns nothing.
270+ *
271+ * This is for compatibility with older kernels.
272+ */
273+static inline void list_add_tail_rcu(struct list_head *new,
274+ struct list_head *head)
275+{
276+ __list_add_rcu(new, head->prev, head);
277+}
278+
279+/**
280+ * list_add_rcu - Add a new entry to rcu-protected list.
281+ *
282+ * @new: Pointer to "struct list_head".
283+ * @head: Pointer to "struct list_head".
284+ *
285+ * Returns nothing.
286+ *
287+ * This is for compatibility with older kernels.
288+ */
289+static inline void list_add_rcu(struct list_head *new, struct list_head *head)
290+{
291+ __list_add_rcu(new, head, head->next);
292+}
293+
294+#endif
295+
296+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
297+
298+/**
299+ * __list_del_entry - Deletes entry from list without re-initialization.
300+ *
301+ * @entry: Pointer to "struct list_head".
302+ *
303+ * Returns nothing.
304+ *
305+ * This is for compatibility with older kernels.
306+ */
307+static inline void __list_del_entry(struct list_head *entry)
308+{
309+ __list_del(entry->prev, entry->next);
310+}
311+
312+#endif
313+
314+#ifndef list_for_each_entry_safe
315+
316+/**
317+ * list_for_each_entry_safe - Iterate over list of given type safe against removal of list entry.
318+ *
319+ * @pos: The "type *" to use as a loop cursor.
320+ * @n: Another "type *" to use as temporary storage.
321+ * @head: Pointer to "struct list_head".
322+ * @member: The name of the list_struct within the struct.
323+ *
324+ * This is for compatibility with older kernels.
325+ */
326+#define list_for_each_entry_safe(pos, n, head, member) \
327+ for (pos = list_entry((head)->next, typeof(*pos), member), \
328+ n = list_entry(pos->member.next, typeof(*pos), member); \
329+ &pos->member != (head); \
330+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
331+
332+#endif
333+
334+#ifndef srcu_dereference
335+
336+/**
337+ * srcu_dereference - Fetch SRCU-protected pointer with checking.
338+ *
339+ * @p: The pointer to read, prior to dereferencing.
340+ * @ss: Pointer to "struct srcu_struct".
341+ *
342+ * Returns @p.
343+ *
344+ * This is for compatibility with older kernels.
345+ */
346+#define srcu_dereference(p, ss) rcu_dereference(p)
347+
348+#endif
349+
350+#ifndef list_for_each_entry_srcu
351+
352+/**
353+ * list_for_each_entry_srcu - Iterate over rcu list of given type.
354+ *
355+ * @pos: The type * to use as a loop cursor.
356+ * @head: The head for your list.
357+ * @member: The name of the list_struct within the struct.
358+ * @ss: Pointer to "struct srcu_struct".
359+ *
360+ * As of 2.6.36, this macro is not provided because only TOMOYO wants it.
361+ */
362+#define list_for_each_entry_srcu(pos, head, member, ss) \
363+ for (pos = list_entry(srcu_dereference((head)->next, ss), \
364+ typeof(*pos), member); \
365+ prefetch(pos->member.next), &pos->member != (head); \
366+ pos = list_entry(srcu_dereference(pos->member.next, ss), \
367+ typeof(*pos), member))
368+
369+#endif
370+
371+#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))
372+
373+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 4, 21)
374+#undef ssleep
375+#endif
376+
377+#ifndef ssleep
378+
379+/**
380+ * ssleep - Sleep for specified seconds.
381+ *
382+ * @secs: Seconds to sleep.
383+ *
384+ * Returns nothing.
385+ *
386+ * This is for compatibility with older kernels.
387+ *
388+ * Since several distributions backported ssleep(), I define it as a macro
389+ * rather than an inlined function in order to avoid multiple definition error.
390+ */
391+#define ssleep(secs) { \
392+ set_current_state(TASK_UNINTERRUPTIBLE); \
393+ schedule_timeout((HZ * secs) + 1); \
394+ }
395+
396+#endif
397+
398+#endif
399+
400+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
401+
402+/**
403+ * from_kuid - Convert kuid_t to uid_t.
404+ *
405+ * @ns: Unused.
406+ * @uid: kuid_t value.
407+ *
408+ * Returns uid seen from init's user namespace.
409+ */
410+#define from_kuid(ns, uid) (uid)
411+
412+/**
413+ * from_kgid - Convert kgid_t to gid_t.
414+ *
415+ * @ns: Unused.
416+ * @gid: kgid_t value.
417+ *
418+ * Returns gid seen from init's user namespace.
419+ */
420+#define from_kgid(ns, gid) (gid)
421+
422+/**
423+ * uid_eq - Check whether the uids are equals or not.
424+ *
425+ * @left: Uid seen from current user namespace.
426+ * @right: Uid seen from current user namespace.
427+ *
428+ * Returns true if uid is root in init's user namespace, false otherwise.
429+ */
430+#define uid_eq(left, right) ((left) == (right))
431+#define GLOBAL_ROOT_UID 0
432+
433+#endif
434+
435+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
436+#define d_backing_inode(upper) (upper)->d_inode
437+#endif
438+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
439+#define d_is_dir(dentry) ({ struct inode *inode = d_backing_inode(dentry); \
440+ inode && S_ISDIR(inode->i_mode); })
441+#endif
442+
443+/*
444+ * TOMOYO specific part start.
445+ */
446+
447+/* Clear TOMOYO 1.8 config. */
448+#undef CONFIG_CCSECURITY
449+#undef CONFIG_CCSECURITY_LKM
450+#undef CONFIG_CCSECURITY_DISABLE_BY_DEFAULT
451+#undef CONFIG_CCSECURITY_MAX_AUDIT_LOG
452+#undef CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY
453+#undef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
454+#undef CONFIG_CCSECURITY_POLICY_LOADER
455+#undef CONFIG_CCSECURITY_ACTIVATION_TRIGGER
456+#undef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
457+#undef CONFIG_CCSECURITY_FILE_READDIR
458+#undef CONFIG_CCSECURITY_FILE_GETATTR
459+#undef CONFIG_CCSECURITY_NETWORK
460+#undef CONFIG_CCSECURITY_NETWORK_RECVMSG
461+#undef CONFIG_CCSECURITY_CAPABILITY
462+#undef CONFIG_CCSECURITY_IPC
463+#undef CONFIG_CCSECURITY_MISC
464+#undef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
465+#undef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
466+#undef CONFIG_CCSECURITY_PORTRESERVE
467+/* Define AKARI 1.0 config. */
468+#include "config.h"
469+#ifndef CONFIG_CCSECURITY
470+#define CONFIG_CCSECURITY
471+#endif
472+#ifndef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
473+#define CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
474+#endif
475+#ifndef CONFIG_CCSECURITY_MAX_AUDIT_LOG
476+#define CONFIG_CCSECURITY_MAX_AUDIT_LOG 1024
477+#endif
478+#ifndef CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY
479+#define CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY 2048
480+#endif
481+#ifndef CONFIG_CCSECURITY_POLICY_LOADER
482+#define CONFIG_CCSECURITY_POLICY_LOADER "/sbin/ccs-init"
483+#endif
484+#ifndef CONFIG_CCSECURITY_ACTIVATION_TRIGGER
485+#define CONFIG_CCSECURITY_ACTIVATION_TRIGGER "/sbin/init"
486+#endif
487+#include "ccsecurity.h"
488+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
489+#error This module supports only 2.6.0 and later kernels.
490+#endif
491+#ifndef CONFIG_SECURITY
492+#error You must choose CONFIG_SECURITY=y for building this module.
493+#endif
494+#ifndef CONFIG_KALLSYMS
495+#error You must choose CONFIG_KALLSYMS=y for building this module.
496+#endif
497+#ifndef CONFIG_PROC_FS
498+#error You must choose CONFIG_PROC_FS=y for building this module.
499+#endif
500+#ifndef CONFIG_MODULES
501+#error You must choose CONFIG_MODULES=y for building this module.
502+#endif
503+
504+/* Enumeration definition for internal use. */
505+
506+/* Index numbers for Access Controls. */
507+enum ccs_acl_entry_type_index {
508+ CCS_TYPE_PATH_ACL,
509+ CCS_TYPE_PATH2_ACL,
510+ CCS_TYPE_PATH_NUMBER_ACL,
511+ CCS_TYPE_MKDEV_ACL,
512+ CCS_TYPE_MOUNT_ACL,
513+#ifdef CONFIG_CCSECURITY_MISC
514+ CCS_TYPE_ENV_ACL,
515+#endif
516+#ifdef CONFIG_CCSECURITY_CAPABILITY
517+ CCS_TYPE_CAPABILITY_ACL,
518+#endif
519+#ifdef CONFIG_CCSECURITY_NETWORK
520+ CCS_TYPE_INET_ACL,
521+ CCS_TYPE_UNIX_ACL,
522+#endif
523+#ifdef CONFIG_CCSECURITY_IPC
524+ CCS_TYPE_SIGNAL_ACL,
525+#endif
526+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
527+ CCS_TYPE_AUTO_EXECUTE_HANDLER,
528+ CCS_TYPE_DENIED_EXECUTE_HANDLER,
529+#endif
530+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
531+ CCS_TYPE_AUTO_TASK_ACL,
532+ CCS_TYPE_MANUAL_TASK_ACL,
533+#endif
534+};
535+
536+/* Index numbers for "struct ccs_condition". */
537+enum ccs_conditions_index {
538+ CCS_TASK_UID, /* current_uid() */
539+ CCS_TASK_EUID, /* current_euid() */
540+ CCS_TASK_SUID, /* current_suid() */
541+ CCS_TASK_FSUID, /* current_fsuid() */
542+ CCS_TASK_GID, /* current_gid() */
543+ CCS_TASK_EGID, /* current_egid() */
544+ CCS_TASK_SGID, /* current_sgid() */
545+ CCS_TASK_FSGID, /* current_fsgid() */
546+ CCS_TASK_PID, /* sys_getpid() */
547+ CCS_TASK_PPID, /* sys_getppid() */
548+ CCS_EXEC_ARGC, /* "struct linux_binprm *"->argc */
549+ CCS_EXEC_ENVC, /* "struct linux_binprm *"->envc */
550+ CCS_TYPE_IS_SOCKET, /* S_IFSOCK */
551+ CCS_TYPE_IS_SYMLINK, /* S_IFLNK */
552+ CCS_TYPE_IS_FILE, /* S_IFREG */
553+ CCS_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
554+ CCS_TYPE_IS_DIRECTORY, /* S_IFDIR */
555+ CCS_TYPE_IS_CHAR_DEV, /* S_IFCHR */
556+ CCS_TYPE_IS_FIFO, /* S_IFIFO */
557+ CCS_MODE_SETUID, /* S_ISUID */
558+ CCS_MODE_SETGID, /* S_ISGID */
559+ CCS_MODE_STICKY, /* S_ISVTX */
560+ CCS_MODE_OWNER_READ, /* S_IRUSR */
561+ CCS_MODE_OWNER_WRITE, /* S_IWUSR */
562+ CCS_MODE_OWNER_EXECUTE, /* S_IXUSR */
563+ CCS_MODE_GROUP_READ, /* S_IRGRP */
564+ CCS_MODE_GROUP_WRITE, /* S_IWGRP */
565+ CCS_MODE_GROUP_EXECUTE, /* S_IXGRP */
566+ CCS_MODE_OTHERS_READ, /* S_IROTH */
567+ CCS_MODE_OTHERS_WRITE, /* S_IWOTH */
568+ CCS_MODE_OTHERS_EXECUTE, /* S_IXOTH */
569+ CCS_TASK_TYPE, /* ((u8) task->ccs_flags) &
570+ CCS_TASK_IS_EXECUTE_HANDLER */
571+ CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
572+ CCS_EXEC_REALPATH,
573+ CCS_SYMLINK_TARGET,
574+ CCS_PATH1_UID,
575+ CCS_PATH1_GID,
576+ CCS_PATH1_INO,
577+ CCS_PATH1_MAJOR,
578+ CCS_PATH1_MINOR,
579+ CCS_PATH1_PERM,
580+ CCS_PATH1_TYPE,
581+ CCS_PATH1_DEV_MAJOR,
582+ CCS_PATH1_DEV_MINOR,
583+ CCS_PATH2_UID,
584+ CCS_PATH2_GID,
585+ CCS_PATH2_INO,
586+ CCS_PATH2_MAJOR,
587+ CCS_PATH2_MINOR,
588+ CCS_PATH2_PERM,
589+ CCS_PATH2_TYPE,
590+ CCS_PATH2_DEV_MAJOR,
591+ CCS_PATH2_DEV_MINOR,
592+ CCS_PATH1_PARENT_UID,
593+ CCS_PATH1_PARENT_GID,
594+ CCS_PATH1_PARENT_INO,
595+ CCS_PATH1_PARENT_PERM,
596+ CCS_PATH2_PARENT_UID,
597+ CCS_PATH2_PARENT_GID,
598+ CCS_PATH2_PARENT_INO,
599+ CCS_PATH2_PARENT_PERM,
600+ CCS_MAX_CONDITION_KEYWORD,
601+ CCS_NUMBER_UNION,
602+ CCS_NAME_UNION,
603+ CCS_ARGV_ENTRY,
604+ CCS_ENVP_ENTRY,
605+};
606+
607+/* Index numbers for domain's attributes. */
608+enum ccs_domain_info_flags_index {
609+ /* Quota warnning flag. */
610+ CCS_DIF_QUOTA_WARNED,
611+ /*
612+ * This domain was unable to create a new domain at
613+ * ccs_find_next_domain() because the name of the domain to be created
614+ * was too long or it could not allocate memory.
615+ * More than one process continued execve() without domain transition.
616+ */
617+ CCS_DIF_TRANSITION_FAILED,
618+ CCS_MAX_DOMAIN_INFO_FLAGS
619+};
620+
621+/* Index numbers for audit type. */
622+enum ccs_grant_log {
623+ /* Follow profile's configuration. */
624+ CCS_GRANTLOG_AUTO,
625+ /* Do not generate grant log. */
626+ CCS_GRANTLOG_NO,
627+ /* Generate grant_log. */
628+ CCS_GRANTLOG_YES,
629+};
630+
631+/* Index numbers for group entries. */
632+enum ccs_group_id {
633+ CCS_PATH_GROUP,
634+ CCS_NUMBER_GROUP,
635+#ifdef CONFIG_CCSECURITY_NETWORK
636+ CCS_ADDRESS_GROUP,
637+#endif
638+ CCS_MAX_GROUP
639+};
640+
641+/* Index numbers for category of functionality. */
642+enum ccs_mac_category_index {
643+ CCS_MAC_CATEGORY_FILE,
644+#ifdef CONFIG_CCSECURITY_NETWORK
645+ CCS_MAC_CATEGORY_NETWORK,
646+#endif
647+#ifdef CONFIG_CCSECURITY_MISC
648+ CCS_MAC_CATEGORY_MISC,
649+#endif
650+#ifdef CONFIG_CCSECURITY_IPC
651+ CCS_MAC_CATEGORY_IPC,
652+#endif
653+#ifdef CONFIG_CCSECURITY_CAPABILITY
654+ CCS_MAC_CATEGORY_CAPABILITY,
655+#endif
656+ CCS_MAX_MAC_CATEGORY_INDEX
657+};
658+
659+/* Index numbers for functionality. */
660+enum ccs_mac_index {
661+ CCS_MAC_FILE_EXECUTE,
662+ CCS_MAC_FILE_OPEN,
663+ CCS_MAC_FILE_CREATE,
664+ CCS_MAC_FILE_UNLINK,
665+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
666+ CCS_MAC_FILE_GETATTR,
667+#endif
668+ CCS_MAC_FILE_MKDIR,
669+ CCS_MAC_FILE_RMDIR,
670+ CCS_MAC_FILE_MKFIFO,
671+ CCS_MAC_FILE_MKSOCK,
672+ CCS_MAC_FILE_TRUNCATE,
673+ CCS_MAC_FILE_SYMLINK,
674+ CCS_MAC_FILE_MKBLOCK,
675+ CCS_MAC_FILE_MKCHAR,
676+ CCS_MAC_FILE_LINK,
677+ CCS_MAC_FILE_RENAME,
678+ CCS_MAC_FILE_CHMOD,
679+ CCS_MAC_FILE_CHOWN,
680+ CCS_MAC_FILE_CHGRP,
681+ CCS_MAC_FILE_IOCTL,
682+ CCS_MAC_FILE_CHROOT,
683+ CCS_MAC_FILE_MOUNT,
684+ CCS_MAC_FILE_UMOUNT,
685+ CCS_MAC_FILE_PIVOT_ROOT,
686+#ifdef CONFIG_CCSECURITY_NETWORK
687+ CCS_MAC_NETWORK_INET_STREAM_BIND,
688+ CCS_MAC_NETWORK_INET_STREAM_LISTEN,
689+ CCS_MAC_NETWORK_INET_STREAM_CONNECT,
690+ CCS_MAC_NETWORK_INET_STREAM_ACCEPT,
691+ CCS_MAC_NETWORK_INET_DGRAM_BIND,
692+ CCS_MAC_NETWORK_INET_DGRAM_SEND,
693+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
694+ CCS_MAC_NETWORK_INET_DGRAM_RECV,
695+#endif
696+ CCS_MAC_NETWORK_INET_RAW_BIND,
697+ CCS_MAC_NETWORK_INET_RAW_SEND,
698+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
699+ CCS_MAC_NETWORK_INET_RAW_RECV,
700+#endif
701+ CCS_MAC_NETWORK_UNIX_STREAM_BIND,
702+ CCS_MAC_NETWORK_UNIX_STREAM_LISTEN,
703+ CCS_MAC_NETWORK_UNIX_STREAM_CONNECT,
704+ CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT,
705+ CCS_MAC_NETWORK_UNIX_DGRAM_BIND,
706+ CCS_MAC_NETWORK_UNIX_DGRAM_SEND,
707+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
708+ CCS_MAC_NETWORK_UNIX_DGRAM_RECV,
709+#endif
710+ CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND,
711+ CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
712+ CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
713+ CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
714+#endif
715+#ifdef CONFIG_CCSECURITY_MISC
716+ CCS_MAC_ENVIRON,
717+#endif
718+#ifdef CONFIG_CCSECURITY_IPC
719+ CCS_MAC_SIGNAL,
720+#endif
721+#ifdef CONFIG_CCSECURITY_CAPABILITY
722+ CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
723+ CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
724+ CCS_MAC_CAPABILITY_SYS_REBOOT,
725+ CCS_MAC_CAPABILITY_SYS_VHANGUP,
726+ CCS_MAC_CAPABILITY_SYS_SETTIME,
727+ CCS_MAC_CAPABILITY_SYS_NICE,
728+ CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
729+ CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
730+ CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
731+ CCS_MAC_CAPABILITY_SYS_PTRACE,
732+#endif
733+ CCS_MAX_MAC_INDEX
734+};
735+
736+/* Index numbers for /proc/ccs/stat interface. */
737+enum ccs_memory_stat_type {
738+ CCS_MEMORY_POLICY,
739+ CCS_MEMORY_AUDIT,
740+ CCS_MEMORY_QUERY,
741+ CCS_MAX_MEMORY_STAT
742+};
743+
744+/* Index numbers for access controls with one pathname and three numbers. */
745+enum ccs_mkdev_acl_index {
746+ CCS_TYPE_MKBLOCK,
747+ CCS_TYPE_MKCHAR,
748+ CCS_MAX_MKDEV_OPERATION
749+};
750+
751+/* Index numbers for operation mode. */
752+enum ccs_mode_value {
753+ CCS_CONFIG_DISABLED,
754+ CCS_CONFIG_LEARNING,
755+ CCS_CONFIG_PERMISSIVE,
756+ CCS_CONFIG_ENFORCING,
757+ CCS_CONFIG_MAX_MODE,
758+ CCS_CONFIG_WANT_REJECT_LOG = 64,
759+ CCS_CONFIG_WANT_GRANT_LOG = 128,
760+ CCS_CONFIG_USE_DEFAULT = 255,
761+};
762+
763+/* Index numbers for socket operations. */
764+enum ccs_network_acl_index {
765+ CCS_NETWORK_BIND, /* bind() operation. */
766+ CCS_NETWORK_LISTEN, /* listen() operation. */
767+ CCS_NETWORK_CONNECT, /* connect() operation. */
768+ CCS_NETWORK_ACCEPT, /* accept() operation. */
769+ CCS_NETWORK_SEND, /* send() operation. */
770+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
771+ CCS_NETWORK_RECV, /* recv() operation. */
772+#endif
773+ CCS_MAX_NETWORK_OPERATION
774+};
775+
776+/* Index numbers for access controls with two pathnames. */
777+enum ccs_path2_acl_index {
778+ CCS_TYPE_LINK,
779+ CCS_TYPE_RENAME,
780+ CCS_TYPE_PIVOT_ROOT,
781+ CCS_MAX_PATH2_OPERATION
782+};
783+
784+/* Index numbers for access controls with one pathname. */
785+enum ccs_path_acl_index {
786+ CCS_TYPE_EXECUTE,
787+ CCS_TYPE_READ,
788+ CCS_TYPE_WRITE,
789+ CCS_TYPE_APPEND,
790+ CCS_TYPE_UNLINK,
791+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
792+ CCS_TYPE_GETATTR,
793+#endif
794+ CCS_TYPE_RMDIR,
795+ CCS_TYPE_TRUNCATE,
796+ CCS_TYPE_SYMLINK,
797+ CCS_TYPE_CHROOT,
798+ CCS_TYPE_UMOUNT,
799+ CCS_MAX_PATH_OPERATION
800+};
801+
802+/* Index numbers for access controls with one pathname and one number. */
803+enum ccs_path_number_acl_index {
804+ CCS_TYPE_CREATE,
805+ CCS_TYPE_MKDIR,
806+ CCS_TYPE_MKFIFO,
807+ CCS_TYPE_MKSOCK,
808+ CCS_TYPE_IOCTL,
809+ CCS_TYPE_CHMOD,
810+ CCS_TYPE_CHOWN,
811+ CCS_TYPE_CHGRP,
812+ CCS_MAX_PATH_NUMBER_OPERATION
813+};
814+
815+/* Index numbers for stat(). */
816+enum ccs_path_stat_index {
817+ /* Do not change this order. */
818+ CCS_PATH1,
819+ CCS_PATH1_PARENT,
820+ CCS_PATH2,
821+ CCS_PATH2_PARENT,
822+ CCS_MAX_PATH_STAT
823+};
824+
825+/* Index numbers for entry type. */
826+enum ccs_policy_id {
827+#ifdef CONFIG_CCSECURITY_PORTRESERVE
828+ CCS_ID_RESERVEDPORT,
829+#endif
830+ CCS_ID_GROUP,
831+#ifdef CONFIG_CCSECURITY_NETWORK
832+ CCS_ID_ADDRESS_GROUP,
833+#endif
834+ CCS_ID_PATH_GROUP,
835+ CCS_ID_NUMBER_GROUP,
836+ CCS_ID_AGGREGATOR,
837+ CCS_ID_TRANSITION_CONTROL,
838+ CCS_ID_MANAGER,
839+ CCS_ID_CONDITION,
840+ CCS_ID_NAME,
841+ CCS_ID_ACL,
842+ CCS_ID_DOMAIN,
843+ CCS_MAX_POLICY
844+};
845+
846+/* Index numbers for /proc/ccs/stat interface. */
847+enum ccs_policy_stat_type {
848+ /* Do not change this order. */
849+ CCS_STAT_POLICY_UPDATES,
850+ CCS_STAT_POLICY_LEARNING, /* == CCS_CONFIG_LEARNING */
851+ CCS_STAT_POLICY_PERMISSIVE, /* == CCS_CONFIG_PERMISSIVE */
852+ CCS_STAT_POLICY_ENFORCING, /* == CCS_CONFIG_ENFORCING */
853+ CCS_MAX_POLICY_STAT
854+};
855+
856+/* Index numbers for profile's PREFERENCE values. */
857+enum ccs_pref_index {
858+ CCS_PREF_MAX_AUDIT_LOG,
859+ CCS_PREF_MAX_LEARNING_ENTRY,
860+ CCS_PREF_ENFORCING_PENALTY,
861+ CCS_MAX_PREF
862+};
863+
864+/* Index numbers for /proc/ccs/ interfaces. */
865+enum ccs_proc_interface_index {
866+ CCS_DOMAIN_POLICY,
867+ CCS_EXCEPTION_POLICY,
868+ CCS_PROCESS_STATUS,
869+ CCS_STAT,
870+ CCS_AUDIT,
871+ CCS_VERSION,
872+ CCS_PROFILE,
873+ CCS_QUERY,
874+ CCS_MANAGER,
875+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
876+ CCS_EXECUTE_HANDLER,
877+#endif
878+};
879+
880+/* Index numbers for special mount operations. */
881+enum ccs_special_mount {
882+ CCS_MOUNT_BIND, /* mount --bind /source /dest */
883+ CCS_MOUNT_MOVE, /* mount --move /old /new */
884+ CCS_MOUNT_REMOUNT, /* mount -o remount /dir */
885+ CCS_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
886+ CCS_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */
887+ CCS_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */
888+ CCS_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */
889+ CCS_MAX_SPECIAL_MOUNT
890+};
891+
892+/* Index numbers for domain transition control keywords. */
893+enum ccs_transition_type {
894+ /* Do not change this order, */
895+ CCS_TRANSITION_CONTROL_NO_RESET,
896+ CCS_TRANSITION_CONTROL_RESET,
897+ CCS_TRANSITION_CONTROL_NO_INITIALIZE,
898+ CCS_TRANSITION_CONTROL_INITIALIZE,
899+ CCS_TRANSITION_CONTROL_NO_KEEP,
900+ CCS_TRANSITION_CONTROL_KEEP,
901+ CCS_MAX_TRANSITION_TYPE
902+};
903+
904+/* Index numbers for type of numeric values. */
905+enum ccs_value_type {
906+ CCS_VALUE_TYPE_INVALID,
907+ CCS_VALUE_TYPE_DECIMAL,
908+ CCS_VALUE_TYPE_OCTAL,
909+ CCS_VALUE_TYPE_HEXADECIMAL,
910+};
911+
912+/* Constants definition for internal use. */
913+
914+/*
915+ * TOMOYO uses this hash only when appending a string into the string table.
916+ * Frequency of appending strings is very low. So we don't need large (e.g.
917+ * 64k) hash size. 256 will be sufficient.
918+ */
919+#define CCS_HASH_BITS 8
920+#define CCS_MAX_HASH (1u << CCS_HASH_BITS)
921+
922+/*
923+ * TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
924+ * Therefore, we don't need SOCK_MAX.
925+ */
926+#define CCS_SOCK_MAX 6
927+
928+/* Size of temporary buffer for execve() operation. */
929+#define CCS_EXEC_TMPSIZE 4096
930+
931+/* Garbage collector is trying to kfree() this element. */
932+#define CCS_GC_IN_PROGRESS -1
933+
934+/* Profile number is an integer between 0 and 255. */
935+#define CCS_MAX_PROFILES 256
936+
937+/* Group number is an integer between 0 and 255. */
938+#define CCS_MAX_ACL_GROUPS 256
939+
940+/* Current thread is doing open(O_RDONLY | O_TRUNC) ? */
941+#define CCS_OPEN_FOR_READ_TRUNCATE 1
942+/* Current thread is doing open(3) ? */
943+#define CCS_OPEN_FOR_IOCTL_ONLY 2
944+/* Current thread is doing do_execve() ? */
945+#define CCS_TASK_IS_IN_EXECVE 4
946+/* Current thread is running as an execute handler program? */
947+#define CCS_TASK_IS_EXECUTE_HANDLER 8
948+/* Current thread is allowed to modify policy via /proc/ccs/ interface? */
949+#define CCS_TASK_IS_MANAGER 16
950+
951+/*
952+ * Retry this request. Returned by ccs_supervisor() if policy violation has
953+ * occurred in enforcing mode and the userspace daemon decided to retry.
954+ *
955+ * We must choose a positive value in order to distinguish "granted" (which is
956+ * 0) and "rejected" (which is a negative value) and "retry".
957+ */
958+#define CCS_RETRY_REQUEST 1
959+
960+/* The gfp flags used by TOMOYO. */
961+#define CCS_GFP_FLAGS GFP_NOFS
962+
963+/* Size of read buffer for /proc/ccs/ interface. */
964+#define CCS_MAX_IO_READ_QUEUE 64
965+
966+/* Structure definition for internal use. */
967+
968+/* Common header for holding ACL entries. */
969+struct ccs_acl_head {
970+ struct list_head list;
971+ s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
972+} __packed;
973+
974+/* Common header for shared entries. */
975+struct ccs_shared_acl_head {
976+ struct list_head list;
977+ atomic_t users;
978+} __packed;
979+
980+/* Common header for individual entries. */
981+struct ccs_acl_info {
982+ struct list_head list;
983+ struct ccs_condition *cond; /* Maybe NULL. */
984+ s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
985+ u8 type; /* One of values in "enum ccs_acl_entry_type_index". */
986+ u16 perm;
987+} __packed;
988+
989+/* Structure for holding a word. */
990+struct ccs_name_union {
991+ /* Either @filename or @group is NULL. */
992+ const struct ccs_path_info *filename;
993+ struct ccs_group *group;
994+};
995+
996+/* Structure for holding a number. */
997+struct ccs_number_union {
998+ unsigned long values[2];
999+ struct ccs_group *group; /* Maybe NULL. */
1000+ /* One of values in "enum ccs_value_type". */
1001+ u8 value_type[2];
1002+};
1003+
1004+/* Structure for holding an IP address. */
1005+struct ccs_ipaddr_union {
1006+ struct in6_addr ip[2]; /* Big endian. */
1007+ struct ccs_group *group; /* Pointer to address group. */
1008+ bool is_ipv6; /* Valid only if @group == NULL. */
1009+};
1010+
1011+/* Structure for "path_group"/"number_group"/"address_group" directive. */
1012+struct ccs_group {
1013+ struct ccs_shared_acl_head head;
1014+ /* Name of group (without leading '@'). */
1015+ const struct ccs_path_info *group_name;
1016+ /*
1017+ * List of "struct ccs_path_group" or "struct ccs_number_group" or
1018+ * "struct ccs_address_group".
1019+ */
1020+ struct list_head member_list;
1021+};
1022+
1023+/* Structure for "path_group" directive. */
1024+struct ccs_path_group {
1025+ struct ccs_acl_head head;
1026+ const struct ccs_path_info *member_name;
1027+};
1028+
1029+/* Structure for "number_group" directive. */
1030+struct ccs_number_group {
1031+ struct ccs_acl_head head;
1032+ struct ccs_number_union number;
1033+};
1034+
1035+/* Structure for "address_group" directive. */
1036+struct ccs_address_group {
1037+ struct ccs_acl_head head;
1038+ /* Structure for holding an IP address. */
1039+ struct ccs_ipaddr_union address;
1040+};
1041+
1042+/* Subset of "struct stat". Used by conditional ACL and audit logs. */
1043+struct ccs_mini_stat {
1044+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1045+ kuid_t uid;
1046+ kgid_t gid;
1047+#else
1048+ uid_t uid;
1049+ gid_t gid;
1050+#endif
1051+ ino_t ino;
1052+ umode_t mode;
1053+ dev_t dev;
1054+ dev_t rdev;
1055+};
1056+
1057+/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
1058+struct ccs_page_dump {
1059+ struct page *page; /* Previously dumped page. */
1060+ char *data; /* Contents of "page". Size is PAGE_SIZE. */
1061+};
1062+
1063+/* Structure for attribute checks in addition to pathname checks. */
1064+struct ccs_obj_info {
1065+ /* True if ccs_get_attributes() was already called, false otherwise. */
1066+ bool validate_done;
1067+ /* True if @stat[] is valid. */
1068+ bool stat_valid[CCS_MAX_PATH_STAT];
1069+ /* First pathname. Initialized with { NULL, NULL } if no path. */
1070+ struct path path1;
1071+ /* Second pathname. Initialized with { NULL, NULL } if no path. */
1072+ struct path path2;
1073+ /*
1074+ * Information on @path1, @path1's parent directory, @path2, @path2's
1075+ * parent directory.
1076+ */
1077+ struct ccs_mini_stat stat[CCS_MAX_PATH_STAT];
1078+ /*
1079+ * Content of symbolic link to be created. NULL for operations other
1080+ * than symlink().
1081+ */
1082+ struct ccs_path_info *symlink_target;
1083+};
1084+
1085+/* Structure for entries which follows "struct ccs_condition". */
1086+struct ccs_condition_element {
1087+ /*
1088+ * Left hand operand. A "struct ccs_argv" for CCS_ARGV_ENTRY, a
1089+ * "struct ccs_envp" for CCS_ENVP_ENTRY is attached to the tail
1090+ * of the array of this struct.
1091+ */
1092+ u8 left;
1093+ /*
1094+ * Right hand operand. A "struct ccs_number_union" for
1095+ * CCS_NUMBER_UNION, a "struct ccs_name_union" for CCS_NAME_UNION is
1096+ * attached to the tail of the array of this struct.
1097+ */
1098+ u8 right;
1099+ /* Equation operator. True if equals or overlaps, false otherwise. */
1100+ bool equals;
1101+};
1102+
1103+/* Structure for optional arguments. */
1104+struct ccs_condition {
1105+ struct ccs_shared_acl_head head;
1106+ u32 size; /* Memory size allocated for this entry. */
1107+ u16 condc; /* Number of conditions in this struct. */
1108+ u16 numbers_count; /* Number of "struct ccs_number_union values". */
1109+ u16 names_count; /* Number of "struct ccs_name_union names". */
1110+ u16 argc; /* Number of "struct ccs_argv". */
1111+ u16 envc; /* Number of "struct ccs_envp". */
1112+ u8 grant_log; /* One of values in "enum ccs_grant_log". */
1113+ bool exec_transit; /* True if transit is for "file execute". */
1114+ const struct ccs_path_info *transit; /* Maybe NULL. */
1115+ /*
1116+ * struct ccs_condition_element condition[condc];
1117+ * struct ccs_number_union values[numbers_count];
1118+ * struct ccs_name_union names[names_count];
1119+ * struct ccs_argv argv[argc];
1120+ * struct ccs_envp envp[envc];
1121+ */
1122+};
1123+
1124+struct ccs_execve;
1125+struct ccs_policy_namespace;
1126+
1127+/* Structure for request info. */
1128+struct ccs_request_info {
1129+ /*
1130+ * For holding parameters specific to operations which deal files.
1131+ * NULL if not dealing files.
1132+ */
1133+ struct ccs_obj_info *obj;
1134+ /*
1135+ * For holding parameters specific to execve() request.
1136+ * NULL if not dealing do_execve().
1137+ */
1138+ struct ccs_execve *ee;
1139+ /*
1140+ * For holding parameters.
1141+ * Pointers in this union are not NULL except path->matched_path.
1142+ */
1143+ union {
1144+ struct {
1145+ const struct ccs_path_info *filename;
1146+ /*
1147+ * For using wildcards at ccs_find_next_domain().
1148+ *
1149+ * The matched_acl cannot be used because it may refer
1150+ * a "struct ccs_path_acl" with ->is_group == true.
1151+ * We want to use exact "struct ccs_path_info" rather
1152+ * than "struct ccs_path_acl".
1153+ */
1154+ const struct ccs_path_info *matched_path;
1155+ /* One of values in "enum ccs_path_acl_index". */
1156+ u8 operation;
1157+ } path;
1158+ struct {
1159+ const struct ccs_path_info *filename1;
1160+ const struct ccs_path_info *filename2;
1161+ /* One of values in "enum ccs_path2_acl_index". */
1162+ u8 operation;
1163+ } path2;
1164+ struct {
1165+ const struct ccs_path_info *filename;
1166+ unsigned int mode;
1167+ unsigned int major;
1168+ unsigned int minor;
1169+ /* One of values in "enum ccs_mkdev_acl_index". */
1170+ u8 operation;
1171+ } mkdev;
1172+ struct {
1173+ const struct ccs_path_info *filename;
1174+ unsigned long number;
1175+ /*
1176+ * One of values in "enum ccs_path_number_acl_index".
1177+ */
1178+ u8 operation;
1179+ } path_number;
1180+#ifdef CONFIG_CCSECURITY_NETWORK
1181+ struct {
1182+ const u32 *address; /* Big endian. */
1183+ u16 port; /* Host endian. */
1184+ /* One of values smaller than CCS_SOCK_MAX. */
1185+ u8 protocol;
1186+ /* One of values in "enum ccs_network_acl_index". */
1187+ u8 operation;
1188+ bool is_ipv6;
1189+ } inet_network;
1190+ struct {
1191+ const struct ccs_path_info *address;
1192+ /* One of values smaller than CCS_SOCK_MAX. */
1193+ u8 protocol;
1194+ /* One of values in "enum ccs_network_acl_index". */
1195+ u8 operation;
1196+ } unix_network;
1197+#endif
1198+#ifdef CONFIG_CCSECURITY_MISC
1199+ struct {
1200+ const struct ccs_path_info *name;
1201+ } environ;
1202+#endif
1203+#ifdef CONFIG_CCSECURITY_CAPABILITY
1204+ struct {
1205+ /* One of values in "enum ccs_capability_acl_index". */
1206+ u8 operation;
1207+ } capability;
1208+#endif
1209+#ifdef CONFIG_CCSECURITY_IPC
1210+ struct {
1211+ const char *dest_pattern;
1212+ int sig;
1213+ } signal;
1214+#endif
1215+ struct {
1216+ const struct ccs_path_info *type;
1217+ const struct ccs_path_info *dir;
1218+ const struct ccs_path_info *dev;
1219+ unsigned long flags;
1220+ int need_dev;
1221+ } mount;
1222+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
1223+ struct {
1224+ const struct ccs_path_info *domainname;
1225+ } task;
1226+#endif
1227+ } param;
1228+ /*
1229+ * For updating current->ccs_domain_info at ccs_update_task_domain().
1230+ * Initialized to NULL at ccs_init_request_info().
1231+ * Matching "struct ccs_acl_info" is copied if access request was
1232+ * granted. Re-initialized to NULL at ccs_update_task_domain().
1233+ */
1234+ struct ccs_acl_info *matched_acl;
1235+ u8 param_type; /* One of values in "enum ccs_acl_entry_type_index". */
1236+ bool granted; /* True if granted, false otherwise. */
1237+ /* True if current thread should not be carried sleep penalty. */
1238+ bool dont_sleep_on_enforce_error;
1239+ /*
1240+ * For counting number of retries made for this request.
1241+ * This counter is incremented whenever ccs_supervisor() returned
1242+ * CCS_RETRY_REQUEST.
1243+ */
1244+ u8 retry;
1245+ /*
1246+ * For holding profile number used for this request.
1247+ * One of values between 0 and CCS_MAX_PROFILES - 1.
1248+ */
1249+ u8 profile;
1250+ /*
1251+ * For holding operation mode used for this request.
1252+ * One of CCS_CONFIG_DISABLED, CCS_CONFIG_LEARNING,
1253+ * CCS_CONFIG_PERMISSIVE, CCS_CONFIG_ENFORCING.
1254+ */
1255+ u8 mode;
1256+ /*
1257+ * For holding operation index used for this request.
1258+ * Used by ccs_init_request_info() / ccs_get_mode() /
1259+ * ccs_write_log(). One of values in "enum ccs_mac_index".
1260+ */
1261+ u8 type;
1262+};
1263+
1264+/* Structure for holding a token. */
1265+struct ccs_path_info {
1266+ const char *name;
1267+ u32 hash; /* = full_name_hash(name, strlen(name)) */
1268+ u16 total_len; /* = strlen(name) */
1269+ u16 const_len; /* = ccs_const_part_length(name) */
1270+ bool is_dir; /* = ccs_strendswith(name, "/") */
1271+ bool is_patterned; /* = const_len < total_len */
1272+};
1273+
1274+/* Structure for execve() operation. */
1275+struct ccs_execve {
1276+ struct ccs_request_info r;
1277+ struct ccs_obj_info obj;
1278+ struct linux_binprm *bprm;
1279+ struct ccs_domain_info *previous_domain;
1280+ const struct ccs_path_info *transition;
1281+ /* For execute_handler */
1282+ const struct ccs_path_info *handler;
1283+ char *handler_path; /* = kstrdup(handler->name, CCS_GFP_FLAGS) */
1284+ /* For dumping argv[] and envp[]. */
1285+ struct ccs_page_dump dump;
1286+ /* For temporary use. */
1287+ char *tmp; /* Size is CCS_EXEC_TMPSIZE bytes */
1288+};
1289+
1290+/* Structure for domain information. */
1291+struct ccs_domain_info {
1292+ struct list_head list;
1293+ struct list_head acl_info_list;
1294+ /* Name of this domain. Never NULL. */
1295+ const struct ccs_path_info *domainname;
1296+ /* Namespace for this domain. Never NULL. */
1297+ struct ccs_policy_namespace *ns;
1298+ /* Group numbers to use. */
1299+ unsigned long group[CCS_MAX_ACL_GROUPS / BITS_PER_LONG];
1300+ u8 profile; /* Profile number to use. */
1301+ bool is_deleted; /* Delete flag. */
1302+ bool flags[CCS_MAX_DOMAIN_INFO_FLAGS];
1303+};
1304+
1305+/*
1306+ * Structure for "reset_domain"/"no_reset_domain"/"initialize_domain"/
1307+ * "no_initialize_domain"/"keep_domain"/"no_keep_domain" keyword.
1308+ */
1309+struct ccs_transition_control {
1310+ struct ccs_acl_head head;
1311+ u8 type; /* One of values in "enum ccs_transition_type" */
1312+ bool is_last_name; /* True if the domainname is ccs_last_word(). */
1313+ const struct ccs_path_info *domainname; /* Maybe NULL */
1314+ const struct ccs_path_info *program; /* Maybe NULL */
1315+};
1316+
1317+/* Structure for "aggregator" keyword. */
1318+struct ccs_aggregator {
1319+ struct ccs_acl_head head;
1320+ const struct ccs_path_info *original_name;
1321+ const struct ccs_path_info *aggregated_name;
1322+};
1323+
1324+/* Structure for "deny_autobind" keyword. */
1325+struct ccs_reserved {
1326+ struct ccs_acl_head head;
1327+ struct ccs_number_union port;
1328+};
1329+
1330+/* Structure for policy manager. */
1331+struct ccs_manager {
1332+ struct ccs_acl_head head;
1333+ /* A path to program or a domainname. */
1334+ const struct ccs_path_info *manager;
1335+};
1336+
1337+/* Structure for argv[]. */
1338+struct ccs_argv {
1339+ unsigned long index;
1340+ const struct ccs_path_info *value;
1341+ bool is_not;
1342+};
1343+
1344+/* Structure for envp[]. */
1345+struct ccs_envp {
1346+ const struct ccs_path_info *name;
1347+ const struct ccs_path_info *value;
1348+ bool is_not;
1349+};
1350+
1351+/*
1352+ * Structure for "task auto_execute_handler" and "task denied_execute_handler"
1353+ * directive.
1354+ *
1355+ * If "task auto_execute_handler" directive exists and the current process is
1356+ * not an execute handler, all execve() requests are replaced by execve()
1357+ * requests of a program specified by "task auto_execute_handler" directive.
1358+ * If the current process is an execute handler, "task auto_execute_handler"
1359+ * and "task denied_execute_handler" directives are ignored.
1360+ * The program specified by "task execute_handler" validates execve()
1361+ * parameters and executes the original execve() requests if appropriate.
1362+ *
1363+ * "task denied_execute_handler" directive is used only when execve() request
1364+ * was rejected in enforcing mode (i.e. CONFIG::file::execute={ mode=enforcing
1365+ * }). The program specified by "task denied_execute_handler" does whatever it
1366+ * wants to do (e.g. silently terminate, change firewall settings, redirect the
1367+ * user to honey pot etc.).
1368+ */
1369+struct ccs_handler_acl {
1370+ struct ccs_acl_info head; /* type = CCS_TYPE_*_EXECUTE_HANDLER */
1371+ const struct ccs_path_info *handler; /* Pointer to single pathname. */
1372+};
1373+
1374+/*
1375+ * Structure for "task auto_domain_transition" and
1376+ * "task manual_domain_transition" directive.
1377+ */
1378+struct ccs_task_acl {
1379+ struct ccs_acl_info head; /* type = CCS_TYPE_*_TASK_ACL */
1380+ /* Pointer to domainname. */
1381+ const struct ccs_path_info *domainname;
1382+};
1383+
1384+/*
1385+ * Structure for "file execute", "file read", "file write", "file append",
1386+ * "file unlink", "file getattr", "file rmdir", "file truncate",
1387+ * "file symlink", "file chroot" and "file unmount" directive.
1388+ */
1389+struct ccs_path_acl {
1390+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
1391+ struct ccs_name_union name;
1392+};
1393+
1394+/*
1395+ * Structure for "file rename", "file link" and "file pivot_root" directive.
1396+ */
1397+struct ccs_path2_acl {
1398+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
1399+ struct ccs_name_union name1;
1400+ struct ccs_name_union name2;
1401+};
1402+
1403+/*
1404+ * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
1405+ * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
1406+ */
1407+struct ccs_path_number_acl {
1408+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */
1409+ struct ccs_name_union name;
1410+ struct ccs_number_union number;
1411+};
1412+
1413+/* Structure for "file mkblock" and "file mkchar" directive. */
1414+struct ccs_mkdev_acl {
1415+ struct ccs_acl_info head; /* type = CCS_TYPE_MKDEV_ACL */
1416+ struct ccs_name_union name;
1417+ struct ccs_number_union mode;
1418+ struct ccs_number_union major;
1419+ struct ccs_number_union minor;
1420+};
1421+
1422+/* Structure for "file mount" directive. */
1423+struct ccs_mount_acl {
1424+ struct ccs_acl_info head; /* type = CCS_TYPE_MOUNT_ACL */
1425+ struct ccs_name_union dev_name;
1426+ struct ccs_name_union dir_name;
1427+ struct ccs_name_union fs_type;
1428+ struct ccs_number_union flags;
1429+};
1430+
1431+/* Structure for "misc env" directive in domain policy. */
1432+struct ccs_env_acl {
1433+ struct ccs_acl_info head; /* type = CCS_TYPE_ENV_ACL */
1434+ const struct ccs_path_info *env; /* environment variable */
1435+};
1436+
1437+/* Structure for "capability" directive. */
1438+struct ccs_capability_acl {
1439+ struct ccs_acl_info head; /* type = CCS_TYPE_CAPABILITY_ACL */
1440+ u8 operation; /* One of values in "enum ccs_capability_acl_index". */
1441+};
1442+
1443+/* Structure for "ipc signal" directive. */
1444+struct ccs_signal_acl {
1445+ struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */
1446+ struct ccs_number_union sig;
1447+ /* Pointer to destination pattern. */
1448+ const struct ccs_path_info *domainname;
1449+};
1450+
1451+/* Structure for "network inet" directive. */
1452+struct ccs_inet_acl {
1453+ struct ccs_acl_info head; /* type = CCS_TYPE_INET_ACL */
1454+ u8 protocol;
1455+ struct ccs_ipaddr_union address;
1456+ struct ccs_number_union port;
1457+};
1458+
1459+/* Structure for "network unix" directive. */
1460+struct ccs_unix_acl {
1461+ struct ccs_acl_info head; /* type = CCS_TYPE_UNIX_ACL */
1462+ u8 protocol;
1463+ struct ccs_name_union name;
1464+};
1465+
1466+/* Structure for holding string data. */
1467+struct ccs_name {
1468+ struct ccs_shared_acl_head head;
1469+ int size; /* Memory size allocated for this entry. */
1470+ struct ccs_path_info entry;
1471+};
1472+
1473+/* Structure for holding a line from /proc/ccs/ interface. */
1474+struct ccs_acl_param {
1475+ char *data; /* Unprocessed data. */
1476+ struct list_head *list; /* List to add or remove. */
1477+ struct ccs_policy_namespace *ns; /* Namespace to use. */
1478+ bool is_delete; /* True if it is a delete request. */
1479+ union ccs_acl_union {
1480+ struct ccs_acl_info acl_info;
1481+ struct ccs_handler_acl handler_acl;
1482+ struct ccs_task_acl task_acl;
1483+ struct ccs_path_acl path_acl;
1484+ struct ccs_path2_acl path2_acl;
1485+ struct ccs_path_number_acl path_number_acl;
1486+ struct ccs_mkdev_acl mkdev_acl;
1487+ struct ccs_mount_acl mount_acl;
1488+ struct ccs_env_acl env_acl;
1489+ struct ccs_capability_acl capability_acl;
1490+ struct ccs_signal_acl signal_acl;
1491+ struct ccs_inet_acl inet_acl;
1492+ struct ccs_unix_acl unix_acl;
1493+ /**/
1494+ struct ccs_acl_head acl_head;
1495+ struct ccs_transition_control transition_control;
1496+ struct ccs_aggregator aggregator;
1497+ struct ccs_reserved reserved;
1498+ struct ccs_manager manager;
1499+ struct ccs_path_group path_group;
1500+ struct ccs_number_group number_group;
1501+ struct ccs_address_group address_group;
1502+ } e;
1503+};
1504+
1505+/* Structure for reading/writing policy via /proc/ccs/ interfaces. */
1506+struct ccs_io_buffer {
1507+ /* Exclusive lock for this structure. */
1508+ struct mutex io_sem;
1509+ char __user *read_user_buf;
1510+ size_t read_user_buf_avail;
1511+ struct {
1512+ struct list_head *ns;
1513+ struct list_head *domain;
1514+ struct list_head *group;
1515+ struct list_head *acl;
1516+ size_t avail;
1517+ unsigned int step;
1518+ unsigned int query_index;
1519+ u16 index;
1520+ u16 cond_index;
1521+ u8 acl_group_index;
1522+ u8 cond_step;
1523+ u8 bit;
1524+ u8 w_pos;
1525+ bool eof;
1526+ bool print_this_domain_only;
1527+ bool print_transition_related_only;
1528+ bool print_cond_part;
1529+ const char *w[CCS_MAX_IO_READ_QUEUE];
1530+ } r;
1531+ struct {
1532+ struct ccs_policy_namespace *ns;
1533+ struct ccs_domain_info *domain;
1534+ size_t avail;
1535+ bool is_delete;
1536+ } w;
1537+ /* Buffer for reading. */
1538+ char *read_buf;
1539+ /* Size of read buffer. */
1540+ size_t readbuf_size;
1541+ /* Buffer for writing. */
1542+ char *write_buf;
1543+ /* Size of write buffer. */
1544+ size_t writebuf_size;
1545+ /* Type of interface. */
1546+ enum ccs_proc_interface_index type;
1547+ /* Users counter protected by ccs_io_buffer_list_lock. */
1548+ u8 users;
1549+ /* List for telling GC not to kfree() elements. */
1550+ struct list_head list;
1551+};
1552+
1553+/* Structure for /proc/ccs/profile interface. */
1554+struct ccs_profile {
1555+ const struct ccs_path_info *comment;
1556+ u8 default_config;
1557+ u8 config[CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX];
1558+ unsigned int pref[CCS_MAX_PREF];
1559+};
1560+
1561+/* Structure for representing YYYY/MM/DD hh/mm/ss. */
1562+struct ccs_time {
1563+ u16 year;
1564+ u8 month;
1565+ u8 day;
1566+ u8 hour;
1567+ u8 min;
1568+ u8 sec;
1569+};
1570+
1571+/* Structure for policy namespace. */
1572+struct ccs_policy_namespace {
1573+ /* Profile table. Memory is allocated as needed. */
1574+ struct ccs_profile *profile_ptr[CCS_MAX_PROFILES];
1575+ /* List of "struct ccs_group". */
1576+ struct list_head group_list[CCS_MAX_GROUP];
1577+ /* List of policy. */
1578+ struct list_head policy_list[CCS_MAX_POLICY];
1579+ /* The global ACL referred by "use_group" keyword. */
1580+ struct list_head acl_group[CCS_MAX_ACL_GROUPS];
1581+ /* List for connecting to ccs_namespace_list list. */
1582+ struct list_head namespace_list;
1583+ /* Profile version. Currently only 20200505 is supported. */
1584+ unsigned int profile_version;
1585+ /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
1586+ const char *name;
1587+};
1588+
1589+/* Prototype definition for "struct ccsecurity_operations". */
1590+
1591+void __init ccs_permission_init(void);
1592+void __init ccs_mm_init(void);
1593+
1594+/* Prototype definition for internal use. */
1595+
1596+bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
1597+ struct ccs_page_dump *dump);
1598+bool ccs_memory_ok(const void *ptr, const unsigned int size);
1599+char *ccs_encode(const char *str);
1600+char *ccs_encode2(const char *str, int str_len);
1601+char *ccs_realpath(const struct path *path);
1602+const char *ccs_get_exe(void);
1603+const struct ccs_path_info *ccs_get_name(const char *name);
1604+int ccs_audit_log(struct ccs_request_info *r);
1605+int ccs_check_acl(struct ccs_request_info *r);
1606+int ccs_init_request_info(struct ccs_request_info *r, const u8 index);
1607+struct ccs_domain_info *ccs_assign_domain(const char *domainname,
1608+ const bool transit);
1609+u8 ccs_get_config(const u8 profile, const u8 index);
1610+void *ccs_commit_ok(void *data, const unsigned int size);
1611+void ccs_del_acl(struct list_head *element);
1612+void ccs_del_condition(struct list_head *element);
1613+void ccs_fill_path_info(struct ccs_path_info *ptr);
1614+void ccs_get_attributes(struct ccs_obj_info *obj);
1615+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register);
1616+void ccs_transition_failed(const char *domainname);
1617+void ccs_warn_oom(const char *function);
1618+void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...)
1619+ __printf(2, 3);
1620+
1621+/* Variable definition for internal use. */
1622+
1623+extern bool ccs_policy_loaded;
1624+extern const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS];
1625+extern const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX];
1626+extern const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION];
1627+extern const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION];
1628+extern const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION];
1629+extern struct ccs_domain_info ccs_kernel_domain;
1630+extern struct list_head ccs_condition_list;
1631+extern struct list_head ccs_domain_list;
1632+extern struct list_head ccs_name_list[CCS_MAX_HASH];
1633+extern struct list_head ccs_namespace_list;
1634+extern struct mutex ccs_policy_lock;
1635+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1636+extern struct srcu_struct ccs_ss;
1637+#endif
1638+extern unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT];
1639+extern unsigned int ccs_memory_used[CCS_MAX_MEMORY_STAT];
1640+
1641+/* Inlined functions for internal use. */
1642+
1643+/**
1644+ * ccs_pathcmp - strcmp() for "struct ccs_path_info" structure.
1645+ *
1646+ * @a: Pointer to "struct ccs_path_info".
1647+ * @b: Pointer to "struct ccs_path_info".
1648+ *
1649+ * Returns true if @a != @b, false otherwise.
1650+ */
1651+static inline bool ccs_pathcmp(const struct ccs_path_info *a,
1652+ const struct ccs_path_info *b)
1653+{
1654+ return a->hash != b->hash || strcmp(a->name, b->name);
1655+}
1656+
1657+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1658+
1659+/**
1660+ * ccs_read_lock - Take lock for protecting policy.
1661+ *
1662+ * Returns index number for ccs_read_unlock().
1663+ */
1664+static inline int ccs_read_lock(void)
1665+{
1666+ return srcu_read_lock(&ccs_ss);
1667+}
1668+
1669+/**
1670+ * ccs_read_unlock - Release lock for protecting policy.
1671+ *
1672+ * @idx: Index number returned by ccs_read_lock().
1673+ *
1674+ * Returns nothing.
1675+ */
1676+static inline void ccs_read_unlock(const int idx)
1677+{
1678+ srcu_read_unlock(&ccs_ss, idx);
1679+}
1680+
1681+#else
1682+
1683+int ccs_lock(void);
1684+void ccs_unlock(const int idx);
1685+
1686+/**
1687+ * ccs_read_lock - Take lock for protecting policy.
1688+ *
1689+ * Returns index number for ccs_read_unlock().
1690+ */
1691+static inline int ccs_read_lock(void)
1692+{
1693+ return ccs_lock();
1694+}
1695+
1696+/**
1697+ * ccs_read_unlock - Release lock for protecting policy.
1698+ *
1699+ * @idx: Index number returned by ccs_read_lock().
1700+ *
1701+ * Returns nothing.
1702+ */
1703+static inline void ccs_read_unlock(const int idx)
1704+{
1705+ ccs_unlock(idx);
1706+}
1707+
1708+#endif
1709+
1710+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
1711+
1712+/**
1713+ * ccs_tasklist_lock - Take lock for reading list of "struct task_struct".
1714+ *
1715+ * Returns nothing.
1716+ */
1717+static inline void ccs_tasklist_lock(void)
1718+{
1719+ rcu_read_lock();
1720+}
1721+
1722+/**
1723+ * ccs_tasklist_unlock - Release lock for reading list of "struct task_struct".
1724+ *
1725+ * Returns nothing.
1726+ */
1727+static inline void ccs_tasklist_unlock(void)
1728+{
1729+ rcu_read_unlock();
1730+}
1731+
1732+#else
1733+
1734+/**
1735+ * ccs_tasklist_lock - Take lock for reading list of "struct task_struct".
1736+ *
1737+ * Returns nothing.
1738+ */
1739+static inline void ccs_tasklist_lock(void)
1740+{
1741+ read_lock(&tasklist_lock);
1742+}
1743+
1744+/**
1745+ * ccs_tasklist_unlock - Release lock for reading list of "struct task_struct".
1746+ *
1747+ * Returns nothing.
1748+ */
1749+static inline void ccs_tasklist_unlock(void)
1750+{
1751+ read_unlock(&tasklist_lock);
1752+}
1753+
1754+#endif
1755+
1756+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1757+
1758+/**
1759+ * ccs_sys_getppid - Copy of getppid().
1760+ *
1761+ * Returns parent process's PID.
1762+ *
1763+ * Alpha does not have getppid() defined. To be able to build this module on
1764+ * Alpha, I have to copy getppid() from kernel/timer.c.
1765+ */
1766+static inline pid_t ccs_sys_getppid(void)
1767+{
1768+ pid_t pid;
1769+ rcu_read_lock();
1770+ pid = task_tgid_vnr(rcu_dereference(current->real_parent));
1771+ rcu_read_unlock();
1772+ return pid;
1773+}
1774+
1775+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1776+
1777+/**
1778+ * ccs_sys_getppid - Copy of getppid().
1779+ *
1780+ * Returns parent process's PID.
1781+ *
1782+ * This function was rewritten to use RCU in 2.6.16.34. However, distributors
1783+ * which use earlier kernels (e.g. 2.6.8/2.6.9) did not backport the bugfix.
1784+ * Therefore, I'm using code for 2.6.16.34 for earlier kernels.
1785+ */
1786+static inline pid_t ccs_sys_getppid(void)
1787+{
1788+ pid_t pid;
1789+ rcu_read_lock();
1790+#if (defined(RHEL_MAJOR) && RHEL_MAJOR == 5) || (defined(AX_MAJOR) && AX_MAJOR == 3)
1791+ pid = rcu_dereference(current->parent)->tgid;
1792+#elif defined(CONFIG_UTRACE)
1793+ /*
1794+ * RHEL 5.0 kernel does not have RHEL_MAJOR/RHEL_MINOR defined.
1795+ * Assume RHEL 5.0 if CONFIG_UTRACE is defined.
1796+ */
1797+ pid = rcu_dereference(current->parent)->tgid;
1798+#else
1799+ pid = rcu_dereference(current->real_parent)->tgid;
1800+#endif
1801+ rcu_read_unlock();
1802+ return pid;
1803+}
1804+
1805+#else
1806+
1807+/**
1808+ * ccs_sys_getppid - Copy of getppid().
1809+ *
1810+ * Returns parent process's PID.
1811+ *
1812+ * I can't use code for 2.6.16.34 for 2.4 kernels because 2.4 kernels does not
1813+ * have RCU. Therefore, I'm using pessimistic lock (i.e. tasklist_lock
1814+ * spinlock).
1815+ */
1816+static inline pid_t ccs_sys_getppid(void)
1817+{
1818+ pid_t pid;
1819+ read_lock(&tasklist_lock);
1820+#ifdef TASK_DEAD
1821+ pid = current->group_leader->real_parent->tgid;
1822+#else
1823+ pid = current->p_opptr->pid;
1824+#endif
1825+ read_unlock(&tasklist_lock);
1826+ return pid;
1827+}
1828+
1829+#endif
1830+
1831+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1832+
1833+/**
1834+ * ccs_sys_getpid - Copy of getpid().
1835+ *
1836+ * Returns current thread's PID.
1837+ *
1838+ * Alpha does not have getpid() defined. To be able to build this module on
1839+ * Alpha, I have to copy getpid() from kernel/timer.c.
1840+ */
1841+static inline pid_t ccs_sys_getpid(void)
1842+{
1843+ return task_tgid_vnr(current);
1844+}
1845+
1846+#else
1847+
1848+/**
1849+ * ccs_sys_getpid - Copy of getpid().
1850+ *
1851+ * Returns current thread's PID.
1852+ */
1853+static inline pid_t ccs_sys_getpid(void)
1854+{
1855+ return current->tgid;
1856+}
1857+
1858+#endif
1859+
1860+/**
1861+ * ccs_get_mode - Get mode for specified functionality.
1862+ *
1863+ * @profile: Profile number.
1864+ * @index: Functionality number.
1865+ *
1866+ * Returns mode.
1867+ */
1868+static inline u8 ccs_get_mode(const u8 profile, const u8 index)
1869+{
1870+ return ccs_get_config(profile, index) & (CCS_CONFIG_MAX_MODE - 1);
1871+}
1872+
1873+#if defined(CONFIG_SLOB)
1874+
1875+/**
1876+ * ccs_round2 - Round up to power of 2 for calculating memory usage.
1877+ *
1878+ * @size: Size to be rounded up.
1879+ *
1880+ * Returns @size.
1881+ *
1882+ * Since SLOB does not round up, this function simply returns @size.
1883+ */
1884+static inline int ccs_round2(size_t size)
1885+{
1886+ return size;
1887+}
1888+
1889+#else
1890+
1891+/**
1892+ * ccs_round2 - Round up to power of 2 for calculating memory usage.
1893+ *
1894+ * @size: Size to be rounded up.
1895+ *
1896+ * Returns rounded size.
1897+ *
1898+ * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
1899+ * (e.g.) 128 bytes.
1900+ */
1901+static inline int ccs_round2(size_t size)
1902+{
1903+#if PAGE_SIZE == 4096
1904+ size_t bsize = 32;
1905+#else
1906+ size_t bsize = 64;
1907+#endif
1908+ if (!size)
1909+ return 0;
1910+ while (size > bsize)
1911+ bsize <<= 1;
1912+ return bsize;
1913+}
1914+
1915+#endif
1916+
1917+/**
1918+ * ccs_put_condition - Drop reference on "struct ccs_condition".
1919+ *
1920+ * @cond: Pointer to "struct ccs_condition". Maybe NULL.
1921+ *
1922+ * Returns nothing.
1923+ */
1924+static inline void ccs_put_condition(struct ccs_condition *cond)
1925+{
1926+ if (cond)
1927+ atomic_dec(&cond->head.users);
1928+}
1929+
1930+/**
1931+ * ccs_put_group - Drop reference on "struct ccs_group".
1932+ *
1933+ * @group: Pointer to "struct ccs_group". Maybe NULL.
1934+ *
1935+ * Returns nothing.
1936+ */
1937+static inline void ccs_put_group(struct ccs_group *group)
1938+{
1939+ if (group)
1940+ atomic_dec(&group->head.users);
1941+}
1942+
1943+/**
1944+ * ccs_put_name - Drop reference on "struct ccs_name".
1945+ *
1946+ * @name: Pointer to "struct ccs_path_info". Maybe NULL.
1947+ *
1948+ * Returns nothing.
1949+ */
1950+static inline void ccs_put_name(const struct ccs_path_info *name)
1951+{
1952+ if (name)
1953+ atomic_dec(&container_of(name, struct ccs_name, entry)->
1954+ head.users);
1955+}
1956+
1957+/* For importing variables and functions. */
1958+extern struct ccsecurity_exports ccsecurity_exports;
1959+
1960+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
1961+
1962+/*
1963+ * Structure for holding "struct ccs_domain_info *" and "struct ccs_execve *"
1964+ * and "u32 ccs_flags" for each "struct task_struct".
1965+ *
1966+ * "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct"
1967+ * are maintained outside that "struct task_struct". Therefore, ccs_security
1968+ * != task_struct . This keeps KABI for distributor's prebuilt kernels but
1969+ * entails slow access.
1970+ *
1971+ * Memory for this structure is allocated when current thread tries to access
1972+ * it. Therefore, if memory allocation failed, current thread will be killed by
1973+ * SIGKILL. Note that if current->pid == 1, sending SIGKILL won't work.
1974+ */
1975+struct ccs_security {
1976+ struct list_head list;
1977+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) || LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1978+ const struct task_struct *task;
1979+#else
1980+ struct pid *pid; /* Maybe NULL. */
1981+ const struct cred *cred; /* Maybe NULL. */
1982+#endif
1983+ struct ccs_domain_info *ccs_domain_info;
1984+ u32 ccs_flags;
1985+ struct ccs_execve *ee; /* Maybe NULL. */
1986+ struct rcu_head rcu;
1987+};
1988+
1989+void __init ccs_main_init(void);
1990+bool ccs_used_by_cred(const struct ccs_domain_info *domain);
1991+int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep);
1992+void ccs_finish_execve(int retval, struct ccs_execve *ee);
1993+void ccs_load_policy(const char *filename);
1994+#ifndef CONFIG_AKARI_TRACE_EXECVE_COUNT
1995+#define ccs_audit_alloc_execve(ee) do { } while (0)
1996+#define ccs_audit_free_execve(ee, is_current) do { } while (0)
1997+#else
1998+void ccs_audit_alloc_execve(const struct ccs_execve * const ee);
1999+void ccs_audit_free_execve(const struct ccs_execve * const ee,
2000+ const bool is_current);
2001+#endif
2002+
2003+#define CCS_TASK_SECURITY_HASH_BITS 12
2004+#define CCS_MAX_TASK_SECURITY_HASH (1u << CCS_TASK_SECURITY_HASH_BITS)
2005+extern struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
2006+
2007+struct ccs_security *ccs_find_task_security(const struct task_struct *task);
2008+
2009+/**
2010+ * ccs_current_security - Get "struct ccs_security" for current thread.
2011+ *
2012+ * Returns pointer to "struct ccs_security" for current thread.
2013+ */
2014+static inline struct ccs_security *ccs_current_security(void)
2015+{
2016+ return ccs_find_task_security(current);
2017+}
2018+
2019+/**
2020+ * ccs_task_domain - Get "struct ccs_domain_info" for specified thread.
2021+ *
2022+ * @task: Pointer to "struct task_struct".
2023+ *
2024+ * Returns pointer to "struct ccs_security" for specified thread.
2025+ */
2026+static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
2027+{
2028+ struct ccs_domain_info *domain;
2029+ rcu_read_lock();
2030+ domain = ccs_find_task_security(task)->ccs_domain_info;
2031+ rcu_read_unlock();
2032+ return domain;
2033+}
2034+
2035+/**
2036+ * ccs_current_domain - Get "struct ccs_domain_info" for current thread.
2037+ *
2038+ * Returns pointer to "struct ccs_domain_info" for current thread.
2039+ */
2040+static inline struct ccs_domain_info *ccs_current_domain(void)
2041+{
2042+ return ccs_find_task_security(current)->ccs_domain_info;
2043+}
2044+
2045+/**
2046+ * ccs_task_flags - Get flags for specified thread.
2047+ *
2048+ * @task: Pointer to "struct task_struct".
2049+ *
2050+ * Returns flags for specified thread.
2051+ */
2052+static inline u32 ccs_task_flags(struct task_struct *task)
2053+{
2054+ u32 ccs_flags;
2055+ rcu_read_lock();
2056+ ccs_flags = ccs_find_task_security(task)->ccs_flags;
2057+ rcu_read_unlock();
2058+ return ccs_flags;
2059+}
2060+
2061+/**
2062+ * ccs_current_flags - Get flags for current thread.
2063+ *
2064+ * Returns flags for current thread.
2065+ */
2066+static inline u32 ccs_current_flags(void)
2067+{
2068+ return ccs_find_task_security(current)->ccs_flags;
2069+}
2070+
2071+#else
2072+
2073+/*
2074+ * "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct"
2075+ * are maintained inside that "struct task_struct". Therefore, ccs_security ==
2076+ * task_struct . This allows fast access but breaks KABI checks for
2077+ * distributor's prebuilt kernels due to changes in "struct task_struct".
2078+ */
2079+#define ccs_security task_struct
2080+
2081+/**
2082+ * ccs_find_task_security - Find "struct ccs_security" for given task.
2083+ *
2084+ * @task: Pointer to "struct task_struct".
2085+ *
2086+ * Returns pointer to "struct ccs_security".
2087+ */
2088+static inline struct ccs_security *ccs_find_task_security(struct task_struct *
2089+ task)
2090+{
2091+ return task;
2092+}
2093+
2094+/**
2095+ * ccs_current_security - Get "struct ccs_security" for current thread.
2096+ *
2097+ * Returns pointer to "struct ccs_security" for current thread.
2098+ */
2099+static inline struct ccs_security *ccs_current_security(void)
2100+{
2101+ return ccs_find_task_security(current);
2102+}
2103+
2104+/**
2105+ * ccs_task_domain - Get "struct ccs_domain_info" for specified thread.
2106+ *
2107+ * @task: Pointer to "struct task_struct".
2108+ *
2109+ * Returns pointer to "struct ccs_security" for specified thread.
2110+ */
2111+static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
2112+{
2113+ struct ccs_domain_info *domain = task->ccs_domain_info;
2114+ return domain ? domain : &ccs_kernel_domain;
2115+}
2116+
2117+/**
2118+ * ccs_current_domain - Get "struct ccs_domain_info" for current thread.
2119+ *
2120+ * Returns pointer to "struct ccs_domain_info" for current thread.
2121+ *
2122+ * If current thread does not belong to a domain (which is true for initial
2123+ * init_task in order to hide ccs_kernel_domain from this module),
2124+ * current thread enters into ccs_kernel_domain.
2125+ */
2126+static inline struct ccs_domain_info *ccs_current_domain(void)
2127+{
2128+ struct task_struct *task = current;
2129+ if (!task->ccs_domain_info)
2130+ task->ccs_domain_info = &ccs_kernel_domain;
2131+ return task->ccs_domain_info;
2132+}
2133+
2134+/**
2135+ * ccs_task_flags - Get flags for specified thread.
2136+ *
2137+ * @task: Pointer to "struct task_struct".
2138+ *
2139+ * Returns flags for specified thread.
2140+ */
2141+static inline u32 ccs_task_flags(struct task_struct *task)
2142+{
2143+ return ccs_find_task_security(task)->ccs_flags;
2144+}
2145+
2146+/**
2147+ * ccs_current_flags - Get flags for current thread.
2148+ *
2149+ * Returns flags for current thread.
2150+ */
2151+static inline u32 ccs_current_flags(void)
2152+{
2153+ return ccs_find_task_security(current)->ccs_flags;
2154+}
2155+
2156+#endif
2157+
2158+/**
2159+ * ccs_current_namespace - Get "struct ccs_policy_namespace" for current thread.
2160+ *
2161+ * Returns pointer to "struct ccs_policy_namespace" for current thread.
2162+ */
2163+static inline struct ccs_policy_namespace *ccs_current_namespace(void)
2164+{
2165+ return ccs_current_domain()->ns;
2166+}
2167+
2168+#endif
--- tags/patches/1.0.47/load_policy.c (nonexistent)
+++ tags/patches/1.0.47/load_policy.c (revision 672)
@@ -0,0 +1,385 @@
1+/*
2+ * security/ccsecurity/load_policy.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#include <linux/version.h>
10+#include <linux/module.h>
11+#include <linux/init.h>
12+#include <linux/binfmts.h>
13+#include <linux/sched.h>
14+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
15+#include <linux/kmod.h>
16+/*
17+ * Regarding 2.4 kernels, we need to define __KERNEL_SYSCALLS__ in order to use
18+ * waitpid() because call_usermodehelper() does not support UMH_WAIT_PROC.
19+ */
20+#define __KERNEL_SYSCALLS__
21+#include <linux/unistd.h>
22+#else
23+#include <linux/fs.h>
24+#include <linux/namei.h>
25+#endif
26+#ifndef LOOKUP_POSITIVE
27+#define LOOKUP_POSITIVE 0
28+#endif
29+
30+/*
31+ * TOMOYO specific part start.
32+ */
33+
34+#include "internal.h"
35+
36+#if 0
37+/**
38+ * ccs_setup - Set enable/disable upon boot.
39+ *
40+ * @str: "off" to disable, "on" to enable.
41+ *
42+ * Returns 0.
43+ */
44+static int __init ccs_setup(char *str)
45+{
46+ if (!strcmp(str, "off"))
47+ ccsecurity_ops.disabled = 1;
48+ else if (!strcmp(str, "on"))
49+ ccsecurity_ops.disabled = 0;
50+ return 0;
51+}
52+
53+__setup("ccsecurity=", ccs_setup);
54+#endif
55+
56+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
57+
58+/* Path to the policy loader. (default = CONFIG_CCSECURITY_POLICY_LOADER) */
59+static const char *ccs_loader;
60+
61+#if 0
62+/**
63+ * ccs_loader_setup - Set policy loader.
64+ *
65+ * @str: Program to use as a policy loader (e.g. /sbin/ccs-init ).
66+ *
67+ * Returns 0.
68+ */
69+static int __init ccs_loader_setup(char *str)
70+{
71+ ccs_loader = str;
72+ return 0;
73+}
74+
75+__setup("CCS_loader=", ccs_loader_setup);
76+#endif
77+
78+/**
79+ * ccs_policy_loader_exists - Check whether /sbin/ccs-init exists.
80+ *
81+ * Returns true if /sbin/ccs-init exists, false otherwise.
82+ */
83+static _Bool ccs_policy_loader_exists(void)
84+{
85+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
86+ struct path path;
87+ if (!ccs_loader)
88+ ccs_loader = CONFIG_CCSECURITY_POLICY_LOADER;
89+ if (kern_path(ccs_loader, LOOKUP_FOLLOW | LOOKUP_POSITIVE,
90+ &path) == 0) {
91+ path_put(&path);
92+ return 1;
93+ }
94+#else
95+ struct nameidata nd;
96+ if (!ccs_loader)
97+ ccs_loader = CONFIG_CCSECURITY_POLICY_LOADER;
98+ if (path_lookup(ccs_loader, LOOKUP_FOLLOW | LOOKUP_POSITIVE,
99+ &nd) == 0) {
100+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
101+ path_put(&nd.path);
102+#else
103+ path_release(&nd);
104+#endif
105+ return 1;
106+ }
107+#endif
108+ printk(KERN_INFO "Not activating Mandatory Access Control "
109+ "as %s does not exist.\n", ccs_loader);
110+ return 0;
111+}
112+
113+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
114+
115+/**
116+ * ccs_run_loader - Start /sbin/ccs-init.
117+ *
118+ * @unused: Not used.
119+ *
120+ * Returns PID of /sbin/ccs-init on success, negative value otherwise.
121+ */
122+static int ccs_run_loader(void *unused)
123+{
124+ char *argv[2];
125+ char *envp[3];
126+ printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
127+ ccs_loader);
128+ argv[0] = (char *) ccs_loader;
129+ argv[1] = NULL;
130+ envp[0] = "HOME=/";
131+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
132+ envp[2] = NULL;
133+ return exec_usermodehelper(argv[0], argv, envp);
134+}
135+
136+#endif
137+
138+/* Path to the trigger. (default = CONFIG_CCSECURITY_ACTIVATION_TRIGGER) */
139+static const char *ccs_trigger;
140+
141+#if 0
142+/**
143+ * ccs_trigger_setup - Set trigger for activation.
144+ *
145+ * @str: Program to use as an activation trigger (e.g. /sbin/init ).
146+ *
147+ * Returns 0.
148+ */
149+static int __init ccs_trigger_setup(char *str)
150+{
151+ ccs_trigger = str;
152+ return 0;
153+}
154+
155+__setup("CCS_trigger=", ccs_trigger_setup);
156+#endif
157+
158+/**
159+ * ccs_load_policy - Run external policy loader to load policy.
160+ *
161+ * @filename: The program about to start.
162+ *
163+ * Returns nothing.
164+ *
165+ * This function checks whether @filename is /sbin/init, and if so
166+ * invoke /sbin/ccs-init and wait for the termination of /sbin/ccs-init
167+ * and then continues invocation of /sbin/init.
168+ * /sbin/ccs-init reads policy files in /etc/ccs/ directory and
169+ * writes to /proc/ccs/ interfaces.
170+ */
171+void ccs_load_policy(const char *filename)
172+{
173+ static _Bool done;
174+ if (ccsecurity_ops.disabled || done)
175+ return;
176+ if (!ccs_trigger)
177+ ccs_trigger = CONFIG_CCSECURITY_ACTIVATION_TRIGGER;
178+ if (strcmp(filename, ccs_trigger))
179+ return;
180+ if (!ccs_policy_loader_exists())
181+ return;
182+ done = 1;
183+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
184+ {
185+ char *argv[2];
186+ char *envp[3];
187+ printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
188+ ccs_loader);
189+ argv[0] = (char *) ccs_loader;
190+ argv[1] = NULL;
191+ envp[0] = "HOME=/";
192+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
193+ envp[2] = NULL;
194+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) || defined(UMH_WAIT_PROC)
195+ call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
196+#else
197+ call_usermodehelper(argv[0], argv, envp, 1);
198+#endif
199+ }
200+#elif defined(TASK_DEAD)
201+ {
202+ /* Copied from kernel/kmod.c */
203+ struct task_struct *task = current;
204+ pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
205+ sigset_t tmpsig;
206+ spin_lock_irq(&task->sighand->siglock);
207+ tmpsig = task->blocked;
208+ siginitsetinv(&task->blocked,
209+ sigmask(SIGKILL) | sigmask(SIGSTOP));
210+ recalc_sigpending();
211+ spin_unlock_irq(&task->sighand->siglock);
212+ if (pid >= 0)
213+ waitpid(pid, NULL, __WCLONE);
214+ spin_lock_irq(&task->sighand->siglock);
215+ task->blocked = tmpsig;
216+ recalc_sigpending();
217+ spin_unlock_irq(&task->sighand->siglock);
218+ }
219+#else
220+ {
221+ /* Copied from kernel/kmod.c */
222+ struct task_struct *task = current;
223+ pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
224+ sigset_t tmpsig;
225+ spin_lock_irq(&task->sigmask_lock);
226+ tmpsig = task->blocked;
227+ siginitsetinv(&task->blocked,
228+ sigmask(SIGKILL) | sigmask(SIGSTOP));
229+ recalc_sigpending(task);
230+ spin_unlock_irq(&task->sigmask_lock);
231+ if (pid >= 0)
232+ waitpid(pid, NULL, __WCLONE);
233+ spin_lock_irq(&task->sigmask_lock);
234+ task->blocked = tmpsig;
235+ recalc_sigpending(task);
236+ spin_unlock_irq(&task->sigmask_lock);
237+ }
238+#endif
239+ if (ccsecurity_ops.check_profile)
240+ ccsecurity_ops.check_profile();
241+ else
242+ panic("Failed to load policy.");
243+}
244+
245+#endif
246+
247+#if 0
248+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
249+
250+/**
251+ * ccs_start_execve - Load policy before calling search_binary_handler().
252+ *
253+ * @bprm: Pointer to "struct linux_binprm".
254+ * @eep: Pointer to "struct ccs_execve *".
255+ *
256+ * Returns 0 on success, negative value otherwise.
257+ */
258+static int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep)
259+{
260+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
261+ ccs_load_policy(bprm->filename);
262+#endif
263+ /*
264+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
265+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
266+ * load loadable kernel module. The loadable kernel module modifies
267+ * "struct ccsecurity_ops". Thus, we need to transfer control to
268+ * ccs_start_execve() in security/ccsecurity/permission.c
269+ * if "struct ccsecurity_ops" was modified.
270+ */
271+ if (ccsecurity_ops.start_execve != ccs_start_execve)
272+ return ccsecurity_ops.start_execve(bprm, eep);
273+ return 0;
274+}
275+
276+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
277+
278+/**
279+ * __ccs_search_binary_handler - Load policy before calling search_binary_handler().
280+ *
281+ * @bprm: Pointer to "struct linux_binprm".
282+ *
283+ * Returns 0 on success, negative value otherwise.
284+ */
285+static int __ccs_search_binary_handler(struct linux_binprm *bprm)
286+{
287+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
288+ ccs_load_policy(bprm->filename);
289+#endif
290+ /*
291+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
292+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
293+ * load loadable kernel module. The loadable kernel module modifies
294+ * "struct ccsecurity_ops". Thus, we need to transfer control to
295+ * __ccs_search_binary_handler() in security/ccsecurity/permission.c
296+ * if "struct ccsecurity_ops" was modified.
297+ */
298+ if (ccsecurity_ops.search_binary_handler
299+ != __ccs_search_binary_handler)
300+ return ccsecurity_ops.search_binary_handler(bprm);
301+ return search_binary_handler(bprm);
302+}
303+
304+#else
305+
306+/**
307+ * __ccs_search_binary_handler - Load policy before calling search_binary_handler().
308+ *
309+ * @bprm: Pointer to "struct linux_binprm".
310+ * @regs: Pointer to "struct pt_regs".
311+ *
312+ * Returns 0 on success, negative value otherwise.
313+ */
314+static int __ccs_search_binary_handler(struct linux_binprm *bprm,
315+ struct pt_regs *regs)
316+{
317+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
318+ ccs_load_policy(bprm->filename);
319+#endif
320+ /*
321+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
322+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
323+ * load loadable kernel module. The loadable kernel module modifies
324+ * "struct ccsecurity_ops". Thus, we need to transfer control to
325+ * __ccs_search_binary_handler() in security/ccsecurity/permission.c
326+ * if "struct ccsecurity_ops" was modified.
327+ */
328+ if (ccsecurity_ops.search_binary_handler
329+ != __ccs_search_binary_handler)
330+ return ccsecurity_ops.search_binary_handler(bprm, regs);
331+ return search_binary_handler(bprm, regs);
332+}
333+
334+#endif
335+
336+/*
337+ * Some exports for loadable kernel module part.
338+ *
339+ * Although scripts/checkpatch.pl complains about use of "extern" in C file,
340+ * we don't put these into security/ccsecurity/internal.h because we want to
341+ * split built-in part and loadable kernel module part.
342+ */
343+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
344+extern spinlock_t vfsmount_lock;
345+#endif
346+
347+/* For exporting variables and functions. */
348+const struct ccsecurity_exports ccsecurity_exports = {
349+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
350+ .load_policy = ccs_load_policy,
351+#endif
352+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
353+ .d_absolute_path = d_absolute_path,
354+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
355+ .__d_path = __d_path,
356+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
357+ .vfsmount_lock = &vfsmount_lock,
358+#endif
359+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
360+ .find_task_by_vpid = find_task_by_vpid,
361+ .find_task_by_pid_ns = find_task_by_pid_ns,
362+#endif
363+};
364+#ifdef CONFIG_CCSECURITY_LKM
365+/* Only ccsecurity module need to access this struct. */
366+EXPORT_SYMBOL_GPL(ccsecurity_exports);
367+#endif
368+
369+/* Members are updated by loadable kernel module. */
370+struct ccsecurity_operations ccsecurity_ops = {
371+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
372+ .start_execve = ccs_start_execve,
373+#else
374+ .search_binary_handler = __ccs_search_binary_handler,
375+#endif
376+#ifdef CONFIG_CCSECURITY_DISABLE_BY_DEFAULT
377+ .disabled = 1,
378+#endif
379+};
380+/*
381+ * Non-GPL modules might need to access this struct via inlined functions
382+ * embedded into include/linux/security.h and include/net/ip.h
383+ */
384+EXPORT_SYMBOL(ccsecurity_ops);
385+#endif
--- tags/patches/1.0.47/lsm-2.6.0-vfs.c (nonexistent)
+++ tags/patches/1.0.47/lsm-2.6.0-vfs.c (revision 672)
@@ -0,0 +1,1588 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+
14+static int __ccs_alloc_task_security(const struct task_struct *task);
15+static void __ccs_free_task_security(const struct task_struct *task);
16+
17+/* Dummy security context for avoiding NULL pointer dereference. */
18+static struct ccs_security ccs_oom_security = {
19+ .ccs_domain_info = &ccs_kernel_domain
20+};
21+
22+/* Dummy security context for avoiding NULL pointer dereference. */
23+static struct ccs_security ccs_default_security = {
24+ .ccs_domain_info = &ccs_kernel_domain
25+};
26+
27+/* List of "struct ccs_security". */
28+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
29+/* Lock for protecting ccs_task_security_list[]. */
30+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
31+
32+/* Dummy marker for calling security_bprm_free(). */
33+static const unsigned long ccs_bprm_security;
34+
35+/* For exporting variables and functions. */
36+struct ccsecurity_exports ccsecurity_exports;
37+/* Members are updated by loadable kernel module. */
38+struct ccsecurity_operations ccsecurity_ops;
39+
40+/* Function pointers originally registered by register_security(). */
41+static struct security_operations original_security_ops /* = *security_ops; */;
42+
43+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
44+
45+/**
46+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
47+ *
48+ * @count: Count to increment or decrement.
49+ *
50+ * Returns updated counter.
51+ */
52+static unsigned int ccs_update_ee_counter(int count)
53+{
54+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) || defined(atomic_add_return)
55+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
56+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
57+ return atomic_add_return(count, &ccs_ee_counter);
58+#else
59+ static DEFINE_SPINLOCK(ccs_ee_lock);
60+ static unsigned int ccs_ee_counter;
61+ unsigned long flags;
62+ spin_lock_irqsave(&ccs_ee_lock, flags);
63+ ccs_ee_counter += count;
64+ count = ccs_ee_counter;
65+ spin_unlock_irqrestore(&ccs_ee_lock, flags);
66+ return count;
67+#endif
68+}
69+
70+/**
71+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
72+ *
73+ * @ee: Pointer to "struct ccs_execve".
74+ *
75+ * Returns nothing.
76+ */
77+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
78+{
79+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
80+ current->pid, ccs_update_ee_counter(1) - 1);
81+}
82+
83+/**
84+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
85+ *
86+ * @ee: Pointer to "struct ccs_execve".
87+ * @task: True if released by current task, false otherwise.
88+ *
89+ * Returns nothing.
90+ */
91+void ccs_audit_free_execve(const struct ccs_execve * const ee,
92+ const bool is_current)
93+{
94+ const unsigned int tmp = ccs_update_ee_counter(-1);
95+ if (is_current)
96+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
97+ ee, current->pid, tmp);
98+ else
99+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
100+ ee, tmp);
101+}
102+
103+#endif
104+
105+#if !defined(CONFIG_AKARI_DEBUG)
106+#define ccs_debug_trace(pos) do { } while (0)
107+#else
108+#define ccs_debug_trace(pos) \
109+ do { \
110+ static bool done; \
111+ if (!done) { \
112+ printk(KERN_INFO \
113+ "AKARI: Debug trace: " pos " of 4\n"); \
114+ done = true; \
115+ } \
116+ } while (0)
117+#endif
118+
119+/**
120+ * ccs_clear_execve - Release memory used by do_execve().
121+ *
122+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
123+ * @security: Pointer to "struct ccs_security".
124+ *
125+ * Returns nothing.
126+ */
127+static void ccs_clear_execve(int ret, struct ccs_security *security)
128+{
129+ struct ccs_execve *ee;
130+ if (security == &ccs_default_security || security == &ccs_oom_security)
131+ return;
132+ ee = security->ee;
133+ security->ee = NULL;
134+ if (!ee)
135+ return;
136+ ccs_finish_execve(ret, ee);
137+}
138+
139+/**
140+ * ccs_task_alloc_security - Allocate memory for new tasks.
141+ *
142+ * @p: Pointer to "struct task_struct".
143+ *
144+ * Returns 0 on success, negative value otherwise.
145+ */
146+static int ccs_task_alloc_security(struct task_struct *p)
147+{
148+ int rc = __ccs_alloc_task_security(p);
149+ if (rc)
150+ return rc;
151+ while (!original_security_ops.task_alloc_security)
152+ smp_rmb();
153+ rc = original_security_ops.task_alloc_security(p);
154+ if (rc)
155+ __ccs_free_task_security(p);
156+ return rc;
157+}
158+
159+/**
160+ * ccs_task_free_security - Release memory for "struct task_struct".
161+ *
162+ * @p: Pointer to "struct task_struct".
163+ *
164+ * Returns nothing.
165+ */
166+static void ccs_task_free_security(struct task_struct *p)
167+{
168+ while (!original_security_ops.task_free_security)
169+ smp_rmb();
170+ original_security_ops.task_free_security(p);
171+ __ccs_free_task_security(p);
172+}
173+
174+/**
175+ * ccs_bprm_alloc_security - Allocate memory for "struct linux_binprm".
176+ *
177+ * @bprm: Pointer to "struct linux_binprm".
178+ *
179+ * Returns 0 on success, negative value otherwise.
180+ */
181+static int ccs_bprm_alloc_security(struct linux_binprm *bprm)
182+{
183+ int rc;
184+ while (!original_security_ops.bprm_alloc_security)
185+ smp_rmb();
186+ rc = original_security_ops.bprm_alloc_security(bprm);
187+ if (bprm->security || rc)
188+ return rc;
189+ /*
190+ * Update bprm->security to &ccs_bprm_security so that
191+ * security_bprm_free() is called even if do_execve() failed at
192+ * search_binary_handler() without allocating memory at
193+ * security_bprm_alloc(). This trick assumes that active LSM module
194+ * does not access bprm->security if that module did not allocate
195+ * memory at security_bprm_alloc().
196+ */
197+ bprm->security = (void *) &ccs_bprm_security;
198+ return 0;
199+}
200+
201+/**
202+ * ccs_bprm_free_security - Release memory for "struct linux_binprm".
203+ *
204+ * @bprm: Pointer to "struct linux_binprm".
205+ *
206+ * Returns nothing.
207+ */
208+static void ccs_bprm_free_security(struct linux_binprm *bprm)
209+{
210+ /*
211+ * If do_execve() succeeded, bprm->security will be updated to NULL at
212+ * security_bprm_compute_creds()/security_bprm_apply_creds() if
213+ * bprm->security was set to &ccs_bprm_security at
214+ * security_bprm_alloc().
215+ *
216+ * If do_execve() failed, bprm->security remains at &ccs_bprm_security
217+ * if bprm->security was set to &ccs_bprm_security at
218+ * security_bprm_alloc().
219+ *
220+ * And do_execve() does not call security_bprm_free() if do_execve()
221+ * failed and bprm->security == NULL. Therefore, do not call
222+ * original_security_ops.bprm_free_security() if bprm->security remains
223+ * at &ccs_bprm_security .
224+ */
225+ if (bprm->security != &ccs_bprm_security) {
226+ while (!original_security_ops.bprm_free_security)
227+ smp_rmb();
228+ original_security_ops.bprm_free_security(bprm);
229+ }
230+ /*
231+ * If do_execve() succeeded,
232+ * ccs_clear_execve(0, ccs_current_security());
233+ * is called before calling below one.
234+ * Thus, below call becomes no-op if do_execve() succeeded.
235+ */
236+ ccs_clear_execve(-1, ccs_current_security());
237+}
238+
239+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
240+
241+/**
242+ * ccs_bprm_compute_creds - A hook which is called when do_execve() succeeded.
243+ *
244+ * @bprm: Pointer to "struct linux_binprm".
245+ *
246+ * Returns nothing.
247+ */
248+static void ccs_bprm_compute_creds(struct linux_binprm *bprm)
249+{
250+ if (bprm->security == &ccs_bprm_security)
251+ bprm->security = NULL;
252+ while (!original_security_ops.bprm_compute_creds)
253+ smp_rmb();
254+ original_security_ops.bprm_compute_creds(bprm);
255+ ccs_clear_execve(0, ccs_current_security());
256+}
257+
258+#else
259+
260+/**
261+ * ccs_bprm_apply_creds - A hook which is called when do_execve() succeeded.
262+ *
263+ * @bprm: Pointer to "struct linux_binprm".
264+ * @unsafe: Unsafe flag.
265+ *
266+ * Returns nothing.
267+ */
268+static void ccs_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
269+{
270+ if (bprm->security == &ccs_bprm_security)
271+ bprm->security = NULL;
272+ while (!original_security_ops.bprm_apply_creds)
273+ smp_rmb();
274+ original_security_ops.bprm_apply_creds(bprm, unsafe);
275+ ccs_clear_execve(0, ccs_current_security());
276+}
277+
278+#endif
279+
280+/**
281+ * ccs_bprm_check_security - Check permission for execve().
282+ *
283+ * @bprm: Pointer to "struct linux_binprm".
284+ *
285+ * Returns 0 on success, negative value otherwise.
286+ */
287+static int ccs_bprm_check_security(struct linux_binprm *bprm)
288+{
289+ struct ccs_security *security = ccs_current_security();
290+ if (security == &ccs_default_security || security == &ccs_oom_security)
291+ return -ENOMEM;
292+ if (!security->ee) {
293+ int rc;
294+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
295+ if (!ccs_policy_loaded)
296+ ccs_load_policy(bprm->filename);
297+#endif
298+ rc = ccs_start_execve(bprm, &security->ee);
299+ if (rc)
300+ return rc;
301+ }
302+ while (!original_security_ops.bprm_check_security)
303+ smp_rmb();
304+ return original_security_ops.bprm_check_security(bprm);
305+}
306+
307+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
308+
309+/**
310+ * ccs_open - Check permission for open().
311+ *
312+ * @f: Pointer to "struct file".
313+ *
314+ * Returns 0 on success, negative value otherwise.
315+ */
316+static int ccs_open(struct file *f)
317+{
318+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
319+ f->f_flags + 1);
320+}
321+
322+#endif
323+
324+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
325+
326+/**
327+ * ccs_dentry_open - Check permission for open().
328+ *
329+ * @f: Pointer to "struct file".
330+ *
331+ * Returns 0 on success, negative value otherwise.
332+ */
333+static int ccs_dentry_open(struct file *f)
334+{
335+ int rc = ccs_open(f);
336+ if (rc)
337+ return rc;
338+ while (!original_security_ops.dentry_open)
339+ smp_rmb();
340+ return original_security_ops.dentry_open(f);
341+}
342+
343+#else
344+
345+/**
346+ * ccs_open - Check permission for open().
347+ *
348+ * @inode: Pointer to "struct inode".
349+ * @mask: Open mode.
350+ * @nd: Pointer to "struct nameidata".
351+ *
352+ * Returns 0 on success, negative value otherwise.
353+ */
354+static int ccs_open(struct inode *inode, int mask, struct nameidata *nd)
355+{
356+ int flags;
357+ if (!nd || !nd->dentry)
358+ return 0;
359+ /* open_exec() passes MAY_EXEC . */
360+ if (mask == MAY_EXEC && inode && S_ISREG(inode->i_mode) &&
361+ (ccs_current_flags() & CCS_TASK_IS_IN_EXECVE))
362+ mask = MAY_READ;
363+ /*
364+ * This flags value is passed to ACC_MODE().
365+ * ccs_open_permission() for older versions uses old ACC_MODE().
366+ */
367+ switch (mask & (MAY_READ | MAY_WRITE)) {
368+ case MAY_READ:
369+ flags = 01;
370+ break;
371+ case MAY_WRITE:
372+ flags = 02;
373+ break;
374+ case MAY_READ | MAY_WRITE:
375+ flags = 03;
376+ break;
377+ default:
378+ return 0;
379+ }
380+ return ccs_open_permission(nd->dentry, nd->mnt, flags);
381+}
382+
383+/**
384+ * ccs_inode_permission - Check permission for open().
385+ *
386+ * @inode: Pointer to "struct inode".
387+ * @mask: Open mode.
388+ * @nd: Pointer to "struct nameidata".
389+ *
390+ * Returns 0 on success, negative value otherwise.
391+ *
392+ * Note that this hook is called from permission(), and may not be called for
393+ * open(). Maybe it is better to use security_file_permission().
394+ */
395+static int ccs_inode_permission(struct inode *inode, int mask,
396+ struct nameidata *nd)
397+{
398+ int rc = ccs_open(inode, mask, nd);
399+ if (rc)
400+ return rc;
401+ while (!original_security_ops.inode_permission)
402+ smp_rmb();
403+ return original_security_ops.inode_permission(inode, mask, nd);
404+}
405+
406+#endif
407+
408+/**
409+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
410+ *
411+ * @dentry: Pointer to "struct dentry".
412+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
413+ * @attr: Pointer to "struct iattr".
414+ *
415+ * Returns 0 on success, negative value otherwise.
416+ */
417+static int ccs_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
418+ struct iattr *attr)
419+{
420+ int rc = 0;
421+ if (attr->ia_valid & ATTR_UID)
422+ rc = ccs_chown_permission(dentry, mnt, attr->ia_uid, -1);
423+ if (!rc && (attr->ia_valid & ATTR_GID))
424+ rc = ccs_chown_permission(dentry, mnt, -1, attr->ia_gid);
425+ if (!rc && (attr->ia_valid & ATTR_MODE))
426+ rc = ccs_chmod_permission(dentry, mnt, attr->ia_mode);
427+ if (!rc && (attr->ia_valid & ATTR_SIZE))
428+ rc = ccs_truncate_permission(dentry, mnt);
429+ if (rc)
430+ return rc;
431+ while (!original_security_ops.inode_setattr)
432+ smp_rmb();
433+ return original_security_ops.inode_setattr(dentry, mnt, attr);
434+}
435+
436+/**
437+ * ccs_inode_getattr - Check permission for stat().
438+ *
439+ * @mnt: Pointer to "struct vfsmount".
440+ * @dentry: Pointer to "struct dentry".
441+ *
442+ * Returns 0 on success, negative value otherwise.
443+ */
444+static int ccs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
445+{
446+ int rc = ccs_getattr_permission(mnt, dentry);
447+ if (rc)
448+ return rc;
449+ while (!original_security_ops.inode_getattr)
450+ smp_rmb();
451+ return original_security_ops.inode_getattr(mnt, dentry);
452+}
453+
454+/**
455+ * ccs_inode_mknod - Check permission for mknod().
456+ *
457+ * @dir: Pointer to "struct inode".
458+ * @dentry: Pointer to "struct dentry".
459+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
460+ * @mode: Create mode.
461+ * @dev: Device major/minor number.
462+ *
463+ * Returns 0 on success, negative value otherwise.
464+ */
465+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
466+ struct vfsmount *mnt, int mode, dev_t dev)
467+{
468+ int rc = ccs_mknod_permission(dentry, mnt, mode, dev);
469+ if (rc)
470+ return rc;
471+ while (!original_security_ops.inode_mknod)
472+ smp_rmb();
473+ return original_security_ops.inode_mknod(dir, dentry, mnt, mode, dev);
474+}
475+
476+/**
477+ * ccs_inode_mkdir - Check permission for mkdir().
478+ *
479+ * @dir: Pointer to "struct inode".
480+ * @dentry: Pointer to "struct dentry".
481+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
482+ * @mode: Create mode.
483+ *
484+ * Returns 0 on success, negative value otherwise.
485+ */
486+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
487+ struct vfsmount *mnt, int mode)
488+{
489+ int rc = ccs_mkdir_permission(dentry, mnt, mode);
490+ if (rc)
491+ return rc;
492+ while (!original_security_ops.inode_mkdir)
493+ smp_rmb();
494+ return original_security_ops.inode_mkdir(dir, dentry, mnt, mode);
495+}
496+
497+/**
498+ * ccs_inode_rmdir - Check permission for rmdir().
499+ *
500+ * @dir: Pointer to "struct inode".
501+ * @dentry: Pointer to "struct dentry".
502+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
503+ *
504+ * Returns 0 on success, negative value otherwise.
505+ */
506+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry,
507+ struct vfsmount *mnt)
508+{
509+ int rc = ccs_rmdir_permission(dentry, mnt);
510+ if (rc)
511+ return rc;
512+ while (!original_security_ops.inode_rmdir)
513+ smp_rmb();
514+ return original_security_ops.inode_rmdir(dir, dentry, mnt);
515+}
516+
517+/**
518+ * ccs_inode_unlink - Check permission for unlink().
519+ *
520+ * @dir: Pointer to "struct inode".
521+ * @dentry: Pointer to "struct dentry".
522+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
523+ *
524+ * Returns 0 on success, negative value otherwise.
525+ */
526+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry,
527+ struct vfsmount *mnt)
528+{
529+ int rc = ccs_unlink_permission(dentry, mnt);
530+ if (rc)
531+ return rc;
532+ while (!original_security_ops.inode_unlink)
533+ smp_rmb();
534+ return original_security_ops.inode_unlink(dir, dentry, mnt);
535+}
536+
537+/**
538+ * ccs_inode_symlink - Check permission for symlink().
539+ *
540+ * @dir: Pointer to "struct inode".
541+ * @dentry: Pointer to "struct dentry".
542+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
543+ * @old_name: Content of symbolic link.
544+ *
545+ * Returns 0 on success, negative value otherwise.
546+ */
547+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
548+ struct vfsmount *mnt, const char *old_name)
549+{
550+ int rc = ccs_symlink_permission(dentry, mnt, old_name);
551+ if (rc)
552+ return rc;
553+ while (!original_security_ops.inode_symlink)
554+ smp_rmb();
555+ return original_security_ops.inode_symlink(dir, dentry, mnt, old_name);
556+}
557+
558+/**
559+ * ccs_inode_rename - Check permission for rename().
560+ *
561+ * @old_dir: Pointer to "struct inode".
562+ * @old_dentry: Pointer to "struct dentry".
563+ * @old_mnt: Pointer to "struct vfsmount". Maybe NULL.
564+ * @new_dir: Pointer to "struct inode".
565+ * @new_dentry: Pointer to "struct dentry".
566+ * @new_mnt: Pointer to "struct vfsmount". Maybe NULL.
567+ *
568+ * Returns 0 on success, negative value otherwise.
569+ */
570+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
571+ struct vfsmount *old_mnt, struct inode *new_dir,
572+ struct dentry *new_dentry,
573+ struct vfsmount *new_mnt)
574+{
575+ int rc = ccs_rename_permission(old_dentry, new_dentry, new_mnt);
576+ if (rc)
577+ return rc;
578+ while (!original_security_ops.inode_rename)
579+ smp_rmb();
580+ return original_security_ops.inode_rename(old_dir, old_dentry, old_mnt,
581+ new_dir, new_dentry,
582+ new_mnt);
583+}
584+
585+/**
586+ * ccs_inode_link - Check permission for link().
587+ *
588+ * @old_dentry: Pointer to "struct dentry".
589+ * @old_mnt: Pointer to "struct vfsmount". Maybe NULL.
590+ * @dir: Pointer to "struct inode".
591+ * @new_dentry: Pointer to "struct dentry".
592+ * @new_mnt: Pointer to "struct vfsmount". Maybe NULL.
593+ *
594+ * Returns 0 on success, negative value otherwise.
595+ */
596+static int ccs_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
597+ struct inode *dir, struct dentry *new_dentry,
598+ struct vfsmount *new_mnt)
599+{
600+ int rc = ccs_link_permission(old_dentry, new_dentry, new_mnt);
601+ if (rc)
602+ return rc;
603+ while (!original_security_ops.inode_link)
604+ smp_rmb();
605+ return original_security_ops.inode_link(old_dentry, old_mnt, dir,
606+ new_dentry, new_mnt);
607+}
608+
609+/**
610+ * ccs_inode_create - Check permission for creat().
611+ *
612+ * @dir: Pointer to "struct inode".
613+ * @dentry: Pointer to "struct dentry".
614+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
615+ * @mode: Create mode.
616+ *
617+ * Returns 0 on success, negative value otherwise.
618+ */
619+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
620+ struct vfsmount *mnt, int mode)
621+{
622+ int rc = ccs_mknod_permission(dentry, mnt, mode, 0);
623+ if (rc)
624+ return rc;
625+ while (!original_security_ops.inode_create)
626+ smp_rmb();
627+ return original_security_ops.inode_create(dir, dentry, mnt, mode);
628+}
629+
630+#ifdef CONFIG_SECURITY_NETWORK
631+
632+#include <net/sock.h>
633+
634+/* Structure for remembering an accept()ed socket's status. */
635+struct ccs_socket_tag {
636+ struct list_head list;
637+ struct inode *inode;
638+ int status;
639+ struct rcu_head rcu;
640+};
641+
642+/*
643+ * List for managing accept()ed sockets.
644+ * Since we don't need to keep an accept()ed socket into this list after
645+ * once the permission was granted, the number of entries in this list is
646+ * likely small. Therefore, we don't use hash tables.
647+ */
648+static LIST_HEAD(ccs_accepted_socket_list);
649+/* Lock for protecting ccs_accepted_socket_list . */
650+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
651+
652+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
653+
654+/**
655+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
656+ *
657+ * @rcu: Pointer to "struct rcu_head".
658+ *
659+ * Returns nothing.
660+ */
661+static void ccs_socket_rcu_free(struct rcu_head *rcu)
662+{
663+ struct ccs_socket_tag *ptr = container_of(rcu, typeof(*ptr), rcu);
664+ kfree(ptr);
665+}
666+
667+#else
668+
669+/**
670+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
671+ *
672+ * @arg: Pointer to "void".
673+ *
674+ * Returns nothing.
675+ */
676+static void ccs_socket_rcu_free(void *arg)
677+{
678+ struct ccs_socket_tag *ptr = arg;
679+ kfree(ptr);
680+}
681+
682+#endif
683+
684+/**
685+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
686+ *
687+ * @inode: Pointer to "struct inode".
688+ * @status: New status.
689+ *
690+ * Returns nothing.
691+ *
692+ * If @status == 0, memory for that socket will be released after RCU grace
693+ * period.
694+ */
695+static void ccs_update_socket_tag(struct inode *inode, int status)
696+{
697+ struct ccs_socket_tag *ptr;
698+ /*
699+ * Protect whole section because multiple threads may call this
700+ * function with same "sock" via ccs_validate_socket().
701+ */
702+ spin_lock(&ccs_accepted_socket_list_lock);
703+ rcu_read_lock();
704+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
705+ if (ptr->inode != inode)
706+ continue;
707+ ptr->status = status;
708+ if (status)
709+ break;
710+ list_del_rcu(&ptr->list);
711+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
712+ call_rcu(&ptr->rcu, ccs_socket_rcu_free);
713+#else
714+ call_rcu(&ptr->rcu, ccs_socket_rcu_free, ptr);
715+#endif
716+ break;
717+ }
718+ rcu_read_unlock();
719+ spin_unlock(&ccs_accepted_socket_list_lock);
720+}
721+
722+/**
723+ * ccs_validate_socket - Check post accept() permission if needed.
724+ *
725+ * @sock: Pointer to "struct socket".
726+ *
727+ * Returns 0 on success, negative value otherwise.
728+ */
729+static int ccs_validate_socket(struct socket *sock)
730+{
731+ struct inode *inode = SOCK_INODE(sock);
732+ struct ccs_socket_tag *ptr;
733+ int ret = 0;
734+ rcu_read_lock();
735+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
736+ if (ptr->inode != inode)
737+ continue;
738+ ret = ptr->status;
739+ break;
740+ }
741+ rcu_read_unlock();
742+ if (ret <= 0)
743+ /*
744+ * This socket is not an accept()ed socket or this socket is
745+ * an accept()ed socket and post accept() permission is done.
746+ */
747+ return ret;
748+ /*
749+ * Check post accept() permission now.
750+ *
751+ * Strictly speaking, we need to pass both listen()ing socket and
752+ * accept()ed socket to __ccs_socket_post_accept_permission().
753+ * But since socket's family and type are same for both sockets,
754+ * passing the accept()ed socket in place for the listen()ing socket
755+ * will work.
756+ */
757+ ret = ccs_socket_post_accept_permission(sock, sock);
758+ /*
759+ * If permission was granted, we forget that this is an accept()ed
760+ * socket. Otherwise, we remember that this socket needs to return
761+ * error for subsequent socketcalls.
762+ */
763+ ccs_update_socket_tag(inode, ret);
764+ return ret;
765+}
766+
767+/**
768+ * ccs_socket_accept - Check permission for accept().
769+ *
770+ * @sock: Pointer to "struct socket".
771+ * @newsock: Pointer to "struct socket".
772+ *
773+ * Returns 0 on success, negative value otherwise.
774+ *
775+ * This hook is used for setting up environment for doing post accept()
776+ * permission check. If dereferencing sock->ops->something() were ordered by
777+ * rcu_dereference(), we could replace sock->ops with "a copy of original
778+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
779+ * in order to do post accept() permission check before returning to userspace.
780+ * If we make the copy in security_socket_post_create(), it would be possible
781+ * to safely replace sock->ops here, but we don't do so because we don't want
782+ * to allocate memory for sockets which do not call sock->ops->accept().
783+ * Therefore, we do post accept() permission check upon next socket syscalls
784+ * rather than between sock->ops->accept() and returning to userspace.
785+ * This means that if a socket was close()d before calling some socket
786+ * syscalls, post accept() permission check will not be done.
787+ */
788+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
789+{
790+ struct ccs_socket_tag *ptr;
791+ int rc = ccs_validate_socket(sock);
792+ if (rc < 0)
793+ return rc;
794+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
795+ if (!ptr)
796+ return -ENOMEM;
797+ while (!original_security_ops.socket_accept)
798+ smp_rmb();
799+ rc = original_security_ops.socket_accept(sock, newsock);
800+ if (rc) {
801+ kfree(ptr);
802+ return rc;
803+ }
804+ /*
805+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
806+ * "newsock" as "an accept()ed socket but post accept() permission
807+ * check is not done yet" by allocating memory using inode of the
808+ * "newsock" as a search key.
809+ */
810+ ptr->inode = SOCK_INODE(newsock);
811+ ptr->status = 1; /* Check post accept() permission later. */
812+ spin_lock(&ccs_accepted_socket_list_lock);
813+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
814+ spin_unlock(&ccs_accepted_socket_list_lock);
815+ return 0;
816+}
817+
818+/**
819+ * ccs_socket_listen - Check permission for listen().
820+ *
821+ * @sock: Pointer to "struct socket".
822+ * @backlog: Backlog parameter.
823+ *
824+ * Returns 0 on success, negative value otherwise.
825+ */
826+static int ccs_socket_listen(struct socket *sock, int backlog)
827+{
828+ int rc = ccs_validate_socket(sock);
829+ if (rc < 0)
830+ return rc;
831+ rc = ccs_socket_listen_permission(sock);
832+ if (rc)
833+ return rc;
834+ while (!original_security_ops.socket_listen)
835+ smp_rmb();
836+ return original_security_ops.socket_listen(sock, backlog);
837+}
838+
839+/**
840+ * ccs_socket_connect - Check permission for connect().
841+ *
842+ * @sock: Pointer to "struct socket".
843+ * @addr: Pointer to "struct sockaddr".
844+ * @addr_len: Size of @addr.
845+ *
846+ * Returns 0 on success, negative value otherwise.
847+ */
848+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
849+ int addr_len)
850+{
851+ int rc = ccs_validate_socket(sock);
852+ if (rc < 0)
853+ return rc;
854+ rc = ccs_socket_connect_permission(sock, addr, addr_len);
855+ if (rc)
856+ return rc;
857+ while (!original_security_ops.socket_connect)
858+ smp_rmb();
859+ return original_security_ops.socket_connect(sock, addr, addr_len);
860+}
861+
862+/**
863+ * ccs_socket_bind - Check permission for bind().
864+ *
865+ * @sock: Pointer to "struct socket".
866+ * @addr: Pointer to "struct sockaddr".
867+ * @addr_len: Size of @addr.
868+ *
869+ * Returns 0 on success, negative value otherwise.
870+ */
871+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
872+ int addr_len)
873+{
874+ int rc = ccs_validate_socket(sock);
875+ if (rc < 0)
876+ return rc;
877+ rc = ccs_socket_bind_permission(sock, addr, addr_len);
878+ if (rc)
879+ return rc;
880+ while (!original_security_ops.socket_bind)
881+ smp_rmb();
882+ return original_security_ops.socket_bind(sock, addr, addr_len);
883+}
884+
885+/**
886+ * ccs_socket_sendmsg - Check permission for sendmsg().
887+ *
888+ * @sock: Pointer to "struct socket".
889+ * @msg: Pointer to "struct msghdr".
890+ * @size: Size of message.
891+ *
892+ * Returns 0 on success, negative value otherwise.
893+ */
894+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
895+ int size)
896+{
897+ int rc = ccs_validate_socket(sock);
898+ if (rc < 0)
899+ return rc;
900+ rc = ccs_socket_sendmsg_permission(sock, msg, size);
901+ if (rc)
902+ return rc;
903+ while (!original_security_ops.socket_sendmsg)
904+ smp_rmb();
905+ return original_security_ops.socket_sendmsg(sock, msg, size);
906+}
907+
908+/**
909+ * ccs_socket_recvmsg - Check permission for recvmsg().
910+ *
911+ * @sock: Pointer to "struct socket".
912+ * @msg: Pointer to "struct msghdr".
913+ * @size: Size of message.
914+ * @flags: Flags.
915+ *
916+ * Returns 0 on success, negative value otherwise.
917+ */
918+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
919+ int size, int flags)
920+{
921+ int rc = ccs_validate_socket(sock);
922+ if (rc < 0)
923+ return rc;
924+ while (!original_security_ops.socket_recvmsg)
925+ smp_rmb();
926+ return original_security_ops.socket_recvmsg(sock, msg, size, flags);
927+}
928+
929+/**
930+ * ccs_socket_getsockname - Check permission for getsockname().
931+ *
932+ * @sock: Pointer to "struct socket".
933+ *
934+ * Returns 0 on success, negative value otherwise.
935+ */
936+static int ccs_socket_getsockname(struct socket *sock)
937+{
938+ int rc = ccs_validate_socket(sock);
939+ if (rc < 0)
940+ return rc;
941+ while (!original_security_ops.socket_getsockname)
942+ smp_rmb();
943+ return original_security_ops.socket_getsockname(sock);
944+}
945+
946+/**
947+ * ccs_socket_getpeername - Check permission for getpeername().
948+ *
949+ * @sock: Pointer to "struct socket".
950+ *
951+ * Returns 0 on success, negative value otherwise.
952+ */
953+static int ccs_socket_getpeername(struct socket *sock)
954+{
955+ int rc = ccs_validate_socket(sock);
956+ if (rc < 0)
957+ return rc;
958+ while (!original_security_ops.socket_getpeername)
959+ smp_rmb();
960+ return original_security_ops.socket_getpeername(sock);
961+}
962+
963+/**
964+ * ccs_socket_getsockopt - Check permission for getsockopt().
965+ *
966+ * @sock: Pointer to "struct socket".
967+ * @level: Level.
968+ * @optname: Option's name,
969+ *
970+ * Returns 0 on success, negative value otherwise.
971+ */
972+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
973+{
974+ int rc = ccs_validate_socket(sock);
975+ if (rc < 0)
976+ return rc;
977+ while (!original_security_ops.socket_getsockopt)
978+ smp_rmb();
979+ return original_security_ops.socket_getsockopt(sock, level, optname);
980+}
981+
982+/**
983+ * ccs_socket_setsockopt - Check permission for setsockopt().
984+ *
985+ * @sock: Pointer to "struct socket".
986+ * @level: Level.
987+ * @optname: Option's name,
988+ *
989+ * Returns 0 on success, negative value otherwise.
990+ */
991+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
992+{
993+ int rc = ccs_validate_socket(sock);
994+ if (rc < 0)
995+ return rc;
996+ while (!original_security_ops.socket_setsockopt)
997+ smp_rmb();
998+ return original_security_ops.socket_setsockopt(sock, level, optname);
999+}
1000+
1001+/**
1002+ * ccs_socket_shutdown - Check permission for shutdown().
1003+ *
1004+ * @sock: Pointer to "struct socket".
1005+ * @how: Shutdown mode.
1006+ *
1007+ * Returns 0 on success, negative value otherwise.
1008+ */
1009+static int ccs_socket_shutdown(struct socket *sock, int how)
1010+{
1011+ int rc = ccs_validate_socket(sock);
1012+ if (rc < 0)
1013+ return rc;
1014+ while (!original_security_ops.socket_shutdown)
1015+ smp_rmb();
1016+ return original_security_ops.socket_shutdown(sock, how);
1017+}
1018+
1019+#define SOCKFS_MAGIC 0x534F434B
1020+
1021+/**
1022+ * ccs_inode_free_security - Release memory associated with an inode.
1023+ *
1024+ * @inode: Pointer to "struct inode".
1025+ *
1026+ * Returns nothing.
1027+ *
1028+ * We use this hook for releasing memory associated with an accept()ed socket.
1029+ */
1030+static void ccs_inode_free_security(struct inode *inode)
1031+{
1032+ while (!original_security_ops.inode_free_security)
1033+ smp_rmb();
1034+ original_security_ops.inode_free_security(inode);
1035+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1036+ ccs_update_socket_tag(inode, 0);
1037+}
1038+
1039+#endif
1040+
1041+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1042+
1043+/**
1044+ * ccs_sb_pivotroot - Check permission for pivot_root().
1045+ *
1046+ * @old_nd: Pointer to "struct nameidata".
1047+ * @new_nd: Pointer to "struct nameidata".
1048+ *
1049+ * Returns 0 on success, negative value otherwise.
1050+ */
1051+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1052+{
1053+ int rc = ccs_pivot_root_permission(old_nd, new_nd);
1054+ if (rc)
1055+ return rc;
1056+ while (!original_security_ops.sb_pivotroot)
1057+ smp_rmb();
1058+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1059+}
1060+
1061+/**
1062+ * ccs_sb_mount - Check permission for mount().
1063+ *
1064+ * @dev_name: Name of device file.
1065+ * @nd: Pointer to "struct nameidata".
1066+ * @type: Name of filesystem type. Maybe NULL.
1067+ * @flags: Mount options.
1068+ * @data_page: Optional data. Maybe NULL.
1069+ *
1070+ * Returns 0 on success, negative value otherwise.
1071+ */
1072+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1073+ unsigned long flags, void *data_page)
1074+{
1075+ int rc = ccs_mount_permission(dev_name, nd, type, flags, data_page);
1076+ if (rc)
1077+ return rc;
1078+ while (!original_security_ops.sb_mount)
1079+ smp_rmb();
1080+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1081+ data_page);
1082+}
1083+
1084+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
1085+
1086+/**
1087+ * ccs_sb_pivotroot - Check permission for pivot_root().
1088+ *
1089+ * @old_nd: Pointer to "struct nameidata".
1090+ * @new_nd: Pointer to "struct nameidata".
1091+ *
1092+ * Returns 0 on success, negative value otherwise.
1093+ */
1094+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1095+{
1096+ int rc = ccs_pivot_root_permission(&old_nd->path, &new_nd->path);
1097+ if (rc)
1098+ return rc;
1099+ while (!original_security_ops.sb_pivotroot)
1100+ smp_rmb();
1101+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1102+}
1103+
1104+/**
1105+ * ccs_sb_mount - Check permission for mount().
1106+ *
1107+ * @dev_name: Name of device file.
1108+ * @nd: Pointer to "struct nameidata".
1109+ * @type: Name of filesystem type. Maybe NULL.
1110+ * @flags: Mount options.
1111+ * @data_page: Optional data. Maybe NULL.
1112+ *
1113+ * Returns 0 on success, negative value otherwise.
1114+ */
1115+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1116+ unsigned long flags, void *data_page)
1117+{
1118+ int rc = ccs_mount_permission(dev_name, &nd->path, type, flags,
1119+ data_page);
1120+ if (rc)
1121+ return rc;
1122+ while (!original_security_ops.sb_mount)
1123+ smp_rmb();
1124+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1125+ data_page);
1126+}
1127+
1128+#else
1129+
1130+/**
1131+ * ccs_sb_pivotroot - Check permission for pivot_root().
1132+ *
1133+ * @old_path: Pointer to "struct path".
1134+ * @new_path: Pointer to "struct path".
1135+ *
1136+ * Returns 0 on success, negative value otherwise.
1137+ */
1138+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1139+{
1140+ int rc = ccs_pivot_root_permission(old_path, new_path);
1141+ if (rc)
1142+ return rc;
1143+ while (!original_security_ops.sb_pivotroot)
1144+ smp_rmb();
1145+ return original_security_ops.sb_pivotroot(old_path, new_path);
1146+}
1147+
1148+/**
1149+ * ccs_sb_mount - Check permission for mount().
1150+ *
1151+ * @dev_name: Name of device file.
1152+ * @path: Pointer to "struct path".
1153+ * @type: Name of filesystem type. Maybe NULL.
1154+ * @flags: Mount options.
1155+ * @data_page: Optional data. Maybe NULL.
1156+ *
1157+ * Returns 0 on success, negative value otherwise.
1158+ */
1159+static int ccs_sb_mount(char *dev_name, struct path *path, char *type,
1160+ unsigned long flags, void *data_page)
1161+{
1162+ int rc = ccs_mount_permission(dev_name, path, type, flags, data_page);
1163+ if (rc)
1164+ return rc;
1165+ while (!original_security_ops.sb_mount)
1166+ smp_rmb();
1167+ return original_security_ops.sb_mount(dev_name, path, type, flags,
1168+ data_page);
1169+}
1170+
1171+#endif
1172+
1173+/**
1174+ * ccs_sb_umount - Check permission for umount().
1175+ *
1176+ * @mnt: Pointer to "struct vfsmount".
1177+ * @flags: Unmount flags.
1178+ *
1179+ * Returns 0 on success, negative value otherwise.
1180+ */
1181+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1182+{
1183+ int rc = ccs_umount_permission(mnt, flags);
1184+ if (rc)
1185+ return rc;
1186+ while (!original_security_ops.sb_umount)
1187+ smp_rmb();
1188+ return original_security_ops.sb_umount(mnt, flags);
1189+}
1190+
1191+/**
1192+ * ccs_file_fcntl - Check permission for fcntl().
1193+ *
1194+ * @file: Pointer to "struct file".
1195+ * @cmd: Command number.
1196+ * @arg: Value for @cmd.
1197+ *
1198+ * Returns 0 on success, negative value otherwise.
1199+ */
1200+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1201+ unsigned long arg)
1202+{
1203+ int rc = ccs_fcntl_permission(file, cmd, arg);
1204+ if (rc)
1205+ return rc;
1206+ while (!original_security_ops.file_fcntl)
1207+ smp_rmb();
1208+ return original_security_ops.file_fcntl(file, cmd, arg);
1209+}
1210+
1211+/**
1212+ * ccs_file_ioctl - Check permission for ioctl().
1213+ *
1214+ * @filp: Pointer to "struct file".
1215+ * @cmd: Command number.
1216+ * @arg: Value for @cmd.
1217+ *
1218+ * Returns 0 on success, negative value otherwise.
1219+ */
1220+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1221+ unsigned long arg)
1222+{
1223+ int rc = ccs_ioctl_permission(filp, cmd, arg);
1224+ if (rc)
1225+ return rc;
1226+ while (!original_security_ops.file_ioctl)
1227+ smp_rmb();
1228+ return original_security_ops.file_ioctl(filp, cmd, arg);
1229+}
1230+
1231+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1232+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
1233+ const struct ccs_path_info *filename);
1234+
1235+/**
1236+ * ccs_prepend - Copy of prepend() in fs/dcache.c.
1237+ *
1238+ * @buffer: Pointer to "struct char *".
1239+ * @buflen: Pointer to int which holds size of @buffer.
1240+ * @str: String to copy.
1241+ *
1242+ * Returns 0 on success, negative value otherwise.
1243+ *
1244+ * @buffer and @buflen are updated upon success.
1245+ */
1246+static int ccs_prepend(char **buffer, int *buflen, const char *str)
1247+{
1248+ int namelen = strlen(str);
1249+ if (*buflen < namelen)
1250+ return -ENOMEM;
1251+ *buflen -= namelen;
1252+ *buffer -= namelen;
1253+ memcpy(*buffer, str, namelen);
1254+ return 0;
1255+}
1256+
1257+/**
1258+ * ccs_sysctl_permission - Check permission for sysctl().
1259+ *
1260+ * @table: Pointer to "struct ctl_table".
1261+ * @op: Operation. (MAY_READ and/or MAY_WRITE)
1262+ *
1263+ * Returns 0 on success, negative value otherwise.
1264+ */
1265+static int ccs_sysctl(struct ctl_table *table, int op)
1266+{
1267+ int error;
1268+ struct ccs_path_info buf;
1269+ struct ccs_request_info r;
1270+ int buflen;
1271+ char *buffer;
1272+ int idx;
1273+ while (!original_security_ops.sysctl)
1274+ smp_rmb();
1275+ error = original_security_ops.sysctl(table, op);
1276+ if (error)
1277+ return error;
1278+ op &= MAY_READ | MAY_WRITE;
1279+ if (!op)
1280+ return 0;
1281+ buffer = NULL;
1282+ buf.name = NULL;
1283+ idx = ccs_read_lock();
1284+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
1285+ == CCS_CONFIG_DISABLED)
1286+ goto out;
1287+ error = -ENOMEM;
1288+ buflen = 4096;
1289+ buffer = kmalloc(buflen, CCS_GFP_FLAGS);
1290+ if (buffer) {
1291+ char *end = buffer + buflen;
1292+ *--end = '\0';
1293+ buflen--;
1294+ while (table) {
1295+ char num[32];
1296+ const char *sp = table->procname;
1297+ if (!sp) {
1298+ memset(num, 0, sizeof(num));
1299+ snprintf(num, sizeof(num) - 1, "=%d=",
1300+ table->ctl_name);
1301+ sp = num;
1302+ }
1303+ if (ccs_prepend(&end, &buflen, sp) ||
1304+ ccs_prepend(&end, &buflen, "/"))
1305+ goto out;
1306+ table = table->parent;
1307+ }
1308+ if (ccs_prepend(&end, &buflen, "proc:/sys"))
1309+ goto out;
1310+ buf.name = ccs_encode(end);
1311+ }
1312+ if (buf.name) {
1313+ ccs_fill_path_info(&buf);
1314+ if (op & MAY_READ)
1315+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
1316+ else
1317+ error = 0;
1318+ if (!error && (op & MAY_WRITE))
1319+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
1320+ }
1321+out:
1322+ ccs_read_unlock(idx);
1323+ kfree(buf.name);
1324+ kfree(buffer);
1325+ return error;
1326+}
1327+
1328+#endif
1329+
1330+/*
1331+ * Why not to copy all operations by "original_security_ops = *ops" ?
1332+ * Because copying byte array is not atomic. Reader checks
1333+ * original_security_ops.op != NULL before doing original_security_ops.op().
1334+ * Thus, modifying original_security_ops.op has to be atomic.
1335+ */
1336+#define swap_security_ops(op) \
1337+ original_security_ops.op = ops->op; smp_wmb(); ops->op = ccs_##op;
1338+
1339+/**
1340+ * ccs_update_security_ops - Overwrite original "struct security_operations".
1341+ *
1342+ * @ops: Pointer to "struct security_operations".
1343+ *
1344+ * Returns nothing.
1345+ */
1346+static void __init ccs_update_security_ops(struct security_operations *ops)
1347+{
1348+ /* Security context allocator. */
1349+ swap_security_ops(task_alloc_security);
1350+ swap_security_ops(task_free_security);
1351+ swap_security_ops(bprm_alloc_security);
1352+ swap_security_ops(bprm_free_security);
1353+ /* Security context updater for successful execve(). */
1354+ swap_security_ops(bprm_check_security);
1355+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
1356+ swap_security_ops(bprm_compute_creds);
1357+#else
1358+ swap_security_ops(bprm_apply_creds);
1359+#endif
1360+ /* Various permission checker. */
1361+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1362+ swap_security_ops(dentry_open);
1363+#else
1364+ swap_security_ops(inode_permission);
1365+#endif
1366+ swap_security_ops(file_fcntl);
1367+ swap_security_ops(file_ioctl);
1368+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1369+ swap_security_ops(sysctl);
1370+#endif
1371+ swap_security_ops(sb_pivotroot);
1372+ swap_security_ops(sb_mount);
1373+ swap_security_ops(sb_umount);
1374+ swap_security_ops(inode_mknod);
1375+ swap_security_ops(inode_mkdir);
1376+ swap_security_ops(inode_rmdir);
1377+ swap_security_ops(inode_unlink);
1378+ swap_security_ops(inode_symlink);
1379+ swap_security_ops(inode_rename);
1380+ swap_security_ops(inode_link);
1381+ swap_security_ops(inode_create);
1382+ swap_security_ops(inode_setattr);
1383+ swap_security_ops(inode_getattr);
1384+#ifdef CONFIG_SECURITY_NETWORK
1385+ swap_security_ops(socket_bind);
1386+ swap_security_ops(socket_connect);
1387+ swap_security_ops(socket_listen);
1388+ swap_security_ops(socket_sendmsg);
1389+ swap_security_ops(socket_recvmsg);
1390+ swap_security_ops(socket_getsockname);
1391+ swap_security_ops(socket_getpeername);
1392+ swap_security_ops(socket_getsockopt);
1393+ swap_security_ops(socket_setsockopt);
1394+ swap_security_ops(socket_shutdown);
1395+ swap_security_ops(socket_accept);
1396+ swap_security_ops(inode_free_security);
1397+#endif
1398+}
1399+
1400+#undef swap_security_ops
1401+
1402+/**
1403+ * ccs_init - Initialize this module.
1404+ *
1405+ * Returns 0 on success, negative value otherwise.
1406+ */
1407+static int __init ccs_init(void)
1408+{
1409+ struct security_operations *ops = probe_security_ops();
1410+ if (!ops)
1411+ goto out;
1412+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1413+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1414+ if (!ccsecurity_exports.find_task_by_vpid)
1415+ goto out;
1416+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1417+ if (!ccsecurity_exports.find_task_by_pid_ns)
1418+ goto out;
1419+#endif
1420+ ccsecurity_exports.vfsmount_lock = probe_vfsmount_lock();
1421+ if (!ccsecurity_exports.vfsmount_lock)
1422+ goto out;
1423+ ccs_main_init();
1424+ ccs_update_security_ops(ops);
1425+ printk(KERN_INFO "AKARI: 1.0.47 2021/04/01\n");
1426+ printk(KERN_INFO
1427+ "Access Keeping And Regulating Instrument registered.\n");
1428+ return 0;
1429+out:
1430+ return -EINVAL;
1431+}
1432+
1433+module_init(ccs_init);
1434+MODULE_LICENSE("GPL");
1435+
1436+/**
1437+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1438+ *
1439+ * @domain: Pointer to "struct ccs_domain_info".
1440+ *
1441+ * Returns true if @domain is in use, false otherwise.
1442+ *
1443+ * Caller holds rcu_read_lock().
1444+ */
1445+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1446+{
1447+ return false;
1448+}
1449+
1450+/**
1451+ * ccs_add_task_security - Add "struct ccs_security" to list.
1452+ *
1453+ * @ptr: Pointer to "struct ccs_security".
1454+ * @list: Pointer to "struct list_head".
1455+ *
1456+ * Returns nothing.
1457+ */
1458+static void ccs_add_task_security(struct ccs_security *ptr,
1459+ struct list_head *list)
1460+{
1461+ unsigned long flags;
1462+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1463+ list_add_rcu(&ptr->list, list);
1464+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1465+}
1466+
1467+/**
1468+ * __ccs_alloc_task_security - Allocate memory for new tasks.
1469+ *
1470+ * @task: Pointer to "struct task_struct".
1471+ *
1472+ * Returns 0 on success, negative value otherwise.
1473+ */
1474+static int __ccs_alloc_task_security(const struct task_struct *task)
1475+{
1476+ struct ccs_security *old_security = ccs_current_security();
1477+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
1478+ GFP_KERNEL);
1479+ struct list_head *list = &ccs_task_security_list
1480+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1481+ if (!new_security)
1482+ return -ENOMEM;
1483+ new_security->task = task;
1484+ new_security->ccs_domain_info = old_security->ccs_domain_info;
1485+ new_security->ccs_flags = old_security->ccs_flags;
1486+ ccs_add_task_security(new_security, list);
1487+ return 0;
1488+}
1489+
1490+/**
1491+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1492+ *
1493+ * @task: Pointer to "struct task_struct".
1494+ *
1495+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1496+ * out of memory, &ccs_default_security otherwise.
1497+ *
1498+ * If @task is current thread and "struct ccs_security" for current thread was
1499+ * not found, I try to allocate it. But if allocation failed, current thread
1500+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1501+ * won't work.
1502+ */
1503+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1504+{
1505+ struct ccs_security *ptr;
1506+ struct list_head *list = &ccs_task_security_list
1507+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1508+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1509+ while (!list->next)
1510+ smp_rmb();
1511+ rcu_read_lock();
1512+ list_for_each_entry_rcu(ptr, list, list) {
1513+ if (ptr->task != task)
1514+ continue;
1515+ rcu_read_unlock();
1516+ return ptr;
1517+ }
1518+ rcu_read_unlock();
1519+ if (task != current)
1520+ return &ccs_default_security;
1521+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1522+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1523+ if (!ptr) {
1524+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1525+ task->pid);
1526+ send_sig(SIGKILL, current, 0);
1527+ return &ccs_oom_security;
1528+ }
1529+ *ptr = ccs_default_security;
1530+ ptr->task = task;
1531+ ccs_add_task_security(ptr, list);
1532+ return ptr;
1533+}
1534+
1535+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1536+
1537+/**
1538+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1539+ *
1540+ * @rcu: Pointer to "struct rcu_head".
1541+ *
1542+ * Returns nothing.
1543+ */
1544+static void ccs_rcu_free(struct rcu_head *rcu)
1545+{
1546+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
1547+ kfree(ptr);
1548+}
1549+
1550+#else
1551+
1552+/**
1553+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1554+ *
1555+ * @arg: Pointer to "void".
1556+ *
1557+ * Returns nothing.
1558+ */
1559+static void ccs_rcu_free(void *arg)
1560+{
1561+ struct ccs_security *ptr = arg;
1562+ kfree(ptr);
1563+}
1564+
1565+#endif
1566+
1567+/**
1568+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
1569+ *
1570+ * @task: Pointer to "struct task_struct".
1571+ *
1572+ * Returns nothing.
1573+ */
1574+static void __ccs_free_task_security(const struct task_struct *task)
1575+{
1576+ unsigned long flags;
1577+ struct ccs_security *ptr = ccs_find_task_security(task);
1578+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
1579+ return;
1580+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1581+ list_del_rcu(&ptr->list);
1582+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1583+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1584+ call_rcu(&ptr->rcu, ccs_rcu_free);
1585+#else
1586+ call_rcu(&ptr->rcu, ccs_rcu_free, ptr);
1587+#endif
1588+}
--- tags/patches/1.0.47/lsm-2.6.0.c (nonexistent)
+++ tags/patches/1.0.47/lsm-2.6.0.c (revision 672)
@@ -0,0 +1,1568 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+
14+static int __ccs_alloc_task_security(const struct task_struct *task);
15+static void __ccs_free_task_security(const struct task_struct *task);
16+
17+/* Dummy security context for avoiding NULL pointer dereference. */
18+static struct ccs_security ccs_oom_security = {
19+ .ccs_domain_info = &ccs_kernel_domain
20+};
21+
22+/* Dummy security context for avoiding NULL pointer dereference. */
23+static struct ccs_security ccs_default_security = {
24+ .ccs_domain_info = &ccs_kernel_domain
25+};
26+
27+/* List of "struct ccs_security". */
28+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
29+/* Lock for protecting ccs_task_security_list[]. */
30+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
31+
32+/* Dummy marker for calling security_bprm_free(). */
33+static const unsigned long ccs_bprm_security;
34+
35+/* For exporting variables and functions. */
36+struct ccsecurity_exports ccsecurity_exports;
37+/* Members are updated by loadable kernel module. */
38+struct ccsecurity_operations ccsecurity_ops;
39+
40+/* Function pointers originally registered by register_security(). */
41+static struct security_operations original_security_ops /* = *security_ops; */;
42+
43+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
44+
45+/**
46+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
47+ *
48+ * @count: Count to increment or decrement.
49+ *
50+ * Returns updated counter.
51+ */
52+static unsigned int ccs_update_ee_counter(int count)
53+{
54+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) || defined(atomic_add_return)
55+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
56+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
57+ return atomic_add_return(count, &ccs_ee_counter);
58+#else
59+ static DEFINE_SPINLOCK(ccs_ee_lock);
60+ static unsigned int ccs_ee_counter;
61+ unsigned long flags;
62+ spin_lock_irqsave(&ccs_ee_lock, flags);
63+ ccs_ee_counter += count;
64+ count = ccs_ee_counter;
65+ spin_unlock_irqrestore(&ccs_ee_lock, flags);
66+ return count;
67+#endif
68+}
69+
70+/**
71+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
72+ *
73+ * @ee: Pointer to "struct ccs_execve".
74+ *
75+ * Returns nothing.
76+ */
77+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
78+{
79+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
80+ current->pid, ccs_update_ee_counter(1) - 1);
81+}
82+
83+/**
84+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
85+ *
86+ * @ee: Pointer to "struct ccs_execve".
87+ * @task: True if released by current task, false otherwise.
88+ *
89+ * Returns nothing.
90+ */
91+void ccs_audit_free_execve(const struct ccs_execve * const ee,
92+ const bool is_current)
93+{
94+ const unsigned int tmp = ccs_update_ee_counter(-1);
95+ if (is_current)
96+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
97+ ee, current->pid, tmp);
98+ else
99+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
100+ ee, tmp);
101+}
102+
103+#endif
104+
105+#if !defined(CONFIG_AKARI_DEBUG)
106+#define ccs_debug_trace(pos) do { } while (0)
107+#else
108+#define ccs_debug_trace(pos) \
109+ do { \
110+ static bool done; \
111+ if (!done) { \
112+ printk(KERN_INFO \
113+ "AKARI: Debug trace: " pos " of 4\n"); \
114+ done = true; \
115+ } \
116+ } while (0)
117+#endif
118+
119+/**
120+ * ccs_clear_execve - Release memory used by do_execve().
121+ *
122+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
123+ * @security: Pointer to "struct ccs_security".
124+ *
125+ * Returns nothing.
126+ */
127+static void ccs_clear_execve(int ret, struct ccs_security *security)
128+{
129+ struct ccs_execve *ee;
130+ if (security == &ccs_default_security || security == &ccs_oom_security)
131+ return;
132+ ee = security->ee;
133+ security->ee = NULL;
134+ if (!ee)
135+ return;
136+ ccs_finish_execve(ret, ee);
137+}
138+
139+/**
140+ * ccs_task_alloc_security - Allocate memory for new tasks.
141+ *
142+ * @p: Pointer to "struct task_struct".
143+ *
144+ * Returns 0 on success, negative value otherwise.
145+ */
146+static int ccs_task_alloc_security(struct task_struct *p)
147+{
148+ int rc = __ccs_alloc_task_security(p);
149+ if (rc)
150+ return rc;
151+ while (!original_security_ops.task_alloc_security)
152+ smp_rmb();
153+ rc = original_security_ops.task_alloc_security(p);
154+ if (rc)
155+ __ccs_free_task_security(p);
156+ return rc;
157+}
158+
159+/**
160+ * ccs_task_free_security - Release memory for "struct task_struct".
161+ *
162+ * @p: Pointer to "struct task_struct".
163+ *
164+ * Returns nothing.
165+ */
166+static void ccs_task_free_security(struct task_struct *p)
167+{
168+ while (!original_security_ops.task_free_security)
169+ smp_rmb();
170+ original_security_ops.task_free_security(p);
171+ __ccs_free_task_security(p);
172+}
173+
174+/**
175+ * ccs_bprm_alloc_security - Allocate memory for "struct linux_binprm".
176+ *
177+ * @bprm: Pointer to "struct linux_binprm".
178+ *
179+ * Returns 0 on success, negative value otherwise.
180+ */
181+static int ccs_bprm_alloc_security(struct linux_binprm *bprm)
182+{
183+ int rc;
184+ while (!original_security_ops.bprm_alloc_security)
185+ smp_rmb();
186+ rc = original_security_ops.bprm_alloc_security(bprm);
187+ if (bprm->security || rc)
188+ return rc;
189+ /*
190+ * Update bprm->security to &ccs_bprm_security so that
191+ * security_bprm_free() is called even if do_execve() failed at
192+ * search_binary_handler() without allocating memory at
193+ * security_bprm_alloc(). This trick assumes that active LSM module
194+ * does not access bprm->security if that module did not allocate
195+ * memory at security_bprm_alloc().
196+ */
197+ bprm->security = (void *) &ccs_bprm_security;
198+ return 0;
199+}
200+
201+/**
202+ * ccs_bprm_free_security - Release memory for "struct linux_binprm".
203+ *
204+ * @bprm: Pointer to "struct linux_binprm".
205+ *
206+ * Returns nothing.
207+ */
208+static void ccs_bprm_free_security(struct linux_binprm *bprm)
209+{
210+ /*
211+ * If do_execve() succeeded, bprm->security will be updated to NULL at
212+ * security_bprm_compute_creds()/security_bprm_apply_creds() if
213+ * bprm->security was set to &ccs_bprm_security at
214+ * security_bprm_alloc().
215+ *
216+ * If do_execve() failed, bprm->security remains at &ccs_bprm_security
217+ * if bprm->security was set to &ccs_bprm_security at
218+ * security_bprm_alloc().
219+ *
220+ * And do_execve() does not call security_bprm_free() if do_execve()
221+ * failed and bprm->security == NULL. Therefore, do not call
222+ * original_security_ops.bprm_free_security() if bprm->security remains
223+ * at &ccs_bprm_security .
224+ */
225+ if (bprm->security != &ccs_bprm_security) {
226+ while (!original_security_ops.bprm_free_security)
227+ smp_rmb();
228+ original_security_ops.bprm_free_security(bprm);
229+ }
230+ /*
231+ * If do_execve() succeeded,
232+ * ccs_clear_execve(0, ccs_current_security());
233+ * is called before calling below one.
234+ * Thus, below call becomes no-op if do_execve() succeeded.
235+ */
236+ ccs_clear_execve(-1, ccs_current_security());
237+}
238+
239+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
240+
241+/**
242+ * ccs_bprm_compute_creds - A hook which is called when do_execve() succeeded.
243+ *
244+ * @bprm: Pointer to "struct linux_binprm".
245+ *
246+ * Returns nothing.
247+ */
248+static void ccs_bprm_compute_creds(struct linux_binprm *bprm)
249+{
250+ if (bprm->security == &ccs_bprm_security)
251+ bprm->security = NULL;
252+ while (!original_security_ops.bprm_compute_creds)
253+ smp_rmb();
254+ original_security_ops.bprm_compute_creds(bprm);
255+ ccs_clear_execve(0, ccs_current_security());
256+}
257+
258+#else
259+
260+/**
261+ * ccs_bprm_apply_creds - A hook which is called when do_execve() succeeded.
262+ *
263+ * @bprm: Pointer to "struct linux_binprm".
264+ * @unsafe: Unsafe flag.
265+ *
266+ * Returns nothing.
267+ */
268+static void ccs_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
269+{
270+ if (bprm->security == &ccs_bprm_security)
271+ bprm->security = NULL;
272+ while (!original_security_ops.bprm_apply_creds)
273+ smp_rmb();
274+ original_security_ops.bprm_apply_creds(bprm, unsafe);
275+ ccs_clear_execve(0, ccs_current_security());
276+}
277+
278+#endif
279+
280+/**
281+ * ccs_bprm_check_security - Check permission for execve().
282+ *
283+ * @bprm: Pointer to "struct linux_binprm".
284+ *
285+ * Returns 0 on success, negative value otherwise.
286+ */
287+static int ccs_bprm_check_security(struct linux_binprm *bprm)
288+{
289+ struct ccs_security *security = ccs_current_security();
290+ if (security == &ccs_default_security || security == &ccs_oom_security)
291+ return -ENOMEM;
292+ if (!security->ee) {
293+ int rc;
294+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
295+ if (!ccs_policy_loaded)
296+ ccs_load_policy(bprm->filename);
297+#endif
298+ rc = ccs_start_execve(bprm, &security->ee);
299+ if (rc)
300+ return rc;
301+ }
302+ while (!original_security_ops.bprm_check_security)
303+ smp_rmb();
304+ return original_security_ops.bprm_check_security(bprm);
305+}
306+
307+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
308+
309+/**
310+ * ccs_open - Check permission for open().
311+ *
312+ * @f: Pointer to "struct file".
313+ *
314+ * Returns 0 on success, negative value otherwise.
315+ */
316+static int ccs_open(struct file *f)
317+{
318+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
319+ f->f_flags + 1);
320+}
321+
322+#endif
323+
324+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
325+
326+/**
327+ * ccs_dentry_open - Check permission for open().
328+ *
329+ * @f: Pointer to "struct file".
330+ *
331+ * Returns 0 on success, negative value otherwise.
332+ */
333+static int ccs_dentry_open(struct file *f)
334+{
335+ int rc = ccs_open(f);
336+ if (rc)
337+ return rc;
338+ while (!original_security_ops.dentry_open)
339+ smp_rmb();
340+ return original_security_ops.dentry_open(f);
341+}
342+
343+#else
344+
345+/**
346+ * ccs_open - Check permission for open().
347+ *
348+ * @inode: Pointer to "struct inode".
349+ * @mask: Open mode.
350+ * @nd: Pointer to "struct nameidata".
351+ *
352+ * Returns 0 on success, negative value otherwise.
353+ */
354+static int ccs_open(struct inode *inode, int mask, struct nameidata *nd)
355+{
356+ int flags;
357+ if (!nd || !nd->dentry)
358+ return 0;
359+ /* open_exec() passes MAY_EXEC . */
360+ if (mask == MAY_EXEC && inode && S_ISREG(inode->i_mode) &&
361+ (ccs_current_flags() & CCS_TASK_IS_IN_EXECVE))
362+ mask = MAY_READ;
363+ /*
364+ * This flags value is passed to ACC_MODE().
365+ * ccs_open_permission() for older versions uses old ACC_MODE().
366+ */
367+ switch (mask & (MAY_READ | MAY_WRITE)) {
368+ case MAY_READ:
369+ flags = 01;
370+ break;
371+ case MAY_WRITE:
372+ flags = 02;
373+ break;
374+ case MAY_READ | MAY_WRITE:
375+ flags = 03;
376+ break;
377+ default:
378+ return 0;
379+ }
380+ return ccs_open_permission(nd->dentry, nd->mnt, flags);
381+}
382+
383+/**
384+ * ccs_inode_permission - Check permission for open().
385+ *
386+ * @inode: Pointer to "struct inode".
387+ * @mask: Open mode.
388+ * @nd: Pointer to "struct nameidata".
389+ *
390+ * Returns 0 on success, negative value otherwise.
391+ *
392+ * Note that this hook is called from permission(), and may not be called for
393+ * open(). Maybe it is better to use security_file_permission().
394+ */
395+static int ccs_inode_permission(struct inode *inode, int mask,
396+ struct nameidata *nd)
397+{
398+ int rc = ccs_open(inode, mask, nd);
399+ if (rc)
400+ return rc;
401+ while (!original_security_ops.inode_permission)
402+ smp_rmb();
403+ return original_security_ops.inode_permission(inode, mask, nd);
404+}
405+
406+#endif
407+
408+/**
409+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
410+ *
411+ * @dentry: Pointer to "struct dentry".
412+ * @attr: Pointer to "struct iattr".
413+ *
414+ * Returns 0 on success, negative value otherwise.
415+ */
416+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
417+{
418+ int rc = 0;
419+ if (attr->ia_valid & ATTR_UID)
420+ rc = ccs_chown_permission(dentry, NULL, attr->ia_uid, -1);
421+ if (!rc && (attr->ia_valid & ATTR_GID))
422+ rc = ccs_chown_permission(dentry, NULL, -1, attr->ia_gid);
423+ if (!rc && (attr->ia_valid & ATTR_MODE))
424+ rc = ccs_chmod_permission(dentry, NULL, attr->ia_mode);
425+ if (!rc && (attr->ia_valid & ATTR_SIZE))
426+ rc = ccs_truncate_permission(dentry, NULL);
427+ if (rc)
428+ return rc;
429+ while (!original_security_ops.inode_setattr)
430+ smp_rmb();
431+ return original_security_ops.inode_setattr(dentry, attr);
432+}
433+
434+/**
435+ * ccs_inode_getattr - Check permission for stat().
436+ *
437+ * @mnt: Pointer to "struct vfsmount".
438+ * @dentry: Pointer to "struct dentry".
439+ *
440+ * Returns 0 on success, negative value otherwise.
441+ */
442+static int ccs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
443+{
444+ int rc = ccs_getattr_permission(mnt, dentry);
445+ if (rc)
446+ return rc;
447+ while (!original_security_ops.inode_getattr)
448+ smp_rmb();
449+ return original_security_ops.inode_getattr(mnt, dentry);
450+}
451+
452+/**
453+ * ccs_inode_mknod - Check permission for mknod().
454+ *
455+ * @dir: Pointer to "struct inode".
456+ * @dentry: Pointer to "struct dentry".
457+ * @mode: Create mode.
458+ * @dev: Device major/minor number.
459+ *
460+ * Returns 0 on success, negative value otherwise.
461+ */
462+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry, int mode,
463+ dev_t dev)
464+{
465+ int rc = ccs_mknod_permission(dentry, NULL, mode, dev);
466+ if (rc)
467+ return rc;
468+ while (!original_security_ops.inode_mknod)
469+ smp_rmb();
470+ return original_security_ops.inode_mknod(dir, dentry, mode, dev);
471+}
472+
473+/**
474+ * ccs_inode_mkdir - Check permission for mkdir().
475+ *
476+ * @dir: Pointer to "struct inode".
477+ * @dentry: Pointer to "struct dentry".
478+ * @mode: Create mode.
479+ *
480+ * Returns 0 on success, negative value otherwise.
481+ */
482+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
483+{
484+ int rc = ccs_mkdir_permission(dentry, NULL, mode);
485+ if (rc)
486+ return rc;
487+ while (!original_security_ops.inode_mkdir)
488+ smp_rmb();
489+ return original_security_ops.inode_mkdir(dir, dentry, mode);
490+}
491+
492+/**
493+ * ccs_inode_rmdir - Check permission for rmdir().
494+ *
495+ * @dir: Pointer to "struct inode".
496+ * @dentry: Pointer to "struct dentry".
497+ *
498+ * Returns 0 on success, negative value otherwise.
499+ */
500+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry)
501+{
502+ int rc = ccs_rmdir_permission(dentry, NULL);
503+ if (rc)
504+ return rc;
505+ while (!original_security_ops.inode_rmdir)
506+ smp_rmb();
507+ return original_security_ops.inode_rmdir(dir, dentry);
508+}
509+
510+/**
511+ * ccs_inode_unlink - Check permission for unlink().
512+ *
513+ * @dir: Pointer to "struct inode".
514+ * @dentry: Pointer to "struct dentry".
515+ *
516+ * Returns 0 on success, negative value otherwise.
517+ */
518+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
519+{
520+ int rc = ccs_unlink_permission(dentry, NULL);
521+ if (rc)
522+ return rc;
523+ while (!original_security_ops.inode_unlink)
524+ smp_rmb();
525+ return original_security_ops.inode_unlink(dir, dentry);
526+}
527+
528+/**
529+ * ccs_inode_symlink - Check permission for symlink().
530+ *
531+ * @dir: Pointer to "struct inode".
532+ * @dentry: Pointer to "struct dentry".
533+ * @old_name: Content of symbolic link.
534+ *
535+ * Returns 0 on success, negative value otherwise.
536+ */
537+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
538+ const char *old_name)
539+{
540+ int rc = ccs_symlink_permission(dentry, NULL, old_name);
541+ if (rc)
542+ return rc;
543+ while (!original_security_ops.inode_symlink)
544+ smp_rmb();
545+ return original_security_ops.inode_symlink(dir, dentry, old_name);
546+}
547+
548+/**
549+ * ccs_inode_rename - Check permission for rename().
550+ *
551+ * @old_dir: Pointer to "struct inode".
552+ * @old_dentry: Pointer to "struct dentry".
553+ * @new_dir: Pointer to "struct inode".
554+ * @new_dentry: Pointer to "struct dentry".
555+ *
556+ * Returns 0 on success, negative value otherwise.
557+ */
558+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
559+ struct inode *new_dir, struct dentry *new_dentry)
560+{
561+ int rc = ccs_rename_permission(old_dentry, new_dentry, NULL);
562+ if (rc)
563+ return rc;
564+ while (!original_security_ops.inode_rename)
565+ smp_rmb();
566+ return original_security_ops.inode_rename(old_dir, old_dentry, new_dir,
567+ new_dentry);
568+}
569+
570+/**
571+ * ccs_inode_link - Check permission for link().
572+ *
573+ * @old_dentry: Pointer to "struct dentry".
574+ * @dir: Pointer to "struct inode".
575+ * @new_dentry: Pointer to "struct dentry".
576+ *
577+ * Returns 0 on success, negative value otherwise.
578+ */
579+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
580+ struct dentry *new_dentry)
581+{
582+ int rc = ccs_link_permission(old_dentry, new_dentry, NULL);
583+ if (rc)
584+ return rc;
585+ while (!original_security_ops.inode_link)
586+ smp_rmb();
587+ return original_security_ops.inode_link(old_dentry, dir, new_dentry);
588+}
589+
590+/**
591+ * ccs_inode_create - Check permission for creat().
592+ *
593+ * @dir: Pointer to "struct inode".
594+ * @dentry: Pointer to "struct dentry".
595+ * @mode: Create mode.
596+ *
597+ * Returns 0 on success, negative value otherwise.
598+ */
599+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
600+ int mode)
601+{
602+ int rc = ccs_mknod_permission(dentry, NULL, mode, 0);
603+ if (rc)
604+ return rc;
605+ while (!original_security_ops.inode_create)
606+ smp_rmb();
607+ return original_security_ops.inode_create(dir, dentry, mode);
608+}
609+
610+#ifdef CONFIG_SECURITY_NETWORK
611+
612+#include <net/sock.h>
613+
614+/* Structure for remembering an accept()ed socket's status. */
615+struct ccs_socket_tag {
616+ struct list_head list;
617+ struct inode *inode;
618+ int status;
619+ struct rcu_head rcu;
620+};
621+
622+/*
623+ * List for managing accept()ed sockets.
624+ * Since we don't need to keep an accept()ed socket into this list after
625+ * once the permission was granted, the number of entries in this list is
626+ * likely small. Therefore, we don't use hash tables.
627+ */
628+static LIST_HEAD(ccs_accepted_socket_list);
629+/* Lock for protecting ccs_accepted_socket_list . */
630+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
631+
632+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
633+
634+/**
635+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
636+ *
637+ * @rcu: Pointer to "struct rcu_head".
638+ *
639+ * Returns nothing.
640+ */
641+static void ccs_socket_rcu_free(struct rcu_head *rcu)
642+{
643+ struct ccs_socket_tag *ptr = container_of(rcu, typeof(*ptr), rcu);
644+ kfree(ptr);
645+}
646+
647+#else
648+
649+/**
650+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
651+ *
652+ * @arg: Pointer to "void".
653+ *
654+ * Returns nothing.
655+ */
656+static void ccs_socket_rcu_free(void *arg)
657+{
658+ struct ccs_socket_tag *ptr = arg;
659+ kfree(ptr);
660+}
661+
662+#endif
663+
664+/**
665+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
666+ *
667+ * @inode: Pointer to "struct inode".
668+ * @status: New status.
669+ *
670+ * Returns nothing.
671+ *
672+ * If @status == 0, memory for that socket will be released after RCU grace
673+ * period.
674+ */
675+static void ccs_update_socket_tag(struct inode *inode, int status)
676+{
677+ struct ccs_socket_tag *ptr;
678+ /*
679+ * Protect whole section because multiple threads may call this
680+ * function with same "sock" via ccs_validate_socket().
681+ */
682+ spin_lock(&ccs_accepted_socket_list_lock);
683+ rcu_read_lock();
684+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
685+ if (ptr->inode != inode)
686+ continue;
687+ ptr->status = status;
688+ if (status)
689+ break;
690+ list_del_rcu(&ptr->list);
691+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
692+ call_rcu(&ptr->rcu, ccs_socket_rcu_free);
693+#else
694+ call_rcu(&ptr->rcu, ccs_socket_rcu_free, ptr);
695+#endif
696+ break;
697+ }
698+ rcu_read_unlock();
699+ spin_unlock(&ccs_accepted_socket_list_lock);
700+}
701+
702+/**
703+ * ccs_validate_socket - Check post accept() permission if needed.
704+ *
705+ * @sock: Pointer to "struct socket".
706+ *
707+ * Returns 0 on success, negative value otherwise.
708+ */
709+static int ccs_validate_socket(struct socket *sock)
710+{
711+ struct inode *inode = SOCK_INODE(sock);
712+ struct ccs_socket_tag *ptr;
713+ int ret = 0;
714+ rcu_read_lock();
715+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
716+ if (ptr->inode != inode)
717+ continue;
718+ ret = ptr->status;
719+ break;
720+ }
721+ rcu_read_unlock();
722+ if (ret <= 0)
723+ /*
724+ * This socket is not an accept()ed socket or this socket is
725+ * an accept()ed socket and post accept() permission is done.
726+ */
727+ return ret;
728+ /*
729+ * Check post accept() permission now.
730+ *
731+ * Strictly speaking, we need to pass both listen()ing socket and
732+ * accept()ed socket to __ccs_socket_post_accept_permission().
733+ * But since socket's family and type are same for both sockets,
734+ * passing the accept()ed socket in place for the listen()ing socket
735+ * will work.
736+ */
737+ ret = ccs_socket_post_accept_permission(sock, sock);
738+ /*
739+ * If permission was granted, we forget that this is an accept()ed
740+ * socket. Otherwise, we remember that this socket needs to return
741+ * error for subsequent socketcalls.
742+ */
743+ ccs_update_socket_tag(inode, ret);
744+ return ret;
745+}
746+
747+/**
748+ * ccs_socket_accept - Check permission for accept().
749+ *
750+ * @sock: Pointer to "struct socket".
751+ * @newsock: Pointer to "struct socket".
752+ *
753+ * Returns 0 on success, negative value otherwise.
754+ *
755+ * This hook is used for setting up environment for doing post accept()
756+ * permission check. If dereferencing sock->ops->something() were ordered by
757+ * rcu_dereference(), we could replace sock->ops with "a copy of original
758+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
759+ * in order to do post accept() permission check before returning to userspace.
760+ * If we make the copy in security_socket_post_create(), it would be possible
761+ * to safely replace sock->ops here, but we don't do so because we don't want
762+ * to allocate memory for sockets which do not call sock->ops->accept().
763+ * Therefore, we do post accept() permission check upon next socket syscalls
764+ * rather than between sock->ops->accept() and returning to userspace.
765+ * This means that if a socket was close()d before calling some socket
766+ * syscalls, post accept() permission check will not be done.
767+ */
768+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
769+{
770+ struct ccs_socket_tag *ptr;
771+ int rc = ccs_validate_socket(sock);
772+ if (rc < 0)
773+ return rc;
774+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
775+ if (!ptr)
776+ return -ENOMEM;
777+ while (!original_security_ops.socket_accept)
778+ smp_rmb();
779+ rc = original_security_ops.socket_accept(sock, newsock);
780+ if (rc) {
781+ kfree(ptr);
782+ return rc;
783+ }
784+ /*
785+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
786+ * "newsock" as "an accept()ed socket but post accept() permission
787+ * check is not done yet" by allocating memory using inode of the
788+ * "newsock" as a search key.
789+ */
790+ ptr->inode = SOCK_INODE(newsock);
791+ ptr->status = 1; /* Check post accept() permission later. */
792+ spin_lock(&ccs_accepted_socket_list_lock);
793+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
794+ spin_unlock(&ccs_accepted_socket_list_lock);
795+ return 0;
796+}
797+
798+/**
799+ * ccs_socket_listen - Check permission for listen().
800+ *
801+ * @sock: Pointer to "struct socket".
802+ * @backlog: Backlog parameter.
803+ *
804+ * Returns 0 on success, negative value otherwise.
805+ */
806+static int ccs_socket_listen(struct socket *sock, int backlog)
807+{
808+ int rc = ccs_validate_socket(sock);
809+ if (rc < 0)
810+ return rc;
811+ rc = ccs_socket_listen_permission(sock);
812+ if (rc)
813+ return rc;
814+ while (!original_security_ops.socket_listen)
815+ smp_rmb();
816+ return original_security_ops.socket_listen(sock, backlog);
817+}
818+
819+/**
820+ * ccs_socket_connect - Check permission for connect().
821+ *
822+ * @sock: Pointer to "struct socket".
823+ * @addr: Pointer to "struct sockaddr".
824+ * @addr_len: Size of @addr.
825+ *
826+ * Returns 0 on success, negative value otherwise.
827+ */
828+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
829+ int addr_len)
830+{
831+ int rc = ccs_validate_socket(sock);
832+ if (rc < 0)
833+ return rc;
834+ rc = ccs_socket_connect_permission(sock, addr, addr_len);
835+ if (rc)
836+ return rc;
837+ while (!original_security_ops.socket_connect)
838+ smp_rmb();
839+ return original_security_ops.socket_connect(sock, addr, addr_len);
840+}
841+
842+/**
843+ * ccs_socket_bind - Check permission for bind().
844+ *
845+ * @sock: Pointer to "struct socket".
846+ * @addr: Pointer to "struct sockaddr".
847+ * @addr_len: Size of @addr.
848+ *
849+ * Returns 0 on success, negative value otherwise.
850+ */
851+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
852+ int addr_len)
853+{
854+ int rc = ccs_validate_socket(sock);
855+ if (rc < 0)
856+ return rc;
857+ rc = ccs_socket_bind_permission(sock, addr, addr_len);
858+ if (rc)
859+ return rc;
860+ while (!original_security_ops.socket_bind)
861+ smp_rmb();
862+ return original_security_ops.socket_bind(sock, addr, addr_len);
863+}
864+
865+/**
866+ * ccs_socket_sendmsg - Check permission for sendmsg().
867+ *
868+ * @sock: Pointer to "struct socket".
869+ * @msg: Pointer to "struct msghdr".
870+ * @size: Size of message.
871+ *
872+ * Returns 0 on success, negative value otherwise.
873+ */
874+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
875+ int size)
876+{
877+ int rc = ccs_validate_socket(sock);
878+ if (rc < 0)
879+ return rc;
880+ rc = ccs_socket_sendmsg_permission(sock, msg, size);
881+ if (rc)
882+ return rc;
883+ while (!original_security_ops.socket_sendmsg)
884+ smp_rmb();
885+ return original_security_ops.socket_sendmsg(sock, msg, size);
886+}
887+
888+/**
889+ * ccs_socket_recvmsg - Check permission for recvmsg().
890+ *
891+ * @sock: Pointer to "struct socket".
892+ * @msg: Pointer to "struct msghdr".
893+ * @size: Size of message.
894+ * @flags: Flags.
895+ *
896+ * Returns 0 on success, negative value otherwise.
897+ */
898+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
899+ int size, int flags)
900+{
901+ int rc = ccs_validate_socket(sock);
902+ if (rc < 0)
903+ return rc;
904+ while (!original_security_ops.socket_recvmsg)
905+ smp_rmb();
906+ return original_security_ops.socket_recvmsg(sock, msg, size, flags);
907+}
908+
909+/**
910+ * ccs_socket_getsockname - Check permission for getsockname().
911+ *
912+ * @sock: Pointer to "struct socket".
913+ *
914+ * Returns 0 on success, negative value otherwise.
915+ */
916+static int ccs_socket_getsockname(struct socket *sock)
917+{
918+ int rc = ccs_validate_socket(sock);
919+ if (rc < 0)
920+ return rc;
921+ while (!original_security_ops.socket_getsockname)
922+ smp_rmb();
923+ return original_security_ops.socket_getsockname(sock);
924+}
925+
926+/**
927+ * ccs_socket_getpeername - Check permission for getpeername().
928+ *
929+ * @sock: Pointer to "struct socket".
930+ *
931+ * Returns 0 on success, negative value otherwise.
932+ */
933+static int ccs_socket_getpeername(struct socket *sock)
934+{
935+ int rc = ccs_validate_socket(sock);
936+ if (rc < 0)
937+ return rc;
938+ while (!original_security_ops.socket_getpeername)
939+ smp_rmb();
940+ return original_security_ops.socket_getpeername(sock);
941+}
942+
943+/**
944+ * ccs_socket_getsockopt - Check permission for getsockopt().
945+ *
946+ * @sock: Pointer to "struct socket".
947+ * @level: Level.
948+ * @optname: Option's name,
949+ *
950+ * Returns 0 on success, negative value otherwise.
951+ */
952+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
953+{
954+ int rc = ccs_validate_socket(sock);
955+ if (rc < 0)
956+ return rc;
957+ while (!original_security_ops.socket_getsockopt)
958+ smp_rmb();
959+ return original_security_ops.socket_getsockopt(sock, level, optname);
960+}
961+
962+/**
963+ * ccs_socket_setsockopt - Check permission for setsockopt().
964+ *
965+ * @sock: Pointer to "struct socket".
966+ * @level: Level.
967+ * @optname: Option's name,
968+ *
969+ * Returns 0 on success, negative value otherwise.
970+ */
971+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
972+{
973+ int rc = ccs_validate_socket(sock);
974+ if (rc < 0)
975+ return rc;
976+ while (!original_security_ops.socket_setsockopt)
977+ smp_rmb();
978+ return original_security_ops.socket_setsockopt(sock, level, optname);
979+}
980+
981+/**
982+ * ccs_socket_shutdown - Check permission for shutdown().
983+ *
984+ * @sock: Pointer to "struct socket".
985+ * @how: Shutdown mode.
986+ *
987+ * Returns 0 on success, negative value otherwise.
988+ */
989+static int ccs_socket_shutdown(struct socket *sock, int how)
990+{
991+ int rc = ccs_validate_socket(sock);
992+ if (rc < 0)
993+ return rc;
994+ while (!original_security_ops.socket_shutdown)
995+ smp_rmb();
996+ return original_security_ops.socket_shutdown(sock, how);
997+}
998+
999+#define SOCKFS_MAGIC 0x534F434B
1000+
1001+/**
1002+ * ccs_inode_free_security - Release memory associated with an inode.
1003+ *
1004+ * @inode: Pointer to "struct inode".
1005+ *
1006+ * Returns nothing.
1007+ *
1008+ * We use this hook for releasing memory associated with an accept()ed socket.
1009+ */
1010+static void ccs_inode_free_security(struct inode *inode)
1011+{
1012+ while (!original_security_ops.inode_free_security)
1013+ smp_rmb();
1014+ original_security_ops.inode_free_security(inode);
1015+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1016+ ccs_update_socket_tag(inode, 0);
1017+}
1018+
1019+#endif
1020+
1021+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1022+
1023+/**
1024+ * ccs_sb_pivotroot - Check permission for pivot_root().
1025+ *
1026+ * @old_nd: Pointer to "struct nameidata".
1027+ * @new_nd: Pointer to "struct nameidata".
1028+ *
1029+ * Returns 0 on success, negative value otherwise.
1030+ */
1031+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1032+{
1033+ int rc = ccs_pivot_root_permission(old_nd, new_nd);
1034+ if (rc)
1035+ return rc;
1036+ while (!original_security_ops.sb_pivotroot)
1037+ smp_rmb();
1038+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1039+}
1040+
1041+/**
1042+ * ccs_sb_mount - Check permission for mount().
1043+ *
1044+ * @dev_name: Name of device file.
1045+ * @nd: Pointer to "struct nameidata".
1046+ * @type: Name of filesystem type. Maybe NULL.
1047+ * @flags: Mount options.
1048+ * @data_page: Optional data. Maybe NULL.
1049+ *
1050+ * Returns 0 on success, negative value otherwise.
1051+ */
1052+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1053+ unsigned long flags, void *data_page)
1054+{
1055+ int rc = ccs_mount_permission(dev_name, nd, type, flags, data_page);
1056+ if (rc)
1057+ return rc;
1058+ while (!original_security_ops.sb_mount)
1059+ smp_rmb();
1060+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1061+ data_page);
1062+}
1063+
1064+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
1065+
1066+/**
1067+ * ccs_sb_pivotroot - Check permission for pivot_root().
1068+ *
1069+ * @old_nd: Pointer to "struct nameidata".
1070+ * @new_nd: Pointer to "struct nameidata".
1071+ *
1072+ * Returns 0 on success, negative value otherwise.
1073+ */
1074+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1075+{
1076+ int rc = ccs_pivot_root_permission(&old_nd->path, &new_nd->path);
1077+ if (rc)
1078+ return rc;
1079+ while (!original_security_ops.sb_pivotroot)
1080+ smp_rmb();
1081+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1082+}
1083+
1084+/**
1085+ * ccs_sb_mount - Check permission for mount().
1086+ *
1087+ * @dev_name: Name of device file.
1088+ * @nd: Pointer to "struct nameidata".
1089+ * @type: Name of filesystem type. Maybe NULL.
1090+ * @flags: Mount options.
1091+ * @data_page: Optional data. Maybe NULL.
1092+ *
1093+ * Returns 0 on success, negative value otherwise.
1094+ */
1095+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1096+ unsigned long flags, void *data_page)
1097+{
1098+ int rc = ccs_mount_permission(dev_name, &nd->path, type, flags,
1099+ data_page);
1100+ if (rc)
1101+ return rc;
1102+ while (!original_security_ops.sb_mount)
1103+ smp_rmb();
1104+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1105+ data_page);
1106+}
1107+
1108+#else
1109+
1110+/**
1111+ * ccs_sb_pivotroot - Check permission for pivot_root().
1112+ *
1113+ * @old_path: Pointer to "struct path".
1114+ * @new_path: Pointer to "struct path".
1115+ *
1116+ * Returns 0 on success, negative value otherwise.
1117+ */
1118+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1119+{
1120+ int rc = ccs_pivot_root_permission(old_path, new_path);
1121+ if (rc)
1122+ return rc;
1123+ while (!original_security_ops.sb_pivotroot)
1124+ smp_rmb();
1125+ return original_security_ops.sb_pivotroot(old_path, new_path);
1126+}
1127+
1128+/**
1129+ * ccs_sb_mount - Check permission for mount().
1130+ *
1131+ * @dev_name: Name of device file.
1132+ * @path: Pointer to "struct path".
1133+ * @type: Name of filesystem type. Maybe NULL.
1134+ * @flags: Mount options.
1135+ * @data_page: Optional data. Maybe NULL.
1136+ *
1137+ * Returns 0 on success, negative value otherwise.
1138+ */
1139+static int ccs_sb_mount(char *dev_name, struct path *path, char *type,
1140+ unsigned long flags, void *data_page)
1141+{
1142+ int rc = ccs_mount_permission(dev_name, path, type, flags, data_page);
1143+ if (rc)
1144+ return rc;
1145+ while (!original_security_ops.sb_mount)
1146+ smp_rmb();
1147+ return original_security_ops.sb_mount(dev_name, path, type, flags,
1148+ data_page);
1149+}
1150+
1151+#endif
1152+
1153+/**
1154+ * ccs_sb_umount - Check permission for umount().
1155+ *
1156+ * @mnt: Pointer to "struct vfsmount".
1157+ * @flags: Unmount flags.
1158+ *
1159+ * Returns 0 on success, negative value otherwise.
1160+ */
1161+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1162+{
1163+ int rc = ccs_umount_permission(mnt, flags);
1164+ if (rc)
1165+ return rc;
1166+ while (!original_security_ops.sb_umount)
1167+ smp_rmb();
1168+ return original_security_ops.sb_umount(mnt, flags);
1169+}
1170+
1171+/**
1172+ * ccs_file_fcntl - Check permission for fcntl().
1173+ *
1174+ * @file: Pointer to "struct file".
1175+ * @cmd: Command number.
1176+ * @arg: Value for @cmd.
1177+ *
1178+ * Returns 0 on success, negative value otherwise.
1179+ */
1180+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1181+ unsigned long arg)
1182+{
1183+ int rc = ccs_fcntl_permission(file, cmd, arg);
1184+ if (rc)
1185+ return rc;
1186+ while (!original_security_ops.file_fcntl)
1187+ smp_rmb();
1188+ return original_security_ops.file_fcntl(file, cmd, arg);
1189+}
1190+
1191+/**
1192+ * ccs_file_ioctl - Check permission for ioctl().
1193+ *
1194+ * @filp: Pointer to "struct file".
1195+ * @cmd: Command number.
1196+ * @arg: Value for @cmd.
1197+ *
1198+ * Returns 0 on success, negative value otherwise.
1199+ */
1200+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1201+ unsigned long arg)
1202+{
1203+ int rc = ccs_ioctl_permission(filp, cmd, arg);
1204+ if (rc)
1205+ return rc;
1206+ while (!original_security_ops.file_ioctl)
1207+ smp_rmb();
1208+ return original_security_ops.file_ioctl(filp, cmd, arg);
1209+}
1210+
1211+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1212+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
1213+ const struct ccs_path_info *filename);
1214+
1215+/**
1216+ * ccs_prepend - Copy of prepend() in fs/dcache.c.
1217+ *
1218+ * @buffer: Pointer to "struct char *".
1219+ * @buflen: Pointer to int which holds size of @buffer.
1220+ * @str: String to copy.
1221+ *
1222+ * Returns 0 on success, negative value otherwise.
1223+ *
1224+ * @buffer and @buflen are updated upon success.
1225+ */
1226+static int ccs_prepend(char **buffer, int *buflen, const char *str)
1227+{
1228+ int namelen = strlen(str);
1229+ if (*buflen < namelen)
1230+ return -ENOMEM;
1231+ *buflen -= namelen;
1232+ *buffer -= namelen;
1233+ memcpy(*buffer, str, namelen);
1234+ return 0;
1235+}
1236+
1237+/**
1238+ * ccs_sysctl_permission - Check permission for sysctl().
1239+ *
1240+ * @table: Pointer to "struct ctl_table".
1241+ * @op: Operation. (MAY_READ and/or MAY_WRITE)
1242+ *
1243+ * Returns 0 on success, negative value otherwise.
1244+ */
1245+static int ccs_sysctl(struct ctl_table *table, int op)
1246+{
1247+ int error;
1248+ struct ccs_path_info buf;
1249+ struct ccs_request_info r;
1250+ int buflen;
1251+ char *buffer;
1252+ int idx;
1253+ while (!original_security_ops.sysctl)
1254+ smp_rmb();
1255+ error = original_security_ops.sysctl(table, op);
1256+ if (error)
1257+ return error;
1258+ op &= MAY_READ | MAY_WRITE;
1259+ if (!op)
1260+ return 0;
1261+ buffer = NULL;
1262+ buf.name = NULL;
1263+ idx = ccs_read_lock();
1264+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
1265+ == CCS_CONFIG_DISABLED)
1266+ goto out;
1267+ error = -ENOMEM;
1268+ buflen = 4096;
1269+ buffer = kmalloc(buflen, CCS_GFP_FLAGS);
1270+ if (buffer) {
1271+ char *end = buffer + buflen;
1272+ *--end = '\0';
1273+ buflen--;
1274+ while (table) {
1275+ char num[32];
1276+ const char *sp = table->procname;
1277+ if (!sp) {
1278+ memset(num, 0, sizeof(num));
1279+ snprintf(num, sizeof(num) - 1, "=%d=",
1280+ table->ctl_name);
1281+ sp = num;
1282+ }
1283+ if (ccs_prepend(&end, &buflen, sp) ||
1284+ ccs_prepend(&end, &buflen, "/"))
1285+ goto out;
1286+ table = table->parent;
1287+ }
1288+ if (ccs_prepend(&end, &buflen, "proc:/sys"))
1289+ goto out;
1290+ buf.name = ccs_encode(end);
1291+ }
1292+ if (buf.name) {
1293+ ccs_fill_path_info(&buf);
1294+ if (op & MAY_READ)
1295+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
1296+ else
1297+ error = 0;
1298+ if (!error && (op & MAY_WRITE))
1299+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
1300+ }
1301+out:
1302+ ccs_read_unlock(idx);
1303+ kfree(buf.name);
1304+ kfree(buffer);
1305+ return error;
1306+}
1307+
1308+#endif
1309+
1310+/*
1311+ * Why not to copy all operations by "original_security_ops = *ops" ?
1312+ * Because copying byte array is not atomic. Reader checks
1313+ * original_security_ops.op != NULL before doing original_security_ops.op().
1314+ * Thus, modifying original_security_ops.op has to be atomic.
1315+ */
1316+#define swap_security_ops(op) \
1317+ original_security_ops.op = ops->op; smp_wmb(); ops->op = ccs_##op;
1318+
1319+/**
1320+ * ccs_update_security_ops - Overwrite original "struct security_operations".
1321+ *
1322+ * @ops: Pointer to "struct security_operations".
1323+ *
1324+ * Returns nothing.
1325+ */
1326+static void __init ccs_update_security_ops(struct security_operations *ops)
1327+{
1328+ /* Security context allocator. */
1329+ swap_security_ops(task_alloc_security);
1330+ swap_security_ops(task_free_security);
1331+ swap_security_ops(bprm_alloc_security);
1332+ swap_security_ops(bprm_free_security);
1333+ /* Security context updater for successful execve(). */
1334+ swap_security_ops(bprm_check_security);
1335+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
1336+ swap_security_ops(bprm_compute_creds);
1337+#else
1338+ swap_security_ops(bprm_apply_creds);
1339+#endif
1340+ /* Various permission checker. */
1341+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1342+ swap_security_ops(dentry_open);
1343+#else
1344+ swap_security_ops(inode_permission);
1345+#endif
1346+ swap_security_ops(file_fcntl);
1347+ swap_security_ops(file_ioctl);
1348+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1349+ swap_security_ops(sysctl);
1350+#endif
1351+ swap_security_ops(sb_pivotroot);
1352+ swap_security_ops(sb_mount);
1353+ swap_security_ops(sb_umount);
1354+ swap_security_ops(inode_mknod);
1355+ swap_security_ops(inode_mkdir);
1356+ swap_security_ops(inode_rmdir);
1357+ swap_security_ops(inode_unlink);
1358+ swap_security_ops(inode_symlink);
1359+ swap_security_ops(inode_rename);
1360+ swap_security_ops(inode_link);
1361+ swap_security_ops(inode_create);
1362+ swap_security_ops(inode_setattr);
1363+ swap_security_ops(inode_getattr);
1364+#ifdef CONFIG_SECURITY_NETWORK
1365+ swap_security_ops(socket_bind);
1366+ swap_security_ops(socket_connect);
1367+ swap_security_ops(socket_listen);
1368+ swap_security_ops(socket_sendmsg);
1369+ swap_security_ops(socket_recvmsg);
1370+ swap_security_ops(socket_getsockname);
1371+ swap_security_ops(socket_getpeername);
1372+ swap_security_ops(socket_getsockopt);
1373+ swap_security_ops(socket_setsockopt);
1374+ swap_security_ops(socket_shutdown);
1375+ swap_security_ops(socket_accept);
1376+ swap_security_ops(inode_free_security);
1377+#endif
1378+}
1379+
1380+#undef swap_security_ops
1381+
1382+/**
1383+ * ccs_init - Initialize this module.
1384+ *
1385+ * Returns 0 on success, negative value otherwise.
1386+ */
1387+static int __init ccs_init(void)
1388+{
1389+ struct security_operations *ops = probe_security_ops();
1390+ if (!ops)
1391+ goto out;
1392+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1393+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1394+ if (!ccsecurity_exports.find_task_by_vpid)
1395+ goto out;
1396+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1397+ if (!ccsecurity_exports.find_task_by_pid_ns)
1398+ goto out;
1399+#endif
1400+ ccsecurity_exports.vfsmount_lock = probe_vfsmount_lock();
1401+ if (!ccsecurity_exports.vfsmount_lock)
1402+ goto out;
1403+ ccs_main_init();
1404+ ccs_update_security_ops(ops);
1405+ printk(KERN_INFO "AKARI: 1.0.47 2021/04/01\n");
1406+ printk(KERN_INFO
1407+ "Access Keeping And Regulating Instrument registered.\n");
1408+ return 0;
1409+out:
1410+ return -EINVAL;
1411+}
1412+
1413+module_init(ccs_init);
1414+MODULE_LICENSE("GPL");
1415+
1416+/**
1417+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1418+ *
1419+ * @domain: Pointer to "struct ccs_domain_info".
1420+ *
1421+ * Returns true if @domain is in use, false otherwise.
1422+ *
1423+ * Caller holds rcu_read_lock().
1424+ */
1425+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1426+{
1427+ return false;
1428+}
1429+
1430+/**
1431+ * ccs_add_task_security - Add "struct ccs_security" to list.
1432+ *
1433+ * @ptr: Pointer to "struct ccs_security".
1434+ * @list: Pointer to "struct list_head".
1435+ *
1436+ * Returns nothing.
1437+ */
1438+static void ccs_add_task_security(struct ccs_security *ptr,
1439+ struct list_head *list)
1440+{
1441+ unsigned long flags;
1442+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1443+ list_add_rcu(&ptr->list, list);
1444+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1445+}
1446+
1447+/**
1448+ * __ccs_alloc_task_security - Allocate memory for new tasks.
1449+ *
1450+ * @task: Pointer to "struct task_struct".
1451+ *
1452+ * Returns 0 on success, negative value otherwise.
1453+ */
1454+static int __ccs_alloc_task_security(const struct task_struct *task)
1455+{
1456+ struct ccs_security *old_security = ccs_current_security();
1457+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
1458+ GFP_KERNEL);
1459+ struct list_head *list = &ccs_task_security_list
1460+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1461+ if (!new_security)
1462+ return -ENOMEM;
1463+ new_security->task = task;
1464+ new_security->ccs_domain_info = old_security->ccs_domain_info;
1465+ new_security->ccs_flags = old_security->ccs_flags;
1466+ ccs_add_task_security(new_security, list);
1467+ return 0;
1468+}
1469+
1470+/**
1471+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1472+ *
1473+ * @task: Pointer to "struct task_struct".
1474+ *
1475+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1476+ * out of memory, &ccs_default_security otherwise.
1477+ *
1478+ * If @task is current thread and "struct ccs_security" for current thread was
1479+ * not found, I try to allocate it. But if allocation failed, current thread
1480+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1481+ * won't work.
1482+ */
1483+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1484+{
1485+ struct ccs_security *ptr;
1486+ struct list_head *list = &ccs_task_security_list
1487+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1488+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1489+ while (!list->next)
1490+ smp_rmb();
1491+ rcu_read_lock();
1492+ list_for_each_entry_rcu(ptr, list, list) {
1493+ if (ptr->task != task)
1494+ continue;
1495+ rcu_read_unlock();
1496+ return ptr;
1497+ }
1498+ rcu_read_unlock();
1499+ if (task != current)
1500+ return &ccs_default_security;
1501+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1502+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1503+ if (!ptr) {
1504+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1505+ task->pid);
1506+ send_sig(SIGKILL, current, 0);
1507+ return &ccs_oom_security;
1508+ }
1509+ *ptr = ccs_default_security;
1510+ ptr->task = task;
1511+ ccs_add_task_security(ptr, list);
1512+ return ptr;
1513+}
1514+
1515+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1516+
1517+/**
1518+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1519+ *
1520+ * @rcu: Pointer to "struct rcu_head".
1521+ *
1522+ * Returns nothing.
1523+ */
1524+static void ccs_rcu_free(struct rcu_head *rcu)
1525+{
1526+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
1527+ kfree(ptr);
1528+}
1529+
1530+#else
1531+
1532+/**
1533+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1534+ *
1535+ * @arg: Pointer to "void".
1536+ *
1537+ * Returns nothing.
1538+ */
1539+static void ccs_rcu_free(void *arg)
1540+{
1541+ struct ccs_security *ptr = arg;
1542+ kfree(ptr);
1543+}
1544+
1545+#endif
1546+
1547+/**
1548+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
1549+ *
1550+ * @task: Pointer to "struct task_struct".
1551+ *
1552+ * Returns nothing.
1553+ */
1554+static void __ccs_free_task_security(const struct task_struct *task)
1555+{
1556+ unsigned long flags;
1557+ struct ccs_security *ptr = ccs_find_task_security(task);
1558+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
1559+ return;
1560+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1561+ list_del_rcu(&ptr->list);
1562+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1563+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1564+ call_rcu(&ptr->rcu, ccs_rcu_free);
1565+#else
1566+ call_rcu(&ptr->rcu, ccs_rcu_free, ptr);
1567+#endif
1568+}
--- tags/patches/1.0.47/lsm-2.6.29.c (nonexistent)
+++ tags/patches/1.0.47/lsm-2.6.29.c (revision 672)
@@ -0,0 +1,2246 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
12+#define USE_UMODE_T
13+#else
14+#include "check_umode_t.h"
15+#endif
16+
17+/* Prototype definition. */
18+static void ccs_task_security_gc(void);
19+static int ccs_copy_cred_security(const struct cred *new,
20+ const struct cred *old, gfp_t gfp);
21+static struct ccs_security *ccs_find_cred_security(const struct cred *cred);
22+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
23+static atomic_t ccs_in_execve_tasks = ATOMIC_INIT(0);
24+/*
25+ * List of "struct ccs_security" for "struct pid".
26+ *
27+ * All instances on this list is guaranteed that "struct ccs_security"->pid !=
28+ * NULL. Also, instances on this list that are in execve() are guaranteed that
29+ * "struct ccs_security"->cred remembers "struct linux_binprm"->cred with a
30+ * refcount on "struct linux_binprm"->cred.
31+ */
32+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
33+/*
34+ * List of "struct ccs_security" for "struct cred".
35+ *
36+ * Since the number of "struct cred" is nearly equals to the number of
37+ * "struct pid", we allocate hash tables like ccs_task_security_list.
38+ *
39+ * All instances on this list are guaranteed that "struct ccs_security"->pid ==
40+ * NULL and "struct ccs_security"->cred != NULL.
41+ */
42+static struct list_head ccs_cred_security_list[CCS_MAX_TASK_SECURITY_HASH];
43+
44+/* Dummy security context for avoiding NULL pointer dereference. */
45+static struct ccs_security ccs_oom_security = {
46+ .ccs_domain_info = &ccs_kernel_domain
47+};
48+
49+/* Dummy security context for avoiding NULL pointer dereference. */
50+static struct ccs_security ccs_default_security = {
51+ .ccs_domain_info = &ccs_kernel_domain
52+};
53+
54+/* For exporting variables and functions. */
55+struct ccsecurity_exports ccsecurity_exports;
56+/* Members are updated by loadable kernel module. */
57+struct ccsecurity_operations ccsecurity_ops;
58+
59+/* Function pointers originally registered by register_security(). */
60+static struct security_operations original_security_ops /* = *security_ops; */;
61+
62+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
63+
64+/**
65+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
66+ *
67+ * @count: Count to increment or decrement.
68+ *
69+ * Returns updated counter.
70+ */
71+static unsigned int ccs_update_ee_counter(int count)
72+{
73+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
74+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
75+ return atomic_add_return(count, &ccs_ee_counter);
76+}
77+
78+/**
79+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
80+ *
81+ * @ee: Pointer to "struct ccs_execve".
82+ *
83+ * Returns nothing.
84+ */
85+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
86+{
87+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
88+ current->pid, ccs_update_ee_counter(1) - 1);
89+}
90+
91+/**
92+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
93+ *
94+ * @ee: Pointer to "struct ccs_execve".
95+ * @task: True if released by current task, false otherwise.
96+ *
97+ * Returns nothing.
98+ */
99+void ccs_audit_free_execve(const struct ccs_execve * const ee,
100+ const bool is_current)
101+{
102+ const unsigned int tmp = ccs_update_ee_counter(-1);
103+ if (is_current)
104+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
105+ ee, current->pid, tmp);
106+ else
107+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
108+ ee, tmp);
109+}
110+
111+#endif
112+
113+#if !defined(CONFIG_AKARI_DEBUG)
114+#define ccs_debug_trace(pos) do { } while (0)
115+#else
116+#define ccs_debug_trace(pos) \
117+ do { \
118+ static bool done; \
119+ if (!done) { \
120+ printk(KERN_INFO \
121+ "AKARI: Debug trace: " pos " of 4\n"); \
122+ done = true; \
123+ } \
124+ } while (0)
125+#endif
126+
127+/**
128+ * ccs_clear_execve - Release memory used by do_execve().
129+ *
130+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
131+ * @security: Pointer to "struct ccs_security".
132+ *
133+ * Returns nothing.
134+ */
135+static void ccs_clear_execve(int ret, struct ccs_security *security)
136+{
137+ struct ccs_execve *ee;
138+ if (security == &ccs_default_security || security == &ccs_oom_security)
139+ return;
140+ ee = security->ee;
141+ security->ee = NULL;
142+ if (!ee)
143+ return;
144+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
145+ /*
146+ * Drop refcount on "struct cred" in "struct linux_binprm" and forget
147+ * it.
148+ */
149+ put_cred(security->cred);
150+ security->cred = NULL;
151+#endif
152+ atomic_dec(&ccs_in_execve_tasks);
153+ ccs_finish_execve(ret, ee);
154+}
155+
156+/**
157+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
158+ *
159+ * @rcu: Pointer to "struct rcu_head".
160+ *
161+ * Returns nothing.
162+ */
163+static void ccs_rcu_free(struct rcu_head *rcu)
164+{
165+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
166+ struct ccs_execve *ee = ptr->ee;
167+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
168+ /*
169+ * If this security context was associated with "struct pid" and
170+ * ptr->ccs_flags has CCS_TASK_IS_IN_EXECVE set, it indicates that a
171+ * "struct task_struct" associated with this security context exited
172+ * immediately after do_execve() has failed.
173+ */
174+ if (ptr->pid && (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
175+ ccs_debug_trace("1");
176+ atomic_dec(&ccs_in_execve_tasks);
177+ }
178+#else
179+ /*
180+ * If this security context was associated with "struct pid" and
181+ * remembers "struct cred" in "struct linux_binprm", it indicates that
182+ * a "struct task_struct" associated with this security context exited
183+ * immediately after do_execve() has failed.
184+ */
185+ if (ptr->pid && ptr->cred) {
186+ ccs_debug_trace("1");
187+ put_cred(ptr->cred);
188+ atomic_dec(&ccs_in_execve_tasks);
189+ }
190+#endif
191+ /*
192+ * If this security context was associated with "struct pid",
193+ * drop refcount obtained by get_pid() in ccs_find_task_security().
194+ */
195+ if (ptr->pid) {
196+ ccs_debug_trace("2");
197+ put_pid(ptr->pid);
198+ }
199+ if (ee) {
200+ ccs_debug_trace("3");
201+ ccs_audit_free_execve(ee, false);
202+ kfree(ee->handler_path);
203+ kfree(ee);
204+ }
205+ kfree(ptr);
206+}
207+
208+/**
209+ * ccs_del_security - Release "struct ccs_security".
210+ *
211+ * @ptr: Pointer to "struct ccs_security".
212+ *
213+ * Returns nothing.
214+ */
215+static void ccs_del_security(struct ccs_security *ptr)
216+{
217+ unsigned long flags;
218+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
219+ return;
220+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
221+ list_del_rcu(&ptr->list);
222+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
223+ call_rcu(&ptr->rcu, ccs_rcu_free);
224+}
225+
226+/**
227+ * ccs_add_cred_security - Add "struct ccs_security" to list.
228+ *
229+ * @ptr: Pointer to "struct ccs_security".
230+ *
231+ * Returns nothing.
232+ */
233+static void ccs_add_cred_security(struct ccs_security *ptr)
234+{
235+ unsigned long flags;
236+ struct list_head *list = &ccs_cred_security_list
237+ [hash_ptr((void *) ptr->cred, CCS_TASK_SECURITY_HASH_BITS)];
238+#ifdef CONFIG_AKARI_DEBUG
239+ if (ptr->pid)
240+ printk(KERN_INFO "AKARI: \"struct ccs_security\"->pid != NULL"
241+ "\n");
242+#endif
243+ ptr->pid = NULL;
244+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
245+ list_add_rcu(&ptr->list, list);
246+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
247+}
248+
249+/**
250+ * ccs_task_create - Make snapshot of security context for new task.
251+ *
252+ * @clone_flags: Flags passed to clone().
253+ *
254+ * Returns 0 on success, negative value otherwise.
255+ */
256+static int ccs_task_create(unsigned long clone_flags)
257+{
258+ int rc;
259+ struct ccs_security *old_security;
260+ struct ccs_security *new_security;
261+ struct cred *cred = prepare_creds();
262+ if (!cred)
263+ return -ENOMEM;
264+ while (!original_security_ops.task_create)
265+ smp_rmb();
266+ rc = original_security_ops.task_create(clone_flags);
267+ if (rc) {
268+ abort_creds(cred);
269+ return rc;
270+ }
271+ old_security = ccs_find_task_security(current);
272+ new_security = ccs_find_cred_security(cred);
273+ new_security->ccs_domain_info = old_security->ccs_domain_info;
274+ new_security->ccs_flags = old_security->ccs_flags;
275+ return commit_creds(cred);
276+}
277+
278+/**
279+ * ccs_cred_prepare - Allocate memory for new credentials.
280+ *
281+ * @new: Pointer to "struct cred".
282+ * @old: Pointer to "struct cred".
283+ * @gfp: Memory allocation flags.
284+ *
285+ * Returns 0 on success, negative value otherwise.
286+ */
287+static int ccs_cred_prepare(struct cred *new, const struct cred *old,
288+ gfp_t gfp)
289+{
290+ int rc;
291+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
292+ /*
293+ * For checking whether reverting domain transition is needed or not.
294+ *
295+ * See ccs_find_task_security() for reason.
296+ */
297+ if (gfp == GFP_KERNEL)
298+ ccs_find_task_security(current);
299+#endif
300+ rc = ccs_copy_cred_security(new, old, gfp);
301+ if (rc)
302+ return rc;
303+ if (gfp == GFP_KERNEL)
304+ ccs_task_security_gc();
305+ while (!original_security_ops.cred_prepare)
306+ smp_rmb();
307+ rc = original_security_ops.cred_prepare(new, old, gfp);
308+ if (rc)
309+ ccs_del_security(ccs_find_cred_security(new));
310+ return rc;
311+}
312+
313+/**
314+ * ccs_cred_free - Release memory used by credentials.
315+ *
316+ * @cred: Pointer to "struct cred".
317+ *
318+ * Returns nothing.
319+ */
320+static void ccs_cred_free(struct cred *cred)
321+{
322+ while (!original_security_ops.cred_free)
323+ smp_rmb();
324+ original_security_ops.cred_free(cred);
325+ ccs_del_security(ccs_find_cred_security(cred));
326+}
327+
328+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
329+
330+/**
331+ * ccs_alloc_cred_security - Allocate memory for new credentials.
332+ *
333+ * @cred: Pointer to "struct cred".
334+ * @gfp: Memory allocation flags.
335+ *
336+ * Returns 0 on success, negative value otherwise.
337+ */
338+static int ccs_alloc_cred_security(const struct cred *cred, gfp_t gfp)
339+{
340+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
341+ gfp);
342+ if (!new_security)
343+ return -ENOMEM;
344+ new_security->cred = cred;
345+ ccs_add_cred_security(new_security);
346+ return 0;
347+}
348+
349+/**
350+ * ccs_cred_alloc_blank - Allocate memory for new credentials.
351+ *
352+ * @new: Pointer to "struct cred".
353+ * @gfp: Memory allocation flags.
354+ *
355+ * Returns 0 on success, negative value otherwise.
356+ */
357+static int ccs_cred_alloc_blank(struct cred *new, gfp_t gfp)
358+{
359+ int rc = ccs_alloc_cred_security(new, gfp);
360+ if (rc)
361+ return rc;
362+ while (!original_security_ops.cred_alloc_blank)
363+ smp_rmb();
364+ rc = original_security_ops.cred_alloc_blank(new, gfp);
365+ if (rc)
366+ ccs_del_security(ccs_find_cred_security(new));
367+ return rc;
368+}
369+
370+/**
371+ * ccs_cred_transfer - Transfer "struct ccs_security" between credentials.
372+ *
373+ * @new: Pointer to "struct cred".
374+ * @old: Pointer to "struct cred".
375+ *
376+ * Returns nothing.
377+ */
378+static void ccs_cred_transfer(struct cred *new, const struct cred *old)
379+{
380+ struct ccs_security *new_security;
381+ struct ccs_security *old_security;
382+ while (!original_security_ops.cred_transfer)
383+ smp_rmb();
384+ original_security_ops.cred_transfer(new, old);
385+ new_security = ccs_find_cred_security(new);
386+ old_security = ccs_find_cred_security(old);
387+ if (new_security == &ccs_default_security ||
388+ new_security == &ccs_oom_security ||
389+ old_security == &ccs_default_security ||
390+ old_security == &ccs_oom_security)
391+ return;
392+ new_security->ccs_flags = old_security->ccs_flags;
393+ new_security->ccs_domain_info = old_security->ccs_domain_info;
394+}
395+
396+#endif
397+
398+/**
399+ * ccs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
400+ *
401+ * @bprm: Pointer to "struct linux_binprm".
402+ *
403+ * Returns nothing.
404+ */
405+static void ccs_bprm_committing_creds(struct linux_binprm *bprm)
406+{
407+ struct ccs_security *old_security;
408+ struct ccs_security *new_security;
409+ while (!original_security_ops.bprm_committing_creds)
410+ smp_rmb();
411+ original_security_ops.bprm_committing_creds(bprm);
412+ old_security = ccs_current_security();
413+ if (old_security == &ccs_default_security ||
414+ old_security == &ccs_oom_security)
415+ return;
416+ ccs_clear_execve(0, old_security);
417+ /* Update current task's cred's domain for future fork(). */
418+ new_security = ccs_find_cred_security(bprm->cred);
419+ new_security->ccs_flags = old_security->ccs_flags;
420+ new_security->ccs_domain_info = old_security->ccs_domain_info;
421+}
422+
423+/**
424+ * ccs_bprm_check_security - Check permission for execve().
425+ *
426+ * @bprm: Pointer to "struct linux_binprm".
427+ *
428+ * Returns 0 on success, negative value otherwise.
429+ */
430+static int ccs_bprm_check_security(struct linux_binprm *bprm)
431+{
432+ struct ccs_security *security = ccs_current_security();
433+ if (security == &ccs_default_security || security == &ccs_oom_security)
434+ return -ENOMEM;
435+ if (!security->ee) {
436+ int rc;
437+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
438+ if (!ccs_policy_loaded)
439+ ccs_load_policy(bprm->filename);
440+#endif
441+ rc = ccs_start_execve(bprm, &security->ee);
442+ if (security->ee) {
443+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
444+ /*
445+ * Get refcount on "struct cred" in
446+ * "struct linux_binprm" and remember it.
447+ */
448+ get_cred(bprm->cred);
449+ security->cred = bprm->cred;
450+#endif
451+ atomic_inc(&ccs_in_execve_tasks);
452+ }
453+ if (rc)
454+ return rc;
455+ }
456+ while (!original_security_ops.bprm_check_security)
457+ smp_rmb();
458+ return original_security_ops.bprm_check_security(bprm);
459+}
460+
461+/**
462+ * ccs_open - Check permission for open().
463+ *
464+ * @f: Pointer to "struct file".
465+ *
466+ * Returns 0 on success, negative value otherwise.
467+ */
468+static int ccs_open(struct file *f)
469+{
470+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
471+ return ccs_open_permission(f);
472+#elif defined(RHEL_MAJOR) && RHEL_MAJOR == 6
473+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
474+ f->f_flags);
475+#else
476+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
477+ f->f_flags + 1);
478+#endif
479+}
480+
481+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
482+
483+/**
484+ * ccs_file_open - Check permission for open().
485+ *
486+ * @f: Pointer to "struct file".
487+ * @cred: Pointer to "struct cred".
488+ *
489+ * Returns 0 on success, negative value otherwise.
490+ */
491+static int ccs_file_open(struct file *f, const struct cred *cred)
492+{
493+ int rc = ccs_open(f);
494+ if (rc)
495+ return rc;
496+ while (!original_security_ops.file_open)
497+ smp_rmb();
498+ return original_security_ops.file_open(f, cred);
499+}
500+
501+#else
502+
503+/**
504+ * ccs_dentry_open - Check permission for open().
505+ *
506+ * @f: Pointer to "struct file".
507+ * @cred: Pointer to "struct cred".
508+ *
509+ * Returns 0 on success, negative value otherwise.
510+ */
511+static int ccs_dentry_open(struct file *f, const struct cred *cred)
512+{
513+ int rc = ccs_open(f);
514+ if (rc)
515+ return rc;
516+ while (!original_security_ops.dentry_open)
517+ smp_rmb();
518+ return original_security_ops.dentry_open(f, cred);
519+}
520+
521+#endif
522+
523+#if defined(CONFIG_SECURITY_PATH)
524+
525+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
526+
527+/**
528+ * ccs_path_chown - Check permission for chown()/chgrp().
529+ *
530+ * @path: Pointer to "struct path".
531+ * @user: User ID.
532+ * @group: Group ID.
533+ *
534+ * Returns 0 on success, negative value otherwise.
535+ */
536+static int ccs_path_chown(struct path *path, kuid_t user, kgid_t group)
537+{
538+ int rc = ccs_chown_permission(path->dentry, path->mnt, user, group);
539+ if (rc)
540+ return rc;
541+ while (!original_security_ops.path_chown)
542+ smp_rmb();
543+ return original_security_ops.path_chown(path, user, group);
544+}
545+
546+/**
547+ * ccs_path_chmod - Check permission for chmod().
548+ *
549+ * @path: Pointer to "struct path".
550+ * @mode: Mode.
551+ *
552+ * Returns 0 on success, negative value otherwise.
553+ */
554+static int ccs_path_chmod(struct path *path, umode_t mode)
555+{
556+ int rc = ccs_chmod_permission(path->dentry, path->mnt, mode);
557+ if (rc)
558+ return rc;
559+ while (!original_security_ops.path_chmod)
560+ smp_rmb();
561+ return original_security_ops.path_chmod(path, mode);
562+}
563+
564+/**
565+ * ccs_path_chroot - Check permission for chroot().
566+ *
567+ * @path: Pointer to "struct path".
568+ *
569+ * Returns 0 on success, negative value otherwise.
570+ */
571+static int ccs_path_chroot(struct path *path)
572+{
573+ int rc = ccs_chroot_permission(path);
574+ if (rc)
575+ return rc;
576+ while (!original_security_ops.path_chroot)
577+ smp_rmb();
578+ return original_security_ops.path_chroot(path);
579+}
580+
581+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
582+
583+/**
584+ * ccs_path_chown - Check permission for chown()/chgrp().
585+ *
586+ * @path: Pointer to "struct path".
587+ * @user: User ID.
588+ * @group: Group ID.
589+ *
590+ * Returns 0 on success, negative value otherwise.
591+ */
592+static int ccs_path_chown(struct path *path, uid_t user, gid_t group)
593+{
594+ int rc = ccs_chown_permission(path->dentry, path->mnt, user, group);
595+ if (rc)
596+ return rc;
597+ while (!original_security_ops.path_chown)
598+ smp_rmb();
599+ return original_security_ops.path_chown(path, user, group);
600+}
601+
602+#if defined(USE_UMODE_T)
603+
604+/**
605+ * ccs_path_chmod - Check permission for chmod().
606+ *
607+ * @path: Pointer to "struct path".
608+ * @mode: Mode.
609+ *
610+ * Returns 0 on success, negative value otherwise.
611+ */
612+static int ccs_path_chmod(struct path *path, umode_t mode)
613+{
614+ int rc = ccs_chmod_permission(path->dentry, path->mnt, mode);
615+ if (rc)
616+ return rc;
617+ while (!original_security_ops.path_chmod)
618+ smp_rmb();
619+ return original_security_ops.path_chmod(path, mode);
620+}
621+
622+#else
623+
624+/**
625+ * ccs_path_chmod - Check permission for chmod().
626+ *
627+ * @dentry: Pointer to "struct dentry".
628+ * @vfsmnt: Pointer to "struct vfsmount".
629+ * @mode: Mode.
630+ *
631+ * Returns 0 on success, negative value otherwise.
632+ */
633+static int ccs_path_chmod(struct dentry *dentry, struct vfsmount *vfsmnt,
634+ mode_t mode)
635+{
636+ int rc = ccs_chmod_permission(dentry, vfsmnt, mode);
637+ if (rc)
638+ return rc;
639+ while (!original_security_ops.path_chmod)
640+ smp_rmb();
641+ return original_security_ops.path_chmod(dentry, vfsmnt, mode);
642+}
643+
644+#endif
645+
646+/**
647+ * ccs_path_chroot - Check permission for chroot().
648+ *
649+ * @path: Pointer to "struct path".
650+ *
651+ * Returns 0 on success, negative value otherwise.
652+ */
653+static int ccs_path_chroot(struct path *path)
654+{
655+ int rc = ccs_chroot_permission(path);
656+ if (rc)
657+ return rc;
658+ while (!original_security_ops.path_chroot)
659+ smp_rmb();
660+ return original_security_ops.path_chroot(path);
661+}
662+
663+#endif
664+
665+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
666+
667+/**
668+ * ccs_path_truncate - Check permission for truncate().
669+ *
670+ * @path: Pointer to "struct path".
671+ *
672+ * Returns 0 on success, negative value otherwise.
673+ */
674+static int ccs_path_truncate(struct path *path)
675+{
676+ int rc = ccs_truncate_permission(path->dentry, path->mnt);
677+ if (rc)
678+ return rc;
679+ while (!original_security_ops.path_truncate)
680+ smp_rmb();
681+ return original_security_ops.path_truncate(path);
682+}
683+
684+#else
685+
686+/**
687+ * ccs_path_truncate - Check permission for truncate().
688+ *
689+ * @path: Pointer to "struct path".
690+ * @length: New length.
691+ * @time_attrs: New time attributes.
692+ *
693+ * Returns 0 on success, negative value otherwise.
694+ */
695+static int ccs_path_truncate(struct path *path, loff_t length,
696+ unsigned int time_attrs)
697+{
698+ int rc = ccs_truncate_permission(path->dentry, path->mnt);
699+ if (rc)
700+ return rc;
701+ while (!original_security_ops.path_truncate)
702+ smp_rmb();
703+ return original_security_ops.path_truncate(path, length, time_attrs);
704+}
705+
706+#endif
707+
708+#endif
709+
710+/**
711+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
712+ *
713+ * @dentry: Pointer to "struct dentry".
714+ * @attr: Pointer to "struct iattr".
715+ *
716+ * Returns 0 on success, negative value otherwise.
717+ */
718+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
719+{
720+ int rc = 0;
721+#if !defined(CONFIG_SECURITY_PATH) || LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
722+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
723+ if (attr->ia_valid & ATTR_UID)
724+ rc = ccs_chown_permission(dentry, NULL, attr->ia_uid,
725+ INVALID_GID);
726+ if (!rc && (attr->ia_valid & ATTR_GID))
727+ rc = ccs_chown_permission(dentry, NULL, INVALID_UID,
728+ attr->ia_gid);
729+#else
730+ if (attr->ia_valid & ATTR_UID)
731+ rc = ccs_chown_permission(dentry, NULL, attr->ia_uid, -1);
732+ if (!rc && (attr->ia_valid & ATTR_GID))
733+ rc = ccs_chown_permission(dentry, NULL, -1, attr->ia_gid);
734+#endif
735+ if (!rc && (attr->ia_valid & ATTR_MODE))
736+ rc = ccs_chmod_permission(dentry, NULL, attr->ia_mode);
737+#endif
738+#if !defined(CONFIG_SECURITY_PATH)
739+ if (!rc && (attr->ia_valid & ATTR_SIZE))
740+ rc = ccs_truncate_permission(dentry, NULL);
741+#endif
742+ if (rc)
743+ return rc;
744+ while (!original_security_ops.inode_setattr)
745+ smp_rmb();
746+ return original_security_ops.inode_setattr(dentry, attr);
747+}
748+
749+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
750+
751+/**
752+ * ccs_inode_getattr - Check permission for stat().
753+ *
754+ * @path: Pointer to "struct path".
755+ *
756+ * Returns 0 on success, negative value otherwise.
757+ */
758+static int ccs_inode_getattr(const struct path *path)
759+{
760+ int rc = ccs_getattr_permission(path->mnt, path->dentry);
761+ if (rc)
762+ return rc;
763+ while (!original_security_ops.inode_getattr)
764+ smp_rmb();
765+ return original_security_ops.inode_getattr(path);
766+}
767+
768+#else
769+
770+/**
771+ * ccs_inode_getattr - Check permission for stat().
772+ *
773+ * @mnt: Pointer to "struct vfsmount".
774+ * @dentry: Pointer to "struct dentry".
775+ *
776+ * Returns 0 on success, negative value otherwise.
777+ */
778+static int ccs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
779+{
780+ int rc = ccs_getattr_permission(mnt, dentry);
781+ if (rc)
782+ return rc;
783+ while (!original_security_ops.inode_getattr)
784+ smp_rmb();
785+ return original_security_ops.inode_getattr(mnt, dentry);
786+}
787+
788+#endif
789+
790+#if defined(CONFIG_SECURITY_PATH)
791+
792+#if defined(USE_UMODE_T)
793+
794+/**
795+ * ccs_path_mknod - Check permission for mknod().
796+ *
797+ * @dir: Pointer to "struct path".
798+ * @dentry: Pointer to "struct dentry".
799+ * @mode: Create mode.
800+ * @dev: Device major/minor number.
801+ *
802+ * Returns 0 on success, negative value otherwise.
803+ */
804+static int ccs_path_mknod(struct path *dir, struct dentry *dentry,
805+ umode_t mode, unsigned int dev)
806+{
807+ int rc = ccs_mknod_permission(dentry, dir->mnt, mode, dev);
808+ if (rc)
809+ return rc;
810+ while (!original_security_ops.path_mknod)
811+ smp_rmb();
812+ return original_security_ops.path_mknod(dir, dentry, mode, dev);
813+}
814+
815+/**
816+ * ccs_path_mkdir - Check permission for mkdir().
817+ *
818+ * @dir: Pointer to "struct path".
819+ * @dentry: Pointer to "struct dentry".
820+ * @mode: Create mode.
821+ *
822+ * Returns 0 on success, negative value otherwise.
823+ */
824+static int ccs_path_mkdir(struct path *dir, struct dentry *dentry,
825+ umode_t mode)
826+{
827+ int rc = ccs_mkdir_permission(dentry, dir->mnt, mode);
828+ if (rc)
829+ return rc;
830+ while (!original_security_ops.path_mkdir)
831+ smp_rmb();
832+ return original_security_ops.path_mkdir(dir, dentry, mode);
833+}
834+
835+#else
836+
837+/**
838+ * ccs_path_mknod - Check permission for mknod().
839+ *
840+ * @dir: Pointer to "struct path".
841+ * @dentry: Pointer to "struct dentry".
842+ * @mode: Create mode.
843+ * @dev: Device major/minor number.
844+ *
845+ * Returns 0 on success, negative value otherwise.
846+ */
847+static int ccs_path_mknod(struct path *dir, struct dentry *dentry, int mode,
848+ unsigned int dev)
849+{
850+ int rc = ccs_mknod_permission(dentry, dir->mnt, mode, dev);
851+ if (rc)
852+ return rc;
853+ while (!original_security_ops.path_mknod)
854+ smp_rmb();
855+ return original_security_ops.path_mknod(dir, dentry, mode, dev);
856