• R/O
  • SSH
  • HTTPS

akari: コミット


コミットメタ情報

リビジョン612 (tree)
日時2019-08-20 14:45:20
作者kumaneko

ログメッセージ

AKARI 1.0.39

変更サマリ

差分

--- tags/patches/1.0.39/README (nonexistent)
+++ tags/patches/1.0.39/README (revision 612)
@@ -0,0 +1,329 @@
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.
--- tags/patches/1.0.39/ccsecurity.h (nonexistent)
+++ tags/patches/1.0.39/ccsecurity.h (revision 612)
@@ -0,0 +1,943 @@
1+/*
2+ * include/linux/ccsecurity.h
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.6 2019/08/20
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+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
33+int search_binary_handler(struct linux_binprm *bprm);
34+#else
35+int search_binary_handler(struct linux_binprm *bprm, struct pt_regs *regs);
36+#endif
37+
38+#ifdef CONFIG_CCSECURITY
39+
40+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
41+/* Obtain prototype of __d_path(). */
42+#include <linux/dcache.h>
43+#endif
44+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
45+/* Obtain definition of kuid_t and kgid_t. */
46+#include <linux/uidgid.h>
47+#endif
48+
49+/* For exporting variables and functions. */
50+struct ccsecurity_exports {
51+ void (*load_policy) (const char *filename);
52+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
53+ char * (*d_absolute_path) (const struct path *, char *, int);
54+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
55+ typeof(__d_path) (*__d_path);
56+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
57+ spinlock_t *vfsmount_lock;
58+#endif
59+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
60+ struct task_struct * (*find_task_by_vpid) (pid_t nr);
61+ struct task_struct * (*find_task_by_pid_ns) (pid_t nr,
62+ struct pid_namespace *ns);
63+#endif
64+};
65+
66+/* For doing access control. */
67+struct ccsecurity_operations {
68+ void (*check_profile) (void);
69+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
70+ int (*chroot_permission) (const struct path *path);
71+ int (*pivot_root_permission) (const struct path *old_path,
72+ const struct path *new_path);
73+ int (*mount_permission) (const char *dev_name, const struct path *path,
74+ const char *type, unsigned long flags,
75+ void *data_page);
76+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
77+ int (*move_mount_permission) (const struct path *from_path,
78+ const struct path *to_path);
79+#endif
80+#else
81+ int (*chroot_permission) (struct nameidata *nd);
82+ int (*pivot_root_permission) (struct nameidata *old_nd,
83+ struct nameidata *new_nd);
84+ int (*mount_permission) (const char *dev_name, struct nameidata *nd,
85+ const char *type, unsigned long flags,
86+ void *data_page);
87+#endif
88+ int (*umount_permission) (struct vfsmount *mnt, int flags);
89+ _Bool (*lport_reserved) (const u16 port);
90+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
91+ void (*save_open_mode) (int mode);
92+ void (*clear_open_mode) (void);
93+ int (*open_permission) (struct dentry *dentry, struct vfsmount *mnt,
94+ const int flag);
95+#else
96+ int (*open_permission) (struct file *file);
97+#endif
98+ int (*ptrace_permission) (long request, long pid);
99+ int (*ioctl_permission) (struct file *filp, unsigned int cmd,
100+ unsigned long arg);
101+ int (*parse_table) (int __user *name, int nlen, void __user *oldval,
102+ void __user *newval, struct ctl_table *table);
103+ _Bool (*capable) (const u8 operation);
104+ int (*mknod_permission) (struct dentry *dentry, struct vfsmount *mnt,
105+ unsigned int mode, unsigned int dev);
106+ int (*mkdir_permission) (struct dentry *dentry, struct vfsmount *mnt,
107+ unsigned int mode);
108+ int (*rmdir_permission) (struct dentry *dentry, struct vfsmount *mnt);
109+ int (*unlink_permission) (struct dentry *dentry, struct vfsmount *mnt);
110+ int (*symlink_permission) (struct dentry *dentry, struct vfsmount *mnt,
111+ const char *from);
112+ int (*truncate_permission) (struct dentry *dentry,
113+ struct vfsmount *mnt);
114+ int (*rename_permission) (struct dentry *old_dentry,
115+ struct dentry *new_dentry,
116+ struct vfsmount *mnt);
117+ int (*link_permission) (struct dentry *old_dentry,
118+ struct dentry *new_dentry,
119+ struct vfsmount *mnt);
120+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
121+ int (*open_exec_permission) (struct dentry *dentry,
122+ struct vfsmount *mnt);
123+ int (*uselib_permission) (struct dentry *dentry, struct vfsmount *mnt);
124+#endif
125+ int (*fcntl_permission) (struct file *file, unsigned int cmd,
126+ unsigned long arg);
127+ int (*kill_permission) (pid_t pid, int sig);
128+ int (*tgkill_permission) (pid_t tgid, pid_t pid, int sig);
129+ int (*tkill_permission) (pid_t pid, int sig);
130+ int (*socket_create_permission) (int family, int type, int protocol);
131+ int (*socket_listen_permission) (struct socket *sock);
132+ int (*socket_connect_permission) (struct socket *sock,
133+ struct sockaddr *addr, int addr_len);
134+ int (*socket_bind_permission) (struct socket *sock,
135+ struct sockaddr *addr, int addr_len);
136+ int (*socket_post_accept_permission) (struct socket *sock,
137+ struct socket *newsock);
138+ int (*socket_sendmsg_permission) (struct socket *sock,
139+ struct msghdr *msg, int size);
140+ int (*socket_post_recvmsg_permission) (struct sock *sk,
141+ struct sk_buff *skb, int flags);
142+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
143+ int (*chown_permission) (struct dentry *dentry, struct vfsmount *mnt,
144+ kuid_t user, kgid_t group);
145+#else
146+ int (*chown_permission) (struct dentry *dentry, struct vfsmount *mnt,
147+ uid_t user, gid_t group);
148+#endif
149+ int (*chmod_permission) (struct dentry *dentry, struct vfsmount *mnt,
150+ mode_t mode);
151+ int (*getattr_permission) (struct vfsmount *mnt,
152+ struct dentry *dentry);
153+ int (*sigqueue_permission) (pid_t pid, int sig);
154+ int (*tgsigqueue_permission) (pid_t tgid, pid_t pid, int sig);
155+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
156+ int (*search_binary_handler) (struct linux_binprm *bprm);
157+#else
158+ int (*search_binary_handler) (struct linux_binprm *bprm,
159+ struct pt_regs *regs);
160+#endif
161+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
162+ int (*alloc_task_security) (const struct task_struct *task);
163+ void (*free_task_security) (const struct task_struct *task);
164+#endif
165+ _Bool disabled;
166+};
167+
168+extern struct ccsecurity_operations ccsecurity_ops;
169+
170+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
171+
172+static inline int ccs_chroot_permission(const struct path *path)
173+{
174+ int (*func) (const struct path *) = ccsecurity_ops.chroot_permission;
175+ return func ? func(path) : 0;
176+}
177+
178+static inline int ccs_pivot_root_permission(const struct path *old_path,
179+ const struct path *new_path)
180+{
181+ int (*func) (const struct path *, const struct path *)
182+ = ccsecurity_ops.pivot_root_permission;
183+ return func ? func(old_path, new_path) : 0;
184+}
185+
186+static inline int ccs_mount_permission(const char *dev_name,
187+ const struct path *path,
188+ const char *type, unsigned long flags,
189+ void *data_page)
190+{
191+ int (*func) (const char *, const struct path *, const char *,
192+ unsigned long, void *) = ccsecurity_ops.mount_permission;
193+ return func ? func(dev_name, path, type, flags, data_page) : 0;
194+}
195+
196+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
197+static inline int ccs_move_mount_permission(const struct path *from_path,
198+ const struct path *to_path)
199+{
200+ int (*func) (const struct path *, const struct path *) =
201+ ccsecurity_ops.move_mount_permission;
202+ return func ? func(from_path, to_path) : 0;
203+}
204+#endif
205+
206+#else
207+
208+static inline int ccs_chroot_permission(struct nameidata *nd)
209+{
210+ int (*func) (struct nameidata *) = ccsecurity_ops.chroot_permission;
211+ return func ? func(nd) : 0;
212+}
213+
214+static inline int ccs_pivot_root_permission(struct nameidata *old_nd,
215+ struct nameidata *new_nd)
216+{
217+ int (*func) (struct nameidata *, struct nameidata *)
218+ = ccsecurity_ops.pivot_root_permission;
219+ return func ? func(old_nd, new_nd) : 0;
220+}
221+
222+static inline int ccs_mount_permission(const char *dev_name,
223+ struct nameidata *nd, const char *type,
224+ unsigned long flags, void *data_page)
225+{
226+ int (*func) (const char *, struct nameidata *, const char *,
227+ unsigned long, void *) = ccsecurity_ops.mount_permission;
228+ return func ? func(dev_name, nd, type, flags, data_page) : 0;
229+}
230+
231+#endif
232+
233+static inline int ccs_umount_permission(struct vfsmount *mnt, int flags)
234+{
235+ int (*func) (struct vfsmount *, int)
236+ = ccsecurity_ops.umount_permission;
237+ return func ? func(mnt, flags) : 0;
238+}
239+
240+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
241+
242+static inline void ccs_save_open_mode(int mode)
243+{
244+ void (*func) (int) = ccsecurity_ops.save_open_mode;
245+ if (func)
246+ func(mode);
247+}
248+
249+static inline void ccs_clear_open_mode(void)
250+{
251+ void (*func) (void) = ccsecurity_ops.clear_open_mode;
252+ if (func)
253+ func();
254+}
255+
256+static inline int ccs_open_permission(struct dentry *dentry,
257+ struct vfsmount *mnt, const int flag)
258+{
259+ int (*func) (struct dentry *, struct vfsmount *, const int)
260+ = ccsecurity_ops.open_permission;
261+ return func ? func(dentry, mnt, flag) : 0;
262+}
263+
264+#else
265+
266+static inline int ccs_open_permission(struct file *filp)
267+{
268+ int (*func) (struct file *) = ccsecurity_ops.open_permission;
269+ return func ? func(filp) : 0;
270+}
271+
272+#endif
273+
274+static inline int ccs_fcntl_permission(struct file *file, unsigned int cmd,
275+ unsigned long arg)
276+{
277+ int (*func) (struct file *, unsigned int, unsigned long)
278+ = ccsecurity_ops.fcntl_permission;
279+ return func ? func(file, cmd, arg) : 0;
280+}
281+
282+static inline int ccs_ioctl_permission(struct file *filp, unsigned int cmd,
283+ unsigned long arg)
284+{
285+ int (*func) (struct file *, unsigned int, unsigned long)
286+ = ccsecurity_ops.ioctl_permission;
287+ return func ? func(filp, cmd, arg) : 0;
288+}
289+
290+static inline int ccs_parse_table(int __user *name, int nlen,
291+ void __user *oldval, void __user *newval,
292+ struct ctl_table *table)
293+{
294+ int (*func) (int __user *, int, void __user *, void __user *,
295+ struct ctl_table *) = ccsecurity_ops.parse_table;
296+ return func ? func(name, nlen, oldval, newval, table) : 0;
297+}
298+
299+static inline int ccs_mknod_permission(struct dentry *dentry,
300+ struct vfsmount *mnt, unsigned int mode,
301+ unsigned int dev)
302+{
303+ int (*func) (struct dentry *, struct vfsmount *, unsigned int,
304+ unsigned int) = ccsecurity_ops.mknod_permission;
305+ return func ? func(dentry, mnt, mode, dev) : 0;
306+}
307+
308+static inline int ccs_mkdir_permission(struct dentry *dentry,
309+ struct vfsmount *mnt, unsigned int mode)
310+{
311+ int (*func) (struct dentry *, struct vfsmount *, unsigned int)
312+ = ccsecurity_ops.mkdir_permission;
313+ return func ? func(dentry, mnt, mode) : 0;
314+}
315+
316+static inline int ccs_rmdir_permission(struct dentry *dentry,
317+ struct vfsmount *mnt)
318+{
319+ int (*func) (struct dentry *, struct vfsmount *)
320+ = ccsecurity_ops.rmdir_permission;
321+ return func ? func(dentry, mnt) : 0;
322+}
323+
324+static inline int ccs_unlink_permission(struct dentry *dentry,
325+ struct vfsmount *mnt)
326+{
327+ int (*func) (struct dentry *, struct vfsmount *)
328+ = ccsecurity_ops.unlink_permission;
329+ return func ? func(dentry, mnt) : 0;
330+}
331+
332+static inline int ccs_symlink_permission(struct dentry *dentry,
333+ struct vfsmount *mnt,
334+ const char *from)
335+{
336+ int (*func) (struct dentry *, struct vfsmount *, const char *)
337+ = ccsecurity_ops.symlink_permission;
338+ return func ? func(dentry, mnt, from) : 0;
339+}
340+
341+static inline int ccs_truncate_permission(struct dentry *dentry,
342+ struct vfsmount *mnt)
343+{
344+ int (*func) (struct dentry *, struct vfsmount *)
345+ = ccsecurity_ops.truncate_permission;
346+ return func ? func(dentry, mnt) : 0;
347+}
348+
349+static inline int ccs_rename_permission(struct dentry *old_dentry,
350+ struct dentry *new_dentry,
351+ struct vfsmount *mnt)
352+{
353+ int (*func) (struct dentry *, struct dentry *, struct vfsmount *)
354+ = ccsecurity_ops.rename_permission;
355+ return func ? func(old_dentry, new_dentry, mnt) : 0;
356+}
357+
358+static inline int ccs_link_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.link_permission;
364+ return func ? func(old_dentry, new_dentry, mnt) : 0;
365+}
366+
367+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
368+
369+static inline int ccs_open_exec_permission(struct dentry *dentry,
370+ struct vfsmount *mnt)
371+{
372+ int (*func) (struct dentry *, struct vfsmount *)
373+ = ccsecurity_ops.open_exec_permission;
374+ return func ? func(dentry, mnt) : 0;
375+}
376+
377+static inline int ccs_uselib_permission(struct dentry *dentry,
378+ struct vfsmount *mnt)
379+{
380+ int (*func) (struct dentry *, struct vfsmount *)
381+ = ccsecurity_ops.uselib_permission;
382+ return func ? func(dentry, mnt) : 0;
383+}
384+
385+#endif
386+
387+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
388+
389+static inline int ccs_chown_permission(struct dentry *dentry,
390+ struct vfsmount *mnt, kuid_t user,
391+ kgid_t group)
392+{
393+ int (*func) (struct dentry *, struct vfsmount *, kuid_t, kgid_t)
394+ = ccsecurity_ops.chown_permission;
395+ return func ? func(dentry, mnt, user, group) : 0;
396+}
397+
398+#else
399+
400+static inline int ccs_chown_permission(struct dentry *dentry,
401+ struct vfsmount *mnt, uid_t user,
402+ gid_t group)
403+{
404+ int (*func) (struct dentry *, struct vfsmount *, uid_t, gid_t)
405+ = ccsecurity_ops.chown_permission;
406+ return func ? func(dentry, mnt, user, group) : 0;
407+}
408+
409+#endif
410+
411+static inline int ccs_chmod_permission(struct dentry *dentry,
412+ struct vfsmount *mnt, mode_t mode)
413+{
414+ int (*func) (struct dentry *, struct vfsmount *, mode_t)
415+ = ccsecurity_ops.chmod_permission;
416+ return func ? func(dentry, mnt, mode) : 0;
417+}
418+
419+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
420+
421+static inline int ccs_search_binary_handler(struct linux_binprm *bprm)
422+{
423+ return ccsecurity_ops.search_binary_handler(bprm);
424+}
425+
426+#else
427+
428+static inline int ccs_search_binary_handler(struct linux_binprm *bprm,
429+ struct pt_regs *regs)
430+{
431+ return ccsecurity_ops.search_binary_handler(bprm, regs);
432+}
433+
434+#endif
435+
436+#else
437+
438+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
439+
440+static inline int ccs_chroot_permission(const struct path *path)
441+{
442+ return 0;
443+}
444+
445+static inline int ccs_pivot_root_permission(const struct path *old_path,
446+ const struct path *new_path)
447+{
448+ return 0;
449+}
450+
451+static inline int ccs_mount_permission(const char *dev_name,
452+ const struct path *path,
453+ const char *type, unsigned long flags,
454+ void *data_page)
455+{
456+ return 0;
457+}
458+
459+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
460+static inline int ccs_move_mount_permission(const struct path *from_path,
461+ const struct path *to_path)
462+{
463+ return 0;
464+}
465+#endif
466+
467+#else
468+
469+static inline int ccs_chroot_permission(struct nameidata *nd)
470+{
471+ return 0;
472+}
473+
474+static inline int ccs_pivot_root_permission(struct nameidata *old_nd,
475+ struct nameidata *new_nd)
476+{
477+ return 0;
478+}
479+
480+static inline int ccs_mount_permission(const char *dev_name,
481+ struct nameidata *nd, const char *type,
482+ unsigned long flags, void *data_page)
483+{
484+ return 0;
485+}
486+
487+#endif
488+
489+static inline int ccs_umount_permission(struct vfsmount *mnt, int flags)
490+{
491+ return 0;
492+}
493+
494+static inline void ccs_save_open_mode(int mode)
495+{
496+}
497+
498+static inline void ccs_clear_open_mode(void)
499+{
500+}
501+
502+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
503+
504+static inline int ccs_open_permission(struct dentry *dentry,
505+ struct vfsmount *mnt, const int flag)
506+{
507+ return 0;
508+}
509+
510+#else
511+
512+static inline int ccs_open_permission(struct file *filp)
513+{
514+ return 0;
515+}
516+
517+#endif
518+
519+static inline int ccs_ioctl_permission(struct file *filp, unsigned int cmd,
520+ unsigned long arg)
521+{
522+ return 0;
523+}
524+
525+static inline int ccs_parse_table(int __user *name, int nlen,
526+ void __user *oldval, void __user *newval,
527+ struct ctl_table *table)
528+{
529+ return 0;
530+}
531+
532+static inline int ccs_mknod_permission(struct dentry *dentry,
533+ struct vfsmount *mnt, unsigned int mode,
534+ unsigned int dev)
535+{
536+ return 0;
537+}
538+
539+static inline int ccs_mkdir_permission(struct dentry *dentry,
540+ struct vfsmount *mnt, unsigned int mode)
541+{
542+ return 0;
543+}
544+
545+static inline int ccs_rmdir_permission(struct dentry *dentry,
546+ struct vfsmount *mnt)
547+{
548+ return 0;
549+}
550+
551+static inline int ccs_unlink_permission(struct dentry *dentry,
552+ struct vfsmount *mnt)
553+{
554+ return 0;
555+}
556+
557+static inline int ccs_symlink_permission(struct dentry *dentry,
558+ struct vfsmount *mnt,
559+ const char *from)
560+{
561+ return 0;
562+}
563+
564+static inline int ccs_truncate_permission(struct dentry *dentry,
565+ struct vfsmount *mnt)
566+{
567+ return 0;
568+}
569+
570+static inline int ccs_rename_permission(struct dentry *old_dentry,
571+ struct dentry *new_dentry,
572+ struct vfsmount *mnt)
573+{
574+ return 0;
575+}
576+
577+static inline int ccs_link_permission(struct dentry *old_dentry,
578+ struct dentry *new_dentry,
579+ struct vfsmount *mnt)
580+{
581+ return 0;
582+}
583+
584+static inline int ccs_open_exec_permission(struct dentry *dentry,
585+ struct vfsmount *mnt)
586+{
587+ return 0;
588+}
589+
590+static inline int ccs_uselib_permission(struct dentry *dentry,
591+ struct vfsmount *mnt)
592+{
593+ return 0;
594+}
595+
596+static inline int ccs_fcntl_permission(struct file *file, unsigned int cmd,
597+ unsigned long arg)
598+{
599+ return 0;
600+}
601+
602+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
603+
604+static inline int ccs_chown_permission(struct dentry *dentry,
605+ struct vfsmount *mnt, kuid_t user,
606+ kgid_t group)
607+{
608+ return 0;
609+}
610+
611+#else
612+
613+static inline int ccs_chown_permission(struct dentry *dentry,
614+ struct vfsmount *mnt, uid_t user,
615+ gid_t group)
616+{
617+ return 0;
618+}
619+
620+#endif
621+
622+static inline int ccs_chmod_permission(struct dentry *dentry,
623+ struct vfsmount *mnt, mode_t mode)
624+{
625+ return 0;
626+}
627+
628+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
629+
630+static inline int ccs_search_binary_handler(struct linux_binprm *bprm)
631+{
632+ return search_binary_handler(bprm);
633+}
634+
635+#else
636+
637+static inline int ccs_search_binary_handler(struct linux_binprm *bprm,
638+ struct pt_regs *regs)
639+{
640+ return search_binary_handler(bprm, regs);
641+}
642+
643+#endif
644+
645+#endif
646+
647+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
648+
649+static inline int ccs_alloc_task_security(const struct task_struct *task)
650+{
651+ int (*func) (const struct task_struct *)
652+ = ccsecurity_ops.alloc_task_security;
653+ return func ? func(task) : 0;
654+}
655+
656+static inline void ccs_free_task_security(const struct task_struct *task)
657+{
658+ void (*func) (const struct task_struct *)
659+ = ccsecurity_ops.free_task_security;
660+ if (func)
661+ func(task);
662+}
663+
664+#else
665+
666+static inline int ccs_alloc_task_security(const struct task_struct *task)
667+{
668+ return 0;
669+}
670+
671+static inline void ccs_free_task_security(const struct task_struct *task)
672+{
673+}
674+
675+#endif
676+
677+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
678+
679+static inline int ccs_getattr_permission(struct vfsmount *mnt,
680+ struct dentry *dentry)
681+{
682+ int (*func) (struct vfsmount *, struct dentry *)
683+ = ccsecurity_ops.getattr_permission;
684+ return func ? func(mnt, dentry) : 0;
685+}
686+
687+#else
688+
689+static inline int ccs_getattr_permission(struct vfsmount *mnt,
690+ struct dentry *dentry)
691+{
692+ return 0;
693+}
694+
695+#endif
696+
697+#ifdef CONFIG_CCSECURITY_NETWORK
698+
699+static inline int ccs_socket_listen_permission(struct socket *sock)
700+{
701+ int (*func) (struct socket *)
702+ = ccsecurity_ops.socket_listen_permission;
703+ return func ? func(sock) : 0;
704+}
705+
706+static inline int ccs_socket_connect_permission(struct socket *sock,
707+ struct sockaddr *addr,
708+ int addr_len)
709+{
710+ int (*func) (struct socket *, struct sockaddr *, int)
711+ = ccsecurity_ops.socket_connect_permission;
712+ return func ? func(sock, addr, addr_len) : 0;
713+}
714+
715+static inline int ccs_socket_bind_permission(struct socket *sock,
716+ struct sockaddr *addr,
717+ int addr_len)
718+{
719+ int (*func) (struct socket *, struct sockaddr *, int)
720+ = ccsecurity_ops.socket_bind_permission;
721+ return func ? func(sock, addr, addr_len) : 0;
722+}
723+
724+static inline int ccs_socket_post_accept_permission(struct socket *sock,
725+ struct socket *newsock)
726+{
727+ int (*func) (struct socket *, struct socket *)
728+ = ccsecurity_ops.socket_post_accept_permission;
729+ return func ? func(sock, newsock) : 0;
730+}
731+
732+static inline int ccs_socket_sendmsg_permission(struct socket *sock,
733+ struct msghdr *msg,
734+ int size)
735+{
736+ int (*func) (struct socket *, struct msghdr *, int)
737+ = ccsecurity_ops.socket_sendmsg_permission;
738+ return func ? func(sock, msg, size) : 0;
739+}
740+
741+#else
742+
743+static inline int ccs_socket_listen_permission(struct socket *sock)
744+{
745+ return 0;
746+}
747+
748+static inline int ccs_socket_connect_permission(struct socket *sock,
749+ struct sockaddr *addr,
750+ int addr_len)
751+{
752+ return 0;
753+}
754+
755+static inline int ccs_socket_bind_permission(struct socket *sock,
756+ struct sockaddr *addr,
757+ int addr_len)
758+{
759+ return 0;
760+}
761+
762+static inline int ccs_socket_post_accept_permission(struct socket *sock,
763+ struct socket *newsock)
764+{
765+ return 0;
766+}
767+
768+static inline int ccs_socket_sendmsg_permission(struct socket *sock,
769+ struct msghdr *msg,
770+ int size)
771+{
772+ return 0;
773+}
774+
775+#endif
776+
777+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
778+
779+static inline int ccs_socket_post_recvmsg_permission(struct sock *sk,
780+ struct sk_buff *skb,
781+ int flags)
782+{
783+ int (*func) (struct sock *, struct sk_buff *, int)
784+ = ccsecurity_ops.socket_post_recvmsg_permission;
785+ return func ? func(sk, skb, flags) : 0;
786+}
787+
788+#else
789+
790+static inline int ccs_socket_post_recvmsg_permission(struct sock *sk,
791+ struct sk_buff *skb,
792+ int flags)
793+{
794+ return 0;
795+}
796+
797+#endif
798+
799+#ifdef CONFIG_CCSECURITY_PORTRESERVE
800+
801+static inline _Bool ccs_lport_reserved(const u16 port)
802+{
803+ _Bool (*func) (const u16) = ccsecurity_ops.lport_reserved;
804+ return func ? func(port) : 0;
805+}
806+
807+#else
808+
809+static inline _Bool ccs_lport_reserved(const u16 port)
810+{
811+ return 0;
812+}
813+
814+#endif
815+
816+#ifdef CONFIG_CCSECURITY_CAPABILITY
817+
818+static inline _Bool ccs_capable(const u8 operation)
819+{
820+ _Bool (*func) (const u8) = ccsecurity_ops.capable;
821+ return func ? func(operation) : 1;
822+}
823+
824+static inline int ccs_socket_create_permission(int family, int type,
825+ int protocol)
826+{
827+ int (*func) (int, int, int) = ccsecurity_ops.socket_create_permission;
828+ return func ? func(family, type, protocol) : 0;
829+}
830+
831+static inline int ccs_ptrace_permission(long request, long pid)
832+{
833+ int (*func) (long, long) = ccsecurity_ops.ptrace_permission;
834+ return func ? func(request, pid) : 0;
835+}
836+
837+#else
838+
839+static inline _Bool ccs_capable(const u8 operation)
840+{
841+ return 1;
842+}
843+
844+static inline int ccs_socket_create_permission(int family, int type,
845+ int protocol)
846+{
847+ return 0;
848+}
849+
850+static inline int ccs_ptrace_permission(long request, long pid)
851+{
852+ return 0;
853+}
854+
855+#endif
856+
857+#ifdef CONFIG_CCSECURITY_IPC
858+
859+static inline int ccs_kill_permission(pid_t pid, int sig)
860+{
861+ int (*func) (pid_t, int) = ccsecurity_ops.kill_permission;
862+ return func ? func(pid, sig) : 0;
863+}
864+
865+static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
866+{
867+ int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgkill_permission;
868+ return func ? func(tgid, pid, sig) : 0;
869+}
870+
871+static inline int ccs_tkill_permission(pid_t pid, int sig)
872+{
873+ int (*func) (pid_t, int) = ccsecurity_ops.tkill_permission;
874+ return func ? func(pid, sig) : 0;
875+}
876+
877+static inline int ccs_sigqueue_permission(pid_t pid, int sig)
878+{
879+ int (*func) (pid_t, int) = ccsecurity_ops.sigqueue_permission;
880+ return func ? func(pid, sig) : 0;
881+}
882+
883+static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
884+{
885+ int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgsigqueue_permission;
886+ return func ? func(tgid, pid, sig) : 0;
887+}
888+
889+#else
890+
891+static inline int ccs_kill_permission(pid_t pid, int sig)
892+{
893+ return 0;
894+}
895+
896+static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
897+{
898+ return 0;
899+}
900+
901+static inline int ccs_tkill_permission(pid_t pid, int sig)
902+{
903+ return 0;
904+}
905+
906+static inline int ccs_sigqueue_permission(pid_t pid, int sig)
907+{
908+ return 0;
909+}
910+
911+static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
912+{
913+ return 0;
914+}
915+
916+#endif
917+
918+/* Index numbers for Capability Controls. */
919+enum ccs_capability_acl_index {
920+ /* socket(PF_ROUTE, *, *) */
921+ CCS_USE_ROUTE_SOCKET,
922+ /* socket(PF_PACKET, *, *) */
923+ CCS_USE_PACKET_SOCKET,
924+ /* sys_reboot() */
925+ CCS_SYS_REBOOT,
926+ /* sys_vhangup() */
927+ CCS_SYS_VHANGUP,
928+ /* do_settimeofday(), sys_adjtimex() */
929+ CCS_SYS_SETTIME,
930+ /* sys_nice(), sys_setpriority() */
931+ CCS_SYS_NICE,
932+ /* sys_sethostname(), sys_setdomainname() */
933+ CCS_SYS_SETHOSTNAME,
934+ /* sys_create_module(), sys_init_module(), sys_delete_module() */
935+ CCS_USE_KERNEL_MODULE,
936+ /* sys_kexec_load() */
937+ CCS_SYS_KEXEC_LOAD,
938+ /* sys_ptrace() */
939+ CCS_SYS_PTRACE,
940+ CCS_MAX_CAPABILITY_INDEX
941+};
942+
943+#endif
--- tags/patches/1.0.39/gc.c (nonexistent)
+++ tags/patches/1.0.39/gc.c (revision 612)
@@ -0,0 +1,1054 @@
1+/*
2+ * security/ccsecurity/gc.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.6 2019/08/20
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 bacause
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.39/internal.h (nonexistent)
+++ tags/patches/1.0.39/internal.h (revision 612)
@@ -0,0 +1,2172 @@
1+/*
2+ * security/ccsecurity/internal.h
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.6 2019/08/20
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(3, 16, 0)
199+#define d_inode(dentry) (dentry)->d_inode
200+#endif
201+
202+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
203+
204+/**
205+ * kzalloc() - Allocate memory. The memory is set to zero.
206+ *
207+ * @size: Size to allocate.
208+ * @flags: GFP flags.
209+ *
210+ * Returns pointer to allocated memory on success, NULL otherwise.
211+ *
212+ * This is for compatibility with older kernels.
213+ *
214+ * Since several distributions backported kzalloc(), I define it as a macro
215+ * rather than an inlined function in order to avoid multiple definition error.
216+ */
217+#define kzalloc(size, flags) ({ \
218+ void *ret = kmalloc((size), (flags)); \
219+ if (ret) \
220+ memset(ret, 0, (size)); \
221+ ret; })
222+
223+#endif
224+
225+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
226+
227+/**
228+ * path_put - Drop reference on "struct path".
229+ *
230+ * @path: Pointer to "struct path".
231+ *
232+ * Returns nothing.
233+ *
234+ * This is for compatibility with older kernels.
235+ */
236+static inline void path_put(struct path *path)
237+{
238+ dput(path->dentry);
239+ mntput(path->mnt);
240+}
241+
242+#endif
243+
244+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
245+
246+/**
247+ * __list_add_rcu - Insert a new entry between two known consecutive entries.
248+ *
249+ * @new: Pointer to "struct list_head".
250+ * @prev: Pointer to "struct list_head".
251+ * @next: Pointer to "struct list_head".
252+ *
253+ * Returns nothing.
254+ *
255+ * This is for compatibility with older kernels.
256+ */
257+static inline void __list_add_rcu(struct list_head *new,
258+ struct list_head *prev,
259+ struct list_head *next)
260+{
261+ new->next = next;
262+ new->prev = prev;
263+ rcu_assign_pointer(prev->next, new);
264+ next->prev = new;
265+}
266+
267+/**
268+ * list_add_tail_rcu - Add a new entry to rcu-protected list.
269+ *
270+ * @new: Pointer to "struct list_head".
271+ * @head: Pointer to "struct list_head".
272+ *
273+ * Returns nothing.
274+ *
275+ * This is for compatibility with older kernels.
276+ */
277+static inline void list_add_tail_rcu(struct list_head *new,
278+ struct list_head *head)
279+{
280+ __list_add_rcu(new, head->prev, head);
281+}
282+
283+/**
284+ * list_add_rcu - Add a new entry to rcu-protected list.
285+ *
286+ * @new: Pointer to "struct list_head".
287+ * @head: Pointer to "struct list_head".
288+ *
289+ * Returns nothing.
290+ *
291+ * This is for compatibility with older kernels.
292+ */
293+static inline void list_add_rcu(struct list_head *new, struct list_head *head)
294+{
295+ __list_add_rcu(new, head, head->next);
296+}
297+
298+#endif
299+
300+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
301+
302+/**
303+ * __list_del_entry - Deletes entry from list without re-initialization.
304+ *
305+ * @entry: Pointer to "struct list_head".
306+ *
307+ * Returns nothing.
308+ *
309+ * This is for compatibility with older kernels.
310+ */
311+static inline void __list_del_entry(struct list_head *entry)
312+{
313+ __list_del(entry->prev, entry->next);
314+}
315+
316+#endif
317+
318+#ifndef list_for_each_entry_safe
319+
320+/**
321+ * list_for_each_entry_safe - Iterate over list of given type safe against removal of list entry.
322+ *
323+ * @pos: The "type *" to use as a loop cursor.
324+ * @n: Another "type *" to use as temporary storage.
325+ * @head: Pointer to "struct list_head".
326+ * @member: The name of the list_struct within the struct.
327+ *
328+ * This is for compatibility with older kernels.
329+ */
330+#define list_for_each_entry_safe(pos, n, head, member) \
331+ for (pos = list_entry((head)->next, typeof(*pos), member), \
332+ n = list_entry(pos->member.next, typeof(*pos), member); \
333+ &pos->member != (head); \
334+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
335+
336+#endif
337+
338+#ifndef srcu_dereference
339+
340+/**
341+ * srcu_dereference - Fetch SRCU-protected pointer with checking.
342+ *
343+ * @p: The pointer to read, prior to dereferencing.
344+ * @ss: Pointer to "struct srcu_struct".
345+ *
346+ * Returns @p.
347+ *
348+ * This is for compatibility with older kernels.
349+ */
350+#define srcu_dereference(p, ss) rcu_dereference(p)
351+
352+#endif
353+
354+#ifndef list_for_each_entry_srcu
355+
356+/**
357+ * list_for_each_entry_srcu - Iterate over rcu list of given type.
358+ *
359+ * @pos: The type * to use as a loop cursor.
360+ * @head: The head for your list.
361+ * @member: The name of the list_struct within the struct.
362+ * @ss: Pointer to "struct srcu_struct".
363+ *
364+ * As of 2.6.36, this macro is not provided because only TOMOYO wants it.
365+ */
366+#define list_for_each_entry_srcu(pos, head, member, ss) \
367+ for (pos = list_entry(srcu_dereference((head)->next, ss), \
368+ typeof(*pos), member); \
369+ prefetch(pos->member.next), &pos->member != (head); \
370+ pos = list_entry(srcu_dereference(pos->member.next, ss), \
371+ typeof(*pos), member))
372+
373+#endif
374+
375+#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))
376+
377+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 4, 21)
378+#undef ssleep
379+#endif
380+
381+#ifndef ssleep
382+
383+/**
384+ * ssleep - Sleep for specified seconds.
385+ *
386+ * @secs: Seconds to sleep.
387+ *
388+ * Returns nothing.
389+ *
390+ * This is for compatibility with older kernels.
391+ *
392+ * Since several distributions backported ssleep(), I define it as a macro
393+ * rather than an inlined function in order to avoid multiple definition error.
394+ */
395+#define ssleep(secs) { \
396+ set_current_state(TASK_UNINTERRUPTIBLE); \
397+ schedule_timeout((HZ * secs) + 1); \
398+ }
399+
400+#endif
401+
402+#endif
403+
404+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
405+
406+/**
407+ * from_kuid - Convert kuid_t to uid_t.
408+ *
409+ * @ns: Unused.
410+ * @uid: kuid_t value.
411+ *
412+ * Returns uid seen from init's user namespace.
413+ */
414+#define from_kuid(ns, uid) (uid)
415+
416+/**
417+ * from_kgid - Convert kgid_t to gid_t.
418+ *
419+ * @ns: Unused.
420+ * @gid: kgid_t value.
421+ *
422+ * Returns gid seen from init's user namespace.
423+ */
424+#define from_kgid(ns, gid) (gid)
425+
426+/**
427+ * uid_eq - Check whether the uids are equals or not.
428+ *
429+ * @left: Uid seen from current user namespace.
430+ * @right: Uid seen from current user namespace.
431+ *
432+ * Returns true if uid is root in init's user namespace, false otherwise.
433+ */
434+#define uid_eq(left, right) ((left) == (right))
435+#define GLOBAL_ROOT_UID 0
436+
437+#endif
438+
439+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
440+#define d_backing_inode(upper) (upper)->d_inode
441+#endif
442+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
443+#define d_is_dir(dentry) ({ struct inode *inode = d_backing_inode(dentry); \
444+ inode && S_ISDIR(inode->i_mode); })
445+#endif
446+
447+/*
448+ * TOMOYO specific part start.
449+ */
450+
451+/* Clear TOMOYO 1.8 config. */
452+#undef CONFIG_CCSECURITY
453+#undef CONFIG_CCSECURITY_LKM
454+#undef CONFIG_CCSECURITY_DISABLE_BY_DEFAULT
455+#undef CONFIG_CCSECURITY_MAX_AUDIT_LOG
456+#undef CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY
457+#undef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
458+#undef CONFIG_CCSECURITY_POLICY_LOADER
459+#undef CONFIG_CCSECURITY_ACTIVATION_TRIGGER
460+#undef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
461+#undef CONFIG_CCSECURITY_FILE_READDIR
462+#undef CONFIG_CCSECURITY_FILE_GETATTR
463+#undef CONFIG_CCSECURITY_NETWORK
464+#undef CONFIG_CCSECURITY_NETWORK_RECVMSG
465+#undef CONFIG_CCSECURITY_CAPABILITY
466+#undef CONFIG_CCSECURITY_IPC
467+#undef CONFIG_CCSECURITY_MISC
468+#undef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
469+#undef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
470+#undef CONFIG_CCSECURITY_PORTRESERVE
471+/* Define AKARI 1.0 config. */
472+#include "config.h"
473+#ifndef CONFIG_CCSECURITY
474+#define CONFIG_CCSECURITY
475+#endif
476+#ifndef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
477+#define CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
478+#endif
479+#ifndef CONFIG_CCSECURITY_MAX_AUDIT_LOG
480+#define CONFIG_CCSECURITY_MAX_AUDIT_LOG 1024
481+#endif
482+#ifndef CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY
483+#define CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY 2048
484+#endif
485+#ifndef CONFIG_CCSECURITY_POLICY_LOADER
486+#define CONFIG_CCSECURITY_POLICY_LOADER "/sbin/ccs-init"
487+#endif
488+#ifndef CONFIG_CCSECURITY_ACTIVATION_TRIGGER
489+#define CONFIG_CCSECURITY_ACTIVATION_TRIGGER "/sbin/init"
490+#endif
491+#include "ccsecurity.h"
492+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
493+#error This module supports only 2.6.0 and later kernels.
494+#endif
495+#ifndef CONFIG_SECURITY
496+#error You must choose CONFIG_SECURITY=y for building this module.
497+#endif
498+#ifndef CONFIG_KALLSYMS
499+#error You must choose CONFIG_KALLSYMS=y for building this module.
500+#endif
501+#ifndef CONFIG_PROC_FS
502+#error You must choose CONFIG_PROC_FS=y for building this module.
503+#endif
504+#ifndef CONFIG_MODULES
505+#error You must choose CONFIG_MODULES=y for building this module.
506+#endif
507+
508+/* Enumeration definition for internal use. */
509+
510+/* Index numbers for Access Controls. */
511+enum ccs_acl_entry_type_index {
512+ CCS_TYPE_PATH_ACL,
513+ CCS_TYPE_PATH2_ACL,
514+ CCS_TYPE_PATH_NUMBER_ACL,
515+ CCS_TYPE_MKDEV_ACL,
516+ CCS_TYPE_MOUNT_ACL,
517+#ifdef CONFIG_CCSECURITY_MISC
518+ CCS_TYPE_ENV_ACL,
519+#endif
520+#ifdef CONFIG_CCSECURITY_CAPABILITY
521+ CCS_TYPE_CAPABILITY_ACL,
522+#endif
523+#ifdef CONFIG_CCSECURITY_NETWORK
524+ CCS_TYPE_INET_ACL,
525+ CCS_TYPE_UNIX_ACL,
526+#endif
527+#ifdef CONFIG_CCSECURITY_IPC
528+ CCS_TYPE_SIGNAL_ACL,
529+#endif
530+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
531+ CCS_TYPE_AUTO_EXECUTE_HANDLER,
532+ CCS_TYPE_DENIED_EXECUTE_HANDLER,
533+#endif
534+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
535+ CCS_TYPE_AUTO_TASK_ACL,
536+ CCS_TYPE_MANUAL_TASK_ACL,
537+#endif
538+};
539+
540+/* Index numbers for "struct ccs_condition". */
541+enum ccs_conditions_index {
542+ CCS_TASK_UID, /* current_uid() */
543+ CCS_TASK_EUID, /* current_euid() */
544+ CCS_TASK_SUID, /* current_suid() */
545+ CCS_TASK_FSUID, /* current_fsuid() */
546+ CCS_TASK_GID, /* current_gid() */
547+ CCS_TASK_EGID, /* current_egid() */
548+ CCS_TASK_SGID, /* current_sgid() */
549+ CCS_TASK_FSGID, /* current_fsgid() */
550+ CCS_TASK_PID, /* sys_getpid() */
551+ CCS_TASK_PPID, /* sys_getppid() */
552+ CCS_EXEC_ARGC, /* "struct linux_binprm *"->argc */
553+ CCS_EXEC_ENVC, /* "struct linux_binprm *"->envc */
554+ CCS_TYPE_IS_SOCKET, /* S_IFSOCK */
555+ CCS_TYPE_IS_SYMLINK, /* S_IFLNK */
556+ CCS_TYPE_IS_FILE, /* S_IFREG */
557+ CCS_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
558+ CCS_TYPE_IS_DIRECTORY, /* S_IFDIR */
559+ CCS_TYPE_IS_CHAR_DEV, /* S_IFCHR */
560+ CCS_TYPE_IS_FIFO, /* S_IFIFO */
561+ CCS_MODE_SETUID, /* S_ISUID */
562+ CCS_MODE_SETGID, /* S_ISGID */
563+ CCS_MODE_STICKY, /* S_ISVTX */
564+ CCS_MODE_OWNER_READ, /* S_IRUSR */
565+ CCS_MODE_OWNER_WRITE, /* S_IWUSR */
566+ CCS_MODE_OWNER_EXECUTE, /* S_IXUSR */
567+ CCS_MODE_GROUP_READ, /* S_IRGRP */
568+ CCS_MODE_GROUP_WRITE, /* S_IWGRP */
569+ CCS_MODE_GROUP_EXECUTE, /* S_IXGRP */
570+ CCS_MODE_OTHERS_READ, /* S_IROTH */
571+ CCS_MODE_OTHERS_WRITE, /* S_IWOTH */
572+ CCS_MODE_OTHERS_EXECUTE, /* S_IXOTH */
573+ CCS_TASK_TYPE, /* ((u8) task->ccs_flags) &
574+ CCS_TASK_IS_EXECUTE_HANDLER */
575+ CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
576+ CCS_EXEC_REALPATH,
577+ CCS_SYMLINK_TARGET,
578+ CCS_PATH1_UID,
579+ CCS_PATH1_GID,
580+ CCS_PATH1_INO,
581+ CCS_PATH1_MAJOR,
582+ CCS_PATH1_MINOR,
583+ CCS_PATH1_PERM,
584+ CCS_PATH1_TYPE,
585+ CCS_PATH1_DEV_MAJOR,
586+ CCS_PATH1_DEV_MINOR,
587+ CCS_PATH2_UID,
588+ CCS_PATH2_GID,
589+ CCS_PATH2_INO,
590+ CCS_PATH2_MAJOR,
591+ CCS_PATH2_MINOR,
592+ CCS_PATH2_PERM,
593+ CCS_PATH2_TYPE,
594+ CCS_PATH2_DEV_MAJOR,
595+ CCS_PATH2_DEV_MINOR,
596+ CCS_PATH1_PARENT_UID,
597+ CCS_PATH1_PARENT_GID,
598+ CCS_PATH1_PARENT_INO,
599+ CCS_PATH1_PARENT_PERM,
600+ CCS_PATH2_PARENT_UID,
601+ CCS_PATH2_PARENT_GID,
602+ CCS_PATH2_PARENT_INO,
603+ CCS_PATH2_PARENT_PERM,
604+ CCS_MAX_CONDITION_KEYWORD,
605+ CCS_NUMBER_UNION,
606+ CCS_NAME_UNION,
607+ CCS_ARGV_ENTRY,
608+ CCS_ENVP_ENTRY,
609+};
610+
611+/* Index numbers for domain's attributes. */
612+enum ccs_domain_info_flags_index {
613+ /* Quota warnning flag. */
614+ CCS_DIF_QUOTA_WARNED,
615+ /*
616+ * This domain was unable to create a new domain at
617+ * ccs_find_next_domain() because the name of the domain to be created
618+ * was too long or it could not allocate memory.
619+ * More than one process continued execve() without domain transition.
620+ */
621+ CCS_DIF_TRANSITION_FAILED,
622+ CCS_MAX_DOMAIN_INFO_FLAGS
623+};
624+
625+/* Index numbers for audit type. */
626+enum ccs_grant_log {
627+ /* Follow profile's configuration. */
628+ CCS_GRANTLOG_AUTO,
629+ /* Do not generate grant log. */
630+ CCS_GRANTLOG_NO,
631+ /* Generate grant_log. */
632+ CCS_GRANTLOG_YES,
633+};
634+
635+/* Index numbers for group entries. */
636+enum ccs_group_id {
637+ CCS_PATH_GROUP,
638+ CCS_NUMBER_GROUP,
639+#ifdef CONFIG_CCSECURITY_NETWORK
640+ CCS_ADDRESS_GROUP,
641+#endif
642+ CCS_MAX_GROUP
643+};
644+
645+/* Index numbers for category of functionality. */
646+enum ccs_mac_category_index {
647+ CCS_MAC_CATEGORY_FILE,
648+#ifdef CONFIG_CCSECURITY_NETWORK
649+ CCS_MAC_CATEGORY_NETWORK,
650+#endif
651+#ifdef CONFIG_CCSECURITY_MISC
652+ CCS_MAC_CATEGORY_MISC,
653+#endif
654+#ifdef CONFIG_CCSECURITY_IPC
655+ CCS_MAC_CATEGORY_IPC,
656+#endif
657+#ifdef CONFIG_CCSECURITY_CAPABILITY
658+ CCS_MAC_CATEGORY_CAPABILITY,
659+#endif
660+ CCS_MAX_MAC_CATEGORY_INDEX
661+};
662+
663+/* Index numbers for functionality. */
664+enum ccs_mac_index {
665+ CCS_MAC_FILE_EXECUTE,
666+ CCS_MAC_FILE_OPEN,
667+ CCS_MAC_FILE_CREATE,
668+ CCS_MAC_FILE_UNLINK,
669+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
670+ CCS_MAC_FILE_GETATTR,
671+#endif
672+ CCS_MAC_FILE_MKDIR,
673+ CCS_MAC_FILE_RMDIR,
674+ CCS_MAC_FILE_MKFIFO,
675+ CCS_MAC_FILE_MKSOCK,
676+ CCS_MAC_FILE_TRUNCATE,
677+ CCS_MAC_FILE_SYMLINK,
678+ CCS_MAC_FILE_MKBLOCK,
679+ CCS_MAC_FILE_MKCHAR,
680+ CCS_MAC_FILE_LINK,
681+ CCS_MAC_FILE_RENAME,
682+ CCS_MAC_FILE_CHMOD,
683+ CCS_MAC_FILE_CHOWN,
684+ CCS_MAC_FILE_CHGRP,
685+ CCS_MAC_FILE_IOCTL,
686+ CCS_MAC_FILE_CHROOT,
687+ CCS_MAC_FILE_MOUNT,
688+ CCS_MAC_FILE_UMOUNT,
689+ CCS_MAC_FILE_PIVOT_ROOT,
690+#ifdef CONFIG_CCSECURITY_NETWORK
691+ CCS_MAC_NETWORK_INET_STREAM_BIND,
692+ CCS_MAC_NETWORK_INET_STREAM_LISTEN,
693+ CCS_MAC_NETWORK_INET_STREAM_CONNECT,
694+ CCS_MAC_NETWORK_INET_STREAM_ACCEPT,
695+ CCS_MAC_NETWORK_INET_DGRAM_BIND,
696+ CCS_MAC_NETWORK_INET_DGRAM_SEND,
697+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
698+ CCS_MAC_NETWORK_INET_DGRAM_RECV,
699+#endif
700+ CCS_MAC_NETWORK_INET_RAW_BIND,
701+ CCS_MAC_NETWORK_INET_RAW_SEND,
702+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
703+ CCS_MAC_NETWORK_INET_RAW_RECV,
704+#endif
705+ CCS_MAC_NETWORK_UNIX_STREAM_BIND,
706+ CCS_MAC_NETWORK_UNIX_STREAM_LISTEN,
707+ CCS_MAC_NETWORK_UNIX_STREAM_CONNECT,
708+ CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT,
709+ CCS_MAC_NETWORK_UNIX_DGRAM_BIND,
710+ CCS_MAC_NETWORK_UNIX_DGRAM_SEND,
711+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
712+ CCS_MAC_NETWORK_UNIX_DGRAM_RECV,
713+#endif
714+ CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND,
715+ CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
716+ CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
717+ CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
718+#endif
719+#ifdef CONFIG_CCSECURITY_MISC
720+ CCS_MAC_ENVIRON,
721+#endif
722+#ifdef CONFIG_CCSECURITY_IPC
723+ CCS_MAC_SIGNAL,
724+#endif
725+#ifdef CONFIG_CCSECURITY_CAPABILITY
726+ CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
727+ CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
728+ CCS_MAC_CAPABILITY_SYS_REBOOT,
729+ CCS_MAC_CAPABILITY_SYS_VHANGUP,
730+ CCS_MAC_CAPABILITY_SYS_SETTIME,
731+ CCS_MAC_CAPABILITY_SYS_NICE,
732+ CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
733+ CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
734+ CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
735+ CCS_MAC_CAPABILITY_SYS_PTRACE,
736+#endif
737+ CCS_MAX_MAC_INDEX
738+};
739+
740+/* Index numbers for /proc/ccs/stat interface. */
741+enum ccs_memory_stat_type {
742+ CCS_MEMORY_POLICY,
743+ CCS_MEMORY_AUDIT,
744+ CCS_MEMORY_QUERY,
745+ CCS_MAX_MEMORY_STAT
746+};
747+
748+/* Index numbers for access controls with one pathname and three numbers. */
749+enum ccs_mkdev_acl_index {
750+ CCS_TYPE_MKBLOCK,
751+ CCS_TYPE_MKCHAR,
752+ CCS_MAX_MKDEV_OPERATION
753+};
754+
755+/* Index numbers for operation mode. */
756+enum ccs_mode_value {
757+ CCS_CONFIG_DISABLED,
758+ CCS_CONFIG_LEARNING,
759+ CCS_CONFIG_PERMISSIVE,
760+ CCS_CONFIG_ENFORCING,
761+ CCS_CONFIG_MAX_MODE,
762+ CCS_CONFIG_WANT_REJECT_LOG = 64,
763+ CCS_CONFIG_WANT_GRANT_LOG = 128,
764+ CCS_CONFIG_USE_DEFAULT = 255,
765+};
766+
767+/* Index numbers for socket operations. */
768+enum ccs_network_acl_index {
769+ CCS_NETWORK_BIND, /* bind() operation. */
770+ CCS_NETWORK_LISTEN, /* listen() operation. */
771+ CCS_NETWORK_CONNECT, /* connect() operation. */
772+ CCS_NETWORK_ACCEPT, /* accept() operation. */
773+ CCS_NETWORK_SEND, /* send() operation. */
774+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
775+ CCS_NETWORK_RECV, /* recv() operation. */
776+#endif
777+ CCS_MAX_NETWORK_OPERATION
778+};
779+
780+/* Index numbers for access controls with two pathnames. */
781+enum ccs_path2_acl_index {
782+ CCS_TYPE_LINK,
783+ CCS_TYPE_RENAME,
784+ CCS_TYPE_PIVOT_ROOT,
785+ CCS_MAX_PATH2_OPERATION
786+};
787+
788+/* Index numbers for access controls with one pathname. */
789+enum ccs_path_acl_index {
790+ CCS_TYPE_EXECUTE,
791+ CCS_TYPE_READ,
792+ CCS_TYPE_WRITE,
793+ CCS_TYPE_APPEND,
794+ CCS_TYPE_UNLINK,
795+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
796+ CCS_TYPE_GETATTR,
797+#endif
798+ CCS_TYPE_RMDIR,
799+ CCS_TYPE_TRUNCATE,
800+ CCS_TYPE_SYMLINK,
801+ CCS_TYPE_CHROOT,
802+ CCS_TYPE_UMOUNT,
803+ CCS_MAX_PATH_OPERATION
804+};
805+
806+/* Index numbers for access controls with one pathname and one number. */
807+enum ccs_path_number_acl_index {
808+ CCS_TYPE_CREATE,
809+ CCS_TYPE_MKDIR,
810+ CCS_TYPE_MKFIFO,
811+ CCS_TYPE_MKSOCK,
812+ CCS_TYPE_IOCTL,
813+ CCS_TYPE_CHMOD,
814+ CCS_TYPE_CHOWN,
815+ CCS_TYPE_CHGRP,
816+ CCS_MAX_PATH_NUMBER_OPERATION
817+};
818+
819+/* Index numbers for stat(). */
820+enum ccs_path_stat_index {
821+ /* Do not change this order. */
822+ CCS_PATH1,
823+ CCS_PATH1_PARENT,
824+ CCS_PATH2,
825+ CCS_PATH2_PARENT,
826+ CCS_MAX_PATH_STAT
827+};
828+
829+/* Index numbers for entry type. */
830+enum ccs_policy_id {
831+#ifdef CONFIG_CCSECURITY_PORTRESERVE
832+ CCS_ID_RESERVEDPORT,
833+#endif
834+ CCS_ID_GROUP,
835+#ifdef CONFIG_CCSECURITY_NETWORK
836+ CCS_ID_ADDRESS_GROUP,
837+#endif
838+ CCS_ID_PATH_GROUP,
839+ CCS_ID_NUMBER_GROUP,
840+ CCS_ID_AGGREGATOR,
841+ CCS_ID_TRANSITION_CONTROL,
842+ CCS_ID_MANAGER,
843+ CCS_ID_CONDITION,
844+ CCS_ID_NAME,
845+ CCS_ID_ACL,
846+ CCS_ID_DOMAIN,
847+ CCS_MAX_POLICY
848+};
849+
850+/* Index numbers for /proc/ccs/stat interface. */
851+enum ccs_policy_stat_type {
852+ /* Do not change this order. */
853+ CCS_STAT_POLICY_UPDATES,
854+ CCS_STAT_POLICY_LEARNING, /* == CCS_CONFIG_LEARNING */
855+ CCS_STAT_POLICY_PERMISSIVE, /* == CCS_CONFIG_PERMISSIVE */
856+ CCS_STAT_POLICY_ENFORCING, /* == CCS_CONFIG_ENFORCING */
857+ CCS_MAX_POLICY_STAT
858+};
859+
860+/* Index numbers for profile's PREFERENCE values. */
861+enum ccs_pref_index {
862+ CCS_PREF_MAX_AUDIT_LOG,
863+ CCS_PREF_MAX_LEARNING_ENTRY,
864+ CCS_PREF_ENFORCING_PENALTY,
865+ CCS_MAX_PREF
866+};
867+
868+/* Index numbers for /proc/ccs/ interfaces. */
869+enum ccs_proc_interface_index {
870+ CCS_DOMAIN_POLICY,
871+ CCS_EXCEPTION_POLICY,
872+ CCS_PROCESS_STATUS,
873+ CCS_STAT,
874+ CCS_AUDIT,
875+ CCS_VERSION,
876+ CCS_PROFILE,
877+ CCS_QUERY,
878+ CCS_MANAGER,
879+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
880+ CCS_EXECUTE_HANDLER,
881+#endif
882+};
883+
884+/* Index numbers for special mount operations. */
885+enum ccs_special_mount {
886+ CCS_MOUNT_BIND, /* mount --bind /source /dest */
887+ CCS_MOUNT_MOVE, /* mount --move /old /new */
888+ CCS_MOUNT_REMOUNT, /* mount -o remount /dir */
889+ CCS_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
890+ CCS_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */
891+ CCS_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */
892+ CCS_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */
893+ CCS_MAX_SPECIAL_MOUNT
894+};
895+
896+/* Index numbers for domain transition control keywords. */
897+enum ccs_transition_type {
898+ /* Do not change this order, */
899+ CCS_TRANSITION_CONTROL_NO_RESET,
900+ CCS_TRANSITION_CONTROL_RESET,
901+ CCS_TRANSITION_CONTROL_NO_INITIALIZE,
902+ CCS_TRANSITION_CONTROL_INITIALIZE,
903+ CCS_TRANSITION_CONTROL_NO_KEEP,
904+ CCS_TRANSITION_CONTROL_KEEP,
905+ CCS_MAX_TRANSITION_TYPE
906+};
907+
908+/* Index numbers for type of numeric values. */
909+enum ccs_value_type {
910+ CCS_VALUE_TYPE_INVALID,
911+ CCS_VALUE_TYPE_DECIMAL,
912+ CCS_VALUE_TYPE_OCTAL,
913+ CCS_VALUE_TYPE_HEXADECIMAL,
914+};
915+
916+/* Constants definition for internal use. */
917+
918+/*
919+ * TOMOYO uses this hash only when appending a string into the string table.
920+ * Frequency of appending strings is very low. So we don't need large (e.g.
921+ * 64k) hash size. 256 will be sufficient.
922+ */
923+#define CCS_HASH_BITS 8
924+#define CCS_MAX_HASH (1u << CCS_HASH_BITS)
925+
926+/*
927+ * TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
928+ * Therefore, we don't need SOCK_MAX.
929+ */
930+#define CCS_SOCK_MAX 6
931+
932+/* Size of temporary buffer for execve() operation. */
933+#define CCS_EXEC_TMPSIZE 4096
934+
935+/* Garbage collector is trying to kfree() this element. */
936+#define CCS_GC_IN_PROGRESS -1
937+
938+/* Profile number is an integer between 0 and 255. */
939+#define CCS_MAX_PROFILES 256
940+
941+/* Group number is an integer between 0 and 255. */
942+#define CCS_MAX_ACL_GROUPS 256
943+
944+/* Current thread is doing open(O_RDONLY | O_TRUNC) ? */
945+#define CCS_OPEN_FOR_READ_TRUNCATE 1
946+/* Current thread is doing open(3) ? */
947+#define CCS_OPEN_FOR_IOCTL_ONLY 2
948+/* Current thread is doing do_execve() ? */
949+#define CCS_TASK_IS_IN_EXECVE 4
950+/* Current thread is running as an execute handler program? */
951+#define CCS_TASK_IS_EXECUTE_HANDLER 8
952+/* Current thread is allowed to modify policy via /proc/ccs/ interface? */
953+#define CCS_TASK_IS_MANAGER 16
954+
955+/*
956+ * Retry this request. Returned by ccs_supervisor() if policy violation has
957+ * occurred in enforcing mode and the userspace daemon decided to retry.
958+ *
959+ * We must choose a positive value in order to distinguish "granted" (which is
960+ * 0) and "rejected" (which is a negative value) and "retry".
961+ */
962+#define CCS_RETRY_REQUEST 1
963+
964+/* The gfp flags used by TOMOYO. */
965+#define CCS_GFP_FLAGS GFP_NOFS
966+
967+/* Size of read buffer for /proc/ccs/ interface. */
968+#define CCS_MAX_IO_READ_QUEUE 64
969+
970+/* Structure definition for internal use. */
971+
972+/* Common header for holding ACL entries. */
973+struct ccs_acl_head {
974+ struct list_head list;
975+ s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
976+} __packed;
977+
978+/* Common header for shared entries. */
979+struct ccs_shared_acl_head {
980+ struct list_head list;
981+ atomic_t users;
982+} __packed;
983+
984+/* Common header for individual entries. */
985+struct ccs_acl_info {
986+ struct list_head list;
987+ struct ccs_condition *cond; /* Maybe NULL. */
988+ s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
989+ u8 type; /* One of values in "enum ccs_acl_entry_type_index". */
990+ u16 perm;
991+} __packed;
992+
993+/* Structure for holding a word. */
994+struct ccs_name_union {
995+ /* Either @filename or @group is NULL. */
996+ const struct ccs_path_info *filename;
997+ struct ccs_group *group;
998+};
999+
1000+/* Structure for holding a number. */
1001+struct ccs_number_union {
1002+ unsigned long values[2];
1003+ struct ccs_group *group; /* Maybe NULL. */
1004+ /* One of values in "enum ccs_value_type". */
1005+ u8 value_type[2];
1006+};
1007+
1008+/* Structure for holding an IP address. */
1009+struct ccs_ipaddr_union {
1010+ struct in6_addr ip[2]; /* Big endian. */
1011+ struct ccs_group *group; /* Pointer to address group. */
1012+ bool is_ipv6; /* Valid only if @group == NULL. */
1013+};
1014+
1015+/* Structure for "path_group"/"number_group"/"address_group" directive. */
1016+struct ccs_group {
1017+ struct ccs_shared_acl_head head;
1018+ /* Name of group (without leading '@'). */
1019+ const struct ccs_path_info *group_name;
1020+ /*
1021+ * List of "struct ccs_path_group" or "struct ccs_number_group" or
1022+ * "struct ccs_address_group".
1023+ */
1024+ struct list_head member_list;
1025+};
1026+
1027+/* Structure for "path_group" directive. */
1028+struct ccs_path_group {
1029+ struct ccs_acl_head head;
1030+ const struct ccs_path_info *member_name;
1031+};
1032+
1033+/* Structure for "number_group" directive. */
1034+struct ccs_number_group {
1035+ struct ccs_acl_head head;
1036+ struct ccs_number_union number;
1037+};
1038+
1039+/* Structure for "address_group" directive. */
1040+struct ccs_address_group {
1041+ struct ccs_acl_head head;
1042+ /* Structure for holding an IP address. */
1043+ struct ccs_ipaddr_union address;
1044+};
1045+
1046+/* Subset of "struct stat". Used by conditional ACL and audit logs. */
1047+struct ccs_mini_stat {
1048+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1049+ kuid_t uid;
1050+ kgid_t gid;
1051+#else
1052+ uid_t uid;
1053+ gid_t gid;
1054+#endif
1055+ ino_t ino;
1056+ umode_t mode;
1057+ dev_t dev;
1058+ dev_t rdev;
1059+};
1060+
1061+/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
1062+struct ccs_page_dump {
1063+ struct page *page; /* Previously dumped page. */
1064+ char *data; /* Contents of "page". Size is PAGE_SIZE. */
1065+};
1066+
1067+/* Structure for attribute checks in addition to pathname checks. */
1068+struct ccs_obj_info {
1069+ /* True if ccs_get_attributes() was already called, false otherwise. */
1070+ bool validate_done;
1071+ /* True if @stat[] is valid. */
1072+ bool stat_valid[CCS_MAX_PATH_STAT];
1073+ /* First pathname. Initialized with { NULL, NULL } if no path. */
1074+ struct path path1;
1075+ /* Second pathname. Initialized with { NULL, NULL } if no path. */
1076+ struct path path2;
1077+ /*
1078+ * Information on @path1, @path1's parent directory, @path2, @path2's
1079+ * parent directory.
1080+ */
1081+ struct ccs_mini_stat stat[CCS_MAX_PATH_STAT];
1082+ /*
1083+ * Content of symbolic link to be created. NULL for operations other
1084+ * than symlink().
1085+ */
1086+ struct ccs_path_info *symlink_target;
1087+};
1088+
1089+/* Structure for entries which follows "struct ccs_condition". */
1090+struct ccs_condition_element {
1091+ /*
1092+ * Left hand operand. A "struct ccs_argv" for CCS_ARGV_ENTRY, a
1093+ * "struct ccs_envp" for CCS_ENVP_ENTRY is attached to the tail
1094+ * of the array of this struct.
1095+ */
1096+ u8 left;
1097+ /*
1098+ * Right hand operand. A "struct ccs_number_union" for
1099+ * CCS_NUMBER_UNION, a "struct ccs_name_union" for CCS_NAME_UNION is
1100+ * attached to the tail of the array of this struct.
1101+ */
1102+ u8 right;
1103+ /* Equation operator. True if equals or overlaps, false otherwise. */
1104+ bool equals;
1105+};
1106+
1107+/* Structure for optional arguments. */
1108+struct ccs_condition {
1109+ struct ccs_shared_acl_head head;
1110+ u32 size; /* Memory size allocated for this entry. */
1111+ u16 condc; /* Number of conditions in this struct. */
1112+ u16 numbers_count; /* Number of "struct ccs_number_union values". */
1113+ u16 names_count; /* Number of "struct ccs_name_union names". */
1114+ u16 argc; /* Number of "struct ccs_argv". */
1115+ u16 envc; /* Number of "struct ccs_envp". */
1116+ u8 grant_log; /* One of values in "enum ccs_grant_log". */
1117+ bool exec_transit; /* True if transit is for "file execute". */
1118+ const struct ccs_path_info *transit; /* Maybe NULL. */
1119+ /*
1120+ * struct ccs_condition_element condition[condc];
1121+ * struct ccs_number_union values[numbers_count];
1122+ * struct ccs_name_union names[names_count];
1123+ * struct ccs_argv argv[argc];
1124+ * struct ccs_envp envp[envc];
1125+ */
1126+};
1127+
1128+struct ccs_execve;
1129+struct ccs_policy_namespace;
1130+
1131+/* Structure for request info. */
1132+struct ccs_request_info {
1133+ /*
1134+ * For holding parameters specific to operations which deal files.
1135+ * NULL if not dealing files.
1136+ */
1137+ struct ccs_obj_info *obj;
1138+ /*
1139+ * For holding parameters specific to execve() request.
1140+ * NULL if not dealing do_execve().
1141+ */
1142+ struct ccs_execve *ee;
1143+ /*
1144+ * For holding parameters.
1145+ * Pointers in this union are not NULL except path->matched_path.
1146+ */
1147+ union {
1148+ struct {
1149+ const struct ccs_path_info *filename;
1150+ /*
1151+ * For using wildcards at ccs_find_next_domain().
1152+ *
1153+ * The matched_acl cannot be used because it may refer
1154+ * a "struct ccs_path_acl" with ->is_group == true.
1155+ * We want to use exact "struct ccs_path_info" rather
1156+ * than "struct ccs_path_acl".
1157+ */
1158+ const struct ccs_path_info *matched_path;
1159+ /* One of values in "enum ccs_path_acl_index". */
1160+ u8 operation;
1161+ } path;
1162+ struct {
1163+ const struct ccs_path_info *filename1;
1164+ const struct ccs_path_info *filename2;
1165+ /* One of values in "enum ccs_path2_acl_index". */
1166+ u8 operation;
1167+ } path2;
1168+ struct {
1169+ const struct ccs_path_info *filename;
1170+ unsigned int mode;
1171+ unsigned int major;
1172+ unsigned int minor;
1173+ /* One of values in "enum ccs_mkdev_acl_index". */
1174+ u8 operation;
1175+ } mkdev;
1176+ struct {
1177+ const struct ccs_path_info *filename;
1178+ unsigned long number;
1179+ /*
1180+ * One of values in "enum ccs_path_number_acl_index".
1181+ */
1182+ u8 operation;
1183+ } path_number;
1184+#ifdef CONFIG_CCSECURITY_NETWORK
1185+ struct {
1186+ const u32 *address; /* Big endian. */
1187+ u16 port; /* Host endian. */
1188+ /* One of values smaller than CCS_SOCK_MAX. */
1189+ u8 protocol;
1190+ /* One of values in "enum ccs_network_acl_index". */
1191+ u8 operation;
1192+ bool is_ipv6;
1193+ } inet_network;
1194+ struct {
1195+ const struct ccs_path_info *address;
1196+ /* One of values smaller than CCS_SOCK_MAX. */
1197+ u8 protocol;
1198+ /* One of values in "enum ccs_network_acl_index". */
1199+ u8 operation;
1200+ } unix_network;
1201+#endif
1202+#ifdef CONFIG_CCSECURITY_MISC
1203+ struct {
1204+ const struct ccs_path_info *name;
1205+ } environ;
1206+#endif
1207+#ifdef CONFIG_CCSECURITY_CAPABILITY
1208+ struct {
1209+ /* One of values in "enum ccs_capability_acl_index". */
1210+ u8 operation;
1211+ } capability;
1212+#endif
1213+#ifdef CONFIG_CCSECURITY_IPC
1214+ struct {
1215+ const char *dest_pattern;
1216+ int sig;
1217+ } signal;
1218+#endif
1219+ struct {
1220+ const struct ccs_path_info *type;
1221+ const struct ccs_path_info *dir;
1222+ const struct ccs_path_info *dev;
1223+ unsigned long flags;
1224+ int need_dev;
1225+ } mount;
1226+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
1227+ struct {
1228+ const struct ccs_path_info *domainname;
1229+ } task;
1230+#endif
1231+ } param;
1232+ /*
1233+ * For updating current->ccs_domain_info at ccs_update_task_domain().
1234+ * Initialized to NULL at ccs_init_request_info().
1235+ * Matching "struct ccs_acl_info" is copied if access request was
1236+ * granted. Re-initialized to NULL at ccs_update_task_domain().
1237+ */
1238+ struct ccs_acl_info *matched_acl;
1239+ u8 param_type; /* One of values in "enum ccs_acl_entry_type_index". */
1240+ bool granted; /* True if granted, false otherwise. */
1241+ /* True if current thread should not be carried sleep penalty. */
1242+ bool dont_sleep_on_enforce_error;
1243+ /*
1244+ * For counting number of retries made for this request.
1245+ * This counter is incremented whenever ccs_supervisor() returned
1246+ * CCS_RETRY_REQUEST.
1247+ */
1248+ u8 retry;
1249+ /*
1250+ * For holding profile number used for this request.
1251+ * One of values between 0 and CCS_MAX_PROFILES - 1.
1252+ */
1253+ u8 profile;
1254+ /*
1255+ * For holding operation mode used for this request.
1256+ * One of CCS_CONFIG_DISABLED, CCS_CONFIG_LEARNING,
1257+ * CCS_CONFIG_PERMISSIVE, CCS_CONFIG_ENFORCING.
1258+ */
1259+ u8 mode;
1260+ /*
1261+ * For holding operation index used for this request.
1262+ * Used by ccs_init_request_info() / ccs_get_mode() /
1263+ * ccs_write_log(). One of values in "enum ccs_mac_index".
1264+ */
1265+ u8 type;
1266+};
1267+
1268+/* Structure for holding a token. */
1269+struct ccs_path_info {
1270+ const char *name;
1271+ u32 hash; /* = full_name_hash(name, strlen(name)) */
1272+ u16 total_len; /* = strlen(name) */
1273+ u16 const_len; /* = ccs_const_part_length(name) */
1274+ bool is_dir; /* = ccs_strendswith(name, "/") */
1275+ bool is_patterned; /* = const_len < total_len */
1276+};
1277+
1278+/* Structure for execve() operation. */
1279+struct ccs_execve {
1280+ struct ccs_request_info r;
1281+ struct ccs_obj_info obj;
1282+ struct linux_binprm *bprm;
1283+ struct ccs_domain_info *previous_domain;
1284+ const struct ccs_path_info *transition;
1285+ /* For execute_handler */
1286+ const struct ccs_path_info *handler;
1287+ char *handler_path; /* = kstrdup(handler->name, CCS_GFP_FLAGS) */
1288+ /* For dumping argv[] and envp[]. */
1289+ struct ccs_page_dump dump;
1290+ /* For temporary use. */
1291+ char *tmp; /* Size is CCS_EXEC_TMPSIZE bytes */
1292+};
1293+
1294+/* Structure for domain information. */
1295+struct ccs_domain_info {
1296+ struct list_head list;
1297+ struct list_head acl_info_list;
1298+ /* Name of this domain. Never NULL. */
1299+ const struct ccs_path_info *domainname;
1300+ /* Namespace for this domain. Never NULL. */
1301+ struct ccs_policy_namespace *ns;
1302+ /* Group numbers to use. */
1303+ unsigned long group[CCS_MAX_ACL_GROUPS / BITS_PER_LONG];
1304+ u8 profile; /* Profile number to use. */
1305+ bool is_deleted; /* Delete flag. */
1306+ bool flags[CCS_MAX_DOMAIN_INFO_FLAGS];
1307+};
1308+
1309+/*
1310+ * Structure for "reset_domain"/"no_reset_domain"/"initialize_domain"/
1311+ * "no_initialize_domain"/"keep_domain"/"no_keep_domain" keyword.
1312+ */
1313+struct ccs_transition_control {
1314+ struct ccs_acl_head head;
1315+ u8 type; /* One of values in "enum ccs_transition_type" */
1316+ bool is_last_name; /* True if the domainname is ccs_last_word(). */
1317+ const struct ccs_path_info *domainname; /* Maybe NULL */
1318+ const struct ccs_path_info *program; /* Maybe NULL */
1319+};
1320+
1321+/* Structure for "aggregator" keyword. */
1322+struct ccs_aggregator {
1323+ struct ccs_acl_head head;
1324+ const struct ccs_path_info *original_name;
1325+ const struct ccs_path_info *aggregated_name;
1326+};
1327+
1328+/* Structure for "deny_autobind" keyword. */
1329+struct ccs_reserved {
1330+ struct ccs_acl_head head;
1331+ struct ccs_number_union port;
1332+};
1333+
1334+/* Structure for policy manager. */
1335+struct ccs_manager {
1336+ struct ccs_acl_head head;
1337+ /* A path to program or a domainname. */
1338+ const struct ccs_path_info *manager;
1339+};
1340+
1341+/* Structure for argv[]. */
1342+struct ccs_argv {
1343+ unsigned long index;
1344+ const struct ccs_path_info *value;
1345+ bool is_not;
1346+};
1347+
1348+/* Structure for envp[]. */
1349+struct ccs_envp {
1350+ const struct ccs_path_info *name;
1351+ const struct ccs_path_info *value;
1352+ bool is_not;
1353+};
1354+
1355+/*
1356+ * Structure for "task auto_execute_handler" and "task denied_execute_handler"
1357+ * directive.
1358+ *
1359+ * If "task auto_execute_handler" directive exists and the current process is
1360+ * not an execute handler, all execve() requests are replaced by execve()
1361+ * requests of a program specified by "task auto_execute_handler" directive.
1362+ * If the current process is an execute handler, "task auto_execute_handler"
1363+ * and "task denied_execute_handler" directives are ignored.
1364+ * The program specified by "task execute_handler" validates execve()
1365+ * parameters and executes the original execve() requests if appropriate.
1366+ *
1367+ * "task denied_execute_handler" directive is used only when execve() request
1368+ * was rejected in enforcing mode (i.e. CONFIG::file::execute={ mode=enforcing
1369+ * }). The program specified by "task denied_execute_handler" does whatever it
1370+ * wants to do (e.g. silently terminate, change firewall settings, redirect the
1371+ * user to honey pot etc.).
1372+ */
1373+struct ccs_handler_acl {
1374+ struct ccs_acl_info head; /* type = CCS_TYPE_*_EXECUTE_HANDLER */
1375+ const struct ccs_path_info *handler; /* Pointer to single pathname. */
1376+};
1377+
1378+/*
1379+ * Structure for "task auto_domain_transition" and
1380+ * "task manual_domain_transition" directive.
1381+ */
1382+struct ccs_task_acl {
1383+ struct ccs_acl_info head; /* type = CCS_TYPE_*_TASK_ACL */
1384+ /* Pointer to domainname. */
1385+ const struct ccs_path_info *domainname;
1386+};
1387+
1388+/*
1389+ * Structure for "file execute", "file read", "file write", "file append",
1390+ * "file unlink", "file getattr", "file rmdir", "file truncate",
1391+ * "file symlink", "file chroot" and "file unmount" directive.
1392+ */
1393+struct ccs_path_acl {
1394+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
1395+ struct ccs_name_union name;
1396+};
1397+
1398+/*
1399+ * Structure for "file rename", "file link" and "file pivot_root" directive.
1400+ */
1401+struct ccs_path2_acl {
1402+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
1403+ struct ccs_name_union name1;
1404+ struct ccs_name_union name2;
1405+};
1406+
1407+/*
1408+ * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
1409+ * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
1410+ */
1411+struct ccs_path_number_acl {
1412+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */
1413+ struct ccs_name_union name;
1414+ struct ccs_number_union number;
1415+};
1416+
1417+/* Structure for "file mkblock" and "file mkchar" directive. */
1418+struct ccs_mkdev_acl {
1419+ struct ccs_acl_info head; /* type = CCS_TYPE_MKDEV_ACL */
1420+ struct ccs_name_union name;
1421+ struct ccs_number_union mode;
1422+ struct ccs_number_union major;
1423+ struct ccs_number_union minor;
1424+};
1425+
1426+/* Structure for "file mount" directive. */
1427+struct ccs_mount_acl {
1428+ struct ccs_acl_info head; /* type = CCS_TYPE_MOUNT_ACL */
1429+ struct ccs_name_union dev_name;
1430+ struct ccs_name_union dir_name;
1431+ struct ccs_name_union fs_type;
1432+ struct ccs_number_union flags;
1433+};
1434+
1435+/* Structure for "misc env" directive in domain policy. */
1436+struct ccs_env_acl {
1437+ struct ccs_acl_info head; /* type = CCS_TYPE_ENV_ACL */
1438+ const struct ccs_path_info *env; /* environment variable */
1439+};
1440+
1441+/* Structure for "capability" directive. */
1442+struct ccs_capability_acl {
1443+ struct ccs_acl_info head; /* type = CCS_TYPE_CAPABILITY_ACL */
1444+ u8 operation; /* One of values in "enum ccs_capability_acl_index". */
1445+};
1446+
1447+/* Structure for "ipc signal" directive. */
1448+struct ccs_signal_acl {
1449+ struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */
1450+ struct ccs_number_union sig;
1451+ /* Pointer to destination pattern. */
1452+ const struct ccs_path_info *domainname;
1453+};
1454+
1455+/* Structure for "network inet" directive. */
1456+struct ccs_inet_acl {
1457+ struct ccs_acl_info head; /* type = CCS_TYPE_INET_ACL */
1458+ u8 protocol;
1459+ struct ccs_ipaddr_union address;
1460+ struct ccs_number_union port;
1461+};
1462+
1463+/* Structure for "network unix" directive. */
1464+struct ccs_unix_acl {
1465+ struct ccs_acl_info head; /* type = CCS_TYPE_UNIX_ACL */
1466+ u8 protocol;
1467+ struct ccs_name_union name;
1468+};
1469+
1470+/* Structure for holding string data. */
1471+struct ccs_name {
1472+ struct ccs_shared_acl_head head;
1473+ int size; /* Memory size allocated for this entry. */
1474+ struct ccs_path_info entry;
1475+};
1476+
1477+/* Structure for holding a line from /proc/ccs/ interface. */
1478+struct ccs_acl_param {
1479+ char *data; /* Unprocessed data. */
1480+ struct list_head *list; /* List to add or remove. */
1481+ struct ccs_policy_namespace *ns; /* Namespace to use. */
1482+ bool is_delete; /* True if it is a delete request. */
1483+ union ccs_acl_union {
1484+ struct ccs_acl_info acl_info;
1485+ struct ccs_handler_acl handler_acl;
1486+ struct ccs_task_acl task_acl;
1487+ struct ccs_path_acl path_acl;
1488+ struct ccs_path2_acl path2_acl;
1489+ struct ccs_path_number_acl path_number_acl;
1490+ struct ccs_mkdev_acl mkdev_acl;
1491+ struct ccs_mount_acl mount_acl;
1492+ struct ccs_env_acl env_acl;
1493+ struct ccs_capability_acl capability_acl;
1494+ struct ccs_signal_acl signal_acl;
1495+ struct ccs_inet_acl inet_acl;
1496+ struct ccs_unix_acl unix_acl;
1497+ /**/
1498+ struct ccs_acl_head acl_head;
1499+ struct ccs_transition_control transition_control;
1500+ struct ccs_aggregator aggregator;
1501+ struct ccs_reserved reserved;
1502+ struct ccs_manager manager;
1503+ struct ccs_path_group path_group;
1504+ struct ccs_number_group number_group;
1505+ struct ccs_address_group address_group;
1506+ } e;
1507+};
1508+
1509+/* Structure for reading/writing policy via /proc/ccs/ interfaces. */
1510+struct ccs_io_buffer {
1511+ /* Exclusive lock for this structure. */
1512+ struct mutex io_sem;
1513+ char __user *read_user_buf;
1514+ size_t read_user_buf_avail;
1515+ struct {
1516+ struct list_head *ns;
1517+ struct list_head *domain;
1518+ struct list_head *group;
1519+ struct list_head *acl;
1520+ size_t avail;
1521+ unsigned int step;
1522+ unsigned int query_index;
1523+ u16 index;
1524+ u16 cond_index;
1525+ u8 acl_group_index;
1526+ u8 cond_step;
1527+ u8 bit;
1528+ u8 w_pos;
1529+ bool eof;
1530+ bool print_this_domain_only;
1531+ bool print_transition_related_only;
1532+ bool print_cond_part;
1533+ const char *w[CCS_MAX_IO_READ_QUEUE];
1534+ } r;
1535+ struct {
1536+ struct ccs_policy_namespace *ns;
1537+ struct ccs_domain_info *domain;
1538+ size_t avail;
1539+ bool is_delete;
1540+ } w;
1541+ /* Buffer for reading. */
1542+ char *read_buf;
1543+ /* Size of read buffer. */
1544+ size_t readbuf_size;
1545+ /* Buffer for writing. */
1546+ char *write_buf;
1547+ /* Size of write buffer. */
1548+ size_t writebuf_size;
1549+ /* Type of interface. */
1550+ enum ccs_proc_interface_index type;
1551+ /* Users counter protected by ccs_io_buffer_list_lock. */
1552+ u8 users;
1553+ /* List for telling GC not to kfree() elements. */
1554+ struct list_head list;
1555+};
1556+
1557+/* Structure for /proc/ccs/profile interface. */
1558+struct ccs_profile {
1559+ const struct ccs_path_info *comment;
1560+ u8 default_config;
1561+ u8 config[CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX];
1562+ unsigned int pref[CCS_MAX_PREF];
1563+};
1564+
1565+/* Structure for representing YYYY/MM/DD hh/mm/ss. */
1566+struct ccs_time {
1567+ u16 year;
1568+ u8 month;
1569+ u8 day;
1570+ u8 hour;
1571+ u8 min;
1572+ u8 sec;
1573+};
1574+
1575+/* Structure for policy namespace. */
1576+struct ccs_policy_namespace {
1577+ /* Profile table. Memory is allocated as needed. */
1578+ struct ccs_profile *profile_ptr[CCS_MAX_PROFILES];
1579+ /* List of "struct ccs_group". */
1580+ struct list_head group_list[CCS_MAX_GROUP];
1581+ /* List of policy. */
1582+ struct list_head policy_list[CCS_MAX_POLICY];
1583+ /* The global ACL referred by "use_group" keyword. */
1584+ struct list_head acl_group[CCS_MAX_ACL_GROUPS];
1585+ /* List for connecting to ccs_namespace_list list. */
1586+ struct list_head namespace_list;
1587+ /* Profile version. Currently only 20150505 is supported. */
1588+ unsigned int profile_version;
1589+ /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
1590+ const char *name;
1591+};
1592+
1593+/* Prototype definition for "struct ccsecurity_operations". */
1594+
1595+void __init ccs_permission_init(void);
1596+void __init ccs_mm_init(void);
1597+
1598+/* Prototype definition for internal use. */
1599+
1600+bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
1601+ struct ccs_page_dump *dump);
1602+bool ccs_memory_ok(const void *ptr, const unsigned int size);
1603+char *ccs_encode(const char *str);
1604+char *ccs_encode2(const char *str, int str_len);
1605+char *ccs_realpath(const struct path *path);
1606+const char *ccs_get_exe(void);
1607+const struct ccs_path_info *ccs_get_name(const char *name);
1608+int ccs_audit_log(struct ccs_request_info *r);
1609+int ccs_check_acl(struct ccs_request_info *r);
1610+int ccs_init_request_info(struct ccs_request_info *r, const u8 index);
1611+struct ccs_domain_info *ccs_assign_domain(const char *domainname,
1612+ const bool transit);
1613+u8 ccs_get_config(const u8 profile, const u8 index);
1614+void *ccs_commit_ok(void *data, const unsigned int size);
1615+void ccs_del_acl(struct list_head *element);
1616+void ccs_del_condition(struct list_head *element);
1617+void ccs_fill_path_info(struct ccs_path_info *ptr);
1618+void ccs_get_attributes(struct ccs_obj_info *obj);
1619+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register);
1620+void ccs_transition_failed(const char *domainname);
1621+void ccs_warn_oom(const char *function);
1622+void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...)
1623+ __printf(2, 3);
1624+
1625+/* Variable definition for internal use. */
1626+
1627+extern bool ccs_policy_loaded;
1628+extern const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS];
1629+extern const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX];
1630+extern const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION];
1631+extern const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION];
1632+extern const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION];
1633+extern struct ccs_domain_info ccs_kernel_domain;
1634+extern struct list_head ccs_condition_list;
1635+extern struct list_head ccs_domain_list;
1636+extern struct list_head ccs_name_list[CCS_MAX_HASH];
1637+extern struct list_head ccs_namespace_list;
1638+extern struct mutex ccs_policy_lock;
1639+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1640+extern struct srcu_struct ccs_ss;
1641+#endif
1642+extern unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT];
1643+extern unsigned int ccs_memory_used[CCS_MAX_MEMORY_STAT];
1644+
1645+/* Inlined functions for internal use. */
1646+
1647+/**
1648+ * ccs_pathcmp - strcmp() for "struct ccs_path_info" structure.
1649+ *
1650+ * @a: Pointer to "struct ccs_path_info".
1651+ * @b: Pointer to "struct ccs_path_info".
1652+ *
1653+ * Returns true if @a != @b, false otherwise.
1654+ */
1655+static inline bool ccs_pathcmp(const struct ccs_path_info *a,
1656+ const struct ccs_path_info *b)
1657+{
1658+ return a->hash != b->hash || strcmp(a->name, b->name);
1659+}
1660+
1661+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1662+
1663+/**
1664+ * ccs_read_lock - Take lock for protecting policy.
1665+ *
1666+ * Returns index number for ccs_read_unlock().
1667+ */
1668+static inline int ccs_read_lock(void)
1669+{
1670+ return srcu_read_lock(&ccs_ss);
1671+}
1672+
1673+/**
1674+ * ccs_read_unlock - Release lock for protecting policy.
1675+ *
1676+ * @idx: Index number returned by ccs_read_lock().
1677+ *
1678+ * Returns nothing.
1679+ */
1680+static inline void ccs_read_unlock(const int idx)
1681+{
1682+ srcu_read_unlock(&ccs_ss, idx);
1683+}
1684+
1685+#else
1686+
1687+int ccs_lock(void);
1688+void ccs_unlock(const int idx);
1689+
1690+/**
1691+ * ccs_read_lock - Take lock for protecting policy.
1692+ *
1693+ * Returns index number for ccs_read_unlock().
1694+ */
1695+static inline int ccs_read_lock(void)
1696+{
1697+ return ccs_lock();
1698+}
1699+
1700+/**
1701+ * ccs_read_unlock - Release lock for protecting policy.
1702+ *
1703+ * @idx: Index number returned by ccs_read_lock().
1704+ *
1705+ * Returns nothing.
1706+ */
1707+static inline void ccs_read_unlock(const int idx)
1708+{
1709+ ccs_unlock(idx);
1710+}
1711+
1712+#endif
1713+
1714+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
1715+
1716+/**
1717+ * ccs_tasklist_lock - Take lock for reading list of "struct task_struct".
1718+ *
1719+ * Returns nothing.
1720+ */
1721+static inline void ccs_tasklist_lock(void)
1722+{
1723+ rcu_read_lock();
1724+}
1725+
1726+/**
1727+ * ccs_tasklist_unlock - Release lock for reading list of "struct task_struct".
1728+ *
1729+ * Returns nothing.
1730+ */
1731+static inline void ccs_tasklist_unlock(void)
1732+{
1733+ rcu_read_unlock();
1734+}
1735+
1736+#else
1737+
1738+/**
1739+ * ccs_tasklist_lock - Take lock for reading list of "struct task_struct".
1740+ *
1741+ * Returns nothing.
1742+ */
1743+static inline void ccs_tasklist_lock(void)
1744+{
1745+ read_lock(&tasklist_lock);
1746+}
1747+
1748+/**
1749+ * ccs_tasklist_unlock - Release lock for reading list of "struct task_struct".
1750+ *
1751+ * Returns nothing.
1752+ */
1753+static inline void ccs_tasklist_unlock(void)
1754+{
1755+ read_unlock(&tasklist_lock);
1756+}
1757+
1758+#endif
1759+
1760+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1761+
1762+/**
1763+ * ccs_sys_getppid - Copy of getppid().
1764+ *
1765+ * Returns parent process's PID.
1766+ *
1767+ * Alpha does not have getppid() defined. To be able to build this module on
1768+ * Alpha, I have to copy getppid() from kernel/timer.c.
1769+ */
1770+static inline pid_t ccs_sys_getppid(void)
1771+{
1772+ pid_t pid;
1773+ rcu_read_lock();
1774+ pid = task_tgid_vnr(rcu_dereference(current->real_parent));
1775+ rcu_read_unlock();
1776+ return pid;
1777+}
1778+
1779+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1780+
1781+/**
1782+ * ccs_sys_getppid - Copy of getppid().
1783+ *
1784+ * Returns parent process's PID.
1785+ *
1786+ * This function was rewritten to use RCU in 2.6.16.34. However, distributors
1787+ * which use earlier kernels (e.g. 2.6.8/2.6.9) did not backport the bugfix.
1788+ * Therefore, I'm using code for 2.6.16.34 for earlier kernels.
1789+ */
1790+static inline pid_t ccs_sys_getppid(void)
1791+{
1792+ pid_t pid;
1793+ rcu_read_lock();
1794+#if (defined(RHEL_MAJOR) && RHEL_MAJOR == 5) || (defined(AX_MAJOR) && AX_MAJOR == 3)
1795+ pid = rcu_dereference(current->parent)->tgid;
1796+#elif defined(CONFIG_UTRACE)
1797+ /*
1798+ * RHEL 5.0 kernel does not have RHEL_MAJOR/RHEL_MINOR defined.
1799+ * Assume RHEL 5.0 if CONFIG_UTRACE is defined.
1800+ */
1801+ pid = rcu_dereference(current->parent)->tgid;
1802+#else
1803+ pid = rcu_dereference(current->real_parent)->tgid;
1804+#endif
1805+ rcu_read_unlock();
1806+ return pid;
1807+}
1808+
1809+#else
1810+
1811+/**
1812+ * ccs_sys_getppid - Copy of getppid().
1813+ *
1814+ * Returns parent process's PID.
1815+ *
1816+ * I can't use code for 2.6.16.34 for 2.4 kernels because 2.4 kernels does not
1817+ * have RCU. Therefore, I'm using pessimistic lock (i.e. tasklist_lock
1818+ * spinlock).
1819+ */
1820+static inline pid_t ccs_sys_getppid(void)
1821+{
1822+ pid_t pid;
1823+ read_lock(&tasklist_lock);
1824+#ifdef TASK_DEAD
1825+ pid = current->group_leader->real_parent->tgid;
1826+#else
1827+ pid = current->p_opptr->pid;
1828+#endif
1829+ read_unlock(&tasklist_lock);
1830+ return pid;
1831+}
1832+
1833+#endif
1834+
1835+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1836+
1837+/**
1838+ * ccs_sys_getpid - Copy of getpid().
1839+ *
1840+ * Returns current thread's PID.
1841+ *
1842+ * Alpha does not have getpid() defined. To be able to build this module on
1843+ * Alpha, I have to copy getpid() from kernel/timer.c.
1844+ */
1845+static inline pid_t ccs_sys_getpid(void)
1846+{
1847+ return task_tgid_vnr(current);
1848+}
1849+
1850+#else
1851+
1852+/**
1853+ * ccs_sys_getpid - Copy of getpid().
1854+ *
1855+ * Returns current thread's PID.
1856+ */
1857+static inline pid_t ccs_sys_getpid(void)
1858+{
1859+ return current->tgid;
1860+}
1861+
1862+#endif
1863+
1864+/**
1865+ * ccs_get_mode - Get mode for specified functionality.
1866+ *
1867+ * @profile: Profile number.
1868+ * @index: Functionality number.
1869+ *
1870+ * Returns mode.
1871+ */
1872+static inline u8 ccs_get_mode(const u8 profile, const u8 index)
1873+{
1874+ return ccs_get_config(profile, index) & (CCS_CONFIG_MAX_MODE - 1);
1875+}
1876+
1877+#if defined(CONFIG_SLOB)
1878+
1879+/**
1880+ * ccs_round2 - Round up to power of 2 for calculating memory usage.
1881+ *
1882+ * @size: Size to be rounded up.
1883+ *
1884+ * Returns @size.
1885+ *
1886+ * Since SLOB does not round up, this function simply returns @size.
1887+ */
1888+static inline int ccs_round2(size_t size)
1889+{
1890+ return size;
1891+}
1892+
1893+#else
1894+
1895+/**
1896+ * ccs_round2 - Round up to power of 2 for calculating memory usage.
1897+ *
1898+ * @size: Size to be rounded up.
1899+ *
1900+ * Returns rounded size.
1901+ *
1902+ * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
1903+ * (e.g.) 128 bytes.
1904+ */
1905+static inline int ccs_round2(size_t size)
1906+{
1907+#if PAGE_SIZE == 4096
1908+ size_t bsize = 32;
1909+#else
1910+ size_t bsize = 64;
1911+#endif
1912+ if (!size)
1913+ return 0;
1914+ while (size > bsize)
1915+ bsize <<= 1;
1916+ return bsize;
1917+}
1918+
1919+#endif
1920+
1921+/**
1922+ * ccs_put_condition - Drop reference on "struct ccs_condition".
1923+ *
1924+ * @cond: Pointer to "struct ccs_condition". Maybe NULL.
1925+ *
1926+ * Returns nothing.
1927+ */
1928+static inline void ccs_put_condition(struct ccs_condition *cond)
1929+{
1930+ if (cond)
1931+ atomic_dec(&cond->head.users);
1932+}
1933+
1934+/**
1935+ * ccs_put_group - Drop reference on "struct ccs_group".
1936+ *
1937+ * @group: Pointer to "struct ccs_group". Maybe NULL.
1938+ *
1939+ * Returns nothing.
1940+ */
1941+static inline void ccs_put_group(struct ccs_group *group)
1942+{
1943+ if (group)
1944+ atomic_dec(&group->head.users);
1945+}
1946+
1947+/**
1948+ * ccs_put_name - Drop reference on "struct ccs_name".
1949+ *
1950+ * @name: Pointer to "struct ccs_path_info". Maybe NULL.
1951+ *
1952+ * Returns nothing.
1953+ */
1954+static inline void ccs_put_name(const struct ccs_path_info *name)
1955+{
1956+ if (name)
1957+ atomic_dec(&container_of(name, struct ccs_name, entry)->
1958+ head.users);
1959+}
1960+
1961+/* For importing variables and functions. */
1962+extern struct ccsecurity_exports ccsecurity_exports;
1963+
1964+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
1965+
1966+/*
1967+ * Structure for holding "struct ccs_domain_info *" and "struct ccs_execve *"
1968+ * and "u32 ccs_flags" for each "struct task_struct".
1969+ *
1970+ * "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct"
1971+ * are maintained outside that "struct task_struct". Therefore, ccs_security
1972+ * != task_struct . This keeps KABI for distributor's prebuilt kernels but
1973+ * entails slow access.
1974+ *
1975+ * Memory for this structure is allocated when current thread tries to access
1976+ * it. Therefore, if memory allocation failed, current thread will be killed by
1977+ * SIGKILL. Note that if current->pid == 1, sending SIGKILL won't work.
1978+ */
1979+struct ccs_security {
1980+ struct list_head list;
1981+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) || LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1982+ const struct task_struct *task;
1983+#else
1984+ struct pid *pid; /* Maybe NULL. */
1985+ const struct cred *cred; /* Maybe NULL. */
1986+#endif
1987+ struct ccs_domain_info *ccs_domain_info;
1988+ u32 ccs_flags;
1989+ struct ccs_execve *ee; /* Maybe NULL. */
1990+ struct rcu_head rcu;
1991+};
1992+
1993+void __init ccs_main_init(void);
1994+bool ccs_used_by_cred(const struct ccs_domain_info *domain);
1995+int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep);
1996+void ccs_finish_execve(int retval, struct ccs_execve *ee);
1997+void ccs_load_policy(const char *filename);
1998+#ifndef CONFIG_AKARI_TRACE_EXECVE_COUNT
1999+#define ccs_audit_alloc_execve(ee) do { } while (0)
2000+#define ccs_audit_free_execve(ee, is_current) do { } while (0)
2001+#else
2002+void ccs_audit_alloc_execve(const struct ccs_execve * const ee);
2003+void ccs_audit_free_execve(const struct ccs_execve * const ee,
2004+ const bool is_current);
2005+#endif
2006+
2007+#define CCS_TASK_SECURITY_HASH_BITS 12
2008+#define CCS_MAX_TASK_SECURITY_HASH (1u << CCS_TASK_SECURITY_HASH_BITS)
2009+extern struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
2010+
2011+struct ccs_security *ccs_find_task_security(const struct task_struct *task);
2012+
2013+/**
2014+ * ccs_current_security - Get "struct ccs_security" for current thread.
2015+ *
2016+ * Returns pointer to "struct ccs_security" for current thread.
2017+ */
2018+static inline struct ccs_security *ccs_current_security(void)
2019+{
2020+ return ccs_find_task_security(current);
2021+}
2022+
2023+/**
2024+ * ccs_task_domain - Get "struct ccs_domain_info" for specified thread.
2025+ *
2026+ * @task: Pointer to "struct task_struct".
2027+ *
2028+ * Returns pointer to "struct ccs_security" for specified thread.
2029+ */
2030+static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
2031+{
2032+ struct ccs_domain_info *domain;
2033+ rcu_read_lock();
2034+ domain = ccs_find_task_security(task)->ccs_domain_info;
2035+ rcu_read_unlock();
2036+ return domain;
2037+}
2038+
2039+/**
2040+ * ccs_current_domain - Get "struct ccs_domain_info" for current thread.
2041+ *
2042+ * Returns pointer to "struct ccs_domain_info" for current thread.
2043+ */
2044+static inline struct ccs_domain_info *ccs_current_domain(void)
2045+{
2046+ return ccs_find_task_security(current)->ccs_domain_info;
2047+}
2048+
2049+/**
2050+ * ccs_task_flags - Get flags for specified thread.
2051+ *
2052+ * @task: Pointer to "struct task_struct".
2053+ *
2054+ * Returns flags for specified thread.
2055+ */
2056+static inline u32 ccs_task_flags(struct task_struct *task)
2057+{
2058+ u32 ccs_flags;
2059+ rcu_read_lock();
2060+ ccs_flags = ccs_find_task_security(task)->ccs_flags;
2061+ rcu_read_unlock();
2062+ return ccs_flags;
2063+}
2064+
2065+/**
2066+ * ccs_current_flags - Get flags for current thread.
2067+ *
2068+ * Returns flags for current thread.
2069+ */
2070+static inline u32 ccs_current_flags(void)
2071+{
2072+ return ccs_find_task_security(current)->ccs_flags;
2073+}
2074+
2075+#else
2076+
2077+/*
2078+ * "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct"
2079+ * are maintained inside that "struct task_struct". Therefore, ccs_security ==
2080+ * task_struct . This allows fast access but breaks KABI checks for
2081+ * distributor's prebuilt kernels due to changes in "struct task_struct".
2082+ */
2083+#define ccs_security task_struct
2084+
2085+/**
2086+ * ccs_find_task_security - Find "struct ccs_security" for given task.
2087+ *
2088+ * @task: Pointer to "struct task_struct".
2089+ *
2090+ * Returns pointer to "struct ccs_security".
2091+ */
2092+static inline struct ccs_security *ccs_find_task_security(struct task_struct *
2093+ task)
2094+{
2095+ return task;
2096+}
2097+
2098+/**
2099+ * ccs_current_security - Get "struct ccs_security" for current thread.
2100+ *
2101+ * Returns pointer to "struct ccs_security" for current thread.
2102+ */
2103+static inline struct ccs_security *ccs_current_security(void)
2104+{
2105+ return ccs_find_task_security(current);
2106+}
2107+
2108+/**
2109+ * ccs_task_domain - Get "struct ccs_domain_info" for specified thread.
2110+ *
2111+ * @task: Pointer to "struct task_struct".
2112+ *
2113+ * Returns pointer to "struct ccs_security" for specified thread.
2114+ */
2115+static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
2116+{
2117+ struct ccs_domain_info *domain = task->ccs_domain_info;
2118+ return domain ? domain : &ccs_kernel_domain;
2119+}
2120+
2121+/**
2122+ * ccs_current_domain - Get "struct ccs_domain_info" for current thread.
2123+ *
2124+ * Returns pointer to "struct ccs_domain_info" for current thread.
2125+ *
2126+ * If current thread does not belong to a domain (which is true for initial
2127+ * init_task in order to hide ccs_kernel_domain from this module),
2128+ * current thread enters into ccs_kernel_domain.
2129+ */
2130+static inline struct ccs_domain_info *ccs_current_domain(void)
2131+{
2132+ struct task_struct *task = current;
2133+ if (!task->ccs_domain_info)
2134+ task->ccs_domain_info = &ccs_kernel_domain;
2135+ return task->ccs_domain_info;
2136+}
2137+
2138+/**
2139+ * ccs_task_flags - Get flags for specified thread.
2140+ *
2141+ * @task: Pointer to "struct task_struct".
2142+ *
2143+ * Returns flags for specified thread.
2144+ */
2145+static inline u32 ccs_task_flags(struct task_struct *task)
2146+{
2147+ return ccs_find_task_security(task)->ccs_flags;
2148+}
2149+
2150+/**
2151+ * ccs_current_flags - Get flags for current thread.
2152+ *
2153+ * Returns flags for current thread.
2154+ */
2155+static inline u32 ccs_current_flags(void)
2156+{
2157+ return ccs_find_task_security(current)->ccs_flags;
2158+}
2159+
2160+#endif
2161+
2162+/**
2163+ * ccs_current_namespace - Get "struct ccs_policy_namespace" for current thread.
2164+ *
2165+ * Returns pointer to "struct ccs_policy_namespace" for current thread.
2166+ */
2167+static inline struct ccs_policy_namespace *ccs_current_namespace(void)
2168+{
2169+ return ccs_current_domain()->ns;
2170+}
2171+
2172+#endif
--- tags/patches/1.0.39/load_policy.c (nonexistent)
+++ tags/patches/1.0.39/load_policy.c (revision 612)
@@ -0,0 +1,353 @@
1+/*
2+ * security/ccsecurity/load_policy.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.6 2019/08/20
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(3, 8, 0)
249+
250+/**
251+ * __ccs_search_binary_handler - Load policy before calling search_binary_handler().
252+ *
253+ * @bprm: Pointer to "struct linux_binprm".
254+ *
255+ * Returns 0 on success, negative value otherwise.
256+ */
257+static int __ccs_search_binary_handler(struct linux_binprm *bprm)
258+{
259+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
260+ ccs_load_policy(bprm->filename);
261+#endif
262+ /*
263+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
264+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
265+ * load loadable kernel module. The loadable kernel module modifies
266+ * "struct ccsecurity_ops". Thus, we need to transfer control to
267+ * __ccs_search_binary_handler() in security/ccsecurity/permission.c
268+ * if "struct ccsecurity_ops" was modified.
269+ */
270+ if (ccsecurity_ops.search_binary_handler
271+ != __ccs_search_binary_handler)
272+ return ccsecurity_ops.search_binary_handler(bprm);
273+ return search_binary_handler(bprm);
274+}
275+
276+#else
277+
278+/**
279+ * __ccs_search_binary_handler - Load policy before calling search_binary_handler().
280+ *
281+ * @bprm: Pointer to "struct linux_binprm".
282+ * @regs: Pointer to "struct pt_regs".
283+ *
284+ * Returns 0 on success, negative value otherwise.
285+ */
286+static int __ccs_search_binary_handler(struct linux_binprm *bprm,
287+ struct pt_regs *regs)
288+{
289+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
290+ ccs_load_policy(bprm->filename);
291+#endif
292+ /*
293+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
294+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
295+ * load loadable kernel module. The loadable kernel module modifies
296+ * "struct ccsecurity_ops". Thus, we need to transfer control to
297+ * __ccs_search_binary_handler() in security/ccsecurity/permission.c
298+ * if "struct ccsecurity_ops" was modified.
299+ */
300+ if (ccsecurity_ops.search_binary_handler
301+ != __ccs_search_binary_handler)
302+ return ccsecurity_ops.search_binary_handler(bprm, regs);
303+ return search_binary_handler(bprm, regs);
304+}
305+
306+#endif
307+
308+/*
309+ * Some exports for loadable kernel module part.
310+ *
311+ * Although scripts/checkpatch.pl complains about use of "extern" in C file,
312+ * we don't put these into security/ccsecurity/internal.h because we want to
313+ * split built-in part and loadable kernel module part.
314+ */
315+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
316+extern spinlock_t vfsmount_lock;
317+#endif
318+
319+/* For exporting variables and functions. */
320+const struct ccsecurity_exports ccsecurity_exports = {
321+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
322+ .load_policy = ccs_load_policy,
323+#endif
324+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
325+ .d_absolute_path = d_absolute_path,
326+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
327+ .__d_path = __d_path,
328+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
329+ .vfsmount_lock = &vfsmount_lock,
330+#endif
331+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
332+ .find_task_by_vpid = find_task_by_vpid,
333+ .find_task_by_pid_ns = find_task_by_pid_ns,
334+#endif
335+};
336+#ifdef CONFIG_CCSECURITY_LKM
337+/* Only ccsecurity module need to access this struct. */
338+EXPORT_SYMBOL_GPL(ccsecurity_exports);
339+#endif
340+
341+/* Members are updated by loadable kernel module. */
342+struct ccsecurity_operations ccsecurity_ops = {
343+ .search_binary_handler = __ccs_search_binary_handler,
344+#ifdef CONFIG_CCSECURITY_DISABLE_BY_DEFAULT
345+ .disabled = 1,
346+#endif
347+};
348+/*
349+ * Non-GPL modules might need to access this struct via inlined functions
350+ * embedded into include/linux/security.h and include/net/ip.h
351+ */
352+EXPORT_SYMBOL(ccsecurity_ops);
353+#endif
--- tags/patches/1.0.39/lsm-2.6.0-vfs.c (nonexistent)
+++ tags/patches/1.0.39/lsm-2.6.0-vfs.c (revision 612)
@@ -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.39 2019/08/20
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.39 2019/08/20\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.39/lsm-2.6.0.c (nonexistent)
+++ tags/patches/1.0.39/lsm-2.6.0.c (revision 612)
@@ -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.39 2019/08/20
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.39 2019/08/20\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.39/lsm-2.6.29.c (nonexistent)
+++ tags/patches/1.0.39/lsm-2.6.29.c (revision 612)
@@ -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.39 2019/08/20
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+}
857+
858+/**
859+ * ccs_path_mkdir - Check permission for mkdir().
860+ *
861+ * @dir: Pointer to "struct path".
862+ * @dentry: Pointer to "struct dentry".
863+ * @mode: Create mode.
864+ *
865+ * Returns 0 on success, negative value otherwise.
866+ */
867+static int ccs_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
868+{
869+ int rc = ccs_mkdir_permission(dentry, dir->mnt, mode);
870+ if (rc)
871+ return rc;
872+ while (!original_security_ops.path_mkdir)
873+ smp_rmb();
874+ return original_security_ops.path_mkdir(dir, dentry, mode);
875+}
876+
877+#endif
878+
879+/**
880+ * ccs_path_rmdir - Check permission for rmdir().
881+ *
882+ * @dir: Pointer to "struct path".
883+ * @dentry: Pointer to "struct dentry".
884+ *
885+ * Returns 0 on success, negative value otherwise.
886+ */
887+static int ccs_path_rmdir(struct path *dir, struct dentry *dentry)
888+{
889+ int rc = ccs_rmdir_permission(dentry, dir->mnt);
890+ if (rc)
891+ return rc;
892+ while (!original_security_ops.path_rmdir)
893+ smp_rmb();
894+ return original_security_ops.path_rmdir(dir, dentry);
895+}
896+
897+/**
898+ * ccs_path_unlink - Check permission for unlink().
899+ *
900+ * @dir: Pointer to "struct path".
901+ * @dentry: Pointer to "struct dentry".
902+ *
903+ * Returns 0 on success, negative value otherwise.
904+ */
905+static int ccs_path_unlink(struct path *dir, struct dentry *dentry)
906+{
907+ int rc = ccs_unlink_permission(dentry, dir->mnt);
908+ if (rc)
909+ return rc;
910+ while (!original_security_ops.path_unlink)
911+ smp_rmb();
912+ return original_security_ops.path_unlink(dir, dentry);
913+}
914+
915+/**
916+ * ccs_path_symlink - Check permission for symlink().
917+ *
918+ * @dir: Pointer to "struct path".
919+ * @dentry: Pointer to "struct dentry".
920+ * @old_name: Content of symbolic link.
921+ *
922+ * Returns 0 on success, negative value otherwise.
923+ */
924+static int ccs_path_symlink(struct path *dir, struct dentry *dentry,
925+ const char *old_name)
926+{
927+ int rc = ccs_symlink_permission(dentry, dir->mnt, old_name);
928+ if (rc)
929+ return rc;
930+ while (!original_security_ops.path_symlink)
931+ smp_rmb();
932+ return original_security_ops.path_symlink(dir, dentry, old_name);
933+}
934+
935+/**
936+ * ccs_path_rename - Check permission for rename().
937+ *
938+ * @old_dir: Pointer to "struct path".
939+ * @old_dentry: Pointer to "struct dentry".
940+ * @new_dir: Pointer to "struct path".
941+ * @new_dentry: Pointer to "struct dentry".
942+ *
943+ * Returns 0 on success, negative value otherwise.
944+ */
945+static int ccs_path_rename(struct path *old_dir, struct dentry *old_dentry,
946+ struct path *new_dir, struct dentry *new_dentry)
947+{
948+ int rc = ccs_rename_permission(old_dentry, new_dentry, old_dir->mnt);
949+ if (rc)
950+ return rc;
951+ while (!original_security_ops.path_rename)
952+ smp_rmb();
953+ return original_security_ops.path_rename(old_dir, old_dentry, new_dir,
954+ new_dentry);
955+}
956+
957+/**
958+ * ccs_path_link - Check permission for link().
959+ *
960+ * @old_dentry: Pointer to "struct dentry".
961+ * @new_dir: Pointer to "struct path".
962+ * @new_dentry: Pointer to "struct dentry".
963+ *
964+ * Returns 0 on success, negative value otherwise.
965+ */
966+static int ccs_path_link(struct dentry *old_dentry, struct path *new_dir,
967+ struct dentry *new_dentry)
968+{
969+ int rc = ccs_link_permission(old_dentry, new_dentry, new_dir->mnt);
970+ if (rc)
971+ return rc;
972+ while (!original_security_ops.path_link)
973+ smp_rmb();
974+ return original_security_ops.path_link(old_dentry, new_dir,
975+ new_dentry);
976+}
977+
978+#else
979+
980+#if defined(USE_UMODE_T)
981+
982+/**
983+ * ccs_inode_mknod - Check permission for mknod().
984+ *
985+ * @dir: Pointer to "struct inode".
986+ * @dentry: Pointer to "struct dentry".
987+ * @mode: Create mode.
988+ * @dev: Device major/minor number.
989+ *
990+ * Returns 0 on success, negative value otherwise.
991+ */
992+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
993+ umode_t mode, dev_t dev)
994+{
995+ int rc = ccs_mknod_permission(dentry, NULL, mode, dev);
996+ if (rc)
997+ return rc;
998+ while (!original_security_ops.inode_mknod)
999+ smp_rmb();
1000+ return original_security_ops.inode_mknod(dir, dentry, mode, dev);
1001+}
1002+
1003+/**
1004+ * ccs_inode_mkdir - Check permission for mkdir().
1005+ *
1006+ * @dir: Pointer to "struct inode".
1007+ * @dentry: Pointer to "struct dentry".
1008+ * @mode: Create mode.
1009+ *
1010+ * Returns 0 on success, negative value otherwise.
1011+ */
1012+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
1013+ umode_t mode)
1014+{
1015+ int rc = ccs_mkdir_permission(dentry, NULL, mode);
1016+ if (rc)
1017+ return rc;
1018+ while (!original_security_ops.inode_mkdir)
1019+ smp_rmb();
1020+ return original_security_ops.inode_mkdir(dir, dentry, mode);
1021+}
1022+
1023+#else
1024+
1025+/**
1026+ * ccs_inode_mknod - Check permission for mknod().
1027+ *
1028+ * @dir: Pointer to "struct inode".
1029+ * @dentry: Pointer to "struct dentry".
1030+ * @mode: Create mode.
1031+ * @dev: Device major/minor number.
1032+ *
1033+ * Returns 0 on success, negative value otherwise.
1034+ */
1035+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry, int mode,
1036+ dev_t dev)
1037+{
1038+ int rc = ccs_mknod_permission(dentry, NULL, mode, dev);
1039+ if (rc)
1040+ return rc;
1041+ while (!original_security_ops.inode_mknod)
1042+ smp_rmb();
1043+ return original_security_ops.inode_mknod(dir, dentry, mode, dev);
1044+}
1045+
1046+/**
1047+ * ccs_inode_mkdir - Check permission for mkdir().
1048+ *
1049+ * @dir: Pointer to "struct inode".
1050+ * @dentry: Pointer to "struct dentry".
1051+ * @mode: Create mode.
1052+ *
1053+ * Returns 0 on success, negative value otherwise.
1054+ */
1055+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1056+{
1057+ int rc = ccs_mkdir_permission(dentry, NULL, mode);
1058+ if (rc)
1059+ return rc;
1060+ while (!original_security_ops.inode_mkdir)
1061+ smp_rmb();
1062+ return original_security_ops.inode_mkdir(dir, dentry, mode);
1063+}
1064+
1065+#endif
1066+
1067+/**
1068+ * ccs_inode_rmdir - Check permission for rmdir().
1069+ *
1070+ * @dir: Pointer to "struct inode".
1071+ * @dentry: Pointer to "struct dentry".
1072+ *
1073+ * Returns 0 on success, negative value otherwise.
1074+ */
1075+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry)
1076+{
1077+ int rc = ccs_rmdir_permission(dentry, NULL);
1078+ if (rc)
1079+ return rc;
1080+ while (!original_security_ops.inode_rmdir)
1081+ smp_rmb();
1082+ return original_security_ops.inode_rmdir(dir, dentry);
1083+}
1084+
1085+/**
1086+ * ccs_inode_unlink - Check permission for unlink().
1087+ *
1088+ * @dir: Pointer to "struct inode".
1089+ * @dentry: Pointer to "struct dentry".
1090+ *
1091+ * Returns 0 on success, negative value otherwise.
1092+ */
1093+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
1094+{
1095+ int rc = ccs_unlink_permission(dentry, NULL);
1096+ if (rc)
1097+ return rc;
1098+ while (!original_security_ops.inode_unlink)
1099+ smp_rmb();
1100+ return original_security_ops.inode_unlink(dir, dentry);
1101+}
1102+
1103+/**
1104+ * ccs_inode_symlink - Check permission for symlink().
1105+ *
1106+ * @dir: Pointer to "struct inode".
1107+ * @dentry: Pointer to "struct dentry".
1108+ * @old_name: Content of symbolic link.
1109+ *
1110+ * Returns 0 on success, negative value otherwise.
1111+ */
1112+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
1113+ const char *old_name)
1114+{
1115+ int rc = ccs_symlink_permission(dentry, NULL, old_name);
1116+ if (rc)
1117+ return rc;
1118+ while (!original_security_ops.inode_symlink)
1119+ smp_rmb();
1120+ return original_security_ops.inode_symlink(dir, dentry, old_name);
1121+}
1122+
1123+/**
1124+ * ccs_inode_rename - Check permission for rename().
1125+ *
1126+ * @old_dir: Pointer to "struct inode".
1127+ * @old_dentry: Pointer to "struct dentry".
1128+ * @new_dir: Pointer to "struct inode".
1129+ * @new_dentry: Pointer to "struct dentry".
1130+ *
1131+ * Returns 0 on success, negative value otherwise.
1132+ */
1133+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
1134+ struct inode *new_dir, struct dentry *new_dentry)
1135+{
1136+ int rc = ccs_rename_permission(old_dentry, new_dentry, NULL);
1137+ if (rc)
1138+ return rc;
1139+ while (!original_security_ops.inode_rename)
1140+ smp_rmb();
1141+ return original_security_ops.inode_rename(old_dir, old_dentry, new_dir,
1142+ new_dentry);
1143+}
1144+
1145+/**
1146+ * ccs_inode_link - Check permission for link().
1147+ *
1148+ * @old_dentry: Pointer to "struct dentry".
1149+ * @dir: Pointer to "struct inode".
1150+ * @new_dentry: Pointer to "struct dentry".
1151+ *
1152+ * Returns 0 on success, negative value otherwise.
1153+ */
1154+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
1155+ struct dentry *new_dentry)
1156+{
1157+ int rc = ccs_link_permission(old_dentry, new_dentry, NULL);
1158+ if (rc)
1159+ return rc;
1160+ while (!original_security_ops.inode_link)
1161+ smp_rmb();
1162+ return original_security_ops.inode_link(old_dentry, dir, new_dentry);
1163+}
1164+
1165+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
1166+
1167+/**
1168+ * ccs_inode_create - Check permission for creat().
1169+ *
1170+ * @dir: Pointer to "struct inode".
1171+ * @dentry: Pointer to "struct dentry".
1172+ * @mode: Create mode.
1173+ *
1174+ * Returns 0 on success, negative value otherwise.
1175+ */
1176+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
1177+ umode_t mode)
1178+{
1179+ int rc = ccs_mknod_permission(dentry, NULL, mode, 0);
1180+ if (rc)
1181+ return rc;
1182+ while (!original_security_ops.inode_create)
1183+ smp_rmb();
1184+ return original_security_ops.inode_create(dir, dentry, mode);
1185+}
1186+
1187+#else
1188+
1189+/**
1190+ * ccs_inode_create - Check permission for creat().
1191+ *
1192+ * @dir: Pointer to "struct inode".
1193+ * @dentry: Pointer to "struct dentry".
1194+ * @mode: Create mode.
1195+ *
1196+ * Returns 0 on success, negative value otherwise.
1197+ */
1198+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
1199+ int mode)
1200+{
1201+ int rc = ccs_mknod_permission(dentry, NULL, mode, 0);
1202+ if (rc)
1203+ return rc;
1204+ while (!original_security_ops.inode_create)
1205+ smp_rmb();
1206+ return original_security_ops.inode_create(dir, dentry, mode);
1207+}
1208+
1209+#endif
1210+
1211+#endif
1212+
1213+#ifdef CONFIG_SECURITY_NETWORK
1214+
1215+#include <net/sock.h>
1216+
1217+/* Structure for remembering an accept()ed socket's status. */
1218+struct ccs_socket_tag {
1219+ struct list_head list;
1220+ struct inode *inode;
1221+ int status;
1222+ struct rcu_head rcu;
1223+};
1224+
1225+/*
1226+ * List for managing accept()ed sockets.
1227+ * Since we don't need to keep an accept()ed socket into this list after
1228+ * once the permission was granted, the number of entries in this list is
1229+ * likely small. Therefore, we don't use hash tables.
1230+ */
1231+static LIST_HEAD(ccs_accepted_socket_list);
1232+/* Lock for protecting ccs_accepted_socket_list . */
1233+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
1234+
1235+/**
1236+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
1237+ *
1238+ * @rcu: Pointer to "struct rcu_head".
1239+ *
1240+ * Returns nothing.
1241+ */
1242+static void ccs_socket_rcu_free(struct rcu_head *rcu)
1243+{
1244+ struct ccs_socket_tag *ptr = container_of(rcu, typeof(*ptr), rcu);
1245+ kfree(ptr);
1246+}
1247+
1248+/**
1249+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
1250+ *
1251+ * @inode: Pointer to "struct inode".
1252+ * @status: New status.
1253+ *
1254+ * Returns nothing.
1255+ *
1256+ * If @status == 0, memory for that socket will be released after RCU grace
1257+ * period.
1258+ */
1259+static void ccs_update_socket_tag(struct inode *inode, int status)
1260+{
1261+ struct ccs_socket_tag *ptr;
1262+ /*
1263+ * Protect whole section because multiple threads may call this
1264+ * function with same "sock" via ccs_validate_socket().
1265+ */
1266+ spin_lock(&ccs_accepted_socket_list_lock);
1267+ rcu_read_lock();
1268+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
1269+ if (ptr->inode != inode)
1270+ continue;
1271+ ptr->status = status;
1272+ if (status)
1273+ break;
1274+ list_del_rcu(&ptr->list);
1275+ call_rcu(&ptr->rcu, ccs_socket_rcu_free);
1276+ break;
1277+ }
1278+ rcu_read_unlock();
1279+ spin_unlock(&ccs_accepted_socket_list_lock);
1280+}
1281+
1282+/**
1283+ * ccs_validate_socket - Check post accept() permission if needed.
1284+ *
1285+ * @sock: Pointer to "struct socket".
1286+ *
1287+ * Returns 0 on success, negative value otherwise.
1288+ */
1289+static int ccs_validate_socket(struct socket *sock)
1290+{
1291+ struct inode *inode = SOCK_INODE(sock);
1292+ struct ccs_socket_tag *ptr;
1293+ int ret = 0;
1294+ rcu_read_lock();
1295+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
1296+ if (ptr->inode != inode)
1297+ continue;
1298+ ret = ptr->status;
1299+ break;
1300+ }
1301+ rcu_read_unlock();
1302+ if (ret <= 0)
1303+ /*
1304+ * This socket is not an accept()ed socket or this socket is
1305+ * an accept()ed socket and post accept() permission is done.
1306+ */
1307+ return ret;
1308+ /*
1309+ * Check post accept() permission now.
1310+ *
1311+ * Strictly speaking, we need to pass both listen()ing socket and
1312+ * accept()ed socket to __ccs_socket_post_accept_permission().
1313+ * But since socket's family and type are same for both sockets,
1314+ * passing the accept()ed socket in place for the listen()ing socket
1315+ * will work.
1316+ */
1317+ ret = ccs_socket_post_accept_permission(sock, sock);
1318+ /*
1319+ * If permission was granted, we forget that this is an accept()ed
1320+ * socket. Otherwise, we remember that this socket needs to return
1321+ * error for subsequent socketcalls.
1322+ */
1323+ ccs_update_socket_tag(inode, ret);
1324+ return ret;
1325+}
1326+
1327+/**
1328+ * ccs_socket_accept - Check permission for accept().
1329+ *
1330+ * @sock: Pointer to "struct socket".
1331+ * @newsock: Pointer to "struct socket".
1332+ *
1333+ * Returns 0 on success, negative value otherwise.
1334+ *
1335+ * This hook is used for setting up environment for doing post accept()
1336+ * permission check. If dereferencing sock->ops->something() were ordered by
1337+ * rcu_dereference(), we could replace sock->ops with "a copy of original
1338+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
1339+ * in order to do post accept() permission check before returning to userspace.
1340+ * If we make the copy in security_socket_post_create(), it would be possible
1341+ * to safely replace sock->ops here, but we don't do so because we don't want
1342+ * to allocate memory for sockets which do not call sock->ops->accept().
1343+ * Therefore, we do post accept() permission check upon next socket syscalls
1344+ * rather than between sock->ops->accept() and returning to userspace.
1345+ * This means that if a socket was close()d before calling some socket
1346+ * syscalls, post accept() permission check will not be done.
1347+ */
1348+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
1349+{
1350+ struct ccs_socket_tag *ptr;
1351+ int rc = ccs_validate_socket(sock);
1352+ if (rc < 0)
1353+ return rc;
1354+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
1355+ if (!ptr)
1356+ return -ENOMEM;
1357+ while (!original_security_ops.socket_accept)
1358+ smp_rmb();
1359+ rc = original_security_ops.socket_accept(sock, newsock);
1360+ if (rc) {
1361+ kfree(ptr);
1362+ return rc;
1363+ }
1364+ /*
1365+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
1366+ * "newsock" as "an accept()ed socket but post accept() permission
1367+ * check is not done yet" by allocating memory using inode of the
1368+ * "newsock" as a search key.
1369+ */
1370+ ptr->inode = SOCK_INODE(newsock);
1371+ ptr->status = 1; /* Check post accept() permission later. */
1372+ spin_lock(&ccs_accepted_socket_list_lock);
1373+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
1374+ spin_unlock(&ccs_accepted_socket_list_lock);
1375+ return 0;
1376+}
1377+
1378+/**
1379+ * ccs_socket_listen - Check permission for listen().
1380+ *
1381+ * @sock: Pointer to "struct socket".
1382+ * @backlog: Backlog parameter.
1383+ *
1384+ * Returns 0 on success, negative value otherwise.
1385+ */
1386+static int ccs_socket_listen(struct socket *sock, int backlog)
1387+{
1388+ int rc = ccs_validate_socket(sock);
1389+ if (rc < 0)
1390+ return rc;
1391+ rc = ccs_socket_listen_permission(sock);
1392+ if (rc)
1393+ return rc;
1394+ while (!original_security_ops.socket_listen)
1395+ smp_rmb();
1396+ return original_security_ops.socket_listen(sock, backlog);
1397+}
1398+
1399+/**
1400+ * ccs_socket_connect - Check permission for connect().
1401+ *
1402+ * @sock: Pointer to "struct socket".
1403+ * @addr: Pointer to "struct sockaddr".
1404+ * @addr_len: Size of @addr.
1405+ *
1406+ * Returns 0 on success, negative value otherwise.
1407+ */
1408+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
1409+ int addr_len)
1410+{
1411+ int rc = ccs_validate_socket(sock);
1412+ if (rc < 0)
1413+ return rc;
1414+ rc = ccs_socket_connect_permission(sock, addr, addr_len);
1415+ if (rc)
1416+ return rc;
1417+ while (!original_security_ops.socket_connect)
1418+ smp_rmb();
1419+ return original_security_ops.socket_connect(sock, addr, addr_len);
1420+}
1421+
1422+/**
1423+ * ccs_socket_bind - Check permission for bind().
1424+ *
1425+ * @sock: Pointer to "struct socket".
1426+ * @addr: Pointer to "struct sockaddr".
1427+ * @addr_len: Size of @addr.
1428+ *
1429+ * Returns 0 on success, negative value otherwise.
1430+ */
1431+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
1432+ int addr_len)
1433+{
1434+ int rc = ccs_validate_socket(sock);
1435+ if (rc < 0)
1436+ return rc;
1437+ rc = ccs_socket_bind_permission(sock, addr, addr_len);
1438+ if (rc)
1439+ return rc;
1440+ while (!original_security_ops.socket_bind)
1441+ smp_rmb();
1442+ return original_security_ops.socket_bind(sock, addr, addr_len);
1443+}
1444+
1445+/**
1446+ * ccs_socket_sendmsg - Check permission for sendmsg().
1447+ *
1448+ * @sock: Pointer to "struct socket".
1449+ * @msg: Pointer to "struct msghdr".
1450+ * @size: Size of message.
1451+ *
1452+ * Returns 0 on success, negative value otherwise.
1453+ */
1454+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
1455+ int size)
1456+{
1457+ int rc = ccs_validate_socket(sock);
1458+ if (rc < 0)
1459+ return rc;
1460+ rc = ccs_socket_sendmsg_permission(sock, msg, size);
1461+ if (rc)
1462+ return rc;
1463+ while (!original_security_ops.socket_sendmsg)
1464+ smp_rmb();
1465+ return original_security_ops.socket_sendmsg(sock, msg, size);
1466+}
1467+
1468+/**
1469+ * ccs_socket_recvmsg - Check permission for recvmsg().
1470+ *
1471+ * @sock: Pointer to "struct socket".
1472+ * @msg: Pointer to "struct msghdr".
1473+ * @size: Size of message.
1474+ * @flags: Flags.
1475+ *
1476+ * Returns 0 on success, negative value otherwise.
1477+ */
1478+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
1479+ int size, int flags)
1480+{
1481+ int rc = ccs_validate_socket(sock);
1482+ if (rc < 0)
1483+ return rc;
1484+ while (!original_security_ops.socket_recvmsg)
1485+ smp_rmb();
1486+ return original_security_ops.socket_recvmsg(sock, msg, size, flags);
1487+}
1488+
1489+/**
1490+ * ccs_socket_getsockname - Check permission for getsockname().
1491+ *
1492+ * @sock: Pointer to "struct socket".
1493+ *
1494+ * Returns 0 on success, negative value otherwise.
1495+ */
1496+static int ccs_socket_getsockname(struct socket *sock)
1497+{
1498+ int rc = ccs_validate_socket(sock);
1499+ if (rc < 0)
1500+ return rc;
1501+ while (!original_security_ops.socket_getsockname)
1502+ smp_rmb();
1503+ return original_security_ops.socket_getsockname(sock);
1504+}
1505+
1506+/**
1507+ * ccs_socket_getpeername - Check permission for getpeername().
1508+ *
1509+ * @sock: Pointer to "struct socket".
1510+ *
1511+ * Returns 0 on success, negative value otherwise.
1512+ */
1513+static int ccs_socket_getpeername(struct socket *sock)
1514+{
1515+ int rc = ccs_validate_socket(sock);
1516+ if (rc < 0)
1517+ return rc;
1518+ while (!original_security_ops.socket_getpeername)
1519+ smp_rmb();
1520+ return original_security_ops.socket_getpeername(sock);
1521+}
1522+
1523+/**
1524+ * ccs_socket_getsockopt - Check permission for getsockopt().
1525+ *
1526+ * @sock: Pointer to "struct socket".
1527+ * @level: Level.
1528+ * @optname: Option's name,
1529+ *
1530+ * Returns 0 on success, negative value otherwise.
1531+ */
1532+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
1533+{
1534+ int rc = ccs_validate_socket(sock);
1535+ if (rc < 0)
1536+ return rc;
1537+ while (!original_security_ops.socket_getsockopt)
1538+ smp_rmb();
1539+ return original_security_ops.socket_getsockopt(sock, level, optname);
1540+}
1541+
1542+/**
1543+ * ccs_socket_setsockopt - Check permission for setsockopt().
1544+ *
1545+ * @sock: Pointer to "struct socket".
1546+ * @level: Level.
1547+ * @optname: Option's name,
1548+ *
1549+ * Returns 0 on success, negative value otherwise.
1550+ */
1551+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
1552+{
1553+ int rc = ccs_validate_socket(sock);
1554+ if (rc < 0)
1555+ return rc;
1556+ while (!original_security_ops.socket_setsockopt)
1557+ smp_rmb();
1558+ return original_security_ops.socket_setsockopt(sock, level, optname);
1559+}
1560+
1561+/**
1562+ * ccs_socket_shutdown - Check permission for shutdown().
1563+ *
1564+ * @sock: Pointer to "struct socket".
1565+ * @how: Shutdown mode.
1566+ *
1567+ * Returns 0 on success, negative value otherwise.
1568+ */
1569+static int ccs_socket_shutdown(struct socket *sock, int how)
1570+{
1571+ int rc = ccs_validate_socket(sock);
1572+ if (rc < 0)
1573+ return rc;
1574+ while (!original_security_ops.socket_shutdown)
1575+ smp_rmb();
1576+ return original_security_ops.socket_shutdown(sock, how);
1577+}
1578+
1579+#define SOCKFS_MAGIC 0x534F434B
1580+
1581+/**
1582+ * ccs_inode_free_security - Release memory associated with an inode.
1583+ *
1584+ * @inode: Pointer to "struct inode".
1585+ *
1586+ * Returns nothing.
1587+ *
1588+ * We use this hook for releasing memory associated with an accept()ed socket.
1589+ */
1590+static void ccs_inode_free_security(struct inode *inode)
1591+{
1592+ while (!original_security_ops.inode_free_security)
1593+ smp_rmb();
1594+ original_security_ops.inode_free_security(inode);
1595+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1596+ ccs_update_socket_tag(inode, 0);
1597+}
1598+
1599+#endif
1600+
1601+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
1602+
1603+/**
1604+ * ccs_sb_pivotroot - Check permission for pivot_root().
1605+ *
1606+ * @old_path: Pointer to "struct path".
1607+ * @new_path: Pointer to "struct path".
1608+ *
1609+ * Returns 0 on success, negative value otherwise.
1610+ */
1611+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1612+{
1613+ int rc = ccs_pivot_root_permission(old_path, new_path);
1614+ if (rc)
1615+ return rc;
1616+ while (!original_security_ops.sb_pivotroot)
1617+ smp_rmb();
1618+ return original_security_ops.sb_pivotroot(old_path, new_path);
1619+}
1620+
1621+/**
1622+ * ccs_sb_mount - Check permission for mount().
1623+ *
1624+ * @dev_name: Name of device file.
1625+ * @path: Pointer to "struct path".
1626+ * @type: Name of filesystem type. Maybe NULL.
1627+ * @flags: Mount options.
1628+ * @data_page: Optional data. Maybe NULL.
1629+ *
1630+ * Returns 0 on success, negative value otherwise.
1631+ */
1632+static int ccs_sb_mount(char *dev_name, struct path *path, char *type,
1633+ unsigned long flags, void *data_page)
1634+{
1635+ int rc = ccs_mount_permission(dev_name, path, type, flags, data_page);
1636+ if (rc)
1637+ return rc;
1638+ while (!original_security_ops.sb_mount)
1639+ smp_rmb();
1640+ return original_security_ops.sb_mount(dev_name, path, type, flags,
1641+ data_page);
1642+}
1643+
1644+#else
1645+
1646+/**
1647+ * ccs_sb_pivotroot - Check permission for pivot_root().
1648+ *
1649+ * @old_path: Pointer to "struct path".
1650+ * @new_path: Pointer to "struct path".
1651+ *
1652+ * Returns 0 on success, negative value otherwise.
1653+ */
1654+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1655+{
1656+ int rc = ccs_pivot_root_permission(old_path, new_path);
1657+ if (rc)
1658+ return rc;
1659+ while (!original_security_ops.sb_pivotroot)
1660+ smp_rmb();
1661+ return original_security_ops.sb_pivotroot(old_path, new_path);
1662+}
1663+
1664+/**
1665+ * ccs_sb_mount - Check permission for mount().
1666+ *
1667+ * @dev_name: Name of device file.
1668+ * @path: Pointer to "struct path".
1669+ * @type: Name of filesystem type. Maybe NULL.
1670+ * @flags: Mount options.
1671+ * @data_page: Optional data. Maybe NULL.
1672+ *
1673+ * Returns 0 on success, negative value otherwise.
1674+ */
1675+static int ccs_sb_mount(const char *dev_name, struct path *path,
1676+ const char *type, unsigned long flags, void *data_page)
1677+{
1678+ int rc = ccs_mount_permission(dev_name, path, type, flags, data_page);
1679+ if (rc)
1680+ return rc;
1681+ while (!original_security_ops.sb_mount)
1682+ smp_rmb();
1683+ return original_security_ops.sb_mount(dev_name, path, type, flags,
1684+ data_page);
1685+}
1686+
1687+#endif
1688+
1689+/**
1690+ * ccs_sb_umount - Check permission for umount().
1691+ *
1692+ * @mnt: Pointer to "struct vfsmount".
1693+ * @flags: Unmount flags.
1694+ *
1695+ * Returns 0 on success, negative value otherwise.
1696+ */
1697+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1698+{
1699+ int rc = ccs_umount_permission(mnt, flags);
1700+ if (rc)
1701+ return rc;
1702+ while (!original_security_ops.sb_umount)
1703+ smp_rmb();
1704+ return original_security_ops.sb_umount(mnt, flags);
1705+}
1706+
1707+/**
1708+ * ccs_file_fcntl - Check permission for fcntl().
1709+ *
1710+ * @file: Pointer to "struct file".
1711+ * @cmd: Command number.
1712+ * @arg: Value for @cmd.
1713+ *
1714+ * Returns 0 on success, negative value otherwise.
1715+ */
1716+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1717+ unsigned long arg)
1718+{
1719+ int rc = ccs_fcntl_permission(file, cmd, arg);
1720+ if (rc)
1721+ return rc;
1722+ while (!original_security_ops.file_fcntl)
1723+ smp_rmb();
1724+ return original_security_ops.file_fcntl(file, cmd, arg);
1725+}
1726+
1727+/**
1728+ * ccs_file_ioctl - Check permission for ioctl().
1729+ *
1730+ * @filp: Pointer to "struct file".
1731+ * @cmd: Command number.
1732+ * @arg: Value for @cmd.
1733+ *
1734+ * Returns 0 on success, negative value otherwise.
1735+ */
1736+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1737+ unsigned long arg)
1738+{
1739+ int rc = ccs_ioctl_permission(filp, cmd, arg);
1740+ if (rc)
1741+ return rc;
1742+ while (!original_security_ops.file_ioctl)
1743+ smp_rmb();
1744+ return original_security_ops.file_ioctl(filp, cmd, arg);
1745+}
1746+
1747+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL)
1748+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
1749+ const struct ccs_path_info *filename);
1750+
1751+/**
1752+ * ccs_prepend - Copy of prepend() in fs/dcache.c.
1753+ *
1754+ * @buffer: Pointer to "struct char *".
1755+ * @buflen: Pointer to int which holds size of @buffer.
1756+ * @str: String to copy.
1757+ *
1758+ * Returns 0 on success, negative value otherwise.
1759+ *
1760+ * @buffer and @buflen are updated upon success.
1761+ */
1762+static int ccs_prepend(char **buffer, int *buflen, const char *str)
1763+{
1764+ int namelen = strlen(str);
1765+ if (*buflen < namelen)
1766+ return -ENOMEM;
1767+ *buflen -= namelen;
1768+ *buffer -= namelen;
1769+ memcpy(*buffer, str, namelen);
1770+ return 0;
1771+}
1772+
1773+/**
1774+ * ccs_sysctl_permission - Check permission for sysctl().
1775+ *
1776+ * @table: Pointer to "struct ctl_table".
1777+ * @op: Operation. (MAY_READ and/or MAY_WRITE)
1778+ *
1779+ * Returns 0 on success, negative value otherwise.
1780+ */
1781+static int ccs_sysctl(struct ctl_table *table, int op)
1782+{
1783+ int error;
1784+ struct ccs_path_info buf;
1785+ struct ccs_request_info r;
1786+ int buflen;
1787+ char *buffer;
1788+ int idx;
1789+ while (!original_security_ops.sysctl)
1790+ smp_rmb();
1791+ error = original_security_ops.sysctl(table, op);
1792+ if (error)
1793+ return error;
1794+ op &= MAY_READ | MAY_WRITE;
1795+ if (!op)
1796+ return 0;
1797+ buffer = NULL;
1798+ buf.name = NULL;
1799+ idx = ccs_read_lock();
1800+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
1801+ == CCS_CONFIG_DISABLED)
1802+ goto out;
1803+ error = -ENOMEM;
1804+ buflen = 4096;
1805+ buffer = kmalloc(buflen, CCS_GFP_FLAGS);
1806+ if (buffer) {
1807+ char *end = buffer + buflen;
1808+ *--end = '\0';
1809+ buflen--;
1810+ while (table) {
1811+ char num[32];
1812+ const char *sp = table->procname;
1813+ if (!sp) {
1814+ memset(num, 0, sizeof(num));
1815+ snprintf(num, sizeof(num) - 1, "=%d=",
1816+ table->ctl_name);
1817+ sp = num;
1818+ }
1819+ if (ccs_prepend(&end, &buflen, sp) ||
1820+ ccs_prepend(&end, &buflen, "/"))
1821+ goto out;
1822+ table = table->parent;
1823+ }
1824+ if (ccs_prepend(&end, &buflen, "proc:/sys"))
1825+ goto out;
1826+ buf.name = ccs_encode(end);
1827+ }
1828+ if (buf.name) {
1829+ ccs_fill_path_info(&buf);
1830+ if (op & MAY_READ)
1831+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
1832+ else
1833+ error = 0;
1834+ if (!error && (op & MAY_WRITE))
1835+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
1836+ }
1837+out:
1838+ ccs_read_unlock(idx);
1839+ kfree(buf.name);
1840+ kfree(buffer);
1841+ return error;
1842+}
1843+
1844+#endif
1845+
1846+/*
1847+ * Why not to copy all operations by "original_security_ops = *ops" ?
1848+ * Because copying byte array is not atomic. Reader checks
1849+ * original_security_ops.op != NULL before doing original_security_ops.op().
1850+ * Thus, modifying original_security_ops.op has to be atomic.
1851+ */
1852+#define swap_security_ops(op) \
1853+ original_security_ops.op = ops->op; smp_wmb(); ops->op = ccs_##op;
1854+
1855+/**
1856+ * ccs_update_security_ops - Overwrite original "struct security_operations".
1857+ *
1858+ * @ops: Pointer to "struct security_operations".
1859+ *
1860+ * Returns nothing.
1861+ */
1862+static void __init ccs_update_security_ops(struct security_operations *ops)
1863+{
1864+ /* Security context allocator. */
1865+ swap_security_ops(task_create);
1866+ swap_security_ops(cred_prepare);
1867+ swap_security_ops(cred_free);
1868+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1869+ swap_security_ops(cred_alloc_blank);
1870+ swap_security_ops(cred_transfer);
1871+#endif
1872+ /* Security context updater for successful execve(). */
1873+ swap_security_ops(bprm_check_security);
1874+ swap_security_ops(bprm_committing_creds);
1875+ /* Various permission checker. */
1876+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1877+ swap_security_ops(file_open);
1878+#else
1879+ swap_security_ops(dentry_open);
1880+#endif
1881+ swap_security_ops(file_fcntl);
1882+ swap_security_ops(file_ioctl);
1883+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL)
1884+ swap_security_ops(sysctl);
1885+#endif
1886+ swap_security_ops(sb_pivotroot);
1887+ swap_security_ops(sb_mount);
1888+ swap_security_ops(sb_umount);
1889+#if defined(CONFIG_SECURITY_PATH)
1890+ swap_security_ops(path_mknod);
1891+ swap_security_ops(path_mkdir);
1892+ swap_security_ops(path_rmdir);
1893+ swap_security_ops(path_unlink);
1894+ swap_security_ops(path_symlink);
1895+ swap_security_ops(path_rename);
1896+ swap_security_ops(path_link);
1897+ swap_security_ops(path_truncate);
1898+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
1899+ swap_security_ops(path_chmod);
1900+ swap_security_ops(path_chown);
1901+ swap_security_ops(path_chroot);
1902+#endif
1903+#else
1904+ swap_security_ops(inode_mknod);
1905+ swap_security_ops(inode_mkdir);
1906+ swap_security_ops(inode_rmdir);
1907+ swap_security_ops(inode_unlink);
1908+ swap_security_ops(inode_symlink);
1909+ swap_security_ops(inode_rename);
1910+ swap_security_ops(inode_link);
1911+ swap_security_ops(inode_create);
1912+#endif
1913+ swap_security_ops(inode_setattr);
1914+ swap_security_ops(inode_getattr);
1915+#ifdef CONFIG_SECURITY_NETWORK
1916+ swap_security_ops(socket_bind);
1917+ swap_security_ops(socket_connect);
1918+ swap_security_ops(socket_listen);
1919+ swap_security_ops(socket_sendmsg);
1920+ swap_security_ops(socket_recvmsg);
1921+ swap_security_ops(socket_getsockname);
1922+ swap_security_ops(socket_getpeername);
1923+ swap_security_ops(socket_getsockopt);
1924+ swap_security_ops(socket_setsockopt);
1925+ swap_security_ops(socket_shutdown);
1926+ swap_security_ops(socket_accept);
1927+ swap_security_ops(inode_free_security);
1928+#endif
1929+}
1930+
1931+#undef swap_security_ops
1932+
1933+/**
1934+ * ccs_init - Initialize this module.
1935+ *
1936+ * Returns 0 on success, negative value otherwise.
1937+ */
1938+static int __init ccs_init(void)
1939+{
1940+ struct security_operations *ops = probe_security_ops();
1941+ if (!ops)
1942+ goto out;
1943+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1944+ if (!ccsecurity_exports.find_task_by_vpid)
1945+ goto out;
1946+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1947+ if (!ccsecurity_exports.find_task_by_pid_ns)
1948+ goto out;
1949+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
1950+ ccsecurity_exports.vfsmount_lock = probe_vfsmount_lock();
1951+ if (!ccsecurity_exports.vfsmount_lock)
1952+ goto out;
1953+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
1954+ ccsecurity_exports.__d_path = probe___d_path();
1955+ if (!ccsecurity_exports.__d_path)
1956+ goto out;
1957+#else
1958+ ccsecurity_exports.d_absolute_path = probe_d_absolute_path();
1959+ if (!ccsecurity_exports.d_absolute_path)
1960+ goto out;
1961+#endif
1962+ {
1963+ int idx;
1964+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1965+ INIT_LIST_HEAD(&ccs_cred_security_list[idx]);
1966+ INIT_LIST_HEAD(&ccs_task_security_list[idx]);
1967+ }
1968+ }
1969+ ccs_main_init();
1970+ ccs_update_security_ops(ops);
1971+ printk(KERN_INFO "AKARI: 1.0.39 2019/08/20\n");
1972+ printk(KERN_INFO
1973+ "Access Keeping And Regulating Instrument registered.\n");
1974+ return 0;
1975+out:
1976+ return -EINVAL;
1977+}
1978+
1979+module_init(ccs_init);
1980+MODULE_LICENSE("GPL");
1981+
1982+/**
1983+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1984+ *
1985+ * @domain: Pointer to "struct ccs_domain_info".
1986+ *
1987+ * Returns true if @domain is in use, false otherwise.
1988+ *
1989+ * Caller holds rcu_read_lock().
1990+ */
1991+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1992+{
1993+ int idx;
1994+ struct ccs_security *ptr;
1995+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1996+ struct list_head *list = &ccs_cred_security_list[idx];
1997+ list_for_each_entry_rcu(ptr, list, list) {
1998+ struct ccs_execve *ee = ptr->ee;
1999+ if (ptr->ccs_domain_info == domain ||
2000+ (ee && ee->previous_domain == domain)) {
2001+ return true;
2002+ }
2003+ }
2004+ }
2005+ return false;
2006+}
2007+
2008+/**
2009+ * ccs_add_task_security - Add "struct ccs_security" to list.
2010+ *
2011+ * @ptr: Pointer to "struct ccs_security".
2012+ * @list: Pointer to "struct list_head".
2013+ *
2014+ * Returns nothing.
2015+ */
2016+static void ccs_add_task_security(struct ccs_security *ptr,
2017+ struct list_head *list)
2018+{
2019+ unsigned long flags;
2020+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
2021+ list_add_rcu(&ptr->list, list);
2022+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
2023+}
2024+
2025+/**
2026+ * ccs_find_task_security - Find "struct ccs_security" for given task.
2027+ *
2028+ * @task: Pointer to "struct task_struct".
2029+ *
2030+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
2031+ * out of memory, &ccs_default_security otherwise.
2032+ *
2033+ * If @task is current thread and "struct ccs_security" for current thread was
2034+ * not found, I try to allocate it. But if allocation failed, current thread
2035+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
2036+ * won't work.
2037+ */
2038+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
2039+{
2040+ struct ccs_security *ptr;
2041+ struct list_head *list = &ccs_task_security_list
2042+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
2043+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
2044+ while (!list->next)
2045+ smp_rmb();
2046+ rcu_read_lock();
2047+ list_for_each_entry_rcu(ptr, list, list) {
2048+ if (ptr->pid != task->pids[PIDTYPE_PID].pid)
2049+ continue;
2050+ rcu_read_unlock();
2051+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
2052+ /*
2053+ * Current thread needs to transit from old domain to new
2054+ * domain before do_execve() succeeds in order to check
2055+ * permission for interpreters and environment variables using
2056+ * new domain's ACL rules. The domain transition has to be
2057+ * visible from other CPU in order to allow interactive
2058+ * enforcing mode. Also, the domain transition has to be
2059+ * reverted if do_execve() failed. However, an LSM hook for
2060+ * reverting domain transition is missing.
2061+ *
2062+ * security_prepare_creds() is called from prepare_creds() from
2063+ * prepare_bprm_creds() from do_execve() before setting
2064+ * current->in_execve flag, and current->in_execve flag is
2065+ * cleared by the time next do_execve() request starts.
2066+ * This means that we can emulate the missing LSM hook for
2067+ * reverting domain transition, by calling this function from
2068+ * security_prepare_creds().
2069+ *
2070+ * If current->in_execve is not set but ptr->ccs_flags has
2071+ * CCS_TASK_IS_IN_EXECVE set, it indicates that do_execve()
2072+ * has failed and reverting domain transition is needed.
2073+ */
2074+ if (task == current &&
2075+ (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE) &&
2076+ !current->in_execve) {
2077+ ccs_debug_trace("4");
2078+ ccs_clear_execve(-1, ptr);
2079+ }
2080+#else
2081+ /*
2082+ * Current thread needs to transit from old domain to new
2083+ * domain before do_execve() succeeds in order to check
2084+ * permission for interpreters and environment variables using
2085+ * new domain's ACL rules. The domain transition has to be
2086+ * visible from other CPU in order to allow interactive
2087+ * enforcing mode. Also, the domain transition has to be
2088+ * reverted if do_execve() failed. However, an LSM hook for
2089+ * reverting domain transition is missing.
2090+ *
2091+ * When do_execve() failed, "struct cred" in
2092+ * "struct linux_binprm" is scheduled for destruction.
2093+ * But current thread returns to userspace without waiting for
2094+ * destruction. The security_cred_free() LSM hook is called
2095+ * after an RCU grace period has elapsed. Since some CPU may be
2096+ * doing long long RCU read side critical section, there is
2097+ * no guarantee that security_cred_free() is called before
2098+ * current thread again calls do_execve().
2099+ *
2100+ * To be able to revert domain transition before processing
2101+ * next do_execve() request, current thread gets a refcount on
2102+ * "struct cred" in "struct linux_binprm" and memorizes it.
2103+ * Current thread drops the refcount and forgets it when
2104+ * do_execve() succeeded.
2105+ *
2106+ * Therefore, if current thread hasn't forgotten it and
2107+ * current thread is the last one using that "struct cred",
2108+ * it indicates that do_execve() has failed and reverting
2109+ * domain transition is needed.
2110+ */
2111+ if (task == current && ptr->cred &&
2112+ atomic_read(&ptr->cred->usage) == 1) {
2113+ ccs_debug_trace("4");
2114+ ccs_clear_execve(-1, ptr);
2115+ }
2116+#endif
2117+ return ptr;
2118+ }
2119+ rcu_read_unlock();
2120+ if (task != current) {
2121+ /*
2122+ * If a thread does nothing after fork(), caller will reach
2123+ * here because "struct ccs_security" for that thread is not
2124+ * yet allocated. But that thread is keeping a snapshot of
2125+ * "struct ccs_security" taken as of ccs_task_create()
2126+ * associated with that thread's "struct cred".
2127+ *
2128+ * Since that snapshot will be used as initial data when that
2129+ * thread allocates "struct ccs_security" for that thread, we
2130+ * can return that snapshot rather than &ccs_default_security.
2131+ *
2132+ * Since this function is called by only ccs_select_one() and
2133+ * ccs_read_pid() (via ccs_task_domain() and ccs_task_flags()),
2134+ * it is guaranteed that caller has called rcu_read_lock()
2135+ * (via ccs_tasklist_lock()) before finding this thread and
2136+ * this thread is valid. Therefore, we can do __task_cred(task)
2137+ * like get_robust_list() does.
2138+ */
2139+ return ccs_find_cred_security(__task_cred(task));
2140+ }
2141+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
2142+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
2143+ if (!ptr) {
2144+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
2145+ task->pid);
2146+ send_sig(SIGKILL, current, 0);
2147+ return &ccs_oom_security;
2148+ }
2149+ *ptr = *ccs_find_cred_security(task->cred);
2150+ /* We can shortcut because task == current. */
2151+ ptr->pid = get_pid(((struct task_struct *) task)->
2152+ pids[PIDTYPE_PID].pid);
2153+ ptr->cred = NULL;
2154+ ccs_add_task_security(ptr, list);
2155+ return ptr;
2156+}
2157+
2158+/**
2159+ * ccs_copy_cred_security - Allocate memory for new credentials.
2160+ *
2161+ * @new: Pointer to "struct cred".
2162+ * @old: Pointer to "struct cred".
2163+ * @gfp: Memory allocation flags.
2164+ *
2165+ * Returns 0 on success, negative value otherwise.
2166+ */
2167+static int ccs_copy_cred_security(const struct cred *new,
2168+ const struct cred *old, gfp_t gfp)
2169+{
2170+ struct ccs_security *old_security = ccs_find_cred_security(old);
2171+ struct ccs_security *new_security =
2172+ kzalloc(sizeof(*new_security), gfp);
2173+ if (!new_security)
2174+ return -ENOMEM;
2175+ *new_security = *old_security;
2176+ new_security->cred = new;
2177+ ccs_add_cred_security(new_security);
2178+ return 0;
2179+}
2180+
2181+/**
2182+ * ccs_find_cred_security - Find "struct ccs_security" for given credential.
2183+ *
2184+ * @cred: Pointer to "struct cred".
2185+ *
2186+ * Returns pointer to "struct ccs_security" on success, &ccs_default_security
2187+ * otherwise.
2188+ */
2189+static struct ccs_security *ccs_find_cred_security(const struct cred *cred)
2190+{
2191+ struct ccs_security *ptr;
2192+ struct list_head *list = &ccs_cred_security_list
2193+ [hash_ptr((void *) cred, CCS_TASK_SECURITY_HASH_BITS)];
2194+ rcu_read_lock();
2195+ list_for_each_entry_rcu(ptr, list, list) {
2196+ if (ptr->cred != cred)
2197+ continue;
2198+ rcu_read_unlock();
2199+ return ptr;
2200+ }
2201+ rcu_read_unlock();
2202+ return &ccs_default_security;
2203+}
2204+
2205+/**
2206+ * ccs_task_security_gc - Do garbage collection for "struct task_struct".
2207+ *
2208+ * Returns nothing.
2209+ *
2210+ * Since security_task_free() is missing, I can't release memory associated
2211+ * with "struct task_struct" when a task dies. Therefore, I hold a reference on
2212+ * "struct pid" and runs garbage collection when associated
2213+ * "struct task_struct" has gone.
2214+ */
2215+static void ccs_task_security_gc(void)
2216+{
2217+ static DEFINE_SPINLOCK(lock);
2218+ static atomic_t gc_counter = ATOMIC_INIT(0);
2219+ unsigned int idx;
2220+ /*
2221+ * If some process is doing execve(), try to garbage collection now.
2222+ * We should kfree() memory associated with "struct ccs_security"->ee
2223+ * as soon as execve() has completed in order to compensate for lack of
2224+ * security_bprm_free() and security_task_free() hooks.
2225+ *
2226+ * Otherwise, reduce frequency for performance reason.
2227+ */
2228+ if (!atomic_read(&ccs_in_execve_tasks) &&
2229+ atomic_inc_return(&gc_counter) < 1024)
2230+ return;
2231+ if (!spin_trylock(&lock))
2232+ return;
2233+ atomic_set(&gc_counter, 0);
2234+ rcu_read_lock();
2235+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
2236+ struct ccs_security *ptr;
2237+ struct list_head *list = &ccs_task_security_list[idx];
2238+ list_for_each_entry_rcu(ptr, list, list) {
2239+ if (pid_task(ptr->pid, PIDTYPE_PID))
2240+ continue;
2241+ ccs_del_security(ptr);
2242+ }
2243+ }
2244+ rcu_read_unlock();
2245+ spin_unlock(&lock);
2246+}
--- tags/patches/1.0.39/lsm-4.12.c (nonexistent)
+++ tags/patches/1.0.39/lsm-4.12.c (revision 612)
@@ -0,0 +1,1376 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.39 2019/08/20
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+static int __ccs_alloc_task_security(const struct task_struct *task);
14+static void __ccs_free_task_security(const struct task_struct *task);
15+
16+/* Dummy security context for avoiding NULL pointer dereference. */
17+static struct ccs_security ccs_oom_security = {
18+ .ccs_domain_info = &ccs_kernel_domain
19+};
20+
21+/* Dummy security context for avoiding NULL pointer dereference. */
22+static struct ccs_security ccs_default_security = {
23+ .ccs_domain_info = &ccs_kernel_domain
24+};
25+
26+/* List of "struct ccs_security". */
27+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
28+/* Lock for protecting ccs_task_security_list[]. */
29+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
30+
31+/* For exporting variables and functions. */
32+struct ccsecurity_exports ccsecurity_exports;
33+/* Members are updated by loadable kernel module. */
34+struct ccsecurity_operations ccsecurity_ops;
35+
36+/* Original hooks. */
37+static union security_list_options original_cred_prepare;
38+static union security_list_options original_task_alloc;
39+static union security_list_options original_task_free;
40+
41+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
42+
43+/**
44+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
45+ *
46+ * @count: Count to increment or decrement.
47+ *
48+ * Returns updated counter.
49+ */
50+static unsigned int ccs_update_ee_counter(int count)
51+{
52+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
53+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
54+ return atomic_add_return(count, &ccs_ee_counter);
55+}
56+
57+/**
58+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
59+ *
60+ * @ee: Pointer to "struct ccs_execve".
61+ *
62+ * Returns nothing.
63+ */
64+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
65+{
66+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
67+ current->pid, ccs_update_ee_counter(1) - 1);
68+}
69+
70+/**
71+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
72+ *
73+ * @ee: Pointer to "struct ccs_execve".
74+ * @task: True if released by current task, false otherwise.
75+ *
76+ * Returns nothing.
77+ */
78+void ccs_audit_free_execve(const struct ccs_execve * const ee,
79+ const bool is_current)
80+{
81+ const unsigned int tmp = ccs_update_ee_counter(-1);
82+ if (is_current)
83+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
84+ ee, current->pid, tmp);
85+ else
86+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
87+ ee, tmp);
88+}
89+
90+#endif
91+
92+#if !defined(CONFIG_AKARI_DEBUG)
93+#define ccs_debug_trace(pos) do { } while (0)
94+#else
95+#define ccs_debug_trace(pos) \
96+ do { \
97+ static bool done; \
98+ if (!done) { \
99+ printk(KERN_INFO \
100+ "AKARI: Debug trace: " pos " of 2\n"); \
101+ done = true; \
102+ } \
103+ } while (0)
104+#endif
105+
106+/**
107+ * ccs_clear_execve - Release memory used by do_execve().
108+ *
109+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
110+ * @security: Pointer to "struct ccs_security".
111+ *
112+ * Returns nothing.
113+ */
114+static void ccs_clear_execve(int ret, struct ccs_security *security)
115+{
116+ struct ccs_execve *ee = security->ee;
117+ if (security == &ccs_default_security || security == &ccs_oom_security
118+ || !ee)
119+ return;
120+ security->ee = NULL;
121+ ccs_finish_execve(ret, ee);
122+}
123+
124+/**
125+ * ccs_task_alloc_security - Allocate memory for new tasks.
126+ *
127+ * @p: Pointer to "struct task_struct".
128+ * @clone_flags: Flags passed to clone().
129+ *
130+ * Returns 0 on success, negative value otherwise.
131+ */
132+static int ccs_task_alloc_security(struct task_struct *p,
133+ unsigned long clone_flags)
134+{
135+ int rc = __ccs_alloc_task_security(p);
136+ if (rc)
137+ return rc;
138+ if (original_task_alloc.task_alloc) {
139+ rc = original_task_alloc.task_alloc(p, clone_flags);
140+ if (rc)
141+ __ccs_free_task_security(p);
142+ }
143+ return rc;
144+}
145+
146+/**
147+ * ccs_task_free_security - Release memory for "struct task_struct".
148+ *
149+ * @p: Pointer to "struct task_struct".
150+ *
151+ * Returns nothing.
152+ */
153+static void ccs_task_free_security(struct task_struct *p)
154+{
155+ struct ccs_security *ptr = ccs_find_task_security(p);
156+ struct ccs_execve *ee = ptr->ee;
157+ if (original_task_free.task_free)
158+ original_task_free.task_free(p);
159+ /*
160+ * Since an LSM hook for reverting domain transition is missing,
161+ * ccs_finish_execve() is not called if exited immediately after
162+ * execve() failed.
163+ */
164+ if (ee) {
165+ ccs_debug_trace("2");
166+ ccs_audit_free_execve(ee, false);
167+ kfree(ee->handler_path);
168+ kfree(ee);
169+ ptr->ee = NULL;
170+ }
171+ __ccs_free_task_security(p);
172+}
173+
174+/**
175+ * ccs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
176+ *
177+ * @bprm: Pointer to "struct linux_binprm".
178+ *
179+ * Returns nothing.
180+ */
181+static void ccs_bprm_committing_creds(struct linux_binprm *bprm)
182+{
183+ ccs_clear_execve(0, ccs_current_security());
184+}
185+
186+/**
187+ * ccs_cred_prepare - Allocate memory for new credentials.
188+ *
189+ * @new: Pointer to "struct cred".
190+ * @old: Pointer to "struct cred".
191+ * @gfp: Memory allocation flags.
192+ *
193+ * Returns 0 on success, negative value otherwise.
194+ */
195+static int ccs_cred_prepare(struct cred *new, const struct cred *old,
196+ gfp_t gfp)
197+{
198+ /*
199+ * For checking whether reverting domain transition is needed or not.
200+ *
201+ * See ccs_find_task_security() for reason.
202+ */
203+ if (gfp == GFP_KERNEL)
204+ ccs_find_task_security(current);
205+ if (original_cred_prepare.cred_prepare)
206+ return original_cred_prepare.cred_prepare(new, old, gfp);
207+ return 0;
208+}
209+
210+/**
211+ * ccs_bprm_check_security - Check permission for execve().
212+ *
213+ * @bprm: Pointer to "struct linux_binprm".
214+ *
215+ * Returns 0 on success, negative value otherwise.
216+ */
217+static int ccs_bprm_check_security(struct linux_binprm *bprm)
218+{
219+ struct ccs_security *security = ccs_current_security();
220+ if (security == &ccs_default_security || security == &ccs_oom_security)
221+ return -ENOMEM;
222+ if (security->ee)
223+ return 0;
224+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
225+ if (!ccs_policy_loaded)
226+ ccs_load_policy(bprm->filename);
227+#endif
228+ return ccs_start_execve(bprm, &security->ee);
229+}
230+
231+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
232+/**
233+ * ccs_file_open - Check permission for open().
234+ *
235+ * @f: Pointer to "struct file".
236+ *
237+ * Returns 0 on success, negative value otherwise.
238+ */
239+static int ccs_file_open(struct file *f)
240+{
241+ return ccs_open_permission(f);
242+}
243+#else
244+/**
245+ * ccs_file_open - Check permission for open().
246+ *
247+ * @f: Pointer to "struct file".
248+ * @cred: Pointer to "struct cred".
249+ *
250+ * Returns 0 on success, negative value otherwise.
251+ */
252+static int ccs_file_open(struct file *f, const struct cred *cred)
253+{
254+ return ccs_open_permission(f);
255+}
256+#endif
257+
258+#ifdef CONFIG_SECURITY_PATH
259+
260+/**
261+ * ccs_path_chown - Check permission for chown()/chgrp().
262+ *
263+ * @path: Pointer to "struct path".
264+ * @user: User ID.
265+ * @group: Group ID.
266+ *
267+ * Returns 0 on success, negative value otherwise.
268+ */
269+static int ccs_path_chown(const struct path *path, kuid_t user, kgid_t group)
270+{
271+ return ccs_chown_permission(path->dentry, path->mnt, user, group);
272+}
273+
274+/**
275+ * ccs_path_chmod - Check permission for chmod().
276+ *
277+ * @path: Pointer to "struct path".
278+ * @mode: Mode.
279+ *
280+ * Returns 0 on success, negative value otherwise.
281+ */
282+static int ccs_path_chmod(const struct path *path, umode_t mode)
283+{
284+ return ccs_chmod_permission(path->dentry, path->mnt, mode);
285+}
286+
287+/**
288+ * ccs_path_chroot - Check permission for chroot().
289+ *
290+ * @path: Pointer to "struct path".
291+ *
292+ * Returns 0 on success, negative value otherwise.
293+ */
294+static int ccs_path_chroot(const struct path *path)
295+{
296+ return ccs_chroot_permission(path);
297+}
298+
299+/**
300+ * ccs_path_truncate - Check permission for truncate().
301+ *
302+ * @path: Pointer to "struct path".
303+ *
304+ * Returns 0 on success, negative value otherwise.
305+ */
306+static int ccs_path_truncate(const struct path *path)
307+{
308+ return ccs_truncate_permission(path->dentry, path->mnt);
309+}
310+
311+#else
312+
313+/**
314+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
315+ *
316+ * @dentry: Pointer to "struct dentry".
317+ * @attr: Pointer to "struct iattr".
318+ *
319+ * Returns 0 on success, negative value otherwise.
320+ */
321+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
322+{
323+ const int rc1 = (attr->ia_valid & ATTR_UID) ?
324+ ccs_chown_permission(dentry, NULL, attr->ia_uid, INVALID_GID) :
325+ 0;
326+ const int rc2 = (attr->ia_valid & ATTR_GID) ?
327+ ccs_chown_permission(dentry, NULL, INVALID_UID, attr->ia_gid) :
328+ 0;
329+ const int rc3 = (attr->ia_valid & ATTR_MODE) ?
330+ ccs_chmod_permission(dentry, NULL, attr->ia_mode) : 0;
331+ const int rc4 = (attr->ia_valid & ATTR_SIZE) ?
332+ ccs_truncate_permission(dentry, NULL) : 0;
333+ if (rc4)
334+ return rc4;
335+ if (rc3)
336+ return rc3;
337+ if (rc2)
338+ return rc2;
339+ return rc1;
340+}
341+
342+#endif
343+
344+/**
345+ * ccs_inode_getattr - Check permission for stat().
346+ *
347+ * @path: Pointer to "struct path".
348+ *
349+ * Returns 0 on success, negative value otherwise.
350+ */
351+static int ccs_inode_getattr(const struct path *path)
352+{
353+ return ccs_getattr_permission(path->mnt, path->dentry);
354+}
355+
356+#ifdef CONFIG_SECURITY_PATH
357+
358+/**
359+ * ccs_path_mknod - Check permission for mknod().
360+ *
361+ * @dir: Pointer to "struct path".
362+ * @dentry: Pointer to "struct dentry".
363+ * @mode: Create mode.
364+ * @dev: Device major/minor number.
365+ *
366+ * Returns 0 on success, negative value otherwise.
367+ */
368+static int ccs_path_mknod(const struct path *dir, struct dentry *dentry,
369+ umode_t mode, unsigned int dev)
370+{
371+ return ccs_mknod_permission(dentry, dir->mnt, mode, dev);
372+}
373+
374+/**
375+ * ccs_path_mkdir - Check permission for mkdir().
376+ *
377+ * @dir: Pointer to "struct path".
378+ * @dentry: Pointer to "struct dentry".
379+ * @mode: Create mode.
380+ *
381+ * Returns 0 on success, negative value otherwise.
382+ */
383+static int ccs_path_mkdir(const struct path *dir, struct dentry *dentry,
384+ umode_t mode)
385+{
386+ return ccs_mkdir_permission(dentry, dir->mnt, mode);
387+}
388+
389+/**
390+ * ccs_path_rmdir - Check permission for rmdir().
391+ *
392+ * @dir: Pointer to "struct path".
393+ * @dentry: Pointer to "struct dentry".
394+ *
395+ * Returns 0 on success, negative value otherwise.
396+ */
397+static int ccs_path_rmdir(const struct path *dir, struct dentry *dentry)
398+{
399+ return ccs_rmdir_permission(dentry, dir->mnt);
400+}
401+
402+/**
403+ * ccs_path_unlink - Check permission for unlink().
404+ *
405+ * @dir: Pointer to "struct path".
406+ * @dentry: Pointer to "struct dentry".
407+ *
408+ * Returns 0 on success, negative value otherwise.
409+ */
410+static int ccs_path_unlink(const struct path *dir, struct dentry *dentry)
411+{
412+ return ccs_unlink_permission(dentry, dir->mnt);
413+}
414+
415+/**
416+ * ccs_path_symlink - Check permission for symlink().
417+ *
418+ * @dir: Pointer to "struct path".
419+ * @dentry: Pointer to "struct dentry".
420+ * @old_name: Content of symbolic link.
421+ *
422+ * Returns 0 on success, negative value otherwise.
423+ */
424+static int ccs_path_symlink(const struct path *dir, struct dentry *dentry,
425+ const char *old_name)
426+{
427+ return ccs_symlink_permission(dentry, dir->mnt, old_name);
428+}
429+
430+/**
431+ * ccs_path_rename - Check permission for rename().
432+ *
433+ * @old_dir: Pointer to "struct path".
434+ * @old_dentry: Pointer to "struct dentry".
435+ * @new_dir: Pointer to "struct path".
436+ * @new_dentry: Pointer to "struct dentry".
437+ *
438+ * Returns 0 on success, negative value otherwise.
439+ */
440+static int ccs_path_rename(const struct path *old_dir,
441+ struct dentry *old_dentry,
442+ const struct path *new_dir,
443+ struct dentry *new_dentry)
444+{
445+ return ccs_rename_permission(old_dentry, new_dentry, old_dir->mnt);
446+}
447+
448+/**
449+ * ccs_path_link - Check permission for link().
450+ *
451+ * @old_dentry: Pointer to "struct dentry".
452+ * @new_dir: Pointer to "struct path".
453+ * @new_dentry: Pointer to "struct dentry".
454+ *
455+ * Returns 0 on success, negative value otherwise.
456+ */
457+static int ccs_path_link(struct dentry *old_dentry, const struct path *new_dir,
458+ struct dentry *new_dentry)
459+{
460+ return ccs_link_permission(old_dentry, new_dentry, new_dir->mnt);
461+}
462+
463+#else
464+
465+/**
466+ * ccs_inode_mknod - Check permission for mknod().
467+ *
468+ * @dir: Pointer to "struct inode".
469+ * @dentry: Pointer to "struct dentry".
470+ * @mode: Create mode.
471+ * @dev: Device major/minor number.
472+ *
473+ * Returns 0 on success, negative value otherwise.
474+ */
475+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
476+ umode_t mode, dev_t dev)
477+{
478+ return ccs_mknod_permission(dentry, NULL, mode, dev);
479+}
480+
481+/**
482+ * ccs_inode_mkdir - Check permission for mkdir().
483+ *
484+ * @dir: Pointer to "struct inode".
485+ * @dentry: Pointer to "struct dentry".
486+ * @mode: Create mode.
487+ *
488+ * Returns 0 on success, negative value otherwise.
489+ */
490+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
491+ umode_t mode)
492+{
493+ return ccs_mkdir_permission(dentry, NULL, mode);
494+}
495+
496+/**
497+ * ccs_inode_rmdir - Check permission for rmdir().
498+ *
499+ * @dir: Pointer to "struct inode".
500+ * @dentry: Pointer to "struct dentry".
501+ *
502+ * Returns 0 on success, negative value otherwise.
503+ */
504+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry)
505+{
506+ return ccs_rmdir_permission(dentry, NULL);
507+}
508+
509+/**
510+ * ccs_inode_unlink - Check permission for unlink().
511+ *
512+ * @dir: Pointer to "struct inode".
513+ * @dentry: Pointer to "struct dentry".
514+ *
515+ * Returns 0 on success, negative value otherwise.
516+ */
517+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
518+{
519+ return ccs_unlink_permission(dentry, NULL);
520+}
521+
522+/**
523+ * ccs_inode_symlink - Check permission for symlink().
524+ *
525+ * @dir: Pointer to "struct inode".
526+ * @dentry: Pointer to "struct dentry".
527+ * @old_name: Content of symbolic link.
528+ *
529+ * Returns 0 on success, negative value otherwise.
530+ */
531+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
532+ const char *old_name)
533+{
534+ return ccs_symlink_permission(dentry, NULL, old_name);
535+}
536+
537+/**
538+ * ccs_inode_rename - Check permission for rename().
539+ *
540+ * @old_dir: Pointer to "struct inode".
541+ * @old_dentry: Pointer to "struct dentry".
542+ * @new_dir: Pointer to "struct inode".
543+ * @new_dentry: Pointer to "struct dentry".
544+ *
545+ * Returns 0 on success, negative value otherwise.
546+ */
547+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
548+ struct inode *new_dir, struct dentry *new_dentry)
549+{
550+ return ccs_rename_permission(old_dentry, new_dentry, NULL);
551+}
552+
553+/**
554+ * ccs_inode_link - Check permission for link().
555+ *
556+ * @old_dentry: Pointer to "struct dentry".
557+ * @dir: Pointer to "struct inode".
558+ * @new_dentry: Pointer to "struct dentry".
559+ *
560+ * Returns 0 on success, negative value otherwise.
561+ */
562+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
563+ struct dentry *new_dentry)
564+{
565+ return ccs_link_permission(old_dentry, new_dentry, NULL);
566+}
567+
568+/**
569+ * ccs_inode_create - Check permission for creat().
570+ *
571+ * @dir: Pointer to "struct inode".
572+ * @dentry: Pointer to "struct dentry".
573+ * @mode: Create mode.
574+ *
575+ * Returns 0 on success, negative value otherwise.
576+ */
577+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
578+ umode_t mode)
579+{
580+ return ccs_mknod_permission(dentry, NULL, mode, 0);
581+}
582+
583+#endif
584+
585+#ifdef CONFIG_SECURITY_NETWORK
586+
587+#include <net/sock.h>
588+
589+/* Structure for remembering an accept()ed socket's status. */
590+struct ccs_socket_tag {
591+ struct list_head list;
592+ struct inode *inode;
593+ int status;
594+ struct rcu_head rcu;
595+};
596+
597+/*
598+ * List for managing accept()ed sockets.
599+ * Since we don't need to keep an accept()ed socket into this list after
600+ * once the permission was granted, the number of entries in this list is
601+ * likely small. Therefore, we don't use hash tables.
602+ */
603+static LIST_HEAD(ccs_accepted_socket_list);
604+/* Lock for protecting ccs_accepted_socket_list . */
605+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
606+
607+/**
608+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
609+ *
610+ * @inode: Pointer to "struct inode".
611+ * @status: New status.
612+ *
613+ * Returns nothing.
614+ *
615+ * If @status == 0, memory for that socket will be released after RCU grace
616+ * period.
617+ */
618+static void ccs_update_socket_tag(struct inode *inode, int status)
619+{
620+ struct ccs_socket_tag *ptr;
621+ /*
622+ * Protect whole section because multiple threads may call this
623+ * function with same "sock" via ccs_validate_socket().
624+ */
625+ spin_lock(&ccs_accepted_socket_list_lock);
626+ rcu_read_lock();
627+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
628+ if (ptr->inode != inode)
629+ continue;
630+ ptr->status = status;
631+ if (status)
632+ break;
633+ list_del_rcu(&ptr->list);
634+ kfree_rcu(ptr, rcu);
635+ break;
636+ }
637+ rcu_read_unlock();
638+ spin_unlock(&ccs_accepted_socket_list_lock);
639+}
640+
641+/**
642+ * ccs_validate_socket - Check post accept() permission if needed.
643+ *
644+ * @sock: Pointer to "struct socket".
645+ *
646+ * Returns 0 on success, negative value otherwise.
647+ */
648+static int ccs_validate_socket(struct socket *sock)
649+{
650+ struct inode *inode = SOCK_INODE(sock);
651+ struct ccs_socket_tag *ptr;
652+ int ret = 0;
653+ rcu_read_lock();
654+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
655+ if (ptr->inode != inode)
656+ continue;
657+ ret = ptr->status;
658+ break;
659+ }
660+ rcu_read_unlock();
661+ if (ret <= 0)
662+ /*
663+ * This socket is not an accept()ed socket or this socket is
664+ * an accept()ed socket and post accept() permission is done.
665+ */
666+ return ret;
667+ /*
668+ * Check post accept() permission now.
669+ *
670+ * Strictly speaking, we need to pass both listen()ing socket and
671+ * accept()ed socket to __ccs_socket_post_accept_permission().
672+ * But since socket's family and type are same for both sockets,
673+ * passing the accept()ed socket in place for the listen()ing socket
674+ * will work.
675+ */
676+ ret = ccs_socket_post_accept_permission(sock, sock);
677+ /*
678+ * If permission was granted, we forget that this is an accept()ed
679+ * socket. Otherwise, we remember that this socket needs to return
680+ * error for subsequent socketcalls.
681+ */
682+ ccs_update_socket_tag(inode, ret);
683+ return ret;
684+}
685+
686+/**
687+ * ccs_socket_accept - Check permission for accept().
688+ *
689+ * @sock: Pointer to "struct socket".
690+ * @newsock: Pointer to "struct socket".
691+ *
692+ * Returns 0 on success, negative value otherwise.
693+ *
694+ * This hook is used for setting up environment for doing post accept()
695+ * permission check. If dereferencing sock->ops->something() were ordered by
696+ * rcu_dereference(), we could replace sock->ops with "a copy of original
697+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
698+ * in order to do post accept() permission check before returning to userspace.
699+ * If we make the copy in security_socket_post_create(), it would be possible
700+ * to safely replace sock->ops here, but we don't do so because we don't want
701+ * to allocate memory for sockets which do not call sock->ops->accept().
702+ * Therefore, we do post accept() permission check upon next socket syscalls
703+ * rather than between sock->ops->accept() and returning to userspace.
704+ * This means that if a socket was close()d before calling some socket
705+ * syscalls, post accept() permission check will not be done.
706+ */
707+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
708+{
709+ struct ccs_socket_tag *ptr;
710+ const int rc = ccs_validate_socket(sock);
711+ if (rc < 0)
712+ return rc;
713+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
714+ if (!ptr)
715+ return -ENOMEM;
716+ /*
717+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
718+ * "newsock" as "an accept()ed socket but post accept() permission
719+ * check is not done yet" by allocating memory using inode of the
720+ * "newsock" as a search key.
721+ */
722+ ptr->inode = SOCK_INODE(newsock);
723+ ptr->status = 1; /* Check post accept() permission later. */
724+ spin_lock(&ccs_accepted_socket_list_lock);
725+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
726+ spin_unlock(&ccs_accepted_socket_list_lock);
727+ return 0;
728+}
729+
730+/**
731+ * ccs_socket_listen - Check permission for listen().
732+ *
733+ * @sock: Pointer to "struct socket".
734+ * @backlog: Backlog parameter.
735+ *
736+ * Returns 0 on success, negative value otherwise.
737+ */
738+static int ccs_socket_listen(struct socket *sock, int backlog)
739+{
740+ const int rc = ccs_validate_socket(sock);
741+ if (rc < 0)
742+ return rc;
743+ return ccs_socket_listen_permission(sock);
744+}
745+
746+/**
747+ * ccs_socket_connect - Check permission for connect().
748+ *
749+ * @sock: Pointer to "struct socket".
750+ * @addr: Pointer to "struct sockaddr".
751+ * @addr_len: Size of @addr.
752+ *
753+ * Returns 0 on success, negative value otherwise.
754+ */
755+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
756+ int addr_len)
757+{
758+ const int rc = ccs_validate_socket(sock);
759+ if (rc < 0)
760+ return rc;
761+ return ccs_socket_connect_permission(sock, addr, addr_len);
762+}
763+
764+/**
765+ * ccs_socket_bind - Check permission for bind().
766+ *
767+ * @sock: Pointer to "struct socket".
768+ * @addr: Pointer to "struct sockaddr".
769+ * @addr_len: Size of @addr.
770+ *
771+ * Returns 0 on success, negative value otherwise.
772+ */
773+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
774+ int addr_len)
775+{
776+ const int rc = ccs_validate_socket(sock);
777+ if (rc < 0)
778+ return rc;
779+ return ccs_socket_bind_permission(sock, addr, addr_len);
780+}
781+
782+/**
783+ * ccs_socket_sendmsg - Check permission for sendmsg().
784+ *
785+ * @sock: Pointer to "struct socket".
786+ * @msg: Pointer to "struct msghdr".
787+ * @size: Size of message.
788+ *
789+ * Returns 0 on success, negative value otherwise.
790+ */
791+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
792+ int size)
793+{
794+ const int rc = ccs_validate_socket(sock);
795+ if (rc < 0)
796+ return rc;
797+ return ccs_socket_sendmsg_permission(sock, msg, size);
798+}
799+
800+/**
801+ * ccs_socket_recvmsg - Check permission for recvmsg().
802+ *
803+ * @sock: Pointer to "struct socket".
804+ * @msg: Pointer to "struct msghdr".
805+ * @size: Size of message.
806+ * @flags: Flags.
807+ *
808+ * Returns 0 on success, negative value otherwise.
809+ */
810+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
811+ int size, int flags)
812+{
813+ return ccs_validate_socket(sock);
814+}
815+
816+/**
817+ * ccs_socket_getsockname - Check permission for getsockname().
818+ *
819+ * @sock: Pointer to "struct socket".
820+ *
821+ * Returns 0 on success, negative value otherwise.
822+ */
823+static int ccs_socket_getsockname(struct socket *sock)
824+{
825+ return ccs_validate_socket(sock);
826+}
827+
828+/**
829+ * ccs_socket_getpeername - Check permission for getpeername().
830+ *
831+ * @sock: Pointer to "struct socket".
832+ *
833+ * Returns 0 on success, negative value otherwise.
834+ */
835+static int ccs_socket_getpeername(struct socket *sock)
836+{
837+ return ccs_validate_socket(sock);
838+}
839+
840+/**
841+ * ccs_socket_getsockopt - Check permission for getsockopt().
842+ *
843+ * @sock: Pointer to "struct socket".
844+ * @level: Level.
845+ * @optname: Option's name,
846+ *
847+ * Returns 0 on success, negative value otherwise.
848+ */
849+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
850+{
851+ return ccs_validate_socket(sock);
852+}
853+
854+/**
855+ * ccs_socket_setsockopt - Check permission for setsockopt().
856+ *
857+ * @sock: Pointer to "struct socket".
858+ * @level: Level.
859+ * @optname: Option's name,
860+ *
861+ * Returns 0 on success, negative value otherwise.
862+ */
863+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
864+{
865+ return ccs_validate_socket(sock);
866+}
867+
868+/**
869+ * ccs_socket_shutdown - Check permission for shutdown().
870+ *
871+ * @sock: Pointer to "struct socket".
872+ * @how: Shutdown mode.
873+ *
874+ * Returns 0 on success, negative value otherwise.
875+ */
876+static int ccs_socket_shutdown(struct socket *sock, int how)
877+{
878+ return ccs_validate_socket(sock);
879+}
880+
881+#define SOCKFS_MAGIC 0x534F434B
882+
883+/**
884+ * ccs_inode_free_security - Release memory associated with an inode.
885+ *
886+ * @inode: Pointer to "struct inode".
887+ *
888+ * Returns nothing.
889+ *
890+ * We use this hook for releasing memory associated with an accept()ed socket.
891+ */
892+static void ccs_inode_free_security(struct inode *inode)
893+{
894+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
895+ ccs_update_socket_tag(inode, 0);
896+}
897+
898+#endif
899+
900+/**
901+ * ccs_sb_pivotroot - Check permission for pivot_root().
902+ *
903+ * @old_path: Pointer to "struct path".
904+ * @new_path: Pointer to "struct path".
905+ *
906+ * Returns 0 on success, negative value otherwise.
907+ */
908+static int ccs_sb_pivotroot(const struct path *old_path,
909+ const struct path *new_path)
910+{
911+ return ccs_pivot_root_permission(old_path, new_path);
912+}
913+
914+/**
915+ * ccs_sb_mount - Check permission for mount().
916+ *
917+ * @dev_name: Name of device file.
918+ * @path: Pointer to "struct path".
919+ * @type: Name of filesystem type. Maybe NULL.
920+ * @flags: Mount options.
921+ * @data_page: Optional data. Maybe NULL.
922+ *
923+ * Returns 0 on success, negative value otherwise.
924+ */
925+static int ccs_sb_mount(const char *dev_name, const struct path *path,
926+ const char *type, unsigned long flags, void *data_page)
927+{
928+ return ccs_mount_permission(dev_name, path, type, flags, data_page);
929+}
930+
931+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
932+/**
933+ * ccs_move_mount - Check permission for move_mount() operation.
934+ *
935+ * @from_path: Pointer to "struct path".
936+ * @to_path: Pointer to "struct path".
937+ *
938+ * Returns 0 on success, negative value otherwise.
939+ */
940+static int ccs_move_mount(const struct path *from_path, const struct path *to_path)
941+{
942+ return ccs_move_mount_permission(from_path, to_path);
943+}
944+#endif
945+
946+/**
947+ * ccs_sb_umount - Check permission for umount().
948+ *
949+ * @mnt: Pointer to "struct vfsmount".
950+ * @flags: Unmount flags.
951+ *
952+ * Returns 0 on success, negative value otherwise.
953+ */
954+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
955+{
956+ return ccs_umount_permission(mnt, flags);
957+}
958+
959+/**
960+ * ccs_file_fcntl - Check permission for fcntl().
961+ *
962+ * @file: Pointer to "struct file".
963+ * @cmd: Command number.
964+ * @arg: Value for @cmd.
965+ *
966+ * Returns 0 on success, negative value otherwise.
967+ */
968+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
969+ unsigned long arg)
970+{
971+ return ccs_fcntl_permission(file, cmd, arg);
972+}
973+
974+/**
975+ * ccs_file_ioctl - Check permission for ioctl().
976+ *
977+ * @filp: Pointer to "struct file".
978+ * @cmd: Command number.
979+ * @arg: Value for @cmd.
980+ *
981+ * Returns 0 on success, negative value otherwise.
982+ */
983+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
984+ unsigned long arg)
985+{
986+ return ccs_ioctl_permission(filp, cmd, arg);
987+}
988+
989+#define MY_HOOK_INIT(HEAD, HOOK) \
990+ { .head = &probe_dummy_security_hook_heads.HEAD, \
991+ .hook = { .HEAD = HOOK } }
992+
993+static struct security_hook_list akari_hooks[] = {
994+ /* Security context allocator. */
995+ MY_HOOK_INIT(task_free, ccs_task_free_security),
996+ MY_HOOK_INIT(cred_prepare, ccs_cred_prepare),
997+ MY_HOOK_INIT(task_alloc, ccs_task_alloc_security),
998+ /* Security context updater for successful execve(). */
999+ MY_HOOK_INIT(bprm_check_security, ccs_bprm_check_security),
1000+ MY_HOOK_INIT(bprm_committing_creds, ccs_bprm_committing_creds),
1001+ /* Various permission checker. */
1002+ MY_HOOK_INIT(file_open, ccs_file_open),
1003+ MY_HOOK_INIT(file_fcntl, ccs_file_fcntl),
1004+ MY_HOOK_INIT(file_ioctl, ccs_file_ioctl),
1005+ MY_HOOK_INIT(sb_pivotroot, ccs_sb_pivotroot),
1006+ MY_HOOK_INIT(sb_mount, ccs_sb_mount),
1007+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1008+ MY_HOOK_INIT(move_mount, ccs_move_mount),
1009+#endif
1010+ MY_HOOK_INIT(sb_umount, ccs_sb_umount),
1011+#ifdef CONFIG_SECURITY_PATH
1012+ MY_HOOK_INIT(path_mknod, ccs_path_mknod),
1013+ MY_HOOK_INIT(path_mkdir, ccs_path_mkdir),
1014+ MY_HOOK_INIT(path_rmdir, ccs_path_rmdir),
1015+ MY_HOOK_INIT(path_unlink, ccs_path_unlink),
1016+ MY_HOOK_INIT(path_symlink, ccs_path_symlink),
1017+ MY_HOOK_INIT(path_rename, ccs_path_rename),
1018+ MY_HOOK_INIT(path_link, ccs_path_link),
1019+ MY_HOOK_INIT(path_truncate, ccs_path_truncate),
1020+ MY_HOOK_INIT(path_chmod, ccs_path_chmod),
1021+ MY_HOOK_INIT(path_chown, ccs_path_chown),
1022+ MY_HOOK_INIT(path_chroot, ccs_path_chroot),
1023+#else
1024+ MY_HOOK_INIT(inode_mknod, ccs_inode_mknod),
1025+ MY_HOOK_INIT(inode_mkdir, ccs_inode_mkdir),
1026+ MY_HOOK_INIT(inode_rmdir, ccs_inode_rmdir),
1027+ MY_HOOK_INIT(inode_unlink, ccs_inode_unlink),
1028+ MY_HOOK_INIT(inode_symlink, ccs_inode_symlink),
1029+ MY_HOOK_INIT(inode_rename, ccs_inode_rename),
1030+ MY_HOOK_INIT(inode_link, ccs_inode_link),
1031+ MY_HOOK_INIT(inode_create, ccs_inode_create),
1032+ MY_HOOK_INIT(inode_setattr, ccs_inode_setattr),
1033+#endif
1034+ MY_HOOK_INIT(inode_getattr, ccs_inode_getattr),
1035+#ifdef CONFIG_SECURITY_NETWORK
1036+ MY_HOOK_INIT(socket_bind, ccs_socket_bind),
1037+ MY_HOOK_INIT(socket_connect, ccs_socket_connect),
1038+ MY_HOOK_INIT(socket_listen, ccs_socket_listen),
1039+ MY_HOOK_INIT(socket_sendmsg, ccs_socket_sendmsg),
1040+ MY_HOOK_INIT(socket_recvmsg, ccs_socket_recvmsg),
1041+ MY_HOOK_INIT(socket_getsockname, ccs_socket_getsockname),
1042+ MY_HOOK_INIT(socket_getpeername, ccs_socket_getpeername),
1043+ MY_HOOK_INIT(socket_getsockopt, ccs_socket_getsockopt),
1044+ MY_HOOK_INIT(socket_setsockopt, ccs_socket_setsockopt),
1045+ MY_HOOK_INIT(socket_shutdown, ccs_socket_shutdown),
1046+ MY_HOOK_INIT(socket_accept, ccs_socket_accept),
1047+ MY_HOOK_INIT(inode_free_security, ccs_inode_free_security),
1048+#endif
1049+};
1050+
1051+static inline void add_hook(struct security_hook_list *hook)
1052+{
1053+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1054+ hlist_add_tail_rcu(&hook->list, hook->head);
1055+#else
1056+ list_add_tail_rcu(&hook->list, hook->head);
1057+#endif
1058+}
1059+
1060+static void __init swap_hook(struct security_hook_list *hook,
1061+ union security_list_options *original)
1062+{
1063+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1064+ struct hlist_head *list = hook->head;
1065+
1066+ if (hlist_empty(list)) {
1067+ add_hook(hook);
1068+ } else {
1069+ struct security_hook_list *shp =
1070+ hlist_entry(list->first, typeof(*shp), list);
1071+
1072+ while (shp->list.next)
1073+ shp = hlist_entry(shp->list.next, typeof(*shp), list);
1074+ *original = shp->hook;
1075+ smp_wmb();
1076+ shp->hook = hook->hook;
1077+ }
1078+#else
1079+ struct list_head *list = hook->head;
1080+
1081+ if (list_empty(list)) {
1082+ add_hook(hook);
1083+ } else {
1084+ struct security_hook_list *shp =
1085+ list_last_entry(list, struct security_hook_list, list);
1086+ *original = shp->hook;
1087+ smp_wmb();
1088+ shp->hook = hook->hook;
1089+ }
1090+#endif
1091+}
1092+
1093+#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS)
1094+#include <linux/uaccess.h> /* probe_kernel_write() */
1095+#define NEED_TO_CHECK_HOOKS_ARE_WRITABLE
1096+
1097+#if defined(CONFIG_X86)
1098+#define MAX_RO_PAGES 1024
1099+static struct page *ro_pages[MAX_RO_PAGES] __initdata;
1100+static unsigned int ro_pages_len __initdata;
1101+
1102+static bool __init lsm_test_page_ro(void *addr)
1103+{
1104+ unsigned int i;
1105+ int unused;
1106+ struct page *page;
1107+
1108+ page = (struct page *) lookup_address((unsigned long) addr, &unused);
1109+ if (!page)
1110+ return false;
1111+ if (test_bit(_PAGE_BIT_RW, &(page->flags)))
1112+ return true;
1113+ for (i = 0; i < ro_pages_len; i++)
1114+ if (page == ro_pages[i])
1115+ return true;
1116+ if (ro_pages_len == MAX_RO_PAGES)
1117+ return false;
1118+ ro_pages[ro_pages_len++] = page;
1119+ return true;
1120+}
1121+
1122+static bool __init check_ro_pages(struct security_hook_heads *hooks)
1123+{
1124+ int i;
1125+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1126+ struct hlist_head *list = &hooks->capable;
1127+
1128+ if (!probe_kernel_write(list, list, sizeof(void *)))
1129+ return true;
1130+ for (i = 0; i < ARRAY_SIZE(akari_hooks); i++) {
1131+ struct hlist_head *head = akari_hooks[i].head;
1132+ struct security_hook_list *shp;
1133+
1134+ if (!lsm_test_page_ro(&head->first))
1135+ return false;
1136+ hlist_for_each_entry(shp, head, list)
1137+ if (!lsm_test_page_ro(&shp->list.next) ||
1138+ !lsm_test_page_ro(&shp->list.pprev))
1139+ return false;
1140+ }
1141+#else
1142+ struct list_head *list = &hooks->capable;
1143+
1144+ if (!probe_kernel_write(list, list, sizeof(void *)))
1145+ return true;
1146+ for (i = 0; i < ARRAY_SIZE(akari_hooks); i++) {
1147+ struct list_head *head = akari_hooks[i].head;
1148+ struct security_hook_list *shp;
1149+
1150+ if (!lsm_test_page_ro(&head->next) ||
1151+ !lsm_test_page_ro(&head->prev))
1152+ return false;
1153+ list_for_each_entry(shp, head, list)
1154+ if (!lsm_test_page_ro(&shp->list.next) ||
1155+ !lsm_test_page_ro(&shp->list.prev))
1156+ return false;
1157+ }
1158+#endif
1159+ return true;
1160+}
1161+#else
1162+static bool __init check_ro_pages(struct security_hook_heads *hooks)
1163+{
1164+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1165+ struct hlist_head *list = &hooks->capable;
1166+#else
1167+ struct list_head *list = &hooks->capable;
1168+#endif
1169+
1170+ return !probe_kernel_write(list, list, sizeof(void *));
1171+}
1172+#endif
1173+#endif
1174+
1175+/**
1176+ * ccs_init - Initialize this module.
1177+ *
1178+ * Returns 0 on success, negative value otherwise.
1179+ */
1180+static int __init ccs_init(void)
1181+{
1182+ int idx;
1183+ struct security_hook_heads *hooks = probe_security_hook_heads();
1184+ if (!hooks)
1185+ goto out;
1186+ for (idx = 0; idx < ARRAY_SIZE(akari_hooks); idx++)
1187+ akari_hooks[idx].head = ((void *) hooks)
1188+ + ((unsigned long) akari_hooks[idx].head)
1189+ - ((unsigned long) &probe_dummy_security_hook_heads);
1190+#if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE)
1191+ if (!check_ro_pages(hooks)) {
1192+ printk(KERN_INFO "Can't update security_hook_heads due to write protected. Retry with rodata=0 kernel command line option added.\n");
1193+ return -EINVAL;
1194+ }
1195+#endif
1196+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1197+ if (!ccsecurity_exports.find_task_by_vpid)
1198+ goto out;
1199+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1200+ if (!ccsecurity_exports.find_task_by_pid_ns)
1201+ goto out;
1202+ ccsecurity_exports.d_absolute_path = probe_d_absolute_path();
1203+ if (!ccsecurity_exports.d_absolute_path)
1204+ goto out;
1205+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++)
1206+ INIT_LIST_HEAD(&ccs_task_security_list[idx]);
1207+ ccs_main_init();
1208+#if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86)
1209+ for (idx = 0; idx < ro_pages_len; idx++)
1210+ set_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags));
1211+#endif
1212+ swap_hook(&akari_hooks[0], &original_task_free);
1213+ swap_hook(&akari_hooks[1], &original_cred_prepare);
1214+ swap_hook(&akari_hooks[2], &original_task_alloc);
1215+ for (idx = 3; idx < ARRAY_SIZE(akari_hooks); idx++)
1216+ add_hook(&akari_hooks[idx]);
1217+#if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86)
1218+ for (idx = 0; idx < ro_pages_len; idx++)
1219+ clear_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags));
1220+#endif
1221+ printk(KERN_INFO "AKARI: 1.0.39 2019/08/20\n");
1222+ printk(KERN_INFO
1223+ "Access Keeping And Regulating Instrument registered.\n");
1224+ return 0;
1225+out:
1226+ return -EINVAL;
1227+}
1228+
1229+module_init(ccs_init);
1230+MODULE_LICENSE("GPL");
1231+
1232+/**
1233+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1234+ *
1235+ * @domain: Pointer to "struct ccs_domain_info".
1236+ *
1237+ * Returns true if @domain is in use, false otherwise.
1238+ *
1239+ * Caller holds rcu_read_lock().
1240+ */
1241+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1242+{
1243+ return false;
1244+}
1245+
1246+/**
1247+ * ccs_add_task_security - Add "struct ccs_security" to list.
1248+ *
1249+ * @ptr: Pointer to "struct ccs_security".
1250+ * @list: Pointer to "struct list_head".
1251+ *
1252+ * Returns nothing.
1253+ */
1254+static void ccs_add_task_security(struct ccs_security *ptr,
1255+ struct list_head *list)
1256+{
1257+ unsigned long flags;
1258+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1259+ list_add_rcu(&ptr->list, list);
1260+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1261+}
1262+
1263+/**
1264+ * __ccs_alloc_task_security - Allocate memory for new tasks.
1265+ *
1266+ * @task: Pointer to "struct task_struct".
1267+ *
1268+ * Returns 0 on success, negative value otherwise.
1269+ */
1270+static int __ccs_alloc_task_security(const struct task_struct *task)
1271+{
1272+ struct ccs_security *old_security = ccs_current_security();
1273+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
1274+ GFP_KERNEL);
1275+ struct list_head *list = &ccs_task_security_list
1276+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1277+ if (!new_security)
1278+ return -ENOMEM;
1279+ new_security->task = task;
1280+ new_security->ccs_domain_info = old_security->ccs_domain_info;
1281+ new_security->ccs_flags = old_security->ccs_flags;
1282+ ccs_add_task_security(new_security, list);
1283+ return 0;
1284+}
1285+
1286+/**
1287+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1288+ *
1289+ * @task: Pointer to "struct task_struct".
1290+ *
1291+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1292+ * out of memory, &ccs_default_security otherwise.
1293+ *
1294+ * If @task is current thread and "struct ccs_security" for current thread was
1295+ * not found, I try to allocate it. But if allocation failed, current thread
1296+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1297+ * won't work.
1298+ */
1299+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1300+{
1301+ struct ccs_security *ptr;
1302+ struct list_head *list = &ccs_task_security_list
1303+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1304+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1305+ while (!list->next)
1306+ smp_rmb();
1307+ rcu_read_lock();
1308+ list_for_each_entry_rcu(ptr, list, list) {
1309+ if (ptr->task != task)
1310+ continue;
1311+ rcu_read_unlock();
1312+ /*
1313+ * Current thread needs to transit from old domain to new
1314+ * domain before do_execve() succeeds in order to check
1315+ * permission for interpreters and environment variables using
1316+ * new domain's ACL rules. The domain transition has to be
1317+ * visible from other CPU in order to allow interactive
1318+ * enforcing mode. Also, the domain transition has to be
1319+ * reverted if do_execve() failed. However, an LSM hook for
1320+ * reverting domain transition is missing.
1321+ *
1322+ * security_prepare_creds() is called from prepare_creds() from
1323+ * prepare_bprm_creds() from do_execve() before setting
1324+ * current->in_execve flag, and current->in_execve flag is
1325+ * cleared by the time next do_execve() request starts.
1326+ * This means that we can emulate the missing LSM hook for
1327+ * reverting domain transition, by calling this function from
1328+ * security_prepare_creds().
1329+ *
1330+ * If current->in_execve is not set but ptr->ccs_flags has
1331+ * CCS_TASK_IS_IN_EXECVE set, it indicates that do_execve()
1332+ * has failed and reverting domain transition is needed.
1333+ */
1334+ if (task == current &&
1335+ (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE) &&
1336+ !current->in_execve) {
1337+ ccs_debug_trace("1");
1338+ ccs_clear_execve(-1, ptr);
1339+ }
1340+ return ptr;
1341+ }
1342+ rcu_read_unlock();
1343+ if (task != current)
1344+ return &ccs_default_security;
1345+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1346+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1347+ if (!ptr) {
1348+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1349+ task->pid);
1350+ send_sig(SIGKILL, current, 0);
1351+ return &ccs_oom_security;
1352+ }
1353+ *ptr = ccs_default_security;
1354+ ptr->task = task;
1355+ ccs_add_task_security(ptr, list);
1356+ return ptr;
1357+}
1358+
1359+/**
1360+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
1361+ *
1362+ * @task: Pointer to "struct task_struct".
1363+ *
1364+ * Returns nothing.
1365+ */
1366+static void __ccs_free_task_security(const struct task_struct *task)
1367+{
1368+ unsigned long flags;
1369+ struct ccs_security *ptr = ccs_find_task_security(task);
1370+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
1371+ return;
1372+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1373+ list_del_rcu(&ptr->list);
1374+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1375+ kfree_rcu(ptr, rcu);
1376+}
--- tags/patches/1.0.39/lsm-4.2.c (nonexistent)
+++ tags/patches/1.0.39/lsm-4.2.c (revision 612)
@@ -0,0 +1,1479 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.39 2019/08/20
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+static void ccs_task_security_gc(void);
14+static int ccs_copy_cred_security(const struct cred *new,
15+ const struct cred *old, gfp_t gfp);
16+static struct ccs_security *ccs_find_cred_security(const struct cred *cred);
17+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
18+static atomic_t ccs_in_execve_tasks = ATOMIC_INIT(0);
19+/*
20+ * List of "struct ccs_security" for "struct pid".
21+ *
22+ * All instances on this list is guaranteed that "struct ccs_security"->pid !=
23+ * NULL. Also, instances on this list that are in execve() are guaranteed that
24+ * "struct ccs_security"->cred remembers "struct linux_binprm"->cred with a
25+ * refcount on "struct linux_binprm"->cred.
26+ */
27+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
28+/*
29+ * List of "struct ccs_security" for "struct cred".
30+ *
31+ * Since the number of "struct cred" is nearly equals to the number of
32+ * "struct pid", we allocate hash tables like ccs_task_security_list.
33+ *
34+ * All instances on this list are guaranteed that "struct ccs_security"->pid ==
35+ * NULL and "struct ccs_security"->cred != NULL.
36+ */
37+static struct list_head ccs_cred_security_list[CCS_MAX_TASK_SECURITY_HASH];
38+
39+/* Dummy security context for avoiding NULL pointer dereference. */
40+static struct ccs_security ccs_oom_security = {
41+ .ccs_domain_info = &ccs_kernel_domain
42+};
43+
44+/* Dummy security context for avoiding NULL pointer dereference. */
45+static struct ccs_security ccs_default_security = {
46+ .ccs_domain_info = &ccs_kernel_domain
47+};
48+
49+/* For exporting variables and functions. */
50+struct ccsecurity_exports ccsecurity_exports;
51+/* Members are updated by loadable kernel module. */
52+struct ccsecurity_operations ccsecurity_ops;
53+
54+/* Original hooks. */
55+static union security_list_options original_cred_prepare;
56+static union security_list_options original_cred_free;
57+static union security_list_options original_cred_alloc_blank;
58+
59+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
60+
61+/**
62+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
63+ *
64+ * @count: Count to increment or decrement.
65+ *
66+ * Returns updated counter.
67+ */
68+static unsigned int ccs_update_ee_counter(int count)
69+{
70+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
71+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
72+ return atomic_add_return(count, &ccs_ee_counter);
73+}
74+
75+/**
76+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
77+ *
78+ * @ee: Pointer to "struct ccs_execve".
79+ *
80+ * Returns nothing.
81+ */
82+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
83+{
84+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
85+ current->pid, ccs_update_ee_counter(1) - 1);
86+}
87+
88+/**
89+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
90+ *
91+ * @ee: Pointer to "struct ccs_execve".
92+ * @task: True if released by current task, false otherwise.
93+ *
94+ * Returns nothing.
95+ */
96+void ccs_audit_free_execve(const struct ccs_execve * const ee,
97+ const bool is_current)
98+{
99+ const unsigned int tmp = ccs_update_ee_counter(-1);
100+ if (is_current)
101+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
102+ ee, current->pid, tmp);
103+ else
104+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
105+ ee, tmp);
106+}
107+
108+#endif
109+
110+#if !defined(CONFIG_AKARI_DEBUG)
111+#define ccs_debug_trace(pos) do { } while (0)
112+#else
113+#define ccs_debug_trace(pos) \
114+ do { \
115+ static bool done; \
116+ if (!done) { \
117+ printk(KERN_INFO \
118+ "AKARI: Debug trace: " pos " of 4\n"); \
119+ done = true; \
120+ } \
121+ } while (0)
122+#endif
123+
124+/**
125+ * ccs_clear_execve - Release memory used by do_execve().
126+ *
127+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
128+ * @security: Pointer to "struct ccs_security".
129+ *
130+ * Returns nothing.
131+ */
132+static void ccs_clear_execve(int ret, struct ccs_security *security)
133+{
134+ struct ccs_execve *ee;
135+ if (security == &ccs_default_security || security == &ccs_oom_security)
136+ return;
137+ ee = security->ee;
138+ security->ee = NULL;
139+ if (!ee)
140+ return;
141+ atomic_dec(&ccs_in_execve_tasks);
142+ ccs_finish_execve(ret, ee);
143+}
144+
145+/**
146+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
147+ *
148+ * @rcu: Pointer to "struct rcu_head".
149+ *
150+ * Returns nothing.
151+ */
152+static void ccs_rcu_free(struct rcu_head *rcu)
153+{
154+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
155+ struct ccs_execve *ee = ptr->ee;
156+ /*
157+ * If this security context was associated with "struct pid" and
158+ * ptr->ccs_flags has CCS_TASK_IS_IN_EXECVE set, it indicates that a
159+ * "struct task_struct" associated with this security context exited
160+ * immediately after do_execve() has failed.
161+ */
162+ if (ptr->pid && (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
163+ ccs_debug_trace("1");
164+ atomic_dec(&ccs_in_execve_tasks);
165+ }
166+ /*
167+ * If this security context was associated with "struct pid",
168+ * drop refcount obtained by get_pid() in ccs_find_task_security().
169+ */
170+ if (ptr->pid) {
171+ ccs_debug_trace("2");
172+ put_pid(ptr->pid);
173+ }
174+ if (ee) {
175+ ccs_debug_trace("3");
176+ ccs_audit_free_execve(ee, false);
177+ kfree(ee->handler_path);
178+ kfree(ee);
179+ }
180+ kfree(ptr);
181+}
182+
183+/**
184+ * ccs_del_security - Release "struct ccs_security".
185+ *
186+ * @ptr: Pointer to "struct ccs_security".
187+ *
188+ * Returns nothing.
189+ */
190+static void ccs_del_security(struct ccs_security *ptr)
191+{
192+ unsigned long flags;
193+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
194+ return;
195+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
196+ list_del_rcu(&ptr->list);
197+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
198+ call_rcu(&ptr->rcu, ccs_rcu_free);
199+}
200+
201+/**
202+ * ccs_add_cred_security - Add "struct ccs_security" to list.
203+ *
204+ * @ptr: Pointer to "struct ccs_security".
205+ *
206+ * Returns nothing.
207+ */
208+static void ccs_add_cred_security(struct ccs_security *ptr)
209+{
210+ unsigned long flags;
211+ struct list_head *list = &ccs_cred_security_list
212+ [hash_ptr((void *) ptr->cred, CCS_TASK_SECURITY_HASH_BITS)];
213+#ifdef CONFIG_AKARI_DEBUG
214+ if (ptr->pid)
215+ printk(KERN_INFO "AKARI: \"struct ccs_security\"->pid != NULL"
216+ "\n");
217+#endif
218+ ptr->pid = NULL;
219+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
220+ list_add_rcu(&ptr->list, list);
221+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
222+}
223+
224+/**
225+ * ccs_task_create - Make snapshot of security context for new task.
226+ *
227+ * @clone_flags: Flags passed to clone().
228+ *
229+ * Returns 0 on success, negative value otherwise.
230+ */
231+static int ccs_task_create(unsigned long clone_flags)
232+{
233+ struct ccs_security *old_security;
234+ struct ccs_security *new_security;
235+ struct cred *cred = prepare_creds();
236+ if (!cred)
237+ return -ENOMEM;
238+ old_security = ccs_find_task_security(current);
239+ new_security = ccs_find_cred_security(cred);
240+ new_security->ccs_domain_info = old_security->ccs_domain_info;
241+ new_security->ccs_flags = old_security->ccs_flags;
242+ return commit_creds(cred);
243+}
244+
245+/**
246+ * ccs_cred_prepare - Allocate memory for new credentials.
247+ *
248+ * @new: Pointer to "struct cred".
249+ * @old: Pointer to "struct cred".
250+ * @gfp: Memory allocation flags.
251+ *
252+ * Returns 0 on success, negative value otherwise.
253+ */
254+static int ccs_cred_prepare(struct cred *new, const struct cred *old,
255+ gfp_t gfp)
256+{
257+ int rc1;
258+ /*
259+ * For checking whether reverting domain transition is needed or not.
260+ *
261+ * See ccs_find_task_security() for reason.
262+ */
263+ if (gfp == GFP_KERNEL)
264+ ccs_find_task_security(current);
265+ rc1 = ccs_copy_cred_security(new, old, gfp);
266+ if (gfp == GFP_KERNEL)
267+ ccs_task_security_gc();
268+ if (original_cred_prepare.cred_prepare) {
269+ const int rc2 = original_cred_prepare.cred_prepare(new, old,
270+ gfp);
271+ if (rc2) {
272+ ccs_del_security(ccs_find_cred_security(new));
273+ return rc2;
274+ }
275+ }
276+ return rc1;
277+}
278+
279+/**
280+ * ccs_cred_free - Release memory used by credentials.
281+ *
282+ * @cred: Pointer to "struct cred".
283+ *
284+ * Returns nothing.
285+ */
286+static void ccs_cred_free(struct cred *cred)
287+{
288+ if (original_cred_free.cred_free)
289+ original_cred_free.cred_free(cred);
290+ ccs_del_security(ccs_find_cred_security(cred));
291+}
292+
293+/**
294+ * ccs_alloc_cred_security - Allocate memory for new credentials.
295+ *
296+ * @cred: Pointer to "struct cred".
297+ * @gfp: Memory allocation flags.
298+ *
299+ * Returns 0 on success, negative value otherwise.
300+ */
301+static int ccs_alloc_cred_security(const struct cred *cred, gfp_t gfp)
302+{
303+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
304+ gfp);
305+ if (!new_security)
306+ return -ENOMEM;
307+ new_security->cred = cred;
308+ ccs_add_cred_security(new_security);
309+ return 0;
310+}
311+
312+/**
313+ * ccs_cred_alloc_blank - Allocate memory for new credentials.
314+ *
315+ * @new: Pointer to "struct cred".
316+ * @gfp: Memory allocation flags.
317+ *
318+ * Returns 0 on success, negative value otherwise.
319+ */
320+static int ccs_cred_alloc_blank(struct cred *new, gfp_t gfp)
321+{
322+ const int rc1 = ccs_alloc_cred_security(new, gfp);
323+ if (original_cred_alloc_blank.cred_alloc_blank) {
324+ const int rc2 = original_cred_alloc_blank.
325+ cred_alloc_blank(new, gfp);
326+ if (rc2) {
327+ ccs_del_security(ccs_find_cred_security(new));
328+ return rc2;
329+ }
330+ }
331+ return rc1;
332+}
333+
334+/**
335+ * ccs_cred_transfer - Transfer "struct ccs_security" between credentials.
336+ *
337+ * @new: Pointer to "struct cred".
338+ * @old: Pointer to "struct cred".
339+ *
340+ * Returns nothing.
341+ */
342+static void ccs_cred_transfer(struct cred *new, const struct cred *old)
343+{
344+ struct ccs_security *new_security = ccs_find_cred_security(new);
345+ struct ccs_security *old_security = ccs_find_cred_security(old);
346+ if (new_security == &ccs_default_security ||
347+ new_security == &ccs_oom_security ||
348+ old_security == &ccs_default_security ||
349+ old_security == &ccs_oom_security)
350+ return;
351+ new_security->ccs_flags = old_security->ccs_flags;
352+ new_security->ccs_domain_info = old_security->ccs_domain_info;
353+}
354+
355+/**
356+ * ccs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
357+ *
358+ * @bprm: Pointer to "struct linux_binprm".
359+ *
360+ * Returns nothing.
361+ */
362+static void ccs_bprm_committing_creds(struct linux_binprm *bprm)
363+{
364+ struct ccs_security *old_security = ccs_current_security();
365+ struct ccs_security *new_security;
366+ if (old_security == &ccs_default_security ||
367+ old_security == &ccs_oom_security)
368+ return;
369+ ccs_clear_execve(0, old_security);
370+ /* Update current task's cred's domain for future fork(). */
371+ new_security = ccs_find_cred_security(bprm->cred);
372+ new_security->ccs_flags = old_security->ccs_flags;
373+ new_security->ccs_domain_info = old_security->ccs_domain_info;
374+}
375+
376+/**
377+ * ccs_bprm_check_security - Check permission for execve().
378+ *
379+ * @bprm: Pointer to "struct linux_binprm".
380+ *
381+ * Returns 0 on success, negative value otherwise.
382+ */
383+static int ccs_bprm_check_security(struct linux_binprm *bprm)
384+{
385+ struct ccs_security *security = ccs_current_security();
386+ int rc;
387+ if (security == &ccs_default_security || security == &ccs_oom_security)
388+ return -ENOMEM;
389+ if (security->ee)
390+ return 0;
391+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
392+ if (!ccs_policy_loaded)
393+ ccs_load_policy(bprm->filename);
394+#endif
395+ rc = ccs_start_execve(bprm, &security->ee);
396+ if (security->ee)
397+ atomic_inc(&ccs_in_execve_tasks);
398+ return rc;
399+}
400+
401+/**
402+ * ccs_file_open - Check permission for open().
403+ *
404+ * @f: Pointer to "struct file".
405+ * @cred: Pointer to "struct cred".
406+ *
407+ * Returns 0 on success, negative value otherwise.
408+ */
409+static int ccs_file_open(struct file *f, const struct cred *cred)
410+{
411+ return ccs_open_permission(f);
412+}
413+
414+#ifdef CONFIG_SECURITY_PATH
415+
416+/**
417+ * ccs_path_chown - Check permission for chown()/chgrp().
418+ *
419+ * @path: Pointer to "struct path".
420+ * @user: User ID.
421+ * @group: Group ID.
422+ *
423+ * Returns 0 on success, negative value otherwise.
424+ */
425+static int ccs_path_chown(struct path *path, kuid_t user, kgid_t group)
426+{
427+ return ccs_chown_permission(path->dentry, path->mnt, user, group);
428+}
429+
430+/**
431+ * ccs_path_chmod - Check permission for chmod().
432+ *
433+ * @path: Pointer to "struct path".
434+ * @mode: Mode.
435+ *
436+ * Returns 0 on success, negative value otherwise.
437+ */
438+static int ccs_path_chmod(struct path *path, umode_t mode)
439+{
440+ return ccs_chmod_permission(path->dentry, path->mnt, mode);
441+}
442+
443+/**
444+ * ccs_path_chroot - Check permission for chroot().
445+ *
446+ * @path: Pointer to "struct path".
447+ *
448+ * Returns 0 on success, negative value otherwise.
449+ */
450+static int ccs_path_chroot(struct path *path)
451+{
452+ return ccs_chroot_permission(path);
453+}
454+
455+/**
456+ * ccs_path_truncate - Check permission for truncate().
457+ *
458+ * @path: Pointer to "struct path".
459+ *
460+ * Returns 0 on success, negative value otherwise.
461+ */
462+static int ccs_path_truncate(struct path *path)
463+{
464+ return ccs_truncate_permission(path->dentry, path->mnt);
465+}
466+
467+#else
468+
469+/**
470+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
471+ *
472+ * @dentry: Pointer to "struct dentry".
473+ * @attr: Pointer to "struct iattr".
474+ *
475+ * Returns 0 on success, negative value otherwise.
476+ */
477+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
478+{
479+ const int rc1 = (attr->ia_valid & ATTR_UID) ?
480+ ccs_chown_permission(dentry, NULL, attr->ia_uid, INVALID_GID) :
481+ 0;
482+ const int rc2 = (attr->ia_valid & ATTR_GID) ?
483+ ccs_chown_permission(dentry, NULL, INVALID_UID, attr->ia_gid) :
484+ 0;
485+ const int rc3 = (attr->ia_valid & ATTR_MODE) ?
486+ ccs_chmod_permission(dentry, NULL, attr->ia_mode) : 0;
487+ const int rc4 = (attr->ia_valid & ATTR_SIZE) ?
488+ ccs_truncate_permission(dentry, NULL) : 0;
489+ if (rc4)
490+ return rc4;
491+ if (rc3)
492+ return rc3;
493+ if (rc2)
494+ return rc2;
495+ return rc1;
496+}
497+
498+#endif
499+
500+/**
501+ * ccs_inode_getattr - Check permission for stat().
502+ *
503+ * @path: Pointer to "struct path".
504+ *
505+ * Returns 0 on success, negative value otherwise.
506+ */
507+static int ccs_inode_getattr(const struct path *path)
508+{
509+ return ccs_getattr_permission(path->mnt, path->dentry);
510+}
511+
512+#ifdef CONFIG_SECURITY_PATH
513+
514+/**
515+ * ccs_path_mknod - Check permission for mknod().
516+ *
517+ * @dir: Pointer to "struct path".
518+ * @dentry: Pointer to "struct dentry".
519+ * @mode: Create mode.
520+ * @dev: Device major/minor number.
521+ *
522+ * Returns 0 on success, negative value otherwise.
523+ */
524+static int ccs_path_mknod(struct path *dir, struct dentry *dentry,
525+ umode_t mode, unsigned int dev)
526+{
527+ return ccs_mknod_permission(dentry, dir->mnt, mode, dev);
528+}
529+
530+/**
531+ * ccs_path_mkdir - Check permission for mkdir().
532+ *
533+ * @dir: Pointer to "struct path".
534+ * @dentry: Pointer to "struct dentry".
535+ * @mode: Create mode.
536+ *
537+ * Returns 0 on success, negative value otherwise.
538+ */
539+static int ccs_path_mkdir(struct path *dir, struct dentry *dentry,
540+ umode_t mode)
541+{
542+ return ccs_mkdir_permission(dentry, dir->mnt, mode);
543+}
544+
545+/**
546+ * ccs_path_rmdir - Check permission for rmdir().
547+ *
548+ * @dir: Pointer to "struct path".
549+ * @dentry: Pointer to "struct dentry".
550+ *
551+ * Returns 0 on success, negative value otherwise.
552+ */
553+static int ccs_path_rmdir(struct path *dir, struct dentry *dentry)
554+{
555+ return ccs_rmdir_permission(dentry, dir->mnt);
556+}
557+
558+/**
559+ * ccs_path_unlink - Check permission for unlink().
560+ *
561+ * @dir: Pointer to "struct path".
562+ * @dentry: Pointer to "struct dentry".
563+ *
564+ * Returns 0 on success, negative value otherwise.
565+ */
566+static int ccs_path_unlink(struct path *dir, struct dentry *dentry)
567+{
568+ return ccs_unlink_permission(dentry, dir->mnt);
569+}
570+
571+/**
572+ * ccs_path_symlink - Check permission for symlink().
573+ *
574+ * @dir: Pointer to "struct path".
575+ * @dentry: Pointer to "struct dentry".
576+ * @old_name: Content of symbolic link.
577+ *
578+ * Returns 0 on success, negative value otherwise.
579+ */
580+static int ccs_path_symlink(struct path *dir, struct dentry *dentry,
581+ const char *old_name)
582+{
583+ return ccs_symlink_permission(dentry, dir->mnt, old_name);
584+}
585+
586+/**
587+ * ccs_path_rename - Check permission for rename().
588+ *
589+ * @old_dir: Pointer to "struct path".
590+ * @old_dentry: Pointer to "struct dentry".
591+ * @new_dir: Pointer to "struct path".
592+ * @new_dentry: Pointer to "struct dentry".
593+ *
594+ * Returns 0 on success, negative value otherwise.
595+ */
596+static int ccs_path_rename(struct path *old_dir, struct dentry *old_dentry,
597+ struct path *new_dir, struct dentry *new_dentry)
598+{
599+ return ccs_rename_permission(old_dentry, new_dentry, old_dir->mnt);
600+}
601+
602+/**
603+ * ccs_path_link - Check permission for link().
604+ *
605+ * @old_dentry: Pointer to "struct dentry".
606+ * @new_dir: Pointer to "struct path".
607+ * @new_dentry: Pointer to "struct dentry".
608+ *
609+ * Returns 0 on success, negative value otherwise.
610+ */
611+static int ccs_path_link(struct dentry *old_dentry, struct path *new_dir,
612+ struct dentry *new_dentry)
613+{
614+ return ccs_link_permission(old_dentry, new_dentry, new_dir->mnt);
615+}
616+
617+#else
618+
619+/**
620+ * ccs_inode_mknod - Check permission for mknod().
621+ *
622+ * @dir: Pointer to "struct inode".
623+ * @dentry: Pointer to "struct dentry".
624+ * @mode: Create mode.
625+ * @dev: Device major/minor number.
626+ *
627+ * Returns 0 on success, negative value otherwise.
628+ */
629+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
630+ umode_t mode, dev_t dev)
631+{
632+ return ccs_mknod_permission(dentry, NULL, mode, dev);
633+}
634+
635+/**
636+ * ccs_inode_mkdir - Check permission for mkdir().
637+ *
638+ * @dir: Pointer to "struct inode".
639+ * @dentry: Pointer to "struct dentry".
640+ * @mode: Create mode.
641+ *
642+ * Returns 0 on success, negative value otherwise.
643+ */
644+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
645+ umode_t mode)
646+{
647+ return ccs_mkdir_permission(dentry, NULL, mode);
648+}
649+
650+/**
651+ * ccs_inode_rmdir - Check permission for rmdir().
652+ *
653+ * @dir: Pointer to "struct inode".
654+ * @dentry: Pointer to "struct dentry".
655+ *
656+ * Returns 0 on success, negative value otherwise.
657+ */
658+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry)
659+{
660+ return ccs_rmdir_permission(dentry, NULL);
661+}
662+
663+/**
664+ * ccs_inode_unlink - Check permission for unlink().
665+ *
666+ * @dir: Pointer to "struct inode".
667+ * @dentry: Pointer to "struct dentry".
668+ *
669+ * Returns 0 on success, negative value otherwise.
670+ */
671+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
672+{
673+ return ccs_unlink_permission(dentry, NULL);
674+}
675+
676+/**
677+ * ccs_inode_symlink - Check permission for symlink().
678+ *
679+ * @dir: Pointer to "struct inode".
680+ * @dentry: Pointer to "struct dentry".
681+ * @old_name: Content of symbolic link.
682+ *
683+ * Returns 0 on success, negative value otherwise.
684+ */
685+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
686+ const char *old_name)
687+{
688+ return ccs_symlink_permission(dentry, NULL, old_name);
689+}
690+
691+/**
692+ * ccs_inode_rename - Check permission for rename().
693+ *
694+ * @old_dir: Pointer to "struct inode".
695+ * @old_dentry: Pointer to "struct dentry".
696+ * @new_dir: Pointer to "struct inode".
697+ * @new_dentry: Pointer to "struct dentry".
698+ *
699+ * Returns 0 on success, negative value otherwise.
700+ */
701+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
702+ struct inode *new_dir, struct dentry *new_dentry)
703+{
704+ return ccs_rename_permission(old_dentry, new_dentry, NULL);
705+}
706+
707+/**
708+ * ccs_inode_link - Check permission for link().
709+ *
710+ * @old_dentry: Pointer to "struct dentry".
711+ * @dir: Pointer to "struct inode".
712+ * @new_dentry: Pointer to "struct dentry".
713+ *
714+ * Returns 0 on success, negative value otherwise.
715+ */
716+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
717+ struct dentry *new_dentry)
718+{
719+ return ccs_link_permission(old_dentry, new_dentry, NULL);
720+}
721+
722+/**
723+ * ccs_inode_create - Check permission for creat().
724+ *
725+ * @dir: Pointer to "struct inode".
726+ * @dentry: Pointer to "struct dentry".
727+ * @mode: Create mode.
728+ *
729+ * Returns 0 on success, negative value otherwise.
730+ */
731+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
732+ umode_t mode)
733+{
734+ return ccs_mknod_permission(dentry, NULL, mode, 0);
735+}
736+
737+#endif
738+
739+#ifdef CONFIG_SECURITY_NETWORK
740+
741+#include <net/sock.h>
742+
743+/* Structure for remembering an accept()ed socket's status. */
744+struct ccs_socket_tag {
745+ struct list_head list;
746+ struct inode *inode;
747+ int status;
748+ struct rcu_head rcu;
749+};
750+
751+/*
752+ * List for managing accept()ed sockets.
753+ * Since we don't need to keep an accept()ed socket into this list after
754+ * once the permission was granted, the number of entries in this list is
755+ * likely small. Therefore, we don't use hash tables.
756+ */
757+static LIST_HEAD(ccs_accepted_socket_list);
758+/* Lock for protecting ccs_accepted_socket_list . */
759+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
760+
761+/**
762+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
763+ *
764+ * @inode: Pointer to "struct inode".
765+ * @status: New status.
766+ *
767+ * Returns nothing.
768+ *
769+ * If @status == 0, memory for that socket will be released after RCU grace
770+ * period.
771+ */
772+static void ccs_update_socket_tag(struct inode *inode, int status)
773+{
774+ struct ccs_socket_tag *ptr;
775+ /*
776+ * Protect whole section because multiple threads may call this
777+ * function with same "sock" via ccs_validate_socket().
778+ */
779+ spin_lock(&ccs_accepted_socket_list_lock);
780+ rcu_read_lock();
781+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
782+ if (ptr->inode != inode)
783+ continue;
784+ ptr->status = status;
785+ if (status)
786+ break;
787+ list_del_rcu(&ptr->list);
788+ kfree_rcu(ptr, rcu);
789+ break;
790+ }
791+ rcu_read_unlock();
792+ spin_unlock(&ccs_accepted_socket_list_lock);
793+}
794+
795+/**
796+ * ccs_validate_socket - Check post accept() permission if needed.
797+ *
798+ * @sock: Pointer to "struct socket".
799+ *
800+ * Returns 0 on success, negative value otherwise.
801+ */
802+static int ccs_validate_socket(struct socket *sock)
803+{
804+ struct inode *inode = SOCK_INODE(sock);
805+ struct ccs_socket_tag *ptr;
806+ int ret = 0;
807+ rcu_read_lock();
808+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
809+ if (ptr->inode != inode)
810+ continue;
811+ ret = ptr->status;
812+ break;
813+ }
814+ rcu_read_unlock();
815+ if (ret <= 0)
816+ /*
817+ * This socket is not an accept()ed socket or this socket is
818+ * an accept()ed socket and post accept() permission is done.
819+ */
820+ return ret;
821+ /*
822+ * Check post accept() permission now.
823+ *
824+ * Strictly speaking, we need to pass both listen()ing socket and
825+ * accept()ed socket to __ccs_socket_post_accept_permission().
826+ * But since socket's family and type are same for both sockets,
827+ * passing the accept()ed socket in place for the listen()ing socket
828+ * will work.
829+ */
830+ ret = ccs_socket_post_accept_permission(sock, sock);
831+ /*
832+ * If permission was granted, we forget that this is an accept()ed
833+ * socket. Otherwise, we remember that this socket needs to return
834+ * error for subsequent socketcalls.
835+ */
836+ ccs_update_socket_tag(inode, ret);
837+ return ret;
838+}
839+
840+/**
841+ * ccs_socket_accept - Check permission for accept().
842+ *
843+ * @sock: Pointer to "struct socket".
844+ * @newsock: Pointer to "struct socket".
845+ *
846+ * Returns 0 on success, negative value otherwise.
847+ *
848+ * This hook is used for setting up environment for doing post accept()
849+ * permission check. If dereferencing sock->ops->something() were ordered by
850+ * rcu_dereference(), we could replace sock->ops with "a copy of original
851+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
852+ * in order to do post accept() permission check before returning to userspace.
853+ * If we make the copy in security_socket_post_create(), it would be possible
854+ * to safely replace sock->ops here, but we don't do so because we don't want
855+ * to allocate memory for sockets which do not call sock->ops->accept().
856+ * Therefore, we do post accept() permission check upon next socket syscalls
857+ * rather than between sock->ops->accept() and returning to userspace.
858+ * This means that if a socket was close()d before calling some socket
859+ * syscalls, post accept() permission check will not be done.
860+ */
861+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
862+{
863+ struct ccs_socket_tag *ptr;
864+ const int rc = ccs_validate_socket(sock);
865+ if (rc < 0)
866+ return rc;
867+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
868+ if (!ptr)
869+ return -ENOMEM;
870+ /*
871+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
872+ * "newsock" as "an accept()ed socket but post accept() permission
873+ * check is not done yet" by allocating memory using inode of the
874+ * "newsock" as a search key.
875+ */
876+ ptr->inode = SOCK_INODE(newsock);
877+ ptr->status = 1; /* Check post accept() permission later. */
878+ spin_lock(&ccs_accepted_socket_list_lock);
879+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
880+ spin_unlock(&ccs_accepted_socket_list_lock);
881+ return 0;
882+}
883+
884+/**
885+ * ccs_socket_listen - Check permission for listen().
886+ *
887+ * @sock: Pointer to "struct socket".
888+ * @backlog: Backlog parameter.
889+ *
890+ * Returns 0 on success, negative value otherwise.
891+ */
892+static int ccs_socket_listen(struct socket *sock, int backlog)
893+{
894+ const int rc = ccs_validate_socket(sock);
895+ if (rc < 0)
896+ return rc;
897+ return ccs_socket_listen_permission(sock);
898+}
899+
900+/**
901+ * ccs_socket_connect - Check permission for connect().
902+ *
903+ * @sock: Pointer to "struct socket".
904+ * @addr: Pointer to "struct sockaddr".
905+ * @addr_len: Size of @addr.
906+ *
907+ * Returns 0 on success, negative value otherwise.
908+ */
909+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
910+ int addr_len)
911+{
912+ const int rc = ccs_validate_socket(sock);
913+ if (rc < 0)
914+ return rc;
915+ return ccs_socket_connect_permission(sock, addr, addr_len);
916+}
917+
918+/**
919+ * ccs_socket_bind - Check permission for bind().
920+ *
921+ * @sock: Pointer to "struct socket".
922+ * @addr: Pointer to "struct sockaddr".
923+ * @addr_len: Size of @addr.
924+ *
925+ * Returns 0 on success, negative value otherwise.
926+ */
927+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
928+ int addr_len)
929+{
930+ const int rc = ccs_validate_socket(sock);
931+ if (rc < 0)
932+ return rc;
933+ return ccs_socket_bind_permission(sock, addr, addr_len);
934+}
935+
936+/**
937+ * ccs_socket_sendmsg - Check permission for sendmsg().
938+ *
939+ * @sock: Pointer to "struct socket".
940+ * @msg: Pointer to "struct msghdr".
941+ * @size: Size of message.
942+ *
943+ * Returns 0 on success, negative value otherwise.
944+ */
945+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
946+ int size)
947+{
948+ const int rc = ccs_validate_socket(sock);
949+ if (rc < 0)
950+ return rc;
951+ return ccs_socket_sendmsg_permission(sock, msg, size);
952+}
953+
954+/**
955+ * ccs_socket_recvmsg - Check permission for recvmsg().
956+ *
957+ * @sock: Pointer to "struct socket".
958+ * @msg: Pointer to "struct msghdr".
959+ * @size: Size of message.
960+ * @flags: Flags.
961+ *
962+ * Returns 0 on success, negative value otherwise.
963+ */
964+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
965+ int size, int flags)
966+{
967+ return ccs_validate_socket(sock);
968+}
969+
970+/**
971+ * ccs_socket_getsockname - Check permission for getsockname().
972+ *
973+ * @sock: Pointer to "struct socket".
974+ *
975+ * Returns 0 on success, negative value otherwise.
976+ */
977+static int ccs_socket_getsockname(struct socket *sock)
978+{
979+ return ccs_validate_socket(sock);
980+}
981+
982+/**
983+ * ccs_socket_getpeername - Check permission for getpeername().
984+ *
985+ * @sock: Pointer to "struct socket".
986+ *
987+ * Returns 0 on success, negative value otherwise.
988+ */
989+static int ccs_socket_getpeername(struct socket *sock)
990+{
991+ return ccs_validate_socket(sock);
992+}
993+
994+/**
995+ * ccs_socket_getsockopt - Check permission for getsockopt().
996+ *
997+ * @sock: Pointer to "struct socket".
998+ * @level: Level.
999+ * @optname: Option's name,
1000+ *
1001+ * Returns 0 on success, negative value otherwise.
1002+ */
1003+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
1004+{
1005+ return ccs_validate_socket(sock);
1006+}
1007+
1008+/**
1009+ * ccs_socket_setsockopt - Check permission for setsockopt().
1010+ *
1011+ * @sock: Pointer to "struct socket".
1012+ * @level: Level.
1013+ * @optname: Option's name,
1014+ *
1015+ * Returns 0 on success, negative value otherwise.
1016+ */
1017+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
1018+{
1019+ return ccs_validate_socket(sock);
1020+}
1021+
1022+/**
1023+ * ccs_socket_shutdown - Check permission for shutdown().
1024+ *
1025+ * @sock: Pointer to "struct socket".
1026+ * @how: Shutdown mode.
1027+ *
1028+ * Returns 0 on success, negative value otherwise.
1029+ */
1030+static int ccs_socket_shutdown(struct socket *sock, int how)
1031+{
1032+ return ccs_validate_socket(sock);
1033+}
1034+
1035+#define SOCKFS_MAGIC 0x534F434B
1036+
1037+/**
1038+ * ccs_inode_free_security - Release memory associated with an inode.
1039+ *
1040+ * @inode: Pointer to "struct inode".
1041+ *
1042+ * Returns nothing.
1043+ *
1044+ * We use this hook for releasing memory associated with an accept()ed socket.
1045+ */
1046+static void ccs_inode_free_security(struct inode *inode)
1047+{
1048+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1049+ ccs_update_socket_tag(inode, 0);
1050+}
1051+
1052+#endif
1053+
1054+/**
1055+ * ccs_sb_pivotroot - Check permission for pivot_root().
1056+ *
1057+ * @old_path: Pointer to "struct path".
1058+ * @new_path: Pointer to "struct path".
1059+ *
1060+ * Returns 0 on success, negative value otherwise.
1061+ */
1062+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1063+{
1064+ return ccs_pivot_root_permission(old_path, new_path);
1065+}
1066+
1067+/**
1068+ * ccs_sb_mount - Check permission for mount().
1069+ *
1070+ * @dev_name: Name of device file.
1071+ * @path: Pointer to "struct path".
1072+ * @type: Name of filesystem type. Maybe NULL.
1073+ * @flags: Mount options.
1074+ * @data_page: Optional data. Maybe NULL.
1075+ *
1076+ * Returns 0 on success, negative value otherwise.
1077+ */
1078+static int ccs_sb_mount(const char *dev_name, struct path *path,
1079+ const char *type, unsigned long flags, void *data_page)
1080+{
1081+ return ccs_mount_permission(dev_name, path, type, flags, data_page);
1082+}
1083+
1084+/**
1085+ * ccs_sb_umount - Check permission for umount().
1086+ *
1087+ * @mnt: Pointer to "struct vfsmount".
1088+ * @flags: Unmount flags.
1089+ *
1090+ * Returns 0 on success, negative value otherwise.
1091+ */
1092+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1093+{
1094+ return ccs_umount_permission(mnt, flags);
1095+}
1096+
1097+/**
1098+ * ccs_file_fcntl - Check permission for fcntl().
1099+ *
1100+ * @file: Pointer to "struct file".
1101+ * @cmd: Command number.
1102+ * @arg: Value for @cmd.
1103+ *
1104+ * Returns 0 on success, negative value otherwise.
1105+ */
1106+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1107+ unsigned long arg)
1108+{
1109+ return ccs_fcntl_permission(file, cmd, arg);
1110+}
1111+
1112+/**
1113+ * ccs_file_ioctl - Check permission for ioctl().
1114+ *
1115+ * @filp: Pointer to "struct file".
1116+ * @cmd: Command number.
1117+ * @arg: Value for @cmd.
1118+ *
1119+ * Returns 0 on success, negative value otherwise.
1120+ */
1121+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1122+ unsigned long arg)
1123+{
1124+ return ccs_ioctl_permission(filp, cmd, arg);
1125+}
1126+
1127+#define MY_HOOK_INIT(HEAD, HOOK) \
1128+ { .head = &probe_dummy_security_hook_heads.HEAD, \
1129+ .hook = { .HEAD = HOOK } }
1130+
1131+static struct security_hook_list akari_hooks[] = {
1132+ /* Security context allocator. */
1133+ MY_HOOK_INIT(cred_free, ccs_cred_free),
1134+ MY_HOOK_INIT(cred_prepare, ccs_cred_prepare),
1135+ MY_HOOK_INIT(cred_alloc_blank, ccs_cred_alloc_blank),
1136+ MY_HOOK_INIT(cred_transfer, ccs_cred_transfer),
1137+ MY_HOOK_INIT(task_create, ccs_task_create),
1138+ /* Security context updater for successful execve(). */
1139+ MY_HOOK_INIT(bprm_check_security, ccs_bprm_check_security),
1140+ MY_HOOK_INIT(bprm_committing_creds, ccs_bprm_committing_creds),
1141+ /* Various permission checker. */
1142+ MY_HOOK_INIT(file_open, ccs_file_open),
1143+ MY_HOOK_INIT(file_fcntl, ccs_file_fcntl),
1144+ MY_HOOK_INIT(file_ioctl, ccs_file_ioctl),
1145+ MY_HOOK_INIT(sb_pivotroot, ccs_sb_pivotroot),
1146+ MY_HOOK_INIT(sb_mount, ccs_sb_mount),
1147+ MY_HOOK_INIT(sb_umount, ccs_sb_umount),
1148+#ifdef CONFIG_SECURITY_PATH
1149+ MY_HOOK_INIT(path_mknod, ccs_path_mknod),
1150+ MY_HOOK_INIT(path_mkdir, ccs_path_mkdir),
1151+ MY_HOOK_INIT(path_rmdir, ccs_path_rmdir),
1152+ MY_HOOK_INIT(path_unlink, ccs_path_unlink),
1153+ MY_HOOK_INIT(path_symlink, ccs_path_symlink),
1154+ MY_HOOK_INIT(path_rename, ccs_path_rename),
1155+ MY_HOOK_INIT(path_link, ccs_path_link),
1156+ MY_HOOK_INIT(path_truncate, ccs_path_truncate),
1157+ MY_HOOK_INIT(path_chmod, ccs_path_chmod),
1158+ MY_HOOK_INIT(path_chown, ccs_path_chown),
1159+ MY_HOOK_INIT(path_chroot, ccs_path_chroot),
1160+#else
1161+ MY_HOOK_INIT(inode_mknod, ccs_inode_mknod),
1162+ MY_HOOK_INIT(inode_mkdir, ccs_inode_mkdir),
1163+ MY_HOOK_INIT(inode_rmdir, ccs_inode_rmdir),
1164+ MY_HOOK_INIT(inode_unlink, ccs_inode_unlink),
1165+ MY_HOOK_INIT(inode_symlink, ccs_inode_symlink),
1166+ MY_HOOK_INIT(inode_rename, ccs_inode_rename),
1167+ MY_HOOK_INIT(inode_link, ccs_inode_link),
1168+ MY_HOOK_INIT(inode_create, ccs_inode_create),
1169+ MY_HOOK_INIT(inode_setattr, ccs_inode_setattr),
1170+#endif
1171+ MY_HOOK_INIT(inode_getattr, ccs_inode_getattr),
1172+#ifdef CONFIG_SECURITY_NETWORK
1173+ MY_HOOK_INIT(socket_bind, ccs_socket_bind),
1174+ MY_HOOK_INIT(socket_connect, ccs_socket_connect),
1175+ MY_HOOK_INIT(socket_listen, ccs_socket_listen),
1176+ MY_HOOK_INIT(socket_sendmsg, ccs_socket_sendmsg),
1177+ MY_HOOK_INIT(socket_recvmsg, ccs_socket_recvmsg),
1178+ MY_HOOK_INIT(socket_getsockname, ccs_socket_getsockname),
1179+ MY_HOOK_INIT(socket_getpeername, ccs_socket_getpeername),
1180+ MY_HOOK_INIT(socket_getsockopt, ccs_socket_getsockopt),
1181+ MY_HOOK_INIT(socket_setsockopt, ccs_socket_setsockopt),
1182+ MY_HOOK_INIT(socket_shutdown, ccs_socket_shutdown),
1183+ MY_HOOK_INIT(socket_accept, ccs_socket_accept),
1184+ MY_HOOK_INIT(inode_free_security, ccs_inode_free_security),
1185+#endif
1186+};
1187+
1188+static inline void add_hook(struct security_hook_list *hook)
1189+{
1190+ list_add_tail_rcu(&hook->list, hook->head);
1191+}
1192+
1193+static void __init swap_hook(struct security_hook_list *hook,
1194+ union security_list_options *original)
1195+{
1196+ struct list_head *list = hook->head;
1197+ if (list_empty(list)) {
1198+ add_hook(hook);
1199+ } else {
1200+ struct security_hook_list *shp =
1201+ list_last_entry(list, struct security_hook_list, list);
1202+ *original = shp->hook;
1203+ smp_wmb();
1204+ shp->hook = hook->hook;
1205+ }
1206+}
1207+
1208+/**
1209+ * ccs_init - Initialize this module.
1210+ *
1211+ * Returns 0 on success, negative value otherwise.
1212+ */
1213+static int __init ccs_init(void)
1214+{
1215+ int idx;
1216+ struct security_hook_heads *hooks = probe_security_hook_heads();
1217+ if (!hooks)
1218+ goto out;
1219+ for (idx = 0; idx < ARRAY_SIZE(akari_hooks); idx++)
1220+ akari_hooks[idx].head = ((void *) hooks)
1221+ + ((unsigned long) akari_hooks[idx].head)
1222+ - ((unsigned long) &probe_dummy_security_hook_heads);
1223+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1224+ if (!ccsecurity_exports.find_task_by_vpid)
1225+ goto out;
1226+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1227+ if (!ccsecurity_exports.find_task_by_pid_ns)
1228+ goto out;
1229+ ccsecurity_exports.d_absolute_path = probe_d_absolute_path();
1230+ if (!ccsecurity_exports.d_absolute_path)
1231+ goto out;
1232+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1233+ INIT_LIST_HEAD(&ccs_cred_security_list[idx]);
1234+ INIT_LIST_HEAD(&ccs_task_security_list[idx]);
1235+ }
1236+ ccs_main_init();
1237+ swap_hook(&akari_hooks[0], &original_cred_free);
1238+ swap_hook(&akari_hooks[1], &original_cred_prepare);
1239+ swap_hook(&akari_hooks[2], &original_cred_alloc_blank);
1240+ for (idx = 3; idx < ARRAY_SIZE(akari_hooks); idx++)
1241+ add_hook(&akari_hooks[idx]);
1242+ printk(KERN_INFO "AKARI: 1.0.39 2019/08/20\n");
1243+ printk(KERN_INFO
1244+ "Access Keeping And Regulating Instrument registered.\n");
1245+ return 0;
1246+out:
1247+ return -EINVAL;
1248+}
1249+
1250+module_init(ccs_init);
1251+MODULE_LICENSE("GPL");
1252+
1253+/**
1254+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1255+ *
1256+ * @domain: Pointer to "struct ccs_domain_info".
1257+ *
1258+ * Returns true if @domain is in use, false otherwise.
1259+ *
1260+ * Caller holds rcu_read_lock().
1261+ */
1262+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1263+{
1264+ int idx;
1265+ struct ccs_security *ptr;
1266+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1267+ struct list_head *list = &ccs_cred_security_list[idx];
1268+ list_for_each_entry_rcu(ptr, list, list) {
1269+ struct ccs_execve *ee = ptr->ee;
1270+ if (ptr->ccs_domain_info == domain ||
1271+ (ee && ee->previous_domain == domain)) {
1272+ return true;
1273+ }
1274+ }
1275+ }
1276+ return false;
1277+}
1278+
1279+/**
1280+ * ccs_add_task_security - Add "struct ccs_security" to list.
1281+ *
1282+ * @ptr: Pointer to "struct ccs_security".
1283+ * @list: Pointer to "struct list_head".
1284+ *
1285+ * Returns nothing.
1286+ */
1287+static void ccs_add_task_security(struct ccs_security *ptr,
1288+ struct list_head *list)
1289+{
1290+ unsigned long flags;
1291+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1292+ list_add_rcu(&ptr->list, list);
1293+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1294+}
1295+
1296+/**
1297+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1298+ *
1299+ * @task: Pointer to "struct task_struct".
1300+ *
1301+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1302+ * out of memory, &ccs_default_security otherwise.
1303+ *
1304+ * If @task is current thread and "struct ccs_security" for current thread was
1305+ * not found, I try to allocate it. But if allocation failed, current thread
1306+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1307+ * won't work.
1308+ */
1309+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1310+{
1311+ struct ccs_security *ptr;
1312+ struct list_head *list = &ccs_task_security_list
1313+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1314+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1315+ while (!list->next)
1316+ smp_rmb();
1317+ rcu_read_lock();
1318+ list_for_each_entry_rcu(ptr, list, list) {
1319+ if (ptr->pid != task->pids[PIDTYPE_PID].pid)
1320+ continue;
1321+ rcu_read_unlock();
1322+ /*
1323+ * Current thread needs to transit from old domain to new
1324+ * domain before do_execve() succeeds in order to check
1325+ * permission for interpreters and environment variables using
1326+ * new domain's ACL rules. The domain transition has to be
1327+ * visible from other CPU in order to allow interactive
1328+ * enforcing mode. Also, the domain transition has to be
1329+ * reverted if do_execve() failed. However, an LSM hook for
1330+ * reverting domain transition is missing.
1331+ *
1332+ * security_prepare_creds() is called from prepare_creds() from
1333+ * prepare_bprm_creds() from do_execve() before setting
1334+ * current->in_execve flag, and current->in_execve flag is
1335+ * cleared by the time next do_execve() request starts.
1336+ * This means that we can emulate the missing LSM hook for
1337+ * reverting domain transition, by calling this function from
1338+ * security_prepare_creds().
1339+ *
1340+ * If current->in_execve is not set but ptr->ccs_flags has
1341+ * CCS_TASK_IS_IN_EXECVE set, it indicates that do_execve()
1342+ * has failed and reverting domain transition is needed.
1343+ */
1344+ if (task == current &&
1345+ (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE) &&
1346+ !current->in_execve) {
1347+ ccs_debug_trace("4");
1348+ ccs_clear_execve(-1, ptr);
1349+ }
1350+ return ptr;
1351+ }
1352+ rcu_read_unlock();
1353+ if (task != current) {
1354+ /*
1355+ * If a thread does nothing after fork(), caller will reach
1356+ * here because "struct ccs_security" for that thread is not
1357+ * yet allocated. But that thread is keeping a snapshot of
1358+ * "struct ccs_security" taken as of ccs_task_create()
1359+ * associated with that thread's "struct cred".
1360+ *
1361+ * Since that snapshot will be used as initial data when that
1362+ * thread allocates "struct ccs_security" for that thread, we
1363+ * can return that snapshot rather than &ccs_default_security.
1364+ *
1365+ * Since this function is called by only ccs_select_one() and
1366+ * ccs_read_pid() (via ccs_task_domain() and ccs_task_flags()),
1367+ * it is guaranteed that caller has called rcu_read_lock()
1368+ * (via ccs_tasklist_lock()) before finding this thread and
1369+ * this thread is valid. Therefore, we can do __task_cred(task)
1370+ * like get_robust_list() does.
1371+ */
1372+ return ccs_find_cred_security(__task_cred(task));
1373+ }
1374+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1375+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1376+ if (!ptr) {
1377+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1378+ task->pid);
1379+ send_sig(SIGKILL, current, 0);
1380+ return &ccs_oom_security;
1381+ }
1382+ *ptr = *ccs_find_cred_security(task->cred);
1383+ /* We can shortcut because task == current. */
1384+ ptr->pid = get_pid(((struct task_struct *) task)->
1385+ pids[PIDTYPE_PID].pid);
1386+ ptr->cred = NULL;
1387+ ccs_add_task_security(ptr, list);
1388+ return ptr;
1389+}
1390+
1391+/**
1392+ * ccs_copy_cred_security - Allocate memory for new credentials.
1393+ *
1394+ * @new: Pointer to "struct cred".
1395+ * @old: Pointer to "struct cred".
1396+ * @gfp: Memory allocation flags.
1397+ *
1398+ * Returns 0 on success, negative value otherwise.
1399+ */
1400+static int ccs_copy_cred_security(const struct cred *new,
1401+ const struct cred *old, gfp_t gfp)
1402+{
1403+ struct ccs_security *old_security = ccs_find_cred_security(old);
1404+ struct ccs_security *new_security =
1405+ kzalloc(sizeof(*new_security), gfp);
1406+ if (!new_security)
1407+ return -ENOMEM;
1408+ *new_security = *old_security;
1409+ new_security->cred = new;
1410+ ccs_add_cred_security(new_security);
1411+ return 0;
1412+}
1413+
1414+/**
1415+ * ccs_find_cred_security - Find "struct ccs_security" for given credential.
1416+ *
1417+ * @cred: Pointer to "struct cred".
1418+ *
1419+ * Returns pointer to "struct ccs_security" on success, &ccs_default_security
1420+ * otherwise.
1421+ */
1422+static struct ccs_security *ccs_find_cred_security(const struct cred *cred)
1423+{
1424+ struct ccs_security *ptr;
1425+ struct list_head *list = &ccs_cred_security_list
1426+ [hash_ptr((void *) cred, CCS_TASK_SECURITY_HASH_BITS)];
1427+ rcu_read_lock();
1428+ list_for_each_entry_rcu(ptr, list, list) {
1429+ if (ptr->cred != cred)
1430+ continue;
1431+ rcu_read_unlock();
1432+ return ptr;
1433+ }
1434+ rcu_read_unlock();
1435+ return &ccs_default_security;
1436+}
1437+
1438+/**
1439+ * ccs_task_security_gc - Do garbage collection for "struct task_struct".
1440+ *
1441+ * Returns nothing.
1442+ *
1443+ * Since security_task_free() is missing, I can't release memory associated
1444+ * with "struct task_struct" when a task dies. Therefore, I hold a reference on
1445+ * "struct pid" and runs garbage collection when associated
1446+ * "struct task_struct" has gone.
1447+ */
1448+static void ccs_task_security_gc(void)
1449+{
1450+ static DEFINE_SPINLOCK(lock);
1451+ static atomic_t gc_counter = ATOMIC_INIT(0);
1452+ unsigned int idx;
1453+ /*
1454+ * If some process is doing execve(), try to garbage collection now.
1455+ * We should kfree() memory associated with "struct ccs_security"->ee
1456+ * as soon as execve() has completed in order to compensate for lack of
1457+ * security_bprm_free() and security_task_free() hooks.
1458+ *
1459+ * Otherwise, reduce frequency for performance reason.
1460+ */
1461+ if (!atomic_read(&ccs_in_execve_tasks) &&
1462+ atomic_inc_return(&gc_counter) < 1024)
1463+ return;
1464+ if (!spin_trylock(&lock))
1465+ return;
1466+ atomic_set(&gc_counter, 0);
1467+ rcu_read_lock();
1468+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1469+ struct ccs_security *ptr;
1470+ struct list_head *list = &ccs_task_security_list[idx];
1471+ list_for_each_entry_rcu(ptr, list, list) {
1472+ if (pid_task(ptr->pid, PIDTYPE_PID))
1473+ continue;
1474+ ccs_del_security(ptr);
1475+ }
1476+ }
1477+ rcu_read_unlock();
1478+ spin_unlock(&lock);
1479+}
--- tags/patches/1.0.39/lsm-4.7.c (nonexistent)
+++ tags/patches/1.0.39/lsm-4.7.c (revision 612)
@@ -0,0 +1,1482 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.39 2019/08/20
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+static void ccs_task_security_gc(void);
14+static int ccs_copy_cred_security(const struct cred *new,
15+ const struct cred *old, gfp_t gfp);
16+static struct ccs_security *ccs_find_cred_security(const struct cred *cred);
17+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
18+static atomic_t ccs_in_execve_tasks = ATOMIC_INIT(0);
19+/*
20+ * List of "struct ccs_security" for "struct pid".
21+ *
22+ * All instances on this list is guaranteed that "struct ccs_security"->pid !=
23+ * NULL. Also, instances on this list that are in execve() are guaranteed that
24+ * "struct ccs_security"->cred remembers "struct linux_binprm"->cred with a
25+ * refcount on "struct linux_binprm"->cred.
26+ */
27+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
28+/*
29+ * List of "struct ccs_security" for "struct cred".
30+ *
31+ * Since the number of "struct cred" is nearly equals to the number of
32+ * "struct pid", we allocate hash tables like ccs_task_security_list.
33+ *
34+ * All instances on this list are guaranteed that "struct ccs_security"->pid ==
35+ * NULL and "struct ccs_security"->cred != NULL.
36+ */
37+static struct list_head ccs_cred_security_list[CCS_MAX_TASK_SECURITY_HASH];
38+
39+/* Dummy security context for avoiding NULL pointer dereference. */
40+static struct ccs_security ccs_oom_security = {
41+ .ccs_domain_info = &ccs_kernel_domain
42+};
43+
44+/* Dummy security context for avoiding NULL pointer dereference. */
45+static struct ccs_security ccs_default_security = {
46+ .ccs_domain_info = &ccs_kernel_domain
47+};
48+
49+/* For exporting variables and functions. */
50+struct ccsecurity_exports ccsecurity_exports;
51+/* Members are updated by loadable kernel module. */
52+struct ccsecurity_operations ccsecurity_ops;
53+
54+/* Original hooks. */
55+static union security_list_options original_cred_prepare;
56+static union security_list_options original_cred_free;
57+static union security_list_options original_cred_alloc_blank;
58+
59+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
60+
61+/**
62+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
63+ *
64+ * @count: Count to increment or decrement.
65+ *
66+ * Returns updated counter.
67+ */
68+static unsigned int ccs_update_ee_counter(int count)
69+{
70+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
71+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
72+ return atomic_add_return(count, &ccs_ee_counter);
73+}
74+
75+/**
76+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
77+ *
78+ * @ee: Pointer to "struct ccs_execve".
79+ *
80+ * Returns nothing.
81+ */
82+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
83+{
84+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
85+ current->pid, ccs_update_ee_counter(1) - 1);
86+}
87+
88+/**
89+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
90+ *
91+ * @ee: Pointer to "struct ccs_execve".
92+ * @task: True if released by current task, false otherwise.
93+ *
94+ * Returns nothing.
95+ */
96+void ccs_audit_free_execve(const struct ccs_execve * const ee,
97+ const bool is_current)
98+{
99+ const unsigned int tmp = ccs_update_ee_counter(-1);
100+ if (is_current)
101+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
102+ ee, current->pid, tmp);
103+ else
104+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
105+ ee, tmp);
106+}
107+
108+#endif
109+
110+#if !defined(CONFIG_AKARI_DEBUG)
111+#define ccs_debug_trace(pos) do { } while (0)
112+#else
113+#define ccs_debug_trace(pos) \
114+ do { \
115+ static bool done; \
116+ if (!done) { \
117+ printk(KERN_INFO \
118+ "AKARI: Debug trace: " pos " of 4\n"); \
119+ done = true; \
120+ } \
121+ } while (0)
122+#endif
123+
124+/**
125+ * ccs_clear_execve - Release memory used by do_execve().
126+ *
127+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
128+ * @security: Pointer to "struct ccs_security".
129+ *
130+ * Returns nothing.
131+ */
132+static void ccs_clear_execve(int ret, struct ccs_security *security)
133+{
134+ struct ccs_execve *ee;
135+ if (security == &ccs_default_security || security == &ccs_oom_security)
136+ return;
137+ ee = security->ee;
138+ security->ee = NULL;
139+ if (!ee)
140+ return;
141+ atomic_dec(&ccs_in_execve_tasks);
142+ ccs_finish_execve(ret, ee);
143+}
144+
145+/**
146+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
147+ *
148+ * @rcu: Pointer to "struct rcu_head".
149+ *
150+ * Returns nothing.
151+ */
152+static void ccs_rcu_free(struct rcu_head *rcu)
153+{
154+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
155+ struct ccs_execve *ee = ptr->ee;
156+ /*
157+ * If this security context was associated with "struct pid" and
158+ * ptr->ccs_flags has CCS_TASK_IS_IN_EXECVE set, it indicates that a
159+ * "struct task_struct" associated with this security context exited
160+ * immediately after do_execve() has failed.
161+ */
162+ if (ptr->pid && (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
163+ ccs_debug_trace("1");
164+ atomic_dec(&ccs_in_execve_tasks);
165+ }
166+ /*
167+ * If this security context was associated with "struct pid",
168+ * drop refcount obtained by get_pid() in ccs_find_task_security().
169+ */
170+ if (ptr->pid) {
171+ ccs_debug_trace("2");
172+ put_pid(ptr->pid);
173+ }
174+ if (ee) {
175+ ccs_debug_trace("3");
176+ ccs_audit_free_execve(ee, false);
177+ kfree(ee->handler_path);
178+ kfree(ee);
179+ }
180+ kfree(ptr);
181+}
182+
183+/**
184+ * ccs_del_security - Release "struct ccs_security".
185+ *
186+ * @ptr: Pointer to "struct ccs_security".
187+ *
188+ * Returns nothing.
189+ */
190+static void ccs_del_security(struct ccs_security *ptr)
191+{
192+ unsigned long flags;
193+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
194+ return;
195+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
196+ list_del_rcu(&ptr->list);
197+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
198+ call_rcu(&ptr->rcu, ccs_rcu_free);
199+}
200+
201+/**
202+ * ccs_add_cred_security - Add "struct ccs_security" to list.
203+ *
204+ * @ptr: Pointer to "struct ccs_security".
205+ *
206+ * Returns nothing.
207+ */
208+static void ccs_add_cred_security(struct ccs_security *ptr)
209+{
210+ unsigned long flags;
211+ struct list_head *list = &ccs_cred_security_list
212+ [hash_ptr((void *) ptr->cred, CCS_TASK_SECURITY_HASH_BITS)];
213+#ifdef CONFIG_AKARI_DEBUG
214+ if (ptr->pid)
215+ printk(KERN_INFO "AKARI: \"struct ccs_security\"->pid != NULL"
216+ "\n");
217+#endif
218+ ptr->pid = NULL;
219+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
220+ list_add_rcu(&ptr->list, list);
221+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
222+}
223+
224+/**
225+ * ccs_task_create - Make snapshot of security context for new task.
226+ *
227+ * @clone_flags: Flags passed to clone().
228+ *
229+ * Returns 0 on success, negative value otherwise.
230+ */
231+static int ccs_task_create(unsigned long clone_flags)
232+{
233+ struct ccs_security *old_security;
234+ struct ccs_security *new_security;
235+ struct cred *cred = prepare_creds();
236+ if (!cred)
237+ return -ENOMEM;
238+ old_security = ccs_find_task_security(current);
239+ new_security = ccs_find_cred_security(cred);
240+ new_security->ccs_domain_info = old_security->ccs_domain_info;
241+ new_security->ccs_flags = old_security->ccs_flags;
242+ return commit_creds(cred);
243+}
244+
245+/**
246+ * ccs_cred_prepare - Allocate memory for new credentials.
247+ *
248+ * @new: Pointer to "struct cred".
249+ * @old: Pointer to "struct cred".
250+ * @gfp: Memory allocation flags.
251+ *
252+ * Returns 0 on success, negative value otherwise.
253+ */
254+static int ccs_cred_prepare(struct cred *new, const struct cred *old,
255+ gfp_t gfp)
256+{
257+ int rc1;
258+ /*
259+ * For checking whether reverting domain transition is needed or not.
260+ *
261+ * See ccs_find_task_security() for reason.
262+ */
263+ if (gfp == GFP_KERNEL)
264+ ccs_find_task_security(current);
265+ rc1 = ccs_copy_cred_security(new, old, gfp);
266+ if (gfp == GFP_KERNEL)
267+ ccs_task_security_gc();
268+ if (original_cred_prepare.cred_prepare) {
269+ const int rc2 = original_cred_prepare.cred_prepare(new, old,
270+ gfp);
271+ if (rc2) {
272+ ccs_del_security(ccs_find_cred_security(new));
273+ return rc2;
274+ }
275+ }
276+ return rc1;
277+}
278+
279+/**
280+ * ccs_cred_free - Release memory used by credentials.
281+ *
282+ * @cred: Pointer to "struct cred".
283+ *
284+ * Returns nothing.
285+ */
286+static void ccs_cred_free(struct cred *cred)
287+{
288+ if (original_cred_free.cred_free)
289+ original_cred_free.cred_free(cred);
290+ ccs_del_security(ccs_find_cred_security(cred));
291+}
292+
293+/**
294+ * ccs_alloc_cred_security - Allocate memory for new credentials.
295+ *
296+ * @cred: Pointer to "struct cred".
297+ * @gfp: Memory allocation flags.
298+ *
299+ * Returns 0 on success, negative value otherwise.
300+ */
301+static int ccs_alloc_cred_security(const struct cred *cred, gfp_t gfp)
302+{
303+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
304+ gfp);
305+ if (!new_security)
306+ return -ENOMEM;
307+ new_security->cred = cred;
308+ ccs_add_cred_security(new_security);
309+ return 0;
310+}
311+
312+/**
313+ * ccs_cred_alloc_blank - Allocate memory for new credentials.
314+ *
315+ * @new: Pointer to "struct cred".
316+ * @gfp: Memory allocation flags.
317+ *
318+ * Returns 0 on success, negative value otherwise.
319+ */
320+static int ccs_cred_alloc_blank(struct cred *new, gfp_t gfp)
321+{
322+ const int rc1 = ccs_alloc_cred_security(new, gfp);
323+ if (original_cred_alloc_blank.cred_alloc_blank) {
324+ const int rc2 = original_cred_alloc_blank.
325+ cred_alloc_blank(new, gfp);
326+ if (rc2) {
327+ ccs_del_security(ccs_find_cred_security(new));
328+ return rc2;
329+ }
330+ }
331+ return rc1;
332+}
333+
334+/**
335+ * ccs_cred_transfer - Transfer "struct ccs_security" between credentials.
336+ *
337+ * @new: Pointer to "struct cred".
338+ * @old: Pointer to "struct cred".
339+ *
340+ * Returns nothing.
341+ */
342+static void ccs_cred_transfer(struct cred *new, const struct cred *old)
343+{
344+ struct ccs_security *new_security = ccs_find_cred_security(new);
345+ struct ccs_security *old_security = ccs_find_cred_security(old);
346+ if (new_security == &ccs_default_security ||
347+ new_security == &ccs_oom_security ||
348+ old_security == &ccs_default_security ||
349+ old_security == &ccs_oom_security)
350+ return;
351+ new_security->ccs_flags = old_security->ccs_flags;
352+ new_security->ccs_domain_info = old_security->ccs_domain_info;
353+}
354+
355+/**
356+ * ccs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
357+ *
358+ * @bprm: Pointer to "struct linux_binprm".
359+ *
360+ * Returns nothing.
361+ */
362+static void ccs_bprm_committing_creds(struct linux_binprm *bprm)
363+{
364+ struct ccs_security *old_security = ccs_current_security();
365+ struct ccs_security *new_security;
366+ if (old_security == &ccs_default_security ||
367+ old_security == &ccs_oom_security)
368+ return;
369+ ccs_clear_execve(0, old_security);
370+ /* Update current task's cred's domain for future fork(). */
371+ new_security = ccs_find_cred_security(bprm->cred);
372+ new_security->ccs_flags = old_security->ccs_flags;
373+ new_security->ccs_domain_info = old_security->ccs_domain_info;
374+}
375+
376+/**
377+ * ccs_bprm_check_security - Check permission for execve().
378+ *
379+ * @bprm: Pointer to "struct linux_binprm".
380+ *
381+ * Returns 0 on success, negative value otherwise.
382+ */
383+static int ccs_bprm_check_security(struct linux_binprm *bprm)
384+{
385+ struct ccs_security *security = ccs_current_security();
386+ int rc;
387+ if (security == &ccs_default_security || security == &ccs_oom_security)
388+ return -ENOMEM;
389+ if (security->ee)
390+ return 0;
391+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
392+ if (!ccs_policy_loaded)
393+ ccs_load_policy(bprm->filename);
394+#endif
395+ rc = ccs_start_execve(bprm, &security->ee);
396+ if (security->ee)
397+ atomic_inc(&ccs_in_execve_tasks);
398+ return rc;
399+}
400+
401+/**
402+ * ccs_file_open - Check permission for open().
403+ *
404+ * @f: Pointer to "struct file".
405+ * @cred: Pointer to "struct cred".
406+ *
407+ * Returns 0 on success, negative value otherwise.
408+ */
409+static int ccs_file_open(struct file *f, const struct cred *cred)
410+{
411+ return ccs_open_permission(f);
412+}
413+
414+#ifdef CONFIG_SECURITY_PATH
415+
416+/**
417+ * ccs_path_chown - Check permission for chown()/chgrp().
418+ *
419+ * @path: Pointer to "struct path".
420+ * @user: User ID.
421+ * @group: Group ID.
422+ *
423+ * Returns 0 on success, negative value otherwise.
424+ */
425+static int ccs_path_chown(const struct path *path, kuid_t user, kgid_t group)
426+{
427+ return ccs_chown_permission(path->dentry, path->mnt, user, group);
428+}
429+
430+/**
431+ * ccs_path_chmod - Check permission for chmod().
432+ *
433+ * @path: Pointer to "struct path".
434+ * @mode: Mode.
435+ *
436+ * Returns 0 on success, negative value otherwise.
437+ */
438+static int ccs_path_chmod(const struct path *path, umode_t mode)
439+{
440+ return ccs_chmod_permission(path->dentry, path->mnt, mode);
441+}
442+
443+/**
444+ * ccs_path_chroot - Check permission for chroot().
445+ *
446+ * @path: Pointer to "struct path".
447+ *
448+ * Returns 0 on success, negative value otherwise.
449+ */
450+static int ccs_path_chroot(const struct path *path)
451+{
452+ return ccs_chroot_permission(path);
453+}
454+
455+/**
456+ * ccs_path_truncate - Check permission for truncate().
457+ *
458+ * @path: Pointer to "struct path".
459+ *
460+ * Returns 0 on success, negative value otherwise.
461+ */
462+static int ccs_path_truncate(const struct path *path)
463+{
464+ return ccs_truncate_permission(path->dentry, path->mnt);
465+}
466+
467+#else
468+
469+/**
470+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
471+ *
472+ * @dentry: Pointer to "struct dentry".
473+ * @attr: Pointer to "struct iattr".
474+ *
475+ * Returns 0 on success, negative value otherwise.
476+ */
477+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
478+{
479+ const int rc1 = (attr->ia_valid & ATTR_UID) ?
480+ ccs_chown_permission(dentry, NULL, attr->ia_uid, INVALID_GID) :
481+ 0;
482+ const int rc2 = (attr->ia_valid & ATTR_GID) ?
483+ ccs_chown_permission(dentry, NULL, INVALID_UID, attr->ia_gid) :
484+ 0;
485+ const int rc3 = (attr->ia_valid & ATTR_MODE) ?
486+ ccs_chmod_permission(dentry, NULL, attr->ia_mode) : 0;
487+ const int rc4 = (attr->ia_valid & ATTR_SIZE) ?
488+ ccs_truncate_permission(dentry, NULL) : 0;
489+ if (rc4)
490+ return rc4;
491+ if (rc3)
492+ return rc3;
493+ if (rc2)
494+ return rc2;
495+ return rc1;
496+}
497+
498+#endif
499+
500+/**
501+ * ccs_inode_getattr - Check permission for stat().
502+ *
503+ * @path: Pointer to "struct path".
504+ *
505+ * Returns 0 on success, negative value otherwise.
506+ */
507+static int ccs_inode_getattr(const struct path *path)
508+{
509+ return ccs_getattr_permission(path->mnt, path->dentry);
510+}
511+
512+#ifdef CONFIG_SECURITY_PATH
513+
514+/**
515+ * ccs_path_mknod - Check permission for mknod().
516+ *
517+ * @dir: Pointer to "struct path".
518+ * @dentry: Pointer to "struct dentry".
519+ * @mode: Create mode.
520+ * @dev: Device major/minor number.
521+ *
522+ * Returns 0 on success, negative value otherwise.
523+ */
524+static int ccs_path_mknod(const struct path *dir, struct dentry *dentry,
525+ umode_t mode, unsigned int dev)
526+{
527+ return ccs_mknod_permission(dentry, dir->mnt, mode, dev);
528+}
529+
530+/**
531+ * ccs_path_mkdir - Check permission for mkdir().
532+ *
533+ * @dir: Pointer to "struct path".
534+ * @dentry: Pointer to "struct dentry".
535+ * @mode: Create mode.
536+ *
537+ * Returns 0 on success, negative value otherwise.
538+ */
539+static int ccs_path_mkdir(const struct path *dir, struct dentry *dentry,
540+ umode_t mode)
541+{
542+ return ccs_mkdir_permission(dentry, dir->mnt, mode);
543+}
544+
545+/**
546+ * ccs_path_rmdir - Check permission for rmdir().
547+ *
548+ * @dir: Pointer to "struct path".
549+ * @dentry: Pointer to "struct dentry".
550+ *
551+ * Returns 0 on success, negative value otherwise.
552+ */
553+static int ccs_path_rmdir(const struct path *dir, struct dentry *dentry)
554+{
555+ return ccs_rmdir_permission(dentry, dir->mnt);
556+}
557+
558+/**
559+ * ccs_path_unlink - Check permission for unlink().
560+ *
561+ * @dir: Pointer to "struct path".
562+ * @dentry: Pointer to "struct dentry".
563+ *
564+ * Returns 0 on success, negative value otherwise.
565+ */
566+static int ccs_path_unlink(const struct path *dir, struct dentry *dentry)
567+{
568+ return ccs_unlink_permission(dentry, dir->mnt);
569+}
570+
571+/**
572+ * ccs_path_symlink - Check permission for symlink().
573+ *
574+ * @dir: Pointer to "struct path".
575+ * @dentry: Pointer to "struct dentry".
576+ * @old_name: Content of symbolic link.
577+ *
578+ * Returns 0 on success, negative value otherwise.
579+ */
580+static int ccs_path_symlink(const struct path *dir, struct dentry *dentry,
581+ const char *old_name)
582+{
583+ return ccs_symlink_permission(dentry, dir->mnt, old_name);
584+}
585+
586+/**
587+ * ccs_path_rename - Check permission for rename().
588+ *
589+ * @old_dir: Pointer to "struct path".
590+ * @old_dentry: Pointer to "struct dentry".
591+ * @new_dir: Pointer to "struct path".
592+ * @new_dentry: Pointer to "struct dentry".
593+ *
594+ * Returns 0 on success, negative value otherwise.
595+ */
596+static int ccs_path_rename(const struct path *old_dir,
597+ struct dentry *old_dentry,
598+ const struct path *new_dir,
599+ struct dentry *new_dentry)
600+{
601+ return ccs_rename_permission(old_dentry, new_dentry, old_dir->mnt);
602+}
603+
604+/**
605+ * ccs_path_link - Check permission for link().
606+ *
607+ * @old_dentry: Pointer to "struct dentry".
608+ * @new_dir: Pointer to "struct path".
609+ * @new_dentry: Pointer to "struct dentry".
610+ *
611+ * Returns 0 on success, negative value otherwise.
612+ */
613+static int ccs_path_link(struct dentry *old_dentry, const struct path *new_dir,
614+ struct dentry *new_dentry)
615+{
616+ return ccs_link_permission(old_dentry, new_dentry, new_dir->mnt);
617+}
618+
619+#else
620+
621+/**
622+ * ccs_inode_mknod - Check permission for mknod().
623+ *
624+ * @dir: Pointer to "struct inode".
625+ * @dentry: Pointer to "struct dentry".
626+ * @mode: Create mode.
627+ * @dev: Device major/minor number.
628+ *
629+ * Returns 0 on success, negative value otherwise.
630+ */
631+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
632+ umode_t mode, dev_t dev)
633+{
634+ return ccs_mknod_permission(dentry, NULL, mode, dev);
635+}
636+
637+/**
638+ * ccs_inode_mkdir - Check permission for mkdir().
639+ *
640+ * @dir: Pointer to "struct inode".
641+ * @dentry: Pointer to "struct dentry".
642+ * @mode: Create mode.
643+ *
644+ * Returns 0 on success, negative value otherwise.
645+ */
646+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
647+ umode_t mode)
648+{
649+ return ccs_mkdir_permission(dentry, NULL, mode);
650+}
651+
652+/**
653+ * ccs_inode_rmdir - Check permission for rmdir().
654+ *
655+ * @dir: Pointer to "struct inode".
656+ * @dentry: Pointer to "struct dentry".
657+ *
658+ * Returns 0 on success, negative value otherwise.
659+ */
660+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry)
661+{
662+ return ccs_rmdir_permission(dentry, NULL);
663+}
664+
665+/**
666+ * ccs_inode_unlink - Check permission for unlink().
667+ *
668+ * @dir: Pointer to "struct inode".
669+ * @dentry: Pointer to "struct dentry".
670+ *
671+ * Returns 0 on success, negative value otherwise.
672+ */
673+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
674+{
675+ return ccs_unlink_permission(dentry, NULL);
676+}
677+
678+/**
679+ * ccs_inode_symlink - Check permission for symlink().
680+ *
681+ * @dir: Pointer to "struct inode".
682+ * @dentry: Pointer to "struct dentry".
683+ * @old_name: Content of symbolic link.
684+ *
685+ * Returns 0 on success, negative value otherwise.
686+ */
687+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
688+ const char *old_name)
689+{
690+ return ccs_symlink_permission(dentry, NULL, old_name);
691+}
692+
693+/**
694+ * ccs_inode_rename - Check permission for rename().
695+ *
696+ * @old_dir: Pointer to "struct inode".
697+ * @old_dentry: Pointer to "struct dentry".
698+ * @new_dir: Pointer to "struct inode".
699+ * @new_dentry: Pointer to "struct dentry".
700+ *
701+ * Returns 0 on success, negative value otherwise.
702+ */
703+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
704+ struct inode *new_dir, struct dentry *new_dentry)
705+{
706+ return ccs_rename_permission(old_dentry, new_dentry, NULL);
707+}
708+
709+/**
710+ * ccs_inode_link - Check permission for link().
711+ *
712+ * @old_dentry: Pointer to "struct dentry".
713+ * @dir: Pointer to "struct inode".
714+ * @new_dentry: Pointer to "struct dentry".
715+ *
716+ * Returns 0 on success, negative value otherwise.
717+ */
718+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
719+ struct dentry *new_dentry)
720+{
721+ return ccs_link_permission(old_dentry, new_dentry, NULL);
722+}
723+
724+/**
725+ * ccs_inode_create - Check permission for creat().
726+ *
727+ * @dir: Pointer to "struct inode".
728+ * @dentry: Pointer to "struct dentry".
729+ * @mode: Create mode.
730+ *
731+ * Returns 0 on success, negative value otherwise.
732+ */
733+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
734+ umode_t mode)
735+{
736+ return ccs_mknod_permission(dentry, NULL, mode, 0);
737+}
738+
739+#endif
740+
741+#ifdef CONFIG_SECURITY_NETWORK
742+
743+#include <net/sock.h>
744+
745+/* Structure for remembering an accept()ed socket's status. */
746+struct ccs_socket_tag {
747+ struct list_head list;
748+ struct inode *inode;
749+ int status;
750+ struct rcu_head rcu;
751+};
752+
753+/*
754+ * List for managing accept()ed sockets.
755+ * Since we don't need to keep an accept()ed socket into this list after
756+ * once the permission was granted, the number of entries in this list is
757+ * likely small. Therefore, we don't use hash tables.
758+ */
759+static LIST_HEAD(ccs_accepted_socket_list);
760+/* Lock for protecting ccs_accepted_socket_list . */
761+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
762+
763+/**
764+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
765+ *
766+ * @inode: Pointer to "struct inode".
767+ * @status: New status.
768+ *
769+ * Returns nothing.
770+ *
771+ * If @status == 0, memory for that socket will be released after RCU grace
772+ * period.
773+ */
774+static void ccs_update_socket_tag(struct inode *inode, int status)
775+{
776+ struct ccs_socket_tag *ptr;
777+ /*
778+ * Protect whole section because multiple threads may call this
779+ * function with same "sock" via ccs_validate_socket().
780+ */
781+ spin_lock(&ccs_accepted_socket_list_lock);
782+ rcu_read_lock();
783+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
784+ if (ptr->inode != inode)
785+ continue;
786+ ptr->status = status;
787+ if (status)
788+ break;
789+ list_del_rcu(&ptr->list);
790+ kfree_rcu(ptr, rcu);
791+ break;
792+ }
793+ rcu_read_unlock();
794+ spin_unlock(&ccs_accepted_socket_list_lock);
795+}
796+
797+/**
798+ * ccs_validate_socket - Check post accept() permission if needed.
799+ *
800+ * @sock: Pointer to "struct socket".
801+ *
802+ * Returns 0 on success, negative value otherwise.
803+ */
804+static int ccs_validate_socket(struct socket *sock)
805+{
806+ struct inode *inode = SOCK_INODE(sock);
807+ struct ccs_socket_tag *ptr;
808+ int ret = 0;
809+ rcu_read_lock();
810+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
811+ if (ptr->inode != inode)
812+ continue;
813+ ret = ptr->status;
814+ break;
815+ }
816+ rcu_read_unlock();
817+ if (ret <= 0)
818+ /*
819+ * This socket is not an accept()ed socket or this socket is
820+ * an accept()ed socket and post accept() permission is done.
821+ */
822+ return ret;
823+ /*
824+ * Check post accept() permission now.
825+ *
826+ * Strictly speaking, we need to pass both listen()ing socket and
827+ * accept()ed socket to __ccs_socket_post_accept_permission().
828+ * But since socket's family and type are same for both sockets,
829+ * passing the accept()ed socket in place for the listen()ing socket
830+ * will work.
831+ */
832+ ret = ccs_socket_post_accept_permission(sock, sock);
833+ /*
834+ * If permission was granted, we forget that this is an accept()ed
835+ * socket. Otherwise, we remember that this socket needs to return
836+ * error for subsequent socketcalls.
837+ */
838+ ccs_update_socket_tag(inode, ret);
839+ return ret;
840+}
841+
842+/**
843+ * ccs_socket_accept - Check permission for accept().
844+ *
845+ * @sock: Pointer to "struct socket".
846+ * @newsock: Pointer to "struct socket".
847+ *
848+ * Returns 0 on success, negative value otherwise.
849+ *
850+ * This hook is used for setting up environment for doing post accept()
851+ * permission check. If dereferencing sock->ops->something() were ordered by
852+ * rcu_dereference(), we could replace sock->ops with "a copy of original
853+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
854+ * in order to do post accept() permission check before returning to userspace.
855+ * If we make the copy in security_socket_post_create(), it would be possible
856+ * to safely replace sock->ops here, but we don't do so because we don't want
857+ * to allocate memory for sockets which do not call sock->ops->accept().
858+ * Therefore, we do post accept() permission check upon next socket syscalls
859+ * rather than between sock->ops->accept() and returning to userspace.
860+ * This means that if a socket was close()d before calling some socket
861+ * syscalls, post accept() permission check will not be done.
862+ */
863+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
864+{
865+ struct ccs_socket_tag *ptr;
866+ const int rc = ccs_validate_socket(sock);
867+ if (rc < 0)
868+ return rc;
869+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
870+ if (!ptr)
871+ return -ENOMEM;
872+ /*
873+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
874+ * "newsock" as "an accept()ed socket but post accept() permission
875+ * check is not done yet" by allocating memory using inode of the
876+ * "newsock" as a search key.
877+ */
878+ ptr->inode = SOCK_INODE(newsock);
879+ ptr->status = 1; /* Check post accept() permission later. */
880+ spin_lock(&ccs_accepted_socket_list_lock);
881+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
882+ spin_unlock(&ccs_accepted_socket_list_lock);
883+ return 0;
884+}
885+
886+/**
887+ * ccs_socket_listen - Check permission for listen().
888+ *
889+ * @sock: Pointer to "struct socket".
890+ * @backlog: Backlog parameter.
891+ *
892+ * Returns 0 on success, negative value otherwise.
893+ */
894+static int ccs_socket_listen(struct socket *sock, int backlog)
895+{
896+ const int rc = ccs_validate_socket(sock);
897+ if (rc < 0)
898+ return rc;
899+ return ccs_socket_listen_permission(sock);
900+}
901+
902+/**
903+ * ccs_socket_connect - Check permission for connect().
904+ *
905+ * @sock: Pointer to "struct socket".
906+ * @addr: Pointer to "struct sockaddr".
907+ * @addr_len: Size of @addr.
908+ *
909+ * Returns 0 on success, negative value otherwise.
910+ */
911+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
912+ int addr_len)
913+{
914+ const int rc = ccs_validate_socket(sock);
915+ if (rc < 0)
916+ return rc;
917+ return ccs_socket_connect_permission(sock, addr, addr_len);
918+}
919+
920+/**
921+ * ccs_socket_bind - Check permission for bind().
922+ *
923+ * @sock: Pointer to "struct socket".
924+ * @addr: Pointer to "struct sockaddr".
925+ * @addr_len: Size of @addr.
926+ *
927+ * Returns 0 on success, negative value otherwise.
928+ */
929+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
930+ int addr_len)
931+{
932+ const int rc = ccs_validate_socket(sock);
933+ if (rc < 0)
934+ return rc;
935+ return ccs_socket_bind_permission(sock, addr, addr_len);
936+}
937+
938+/**
939+ * ccs_socket_sendmsg - Check permission for sendmsg().
940+ *
941+ * @sock: Pointer to "struct socket".
942+ * @msg: Pointer to "struct msghdr".
943+ * @size: Size of message.
944+ *
945+ * Returns 0 on success, negative value otherwise.
946+ */
947+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
948+ int size)
949+{
950+ const int rc = ccs_validate_socket(sock);
951+ if (rc < 0)
952+ return rc;
953+ return ccs_socket_sendmsg_permission(sock, msg, size);
954+}
955+
956+/**
957+ * ccs_socket_recvmsg - Check permission for recvmsg().
958+ *
959+ * @sock: Pointer to "struct socket".
960+ * @msg: Pointer to "struct msghdr".
961+ * @size: Size of message.
962+ * @flags: Flags.
963+ *
964+ * Returns 0 on success, negative value otherwise.
965+ */
966+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
967+ int size, int flags)
968+{
969+ return ccs_validate_socket(sock);
970+}
971+
972+/**
973+ * ccs_socket_getsockname - Check permission for getsockname().
974+ *
975+ * @sock: Pointer to "struct socket".
976+ *
977+ * Returns 0 on success, negative value otherwise.
978+ */
979+static int ccs_socket_getsockname(struct socket *sock)
980+{
981+ return ccs_validate_socket(sock);
982+}
983+
984+/**
985+ * ccs_socket_getpeername - Check permission for getpeername().
986+ *
987+ * @sock: Pointer to "struct socket".
988+ *
989+ * Returns 0 on success, negative value otherwise.
990+ */
991+static int ccs_socket_getpeername(struct socket *sock)
992+{
993+ return ccs_validate_socket(sock);
994+}
995+
996+/**
997+ * ccs_socket_getsockopt - Check permission for getsockopt().
998+ *
999+ * @sock: Pointer to "struct socket".
1000+ * @level: Level.
1001+ * @optname: Option's name,
1002+ *
1003+ * Returns 0 on success, negative value otherwise.
1004+ */
1005+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
1006+{
1007+ return ccs_validate_socket(sock);
1008+}
1009+
1010+/**
1011+ * ccs_socket_setsockopt - Check permission for setsockopt().
1012+ *
1013+ * @sock: Pointer to "struct socket".
1014+ * @level: Level.
1015+ * @optname: Option's name,
1016+ *
1017+ * Returns 0 on success, negative value otherwise.
1018+ */
1019+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
1020+{
1021+ return ccs_validate_socket(sock);
1022+}
1023+
1024+/**
1025+ * ccs_socket_shutdown - Check permission for shutdown().
1026+ *
1027+ * @sock: Pointer to "struct socket".
1028+ * @how: Shutdown mode.
1029+ *
1030+ * Returns 0 on success, negative value otherwise.
1031+ */
1032+static int ccs_socket_shutdown(struct socket *sock, int how)
1033+{
1034+ return ccs_validate_socket(sock);
1035+}
1036+
1037+#define SOCKFS_MAGIC 0x534F434B
1038+
1039+/**
1040+ * ccs_inode_free_security - Release memory associated with an inode.
1041+ *
1042+ * @inode: Pointer to "struct inode".
1043+ *
1044+ * Returns nothing.
1045+ *
1046+ * We use this hook for releasing memory associated with an accept()ed socket.
1047+ */
1048+static void ccs_inode_free_security(struct inode *inode)
1049+{
1050+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1051+ ccs_update_socket_tag(inode, 0);
1052+}
1053+
1054+#endif
1055+
1056+/**
1057+ * ccs_sb_pivotroot - Check permission for pivot_root().
1058+ *
1059+ * @old_path: Pointer to "struct path".
1060+ * @new_path: Pointer to "struct path".
1061+ *
1062+ * Returns 0 on success, negative value otherwise.
1063+ */
1064+static int ccs_sb_pivotroot(const struct path *old_path,
1065+ const struct path *new_path)
1066+{
1067+ return ccs_pivot_root_permission(old_path, new_path);
1068+}
1069+
1070+/**
1071+ * ccs_sb_mount - Check permission for mount().
1072+ *
1073+ * @dev_name: Name of device file.
1074+ * @path: Pointer to "struct path".
1075+ * @type: Name of filesystem type. Maybe NULL.
1076+ * @flags: Mount options.
1077+ * @data_page: Optional data. Maybe NULL.
1078+ *
1079+ * Returns 0 on success, negative value otherwise.
1080+ */
1081+static int ccs_sb_mount(const char *dev_name, const struct path *path,
1082+ const char *type, unsigned long flags, void *data_page)
1083+{
1084+ return ccs_mount_permission(dev_name, path, type, flags, data_page);
1085+}
1086+
1087+/**
1088+ * ccs_sb_umount - Check permission for umount().
1089+ *
1090+ * @mnt: Pointer to "struct vfsmount".
1091+ * @flags: Unmount flags.
1092+ *
1093+ * Returns 0 on success, negative value otherwise.
1094+ */
1095+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1096+{
1097+ return ccs_umount_permission(mnt, flags);
1098+}
1099+
1100+/**
1101+ * ccs_file_fcntl - Check permission for fcntl().
1102+ *
1103+ * @file: Pointer to "struct file".
1104+ * @cmd: Command number.
1105+ * @arg: Value for @cmd.
1106+ *
1107+ * Returns 0 on success, negative value otherwise.
1108+ */
1109+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1110+ unsigned long arg)
1111+{
1112+ return ccs_fcntl_permission(file, cmd, arg);
1113+}
1114+
1115+/**
1116+ * ccs_file_ioctl - Check permission for ioctl().
1117+ *
1118+ * @filp: Pointer to "struct file".
1119+ * @cmd: Command number.
1120+ * @arg: Value for @cmd.
1121+ *
1122+ * Returns 0 on success, negative value otherwise.
1123+ */
1124+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1125+ unsigned long arg)
1126+{
1127+ return ccs_ioctl_permission(filp, cmd, arg);
1128+}
1129+
1130+#define MY_HOOK_INIT(HEAD, HOOK) \
1131+ { .head = &probe_dummy_security_hook_heads.HEAD, \
1132+ .hook = { .HEAD = HOOK } }
1133+
1134+static struct security_hook_list akari_hooks[] = {
1135+ /* Security context allocator. */
1136+ MY_HOOK_INIT(cred_free, ccs_cred_free),
1137+ MY_HOOK_INIT(cred_prepare, ccs_cred_prepare),
1138+ MY_HOOK_INIT(cred_alloc_blank, ccs_cred_alloc_blank),
1139+ MY_HOOK_INIT(cred_transfer, ccs_cred_transfer),
1140+ MY_HOOK_INIT(task_create, ccs_task_create),
1141+ /* Security context updater for successful execve(). */
1142+ MY_HOOK_INIT(bprm_check_security, ccs_bprm_check_security),
1143+ MY_HOOK_INIT(bprm_committing_creds, ccs_bprm_committing_creds),
1144+ /* Various permission checker. */
1145+ MY_HOOK_INIT(file_open, ccs_file_open),
1146+ MY_HOOK_INIT(file_fcntl, ccs_file_fcntl),
1147+ MY_HOOK_INIT(file_ioctl, ccs_file_ioctl),
1148+ MY_HOOK_INIT(sb_pivotroot, ccs_sb_pivotroot),
1149+ MY_HOOK_INIT(sb_mount, ccs_sb_mount),
1150+ MY_HOOK_INIT(sb_umount, ccs_sb_umount),
1151+#ifdef CONFIG_SECURITY_PATH
1152+ MY_HOOK_INIT(path_mknod, ccs_path_mknod),
1153+ MY_HOOK_INIT(path_mkdir, ccs_path_mkdir),
1154+ MY_HOOK_INIT(path_rmdir, ccs_path_rmdir),
1155+ MY_HOOK_INIT(path_unlink, ccs_path_unlink),
1156+ MY_HOOK_INIT(path_symlink, ccs_path_symlink),
1157+ MY_HOOK_INIT(path_rename, ccs_path_rename),
1158+ MY_HOOK_INIT(path_link, ccs_path_link),
1159+ MY_HOOK_INIT(path_truncate, ccs_path_truncate),
1160+ MY_HOOK_INIT(path_chmod, ccs_path_chmod),
1161+ MY_HOOK_INIT(path_chown, ccs_path_chown),
1162+ MY_HOOK_INIT(path_chroot, ccs_path_chroot),
1163+#else
1164+ MY_HOOK_INIT(inode_mknod, ccs_inode_mknod),
1165+ MY_HOOK_INIT(inode_mkdir, ccs_inode_mkdir),
1166+ MY_HOOK_INIT(inode_rmdir, ccs_inode_rmdir),
1167+ MY_HOOK_INIT(inode_unlink, ccs_inode_unlink),
1168+ MY_HOOK_INIT(inode_symlink, ccs_inode_symlink),
1169+ MY_HOOK_INIT(inode_rename, ccs_inode_rename),
1170+ MY_HOOK_INIT(inode_link, ccs_inode_link),
1171+ MY_HOOK_INIT(inode_create, ccs_inode_create),
1172+ MY_HOOK_INIT(inode_setattr, ccs_inode_setattr),
1173+#endif
1174+ MY_HOOK_INIT(inode_getattr, ccs_inode_getattr),
1175+#ifdef CONFIG_SECURITY_NETWORK
1176+ MY_HOOK_INIT(socket_bind, ccs_socket_bind),
1177+ MY_HOOK_INIT(socket_connect, ccs_socket_connect),
1178+ MY_HOOK_INIT(socket_listen, ccs_socket_listen),
1179+ MY_HOOK_INIT(socket_sendmsg, ccs_socket_sendmsg),
1180+ MY_HOOK_INIT(socket_recvmsg, ccs_socket_recvmsg),
1181+ MY_HOOK_INIT(socket_getsockname, ccs_socket_getsockname),
1182+ MY_HOOK_INIT(socket_getpeername, ccs_socket_getpeername),
1183+ MY_HOOK_INIT(socket_getsockopt, ccs_socket_getsockopt),
1184+ MY_HOOK_INIT(socket_setsockopt, ccs_socket_setsockopt),
1185+ MY_HOOK_INIT(socket_shutdown, ccs_socket_shutdown),
1186+ MY_HOOK_INIT(socket_accept, ccs_socket_accept),
1187+ MY_HOOK_INIT(inode_free_security, ccs_inode_free_security),
1188+#endif
1189+};
1190+
1191+static inline void add_hook(struct security_hook_list *hook)
1192+{
1193+ list_add_tail_rcu(&hook->list, hook->head);
1194+}
1195+
1196+static void __init swap_hook(struct security_hook_list *hook,
1197+ union security_list_options *original)
1198+{
1199+ struct list_head *list = hook->head;
1200+ if (list_empty(list)) {
1201+ add_hook(hook);
1202+ } else {
1203+ struct security_hook_list *shp =
1204+ list_last_entry(list, struct security_hook_list, list);
1205+ *original = shp->hook;
1206+ smp_wmb();
1207+ shp->hook = hook->hook;
1208+ }
1209+}
1210+
1211+/**
1212+ * ccs_init - Initialize this module.
1213+ *
1214+ * Returns 0 on success, negative value otherwise.
1215+ */
1216+static int __init ccs_init(void)
1217+{
1218+ int idx;
1219+ struct security_hook_heads *hooks = probe_security_hook_heads();
1220+ if (!hooks)
1221+ goto out;
1222+ for (idx = 0; idx < ARRAY_SIZE(akari_hooks); idx++)
1223+ akari_hooks[idx].head = ((void *) hooks)
1224+ + ((unsigned long) akari_hooks[idx].head)
1225+ - ((unsigned long) &probe_dummy_security_hook_heads);
1226+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1227+ if (!ccsecurity_exports.find_task_by_vpid)
1228+ goto out;
1229+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1230+ if (!ccsecurity_exports.find_task_by_pid_ns)
1231+ goto out;
1232+ ccsecurity_exports.d_absolute_path = probe_d_absolute_path();
1233+ if (!ccsecurity_exports.d_absolute_path)
1234+ goto out;
1235+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1236+ INIT_LIST_HEAD(&ccs_cred_security_list[idx]);
1237+ INIT_LIST_HEAD(&ccs_task_security_list[idx]);
1238+ }
1239+ ccs_main_init();
1240+ swap_hook(&akari_hooks[0], &original_cred_free);
1241+ swap_hook(&akari_hooks[1], &original_cred_prepare);
1242+ swap_hook(&akari_hooks[2], &original_cred_alloc_blank);
1243+ for (idx = 3; idx < ARRAY_SIZE(akari_hooks); idx++)
1244+ add_hook(&akari_hooks[idx]);
1245+ printk(KERN_INFO "AKARI: 1.0.39 2019/08/20\n");
1246+ printk(KERN_INFO
1247+ "Access Keeping And Regulating Instrument registered.\n");
1248+ return 0;
1249+out:
1250+ return -EINVAL;
1251+}
1252+
1253+module_init(ccs_init);
1254+MODULE_LICENSE("GPL");
1255+
1256+/**
1257+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1258+ *
1259+ * @domain: Pointer to "struct ccs_domain_info".
1260+ *
1261+ * Returns true if @domain is in use, false otherwise.
1262+ *
1263+ * Caller holds rcu_read_lock().
1264+ */
1265+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1266+{
1267+ int idx;
1268+ struct ccs_security *ptr;
1269+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1270+ struct list_head *list = &ccs_cred_security_list[idx];
1271+ list_for_each_entry_rcu(ptr, list, list) {
1272+ struct ccs_execve *ee = ptr->ee;
1273+ if (ptr->ccs_domain_info == domain ||
1274+ (ee && ee->previous_domain == domain)) {
1275+ return true;
1276+ }
1277+ }
1278+ }
1279+ return false;
1280+}
1281+
1282+/**
1283+ * ccs_add_task_security - Add "struct ccs_security" to list.
1284+ *
1285+ * @ptr: Pointer to "struct ccs_security".
1286+ * @list: Pointer to "struct list_head".
1287+ *
1288+ * Returns nothing.
1289+ */
1290+static void ccs_add_task_security(struct ccs_security *ptr,
1291+ struct list_head *list)
1292+{
1293+ unsigned long flags;
1294+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1295+ list_add_rcu(&ptr->list, list);
1296+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1297+}
1298+
1299+/**
1300+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1301+ *
1302+ * @task: Pointer to "struct task_struct".
1303+ *
1304+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1305+ * out of memory, &ccs_default_security otherwise.
1306+ *
1307+ * If @task is current thread and "struct ccs_security" for current thread was
1308+ * not found, I try to allocate it. But if allocation failed, current thread
1309+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1310+ * won't work.
1311+ */
1312+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1313+{
1314+ struct ccs_security *ptr;
1315+ struct list_head *list = &ccs_task_security_list
1316+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1317+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1318+ while (!list->next)
1319+ smp_rmb();
1320+ rcu_read_lock();
1321+ list_for_each_entry_rcu(ptr, list, list) {
1322+ if (ptr->pid != task->pids[PIDTYPE_PID].pid)
1323+ continue;
1324+ rcu_read_unlock();
1325+ /*
1326+ * Current thread needs to transit from old domain to new
1327+ * domain before do_execve() succeeds in order to check
1328+ * permission for interpreters and environment variables using
1329+ * new domain's ACL rules. The domain transition has to be
1330+ * visible from other CPU in order to allow interactive
1331+ * enforcing mode. Also, the domain transition has to be
1332+ * reverted if do_execve() failed. However, an LSM hook for
1333+ * reverting domain transition is missing.
1334+ *
1335+ * security_prepare_creds() is called from prepare_creds() from
1336+ * prepare_bprm_creds() from do_execve() before setting
1337+ * current->in_execve flag, and current->in_execve flag is
1338+ * cleared by the time next do_execve() request starts.
1339+ * This means that we can emulate the missing LSM hook for
1340+ * reverting domain transition, by calling this function from
1341+ * security_prepare_creds().
1342+ *
1343+ * If current->in_execve is not set but ptr->ccs_flags has
1344+ * CCS_TASK_IS_IN_EXECVE set, it indicates that do_execve()
1345+ * has failed and reverting domain transition is needed.
1346+ */
1347+ if (task == current &&
1348+ (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE) &&
1349+ !current->in_execve) {
1350+ ccs_debug_trace("4");
1351+ ccs_clear_execve(-1, ptr);
1352+ }
1353+ return ptr;
1354+ }
1355+ rcu_read_unlock();
1356+ if (task != current) {
1357+ /*
1358+ * If a thread does nothing after fork(), caller will reach
1359+ * here because "struct ccs_security" for that thread is not
1360+ * yet allocated. But that thread is keeping a snapshot of
1361+ * "struct ccs_security" taken as of ccs_task_create()
1362+ * associated with that thread's "struct cred".
1363+ *
1364+ * Since that snapshot will be used as initial data when that
1365+ * thread allocates "struct ccs_security" for that thread, we
1366+ * can return that snapshot rather than &ccs_default_security.
1367+ *
1368+ * Since this function is called by only ccs_select_one() and
1369+ * ccs_read_pid() (via ccs_task_domain() and ccs_task_flags()),
1370+ * it is guaranteed that caller has called rcu_read_lock()
1371+ * (via ccs_tasklist_lock()) before finding this thread and
1372+ * this thread is valid. Therefore, we can do __task_cred(task)
1373+ * like get_robust_list() does.
1374+ */
1375+ return ccs_find_cred_security(__task_cred(task));
1376+ }
1377+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1378+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1379+ if (!ptr) {
1380+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1381+ task->pid);
1382+ send_sig(SIGKILL, current, 0);
1383+ return &ccs_oom_security;
1384+ }
1385+ *ptr = *ccs_find_cred_security(task->cred);
1386+ /* We can shortcut because task == current. */
1387+ ptr->pid = get_pid(((struct task_struct *) task)->
1388+ pids[PIDTYPE_PID].pid);
1389+ ptr->cred = NULL;
1390+ ccs_add_task_security(ptr, list);
1391+ return ptr;
1392+}
1393+
1394+/**
1395+ * ccs_copy_cred_security - Allocate memory for new credentials.
1396+ *
1397+ * @new: Pointer to "struct cred".
1398+ * @old: Pointer to "struct cred".
1399+ * @gfp: Memory allocation flags.
1400+ *
1401+ * Returns 0 on success, negative value otherwise.
1402+ */
1403+static int ccs_copy_cred_security(const struct cred *new,
1404+ const struct cred *old, gfp_t gfp)
1405+{
1406+ struct ccs_security *old_security = ccs_find_cred_security(old);
1407+ struct ccs_security *new_security =
1408+ kzalloc(sizeof(*new_security), gfp);
1409+ if (!new_security)
1410+ return -ENOMEM;
1411+ *new_security = *old_security;
1412+ new_security->cred = new;
1413+ ccs_add_cred_security(new_security);
1414+ return 0;
1415+}
1416+
1417+/**
1418+ * ccs_find_cred_security - Find "struct ccs_security" for given credential.
1419+ *
1420+ * @cred: Pointer to "struct cred".
1421+ *
1422+ * Returns pointer to "struct ccs_security" on success, &ccs_default_security
1423+ * otherwise.
1424+ */
1425+static struct ccs_security *ccs_find_cred_security(const struct cred *cred)
1426+{
1427+ struct ccs_security *ptr;
1428+ struct list_head *list = &ccs_cred_security_list
1429+ [hash_ptr((void *) cred, CCS_TASK_SECURITY_HASH_BITS)];
1430+ rcu_read_lock();
1431+ list_for_each_entry_rcu(ptr, list, list) {
1432+ if (ptr->cred != cred)
1433+ continue;
1434+ rcu_read_unlock();
1435+ return ptr;
1436+ }
1437+ rcu_read_unlock();
1438+ return &ccs_default_security;
1439+}
1440+
1441+/**
1442+ * ccs_task_security_gc - Do garbage collection for "struct task_struct".
1443+ *
1444+ * Returns nothing.
1445+ *
1446+ * Since security_task_free() is missing, I can't release memory associated
1447+ * with "struct task_struct" when a task dies. Therefore, I hold a reference on
1448+ * "struct pid" and runs garbage collection when associated
1449+ * "struct task_struct" has gone.
1450+ */
1451+static void ccs_task_security_gc(void)
1452+{
1453+ static DEFINE_SPINLOCK(lock);
1454+ static atomic_t gc_counter = ATOMIC_INIT(0);
1455+ unsigned int idx;
1456+ /*
1457+ * If some process is doing execve(), try to garbage collection now.
1458+ * We should kfree() memory associated with "struct ccs_security"->ee
1459+ * as soon as execve() has completed in order to compensate for lack of
1460+ * security_bprm_free() and security_task_free() hooks.
1461+ *
1462+ * Otherwise, reduce frequency for performance reason.
1463+ */
1464+ if (!atomic_read(&ccs_in_execve_tasks) &&
1465+ atomic_inc_return(&gc_counter) < 1024)
1466+ return;
1467+ if (!spin_trylock(&lock))
1468+ return;
1469+ atomic_set(&gc_counter, 0);
1470+ rcu_read_lock();
1471+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
1472+ struct ccs_security *ptr;
1473+ struct list_head *list = &ccs_task_security_list[idx];
1474+ list_for_each_entry_rcu(ptr, list, list) {
1475+ if (pid_task(ptr->pid, PIDTYPE_PID))
1476+ continue;
1477+ ccs_del_security(ptr);
1478+ }
1479+ }
1480+ rcu_read_unlock();
1481+ spin_unlock(&lock);
1482+}
--- tags/patches/1.0.39/lsm.c (nonexistent)
+++ tags/patches/1.0.39/lsm.c (revision 612)
@@ -0,0 +1,34 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.39 2019/08/20
7+ */
8+
9+#include <linux/version.h>
10+#include <linux/security.h>
11+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
12+#include "lsm-4.12.c"
13+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
14+#include "lsm-4.7.c"
15+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
16+#include "lsm-4.2.c"
17+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
18+#include "lsm-2.6.29.c"
19+/*
20+ * AppArmor patch added "struct vfsmount *" to security_inode_\*() hooks.
21+ * Detect it by checking whether D_PATH_DISCONNECT is defined or not.
22+ * Also, there may be other kernels with "struct vfsmount *" added.
23+ * If you got build failure, check security_inode_\*() hooks in
24+ * include/linux/security.h.
25+ */
26+#elif defined(D_PATH_DISCONNECT)
27+#include "lsm-2.6.0-vfs.c"
28+#elif defined(CONFIG_SUSE_KERNEL) && LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 25)
29+#include "lsm-2.6.0-vfs.c"
30+#elif defined(CONFIG_SECURITY_APPARMOR) && LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
31+#include "lsm-2.6.0-vfs.c"
32+#else
33+#include "lsm-2.6.0.c"
34+#endif
--- tags/patches/1.0.39/memory.c (nonexistent)
+++ tags/patches/1.0.39/memory.c (revision 612)
@@ -0,0 +1,364 @@
1+/*
2+ * security/ccsecurity/memory.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.6 2019/08/20
7+ */
8+
9+#include "internal.h"
10+
11+/* Use functions in lsm.c */
12+#undef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
13+
14+/***** SECTION1: Constants definition *****/
15+
16+/***** SECTION2: Structure definition *****/
17+
18+/***** SECTION3: Prototype definition section *****/
19+
20+bool ccs_memory_ok(const void *ptr, const unsigned int size);
21+const struct ccs_path_info *ccs_get_name(const char *name);
22+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
23+struct ccs_security *ccs_find_task_security(const struct task_struct *task);
24+#endif
25+void *ccs_commit_ok(void *data, const unsigned int size);
26+void __init ccs_mm_init(void);
27+void ccs_warn_oom(const char *function);
28+
29+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
30+static int __ccs_alloc_task_security(const struct task_struct *task);
31+static void __ccs_free_task_security(const struct task_struct *task);
32+static void ccs_add_task_security(struct ccs_security *ptr,
33+ struct list_head *list);
34+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
35+static void ccs_rcu_free(struct rcu_head *rcu);
36+#else
37+static void ccs_rcu_free(void *arg);
38+#endif
39+#endif
40+
41+/***** SECTION4: Standalone functions section *****/
42+
43+/***** SECTION5: Variables definition section *****/
44+
45+/* Memoy currently used by policy/audit log/query. */
46+unsigned int ccs_memory_used[CCS_MAX_MEMORY_STAT];
47+
48+/* Memory quota for "policy"/"audit log"/"query". */
49+unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT];
50+
51+/* The list for "struct ccs_name". */
52+struct list_head ccs_name_list[CCS_MAX_HASH];
53+
54+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
55+
56+/* Dummy security context for avoiding NULL pointer dereference. */
57+static struct ccs_security ccs_oom_security = {
58+ .ccs_domain_info = &ccs_kernel_domain
59+};
60+
61+/* Dummy security context for avoiding NULL pointer dereference. */
62+static struct ccs_security ccs_default_security = {
63+ .ccs_domain_info = &ccs_kernel_domain
64+};
65+
66+/* List of "struct ccs_security". */
67+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
68+/* Lock for protecting ccs_task_security_list[]. */
69+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
70+
71+#endif
72+
73+/***** SECTION6: Dependent functions section *****/
74+
75+/**
76+ * ccs_warn_oom - Print out of memory warning message.
77+ *
78+ * @function: Function's name.
79+ *
80+ * Returns nothing.
81+ */
82+void ccs_warn_oom(const char *function)
83+{
84+ /* Reduce error messages. */
85+ static pid_t ccs_last_pid;
86+ const pid_t pid = current->pid;
87+ if (ccs_last_pid != pid) {
88+ printk(KERN_WARNING "ERROR: Out of memory at %s.\n",
89+ function);
90+ ccs_last_pid = pid;
91+ }
92+ if (!ccs_policy_loaded)
93+ panic("MAC Initialization failed.\n");
94+}
95+
96+/**
97+ * ccs_memory_ok - Check memory quota.
98+ *
99+ * @ptr: Pointer to allocated memory. Maybe NULL.
100+ * @size: Size in byte. Not used if @ptr is NULL.
101+ *
102+ * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
103+ *
104+ * Caller holds ccs_policy_lock mutex.
105+ */
106+bool ccs_memory_ok(const void *ptr, const unsigned int size)
107+{
108+ if (ptr) {
109+ const size_t s = ccs_round2(size);
110+ ccs_memory_used[CCS_MEMORY_POLICY] += s;
111+ if (!ccs_memory_quota[CCS_MEMORY_POLICY] ||
112+ ccs_memory_used[CCS_MEMORY_POLICY] <=
113+ ccs_memory_quota[CCS_MEMORY_POLICY])
114+ return true;
115+ ccs_memory_used[CCS_MEMORY_POLICY] -= s;
116+ }
117+ ccs_warn_oom(__func__);
118+ return false;
119+}
120+
121+/**
122+ * ccs_commit_ok - Allocate memory and check memory quota.
123+ *
124+ * @data: Data to copy from.
125+ * @size: Size in byte.
126+ *
127+ * Returns pointer to allocated memory on success, NULL otherwise.
128+ * @data is zero-cleared on success.
129+ *
130+ * Caller holds ccs_policy_lock mutex.
131+ */
132+void *ccs_commit_ok(void *data, const unsigned int size)
133+{
134+ void *ptr = kmalloc(size, CCS_GFP_FLAGS);
135+ if (ccs_memory_ok(ptr, size)) {
136+ memmove(ptr, data, size);
137+ memset(data, 0, size);
138+ return ptr;
139+ }
140+ kfree(ptr);
141+ return NULL;
142+}
143+
144+/**
145+ * ccs_get_name - Allocate memory for string data.
146+ *
147+ * @name: The string to store into the permernent memory.
148+ *
149+ * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
150+ */
151+const struct ccs_path_info *ccs_get_name(const char *name)
152+{
153+ struct ccs_name *ptr;
154+ unsigned int hash;
155+ int len;
156+ int allocated_len;
157+ struct list_head *head;
158+
159+ if (!name)
160+ return NULL;
161+ len = strlen(name) + 1;
162+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
163+ hash = full_name_hash(NULL, name, len - 1);
164+#else
165+ hash = full_name_hash((const unsigned char *) name, len - 1);
166+#endif
167+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
168+ head = &ccs_name_list[hash_long(hash, CCS_HASH_BITS)];
169+#else
170+ head = &ccs_name_list[hash % CCS_MAX_HASH];
171+#endif
172+ if (mutex_lock_interruptible(&ccs_policy_lock))
173+ return NULL;
174+ list_for_each_entry(ptr, head, head.list) {
175+ if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name) ||
176+ atomic_read(&ptr->head.users) == CCS_GC_IN_PROGRESS)
177+ continue;
178+ atomic_inc(&ptr->head.users);
179+ goto out;
180+ }
181+ allocated_len = sizeof(*ptr) + len;
182+ ptr = kzalloc(allocated_len, CCS_GFP_FLAGS);
183+ if (ccs_memory_ok(ptr, allocated_len)) {
184+ ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
185+ memmove((char *) ptr->entry.name, name, len);
186+ atomic_set(&ptr->head.users, 1);
187+ ccs_fill_path_info(&ptr->entry);
188+ ptr->size = allocated_len;
189+ list_add_tail(&ptr->head.list, head);
190+ } else {
191+ kfree(ptr);
192+ ptr = NULL;
193+ }
194+out:
195+ mutex_unlock(&ccs_policy_lock);
196+ return ptr ? &ptr->entry : NULL;
197+}
198+
199+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
200+
201+/**
202+ * ccs_add_task_security - Add "struct ccs_security" to list.
203+ *
204+ * @ptr: Pointer to "struct ccs_security".
205+ * @list: Pointer to "struct list_head".
206+ *
207+ * Returns nothing.
208+ */
209+static void ccs_add_task_security(struct ccs_security *ptr,
210+ struct list_head *list)
211+{
212+ unsigned long flags;
213+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
214+ list_add_rcu(&ptr->list, list);
215+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
216+}
217+
218+/**
219+ * __ccs_alloc_task_security - Allocate memory for new tasks.
220+ *
221+ * @task: Pointer to "struct task_struct".
222+ *
223+ * Returns 0 on success, negative value otherwise.
224+ */
225+static int __ccs_alloc_task_security(const struct task_struct *task)
226+{
227+ struct ccs_security *old_security = ccs_current_security();
228+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
229+ GFP_KERNEL);
230+ struct list_head *list = &ccs_task_security_list
231+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
232+ if (!new_security)
233+ return -ENOMEM;
234+ new_security->task = task;
235+ new_security->ccs_domain_info = old_security->ccs_domain_info;
236+ new_security->ccs_flags = old_security->ccs_flags;
237+ ccs_add_task_security(new_security, list);
238+ return 0;
239+}
240+
241+/**
242+ * ccs_find_task_security - Find "struct ccs_security" for given task.
243+ *
244+ * @task: Pointer to "struct task_struct".
245+ *
246+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
247+ * out of memory, &ccs_default_security otherwise.
248+ *
249+ * If @task is current thread and "struct ccs_security" for current thread was
250+ * not found, I try to allocate it. But if allocation failed, current thread
251+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
252+ * won't work.
253+ */
254+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
255+{
256+ struct ccs_security *ptr;
257+ struct list_head *list = &ccs_task_security_list
258+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
259+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
260+ while (!list->next)
261+ smp_rmb();
262+ rcu_read_lock();
263+ list_for_each_entry_rcu(ptr, list, list) {
264+ if (ptr->task != task)
265+ continue;
266+ rcu_read_unlock();
267+ return ptr;
268+ }
269+ rcu_read_unlock();
270+ if (task != current)
271+ return &ccs_default_security;
272+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
273+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
274+ if (!ptr) {
275+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
276+ task->pid);
277+ send_sig(SIGKILL, current, 0);
278+ return &ccs_oom_security;
279+ }
280+ *ptr = ccs_default_security;
281+ ptr->task = task;
282+ ccs_add_task_security(ptr, list);
283+ return ptr;
284+}
285+
286+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
287+
288+/**
289+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
290+ *
291+ * @rcu: Pointer to "struct rcu_head".
292+ *
293+ * Returns nothing.
294+ */
295+static void ccs_rcu_free(struct rcu_head *rcu)
296+{
297+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
298+ kfree(ptr);
299+}
300+
301+#else
302+
303+/**
304+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
305+ *
306+ * @arg: Pointer to "void".
307+ *
308+ * Returns nothing.
309+ */
310+static void ccs_rcu_free(void *arg)
311+{
312+ struct ccs_security *ptr = arg;
313+ kfree(ptr);
314+}
315+
316+#endif
317+
318+/**
319+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
320+ *
321+ * @task: Pointer to "struct task_struct".
322+ *
323+ * Returns nothing.
324+ */
325+static void __ccs_free_task_security(const struct task_struct *task)
326+{
327+ unsigned long flags;
328+ struct ccs_security *ptr = ccs_find_task_security(task);
329+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
330+ return;
331+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
332+ list_del_rcu(&ptr->list);
333+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
334+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
335+ call_rcu(&ptr->rcu, ccs_rcu_free);
336+#else
337+ call_rcu(&ptr->rcu, ccs_rcu_free, ptr);
338+#endif
339+}
340+
341+#endif
342+
343+/**
344+ * ccs_mm_init - Initialize mm related code.
345+ *
346+ * Returns nothing.
347+ */
348+void __init ccs_mm_init(void)
349+{
350+ int idx;
351+ for (idx = 0; idx < CCS_MAX_HASH; idx++)
352+ INIT_LIST_HEAD(&ccs_name_list[idx]);
353+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
354+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++)
355+ INIT_LIST_HEAD(&ccs_task_security_list[idx]);
356+#endif
357+ smp_wmb(); /* Avoid out of order execution. */
358+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
359+ ccsecurity_ops.alloc_task_security = __ccs_alloc_task_security;
360+ ccsecurity_ops.free_task_security = __ccs_free_task_security;
361+#endif
362+ ccs_kernel_domain.domainname = ccs_get_name("<kernel>");
363+ list_add_tail_rcu(&ccs_kernel_domain.list, &ccs_domain_list);
364+}
--- tags/patches/1.0.39/permission.c (nonexistent)
+++ tags/patches/1.0.39/permission.c (revision 612)
@@ -0,0 +1,5087 @@
1+/*
2+ * security/ccsecurity/permission.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.6 2019/08/20
7+ */
8+
9+#include "internal.h"
10+
11+/***** SECTION1: Constants definition *****/
12+
13+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
14+
15+/*
16+ * may_open() receives open flags modified by open_to_namei_flags() until
17+ * 2.6.32. We stop here in case some distributions backported ACC_MODE changes,
18+ * for we can't determine whether may_open() receives open flags modified by
19+ * open_to_namei_flags() or not.
20+ */
21+#ifdef ACC_MODE
22+#error ACC_MODE already defined.
23+#endif
24+#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
25+
26+#if defined(RHEL_MAJOR) && RHEL_MAJOR == 6
27+/* RHEL6 passes unmodified flags since 2.6.32-71.14.1.el6 . */
28+#undef ACC_MODE
29+#define ACC_MODE(x) ("\004\002\006"[(x)&O_ACCMODE])
30+#endif
31+
32+#endif
33+
34+/* String table for special mount operations. */
35+static const char * const ccs_mounts[CCS_MAX_SPECIAL_MOUNT] = {
36+ [CCS_MOUNT_BIND] = "--bind",
37+ [CCS_MOUNT_MOVE] = "--move",
38+ [CCS_MOUNT_REMOUNT] = "--remount",
39+ [CCS_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable",
40+ [CCS_MOUNT_MAKE_PRIVATE] = "--make-private",
41+ [CCS_MOUNT_MAKE_SLAVE] = "--make-slave",
42+ [CCS_MOUNT_MAKE_SHARED] = "--make-shared",
43+};
44+
45+/* Mapping table from "enum ccs_path_acl_index" to "enum ccs_mac_index". */
46+static const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION] = {
47+ [CCS_TYPE_EXECUTE] = CCS_MAC_FILE_EXECUTE,
48+ [CCS_TYPE_READ] = CCS_MAC_FILE_OPEN,
49+ [CCS_TYPE_WRITE] = CCS_MAC_FILE_OPEN,
50+ [CCS_TYPE_APPEND] = CCS_MAC_FILE_OPEN,
51+ [CCS_TYPE_UNLINK] = CCS_MAC_FILE_UNLINK,
52+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
53+ [CCS_TYPE_GETATTR] = CCS_MAC_FILE_GETATTR,
54+#endif
55+ [CCS_TYPE_RMDIR] = CCS_MAC_FILE_RMDIR,
56+ [CCS_TYPE_TRUNCATE] = CCS_MAC_FILE_TRUNCATE,
57+ [CCS_TYPE_SYMLINK] = CCS_MAC_FILE_SYMLINK,
58+ [CCS_TYPE_CHROOT] = CCS_MAC_FILE_CHROOT,
59+ [CCS_TYPE_UMOUNT] = CCS_MAC_FILE_UMOUNT,
60+};
61+
62+/* Mapping table from "enum ccs_mkdev_acl_index" to "enum ccs_mac_index". */
63+const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION] = {
64+ [CCS_TYPE_MKBLOCK] = CCS_MAC_FILE_MKBLOCK,
65+ [CCS_TYPE_MKCHAR] = CCS_MAC_FILE_MKCHAR,
66+};
67+
68+/* Mapping table from "enum ccs_path2_acl_index" to "enum ccs_mac_index". */
69+const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION] = {
70+ [CCS_TYPE_LINK] = CCS_MAC_FILE_LINK,
71+ [CCS_TYPE_RENAME] = CCS_MAC_FILE_RENAME,
72+ [CCS_TYPE_PIVOT_ROOT] = CCS_MAC_FILE_PIVOT_ROOT,
73+};
74+
75+/*
76+ * Mapping table from "enum ccs_path_number_acl_index" to "enum ccs_mac_index".
77+ */
78+const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION] = {
79+ [CCS_TYPE_CREATE] = CCS_MAC_FILE_CREATE,
80+ [CCS_TYPE_MKDIR] = CCS_MAC_FILE_MKDIR,
81+ [CCS_TYPE_MKFIFO] = CCS_MAC_FILE_MKFIFO,
82+ [CCS_TYPE_MKSOCK] = CCS_MAC_FILE_MKSOCK,
83+ [CCS_TYPE_IOCTL] = CCS_MAC_FILE_IOCTL,
84+ [CCS_TYPE_CHMOD] = CCS_MAC_FILE_CHMOD,
85+ [CCS_TYPE_CHOWN] = CCS_MAC_FILE_CHOWN,
86+ [CCS_TYPE_CHGRP] = CCS_MAC_FILE_CHGRP,
87+};
88+
89+#ifdef CONFIG_CCSECURITY_NETWORK
90+
91+/*
92+ * Mapping table from "enum ccs_network_acl_index" to "enum ccs_mac_index" for
93+ * inet domain socket.
94+ */
95+static const u8 ccs_inet2mac[CCS_SOCK_MAX][CCS_MAX_NETWORK_OPERATION] = {
96+ [SOCK_STREAM] = {
97+ [CCS_NETWORK_BIND] = CCS_MAC_NETWORK_INET_STREAM_BIND,
98+ [CCS_NETWORK_LISTEN] = CCS_MAC_NETWORK_INET_STREAM_LISTEN,
99+ [CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_INET_STREAM_CONNECT,
100+ [CCS_NETWORK_ACCEPT] = CCS_MAC_NETWORK_INET_STREAM_ACCEPT,
101+ },
102+ [SOCK_DGRAM] = {
103+ [CCS_NETWORK_BIND] = CCS_MAC_NETWORK_INET_DGRAM_BIND,
104+ [CCS_NETWORK_SEND] = CCS_MAC_NETWORK_INET_DGRAM_SEND,
105+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
106+ [CCS_NETWORK_RECV] = CCS_MAC_NETWORK_INET_DGRAM_RECV,
107+#endif
108+ },
109+ [SOCK_RAW] = {
110+ [CCS_NETWORK_BIND] = CCS_MAC_NETWORK_INET_RAW_BIND,
111+ [CCS_NETWORK_SEND] = CCS_MAC_NETWORK_INET_RAW_SEND,
112+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
113+ [CCS_NETWORK_RECV] = CCS_MAC_NETWORK_INET_RAW_RECV,
114+#endif
115+ },
116+};
117+
118+/*
119+ * Mapping table from "enum ccs_network_acl_index" to "enum ccs_mac_index" for
120+ * unix domain socket.
121+ */
122+static const u8 ccs_unix2mac[CCS_SOCK_MAX][CCS_MAX_NETWORK_OPERATION] = {
123+ [SOCK_STREAM] = {
124+ [CCS_NETWORK_BIND] = CCS_MAC_NETWORK_UNIX_STREAM_BIND,
125+ [CCS_NETWORK_LISTEN] = CCS_MAC_NETWORK_UNIX_STREAM_LISTEN,
126+ [CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_UNIX_STREAM_CONNECT,
127+ [CCS_NETWORK_ACCEPT] = CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT,
128+ },
129+ [SOCK_DGRAM] = {
130+ [CCS_NETWORK_BIND] = CCS_MAC_NETWORK_UNIX_DGRAM_BIND,
131+ [CCS_NETWORK_SEND] = CCS_MAC_NETWORK_UNIX_DGRAM_SEND,
132+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
133+ [CCS_NETWORK_RECV] = CCS_MAC_NETWORK_UNIX_DGRAM_RECV,
134+#endif
135+ },
136+ [SOCK_SEQPACKET] = {
137+ [CCS_NETWORK_BIND] = CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND,
138+ [CCS_NETWORK_LISTEN] = CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
139+ [CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
140+ [CCS_NETWORK_ACCEPT] = CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
141+ },
142+};
143+
144+#endif
145+
146+#ifdef CONFIG_CCSECURITY_CAPABILITY
147+
148+/*
149+ * Mapping table from "enum ccs_capability_acl_index" to "enum ccs_mac_index".
150+ */
151+const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX] = {
152+ [CCS_USE_ROUTE_SOCKET] = CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
153+ [CCS_USE_PACKET_SOCKET] = CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
154+ [CCS_SYS_REBOOT] = CCS_MAC_CAPABILITY_SYS_REBOOT,
155+ [CCS_SYS_VHANGUP] = CCS_MAC_CAPABILITY_SYS_VHANGUP,
156+ [CCS_SYS_SETTIME] = CCS_MAC_CAPABILITY_SYS_SETTIME,
157+ [CCS_SYS_NICE] = CCS_MAC_CAPABILITY_SYS_NICE,
158+ [CCS_SYS_SETHOSTNAME] = CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
159+ [CCS_USE_KERNEL_MODULE] = CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
160+ [CCS_SYS_KEXEC_LOAD] = CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
161+ [CCS_SYS_PTRACE] = CCS_MAC_CAPABILITY_SYS_PTRACE,
162+};
163+
164+#endif
165+
166+/***** SECTION2: Structure definition *****/
167+
168+/* Structure for holding inet domain socket's address. */
169+struct ccs_inet_addr_info {
170+ u16 port; /* In network byte order. */
171+ const u32 *address; /* In network byte order. */
172+ bool is_ipv6;
173+};
174+
175+/* Structure for holding unix domain socket's address. */
176+struct ccs_unix_addr_info {
177+ u8 *addr; /* This may not be '\0' terminated string. */
178+ unsigned int addr_len;
179+};
180+
181+/* Structure for holding socket address. */
182+struct ccs_addr_info {
183+ u8 protocol;
184+ u8 operation;
185+ struct ccs_inet_addr_info inet;
186+ struct ccs_unix_addr_info unix0;
187+};
188+
189+/***** SECTION3: Prototype definition section *****/
190+
191+bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
192+ struct ccs_page_dump *dump);
193+void ccs_get_attributes(struct ccs_obj_info *obj);
194+
195+static bool ccs_alphabet_char(const char c);
196+static bool ccs_argv(const unsigned int index, const char *arg_ptr,
197+ const int argc, const struct ccs_argv *argv, u8 *checked);
198+static bool ccs_byte_range(const char *str);
199+static bool ccs_check_entry(struct ccs_request_info *r,
200+ struct ccs_acl_info *ptr);
201+static bool ccs_check_mkdev_acl(struct ccs_request_info *r,
202+ const struct ccs_acl_info *ptr);
203+static bool ccs_check_mount_acl(struct ccs_request_info *r,
204+ const struct ccs_acl_info *ptr);
205+static bool ccs_check_path2_acl(struct ccs_request_info *r,
206+ const struct ccs_acl_info *ptr);
207+static bool ccs_check_path_acl(struct ccs_request_info *r,
208+ const struct ccs_acl_info *ptr);
209+static bool ccs_check_path_number_acl(struct ccs_request_info *r,
210+ const struct ccs_acl_info *ptr);
211+static bool ccs_compare_number_union(const unsigned long value,
212+ const struct ccs_number_union *ptr);
213+static bool ccs_condition(struct ccs_request_info *r,
214+ const struct ccs_condition *cond);
215+static bool ccs_decimal(const char c);
216+static bool ccs_envp(const char *env_name, const char *env_value,
217+ const int envc, const struct ccs_envp *envp, u8 *checked);
218+static bool ccs_file_matches_pattern(const char *filename,
219+ const char *filename_end,
220+ const char *pattern,
221+ const char *pattern_end);
222+static bool ccs_file_matches_pattern2(const char *filename,
223+ const char *filename_end,
224+ const char *pattern,
225+ const char *pattern_end);
226+static bool ccs_get_realpath(struct ccs_path_info *buf, struct path *path);
227+static bool ccs_hexadecimal(const char c);
228+static bool ccs_number_matches_group(const unsigned long min,
229+ const unsigned long max,
230+ const struct ccs_group *group);
231+static bool ccs_path_matches_pattern(const struct ccs_path_info *filename,
232+ const struct ccs_path_info *pattern);
233+static bool ccs_path_matches_pattern2(const char *f, const char *p);
234+static bool ccs_scan_bprm(struct ccs_execve *ee, const u16 argc,
235+ const struct ccs_argv *argv, const u16 envc,
236+ const struct ccs_envp *envp);
237+static bool ccs_scan_exec_realpath(struct file *file,
238+ const struct ccs_name_union *ptr,
239+ const bool match);
240+static bool ccs_scan_transition(const struct list_head *list,
241+ const struct ccs_path_info *domainname,
242+ const struct ccs_path_info *program,
243+ const char *last_name,
244+ const enum ccs_transition_type type);
245+static const char *ccs_last_word(const char *name);
246+static const struct ccs_path_info *ccs_compare_name_union
247+(const struct ccs_path_info *name, const struct ccs_name_union *ptr);
248+static const struct ccs_path_info *ccs_path_matches_group
249+(const struct ccs_path_info *pathname, const struct ccs_group *group);
250+static enum ccs_transition_type ccs_transition_type
251+(const struct ccs_policy_namespace *ns, const struct ccs_path_info *domainname,
252+ const struct ccs_path_info *program);
253+static int __ccs_chmod_permission(struct dentry *dentry,
254+ struct vfsmount *vfsmnt, mode_t mode);
255+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
256+static int __ccs_chown_permission(struct dentry *dentry,
257+ struct vfsmount *vfsmnt, kuid_t user,
258+ kgid_t group);
259+#else
260+static int __ccs_chown_permission(struct dentry *dentry,
261+ struct vfsmount *vfsmnt, uid_t user,
262+ gid_t group);
263+#endif
264+static int __ccs_chroot_permission(const struct path *path);
265+static int __ccs_fcntl_permission(struct file *file, unsigned int cmd,
266+ unsigned long arg);
267+static int __ccs_ioctl_permission(struct file *filp, unsigned int cmd,
268+ unsigned long arg);
269+static int __ccs_link_permission(struct dentry *old_dentry,
270+ struct dentry *new_dentry,
271+ struct vfsmount *mnt);
272+static int __ccs_mkdir_permission(struct dentry *dentry, struct vfsmount *mnt,
273+ unsigned int mode);
274+static int __ccs_mknod_permission(struct dentry *dentry, struct vfsmount *mnt,
275+ const unsigned int mode, unsigned int dev);
276+static int __ccs_mount_permission(const char *dev_name,
277+ const struct path *path, const char *type,
278+ unsigned long flags, void *data_page);
279+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
280+static int __ccs_move_mount_permission(const struct path *from_path,
281+ const struct path *to_path);
282+#endif
283+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
284+static int __ccs_open_exec_permission(struct dentry *dentry,
285+ struct vfsmount *mnt);
286+#endif
287+static int __ccs_open_permission(struct dentry *dentry, struct vfsmount *mnt,
288+ const int flag);
289+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
290+static int __ccs_parse_table(int __user *name, int nlen, void __user *oldval,
291+ void __user *newval, struct ctl_table *table);
292+#endif
293+static int __ccs_pivot_root_permission(const struct path *old_path,
294+ const struct path *new_path);
295+static int __ccs_rename_permission(struct dentry *old_dentry,
296+ struct dentry *new_dentry,
297+ struct vfsmount *mnt);
298+static int __ccs_rmdir_permission(struct dentry *dentry, struct vfsmount *mnt);
299+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
300+static int __ccs_search_binary_handler(struct linux_binprm *bprm);
301+#else
302+static int __ccs_search_binary_handler(struct linux_binprm *bprm,
303+ struct pt_regs *regs);
304+#endif
305+static int __ccs_symlink_permission(struct dentry *dentry,
306+ struct vfsmount *mnt, const char *from);
307+static int __ccs_truncate_permission(struct dentry *dentry,
308+ struct vfsmount *mnt);
309+static int __ccs_umount_permission(struct vfsmount *mnt, int flags);
310+static int __ccs_unlink_permission(struct dentry *dentry,
311+ struct vfsmount *mnt);
312+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
313+static int __ccs_uselib_permission(struct dentry *dentry,
314+ struct vfsmount *mnt);
315+#endif
316+static int ccs_execute_permission(struct ccs_request_info *r,
317+ const struct ccs_path_info *filename);
318+static int ccs_find_next_domain(struct ccs_execve *ee);
319+static int ccs_get_path(const char *pathname, struct path *path);
320+static int ccs_kern_path(const char *pathname, int flags, struct path *path);
321+static int ccs_mkdev_perm(const u8 operation, struct dentry *dentry,
322+ struct vfsmount *mnt, const unsigned int mode,
323+ unsigned int dev);
324+static int ccs_mount_acl(struct ccs_request_info *r, const char *dev_name,
325+ const struct path *dir, const char *type,
326+ unsigned long flags);
327+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
328+static int ccs_new_open_permission(struct file *filp);
329+#endif
330+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
331+static int ccs_old_chroot_permission(struct nameidata *nd);
332+static int ccs_old_mount_permission(const char *dev_name, struct nameidata *nd,
333+ const char *type, unsigned long flags,
334+ void *data_page);
335+static int ccs_old_pivot_root_permission(struct nameidata *old_nd,
336+ struct nameidata *new_nd);
337+#endif
338+static int ccs_path2_perm(const u8 operation, struct dentry *dentry1,
339+ struct vfsmount *mnt1, struct dentry *dentry2,
340+ struct vfsmount *mnt2);
341+static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
342+ struct vfsmount *vfsmnt, unsigned long number);
343+static int ccs_path_perm(const u8 operation, struct dentry *dentry,
344+ struct vfsmount *mnt, const char *target);
345+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || !defined(CONFIG_SYSCTL_SYSCALL)
346+static
347+#endif
348+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
349+ const struct ccs_path_info *filename);
350+static int ccs_symlink_path(const char *pathname, struct ccs_path_info *name);
351+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
352+static void __ccs_clear_open_mode(void);
353+static void __ccs_save_open_mode(int mode);
354+#endif
355+static void ccs_add_slash(struct ccs_path_info *buf);
356+
357+#ifdef CONFIG_CCSECURITY_MISC
358+static bool ccs_check_env_acl(struct ccs_request_info *r,
359+ const struct ccs_acl_info *ptr);
360+static int ccs_env_perm(struct ccs_request_info *r, const char *env);
361+static int ccs_environ(struct ccs_execve *ee);
362+#endif
363+
364+#ifdef CONFIG_CCSECURITY_CAPABILITY
365+static bool __ccs_capable(const u8 operation);
366+static bool ccs_check_capability_acl(struct ccs_request_info *r,
367+ const struct ccs_acl_info *ptr);
368+static bool ccs_kernel_service(void);
369+static int __ccs_ptrace_permission(long request, long pid);
370+static int __ccs_socket_create_permission(int family, int type, int protocol);
371+#endif
372+
373+#ifdef CONFIG_CCSECURITY_NETWORK
374+static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
375+ const struct ccs_group *group);
376+static bool ccs_check_inet_acl(struct ccs_request_info *r,
377+ const struct ccs_acl_info *ptr);
378+static bool ccs_check_unix_acl(struct ccs_request_info *r,
379+ const struct ccs_acl_info *ptr);
380+static bool ccs_kernel_service(void);
381+static int __ccs_socket_bind_permission(struct socket *sock,
382+ struct sockaddr *addr, int addr_len);
383+static int __ccs_socket_connect_permission(struct socket *sock,
384+ struct sockaddr *addr,
385+ int addr_len);
386+static int __ccs_socket_listen_permission(struct socket *sock);
387+static int __ccs_socket_post_accept_permission(struct socket *sock,
388+ struct socket *newsock);
389+static int __ccs_socket_sendmsg_permission(struct socket *sock,
390+ struct msghdr *msg, int size);
391+static int ccs_check_inet_address(const struct sockaddr *addr,
392+ const unsigned int addr_len, const u16 port,
393+ struct ccs_addr_info *address);
394+static int ccs_check_unix_address(struct sockaddr *addr,
395+ const unsigned int addr_len,
396+ struct ccs_addr_info *address);
397+static int ccs_inet_entry(const struct ccs_addr_info *address);
398+static int ccs_unix_entry(const struct ccs_addr_info *address);
399+static u8 ccs_sock_family(struct sock *sk);
400+#endif
401+
402+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
403+static int __ccs_socket_post_recvmsg_permission(struct sock *sk,
404+ struct sk_buff *skb,
405+ int flags);
406+#endif
407+
408+#ifdef CONFIG_CCSECURITY_IPC
409+static bool ccs_check_signal_acl(struct ccs_request_info *r,
410+ const struct ccs_acl_info *ptr);
411+static int ccs_signal_acl(const int pid, const int sig);
412+static int ccs_signal_acl0(pid_t tgid, pid_t pid, int sig);
413+static int ccs_signal_acl2(const int sig, const int pid);
414+#endif
415+
416+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
417+static int __ccs_getattr_permission(struct vfsmount *mnt,
418+ struct dentry *dentry);
419+#endif
420+
421+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
422+static bool ccs_find_execute_handler(struct ccs_execve *ee, const u8 type);
423+static int ccs_try_alt_exec(struct ccs_execve *ee);
424+static void ccs_unescape(unsigned char *dest);
425+#endif
426+
427+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
428+static bool ccs_check_task_acl(struct ccs_request_info *r,
429+ const struct ccs_acl_info *ptr);
430+#endif
431+
432+/***** SECTION4: Standalone functions section *****/
433+
434+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
435+
436+/**
437+ * ccs_copy_argv - Wrapper for copy_strings_kernel().
438+ *
439+ * @arg: String to copy.
440+ * @bprm: Pointer to "struct linux_binprm".
441+ *
442+ * Returns return value of copy_strings_kernel().
443+ */
444+static inline int ccs_copy_argv(const char *arg, struct linux_binprm *bprm)
445+{
446+ const int ret = copy_strings_kernel(1, &arg, bprm);
447+ if (ret >= 0)
448+ bprm->argc++;
449+ return ret;
450+}
451+
452+#else
453+
454+/**
455+ * ccs_copy_argv - Wrapper for copy_strings_kernel().
456+ *
457+ * @arg: String to copy.
458+ * @bprm: Pointer to "struct linux_binprm".
459+ *
460+ * Returns return value of copy_strings_kernel().
461+ */
462+static inline int ccs_copy_argv(char *arg, struct linux_binprm *bprm)
463+{
464+ const int ret = copy_strings_kernel(1, &arg, bprm);
465+ if (ret >= 0)
466+ bprm->argc++;
467+ return ret;
468+}
469+
470+#endif
471+
472+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
473+
474+/**
475+ * get_fs_root - Get reference on root directory.
476+ *
477+ * @fs: Pointer to "struct fs_struct".
478+ * @root: Pointer to "struct path".
479+ *
480+ * Returns nothing.
481+ *
482+ * This is for compatibility with older kernels.
483+ */
484+static inline void get_fs_root(struct fs_struct *fs, struct path *root)
485+{
486+ read_lock(&fs->lock);
487+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
488+ *root = fs->root;
489+ path_get(root);
490+#else
491+ root->dentry = dget(fs->root);
492+ root->mnt = mntget(fs->rootmnt);
493+#endif
494+ read_unlock(&fs->lock);
495+}
496+
497+#endif
498+
499+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
500+
501+/**
502+ * module_put - Put a reference on module.
503+ *
504+ * @module: Pointer to "struct module". Maybe NULL.
505+ *
506+ * Returns nothing.
507+ *
508+ * This is for compatibility with older kernels.
509+ */
510+static inline void module_put(struct module *module)
511+{
512+ if (module)
513+ __MOD_DEC_USE_COUNT(module);
514+}
515+
516+#endif
517+
518+/**
519+ * ccs_put_filesystem - Wrapper for put_filesystem().
520+ *
521+ * @fstype: Pointer to "struct file_system_type".
522+ *
523+ * Returns nothing.
524+ *
525+ * Since put_filesystem() is not exported, I embed put_filesystem() here.
526+ */
527+static inline void ccs_put_filesystem(struct file_system_type *fstype)
528+{
529+ module_put(fstype->owner);
530+}
531+
532+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
533+
534+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
535+#if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5
536+#if !defined(AX_MAJOR) || AX_MAJOR != 3
537+
538+/**
539+ * ip_hdr - Get "struct iphdr".
540+ *
541+ * @skb: Pointer to "struct sk_buff".
542+ *
543+ * Returns pointer to "struct iphdr".
544+ *
545+ * This is for compatibility with older kernels.
546+ */
547+static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
548+{
549+ return skb->nh.iph;
550+}
551+
552+/**
553+ * udp_hdr - Get "struct udphdr".
554+ *
555+ * @skb: Pointer to "struct sk_buff".
556+ *
557+ * Returns pointer to "struct udphdr".
558+ *
559+ * This is for compatibility with older kernels.
560+ */
561+static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
562+{
563+ return skb->h.uh;
564+}
565+
566+/**
567+ * ipv6_hdr - Get "struct ipv6hdr".
568+ *
569+ * @skb: Pointer to "struct sk_buff".
570+ *
571+ * Returns pointer to "struct ipv6hdr".
572+ *
573+ * This is for compatibility with older kernels.
574+ */
575+static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
576+{
577+ return skb->nh.ipv6h;
578+}
579+
580+#endif
581+#endif
582+#endif
583+
584+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
585+
586+/**
587+ * skb_kill_datagram - Kill a datagram forcibly.
588+ *
589+ * @sk: Pointer to "struct sock".
590+ * @skb: Pointer to "struct sk_buff".
591+ * @flags: Flags passed to skb_recv_datagram().
592+ *
593+ * Returns nothing.
594+ */
595+static inline void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
596+ int flags)
597+{
598+ /* Clear queue. */
599+ if (flags & MSG_PEEK) {
600+ int clear = 0;
601+ spin_lock_irq(&sk->receive_queue.lock);
602+ if (skb == skb_peek(&sk->receive_queue)) {
603+ __skb_unlink(skb, &sk->receive_queue);
604+ clear = 1;
605+ }
606+ spin_unlock_irq(&sk->receive_queue.lock);
607+ if (clear)
608+ kfree_skb(skb);
609+ }
610+ skb_free_datagram(sk, skb);
611+}
612+
613+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
614+
615+/**
616+ * skb_kill_datagram - Kill a datagram forcibly.
617+ *
618+ * @sk: Pointer to "struct sock".
619+ * @skb: Pointer to "struct sk_buff".
620+ * @flags: Flags passed to skb_recv_datagram().
621+ *
622+ * Returns nothing.
623+ */
624+static inline void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
625+ int flags)
626+{
627+ /* Clear queue. */
628+ if (flags & MSG_PEEK) {
629+ int clear = 0;
630+ spin_lock_bh(&sk->sk_receive_queue.lock);
631+ if (skb == skb_peek(&sk->sk_receive_queue)) {
632+ __skb_unlink(skb, &sk->sk_receive_queue);
633+ clear = 1;
634+ }
635+ spin_unlock_bh(&sk->sk_receive_queue.lock);
636+ if (clear)
637+ kfree_skb(skb);
638+ }
639+ skb_free_datagram(sk, skb);
640+}
641+
642+#endif
643+
644+#endif
645+
646+/***** SECTION5: Variables definition section *****/
647+
648+/* The initial domain. */
649+struct ccs_domain_info ccs_kernel_domain;
650+
651+/* The list for "struct ccs_domain_info". */
652+LIST_HEAD(ccs_domain_list);
653+
654+/***** SECTION6: Dependent functions section *****/
655+
656+/**
657+ * ccs_path_matches_group - Check whether the given pathname matches members of the given pathname group.
658+ *
659+ * @pathname: The name of pathname.
660+ * @group: Pointer to "struct ccs_path_group".
661+ *
662+ * Returns matched member's pathname if @pathname matches pathnames in @group,
663+ * NULL otherwise.
664+ *
665+ * Caller holds ccs_read_lock().
666+ */
667+static const struct ccs_path_info *ccs_path_matches_group
668+(const struct ccs_path_info *pathname, const struct ccs_group *group)
669+{
670+ struct ccs_path_group *member;
671+ list_for_each_entry_srcu(member, &group->member_list, head.list,
672+ &ccs_ss) {
673+ if (member->head.is_deleted)
674+ continue;
675+ if (!ccs_path_matches_pattern(pathname, member->member_name))
676+ continue;
677+ return member->member_name;
678+ }
679+ return NULL;
680+}
681+
682+/**
683+ * ccs_number_matches_group - Check whether the given number matches members of the given number group.
684+ *
685+ * @min: Min number.
686+ * @max: Max number.
687+ * @group: Pointer to "struct ccs_number_group".
688+ *
689+ * Returns true if @min and @max partially overlaps @group, false otherwise.
690+ *
691+ * Caller holds ccs_read_lock().
692+ */
693+static bool ccs_number_matches_group(const unsigned long min,
694+ const unsigned long max,
695+ const struct ccs_group *group)
696+{
697+ struct ccs_number_group *member;
698+ bool matched = false;
699+ list_for_each_entry_srcu(member, &group->member_list, head.list,
700+ &ccs_ss) {
701+ if (member->head.is_deleted)
702+ continue;
703+ if (min > member->number.values[1] ||
704+ max < member->number.values[0])
705+ continue;
706+ matched = true;
707+ break;
708+ }
709+ return matched;
710+}
711+
712+/**
713+ * ccs_check_entry - Do permission check.
714+ *
715+ * @r: Pointer to "struct ccs_request_info".
716+ * @ptr: Pointer to "struct ccs_acl_info".
717+ *
718+ * Returns true on match, false otherwise.
719+ *
720+ * Caller holds ccs_read_lock().
721+ */
722+static bool ccs_check_entry(struct ccs_request_info *r,
723+ struct ccs_acl_info *ptr)
724+{
725+ if (ptr->is_deleted || ptr->type != r->param_type)
726+ return false;
727+ switch (r->param_type) {
728+ case CCS_TYPE_PATH_ACL:
729+ return ccs_check_path_acl(r, ptr);
730+ case CCS_TYPE_PATH2_ACL:
731+ return ccs_check_path2_acl(r, ptr);
732+ case CCS_TYPE_PATH_NUMBER_ACL:
733+ return ccs_check_path_number_acl(r, ptr);
734+ case CCS_TYPE_MKDEV_ACL:
735+ return ccs_check_mkdev_acl(r, ptr);
736+ case CCS_TYPE_MOUNT_ACL:
737+ return ccs_check_mount_acl(r, ptr);
738+#ifdef CONFIG_CCSECURITY_MISC
739+ case CCS_TYPE_ENV_ACL:
740+ return ccs_check_env_acl(r, ptr);
741+#endif
742+#ifdef CONFIG_CCSECURITY_CAPABILITY
743+ case CCS_TYPE_CAPABILITY_ACL:
744+ return ccs_check_capability_acl(r, ptr);
745+#endif
746+#ifdef CONFIG_CCSECURITY_NETWORK
747+ case CCS_TYPE_INET_ACL:
748+ return ccs_check_inet_acl(r, ptr);
749+ case CCS_TYPE_UNIX_ACL:
750+ return ccs_check_unix_acl(r, ptr);
751+#endif
752+#ifdef CONFIG_CCSECURITY_IPC
753+ case CCS_TYPE_SIGNAL_ACL:
754+ return ccs_check_signal_acl(r, ptr);
755+#endif
756+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
757+ case CCS_TYPE_MANUAL_TASK_ACL:
758+ return ccs_check_task_acl(r, ptr);
759+#endif
760+ }
761+ return true;
762+}
763+
764+/**
765+ * ccs_check_acl - Do permission check.
766+ *
767+ * @r: Pointer to "struct ccs_request_info".
768+ *
769+ * Returns 0 on success, negative value otherwise.
770+ *
771+ * Caller holds ccs_read_lock().
772+ */
773+int ccs_check_acl(struct ccs_request_info *r)
774+{
775+ const struct ccs_domain_info *domain = ccs_current_domain();
776+ int error;
777+ do {
778+ struct ccs_acl_info *ptr;
779+ const struct list_head *list = &domain->acl_info_list;
780+ u16 i = 0;
781+retry:
782+ list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
783+ if (!ccs_check_entry(r, ptr))
784+ continue;
785+ if (!ccs_condition(r, ptr->cond))
786+ continue;
787+ r->matched_acl = ptr;
788+ r->granted = true;
789+ ccs_audit_log(r);
790+ return 0;
791+ }
792+ for (; i < CCS_MAX_ACL_GROUPS; i++) {
793+ if (!test_bit(i, domain->group))
794+ continue;
795+ list = &domain->ns->acl_group[i++];
796+ goto retry;
797+ }
798+ r->granted = false;
799+ error = ccs_audit_log(r);
800+ } while (error == CCS_RETRY_REQUEST &&
801+ r->type != CCS_MAC_FILE_EXECUTE);
802+ return error;
803+}
804+
805+/**
806+ * ccs_last_word - Get last component of a domainname.
807+ *
808+ * @name: Domainname to check.
809+ *
810+ * Returns the last word of @name.
811+ */
812+static const char *ccs_last_word(const char *name)
813+{
814+ const char *cp = strrchr(name, ' ');
815+ if (cp)
816+ return cp + 1;
817+ return name;
818+}
819+
820+/**
821+ * ccs_scan_transition - Try to find specific domain transition type.
822+ *
823+ * @list: Pointer to "struct list_head".
824+ * @domainname: The name of current domain.
825+ * @program: The name of requested program.
826+ * @last_name: The last component of @domainname.
827+ * @type: One of values in "enum ccs_transition_type".
828+ *
829+ * Returns true if found one, false otherwise.
830+ *
831+ * Caller holds ccs_read_lock().
832+ */
833+static bool ccs_scan_transition(const struct list_head *list,
834+ const struct ccs_path_info *domainname,
835+ const struct ccs_path_info *program,
836+ const char *last_name,
837+ const enum ccs_transition_type type)
838+{
839+ const struct ccs_transition_control *ptr;
840+ list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
841+ if (ptr->head.is_deleted || ptr->type != type)
842+ continue;
843+ if (ptr->domainname) {
844+ if (!ptr->is_last_name) {
845+ if (ptr->domainname != domainname)
846+ continue;
847+ } else {
848+ /*
849+ * Use direct strcmp() since this is
850+ * unlikely used.
851+ */
852+ if (strcmp(ptr->domainname->name, last_name))
853+ continue;
854+ }
855+ }
856+ if (ptr->program && ccs_pathcmp(ptr->program, program))
857+ continue;
858+ return true;
859+ }
860+ return false;
861+}
862+
863+/**
864+ * ccs_transition_type - Get domain transition type.
865+ *
866+ * @ns: Pointer to "struct ccs_policy_namespace".
867+ * @domainname: The name of current domain.
868+ * @program: The name of requested program.
869+ *
870+ * Returns CCS_TRANSITION_CONTROL_TRANSIT if executing @program causes domain
871+ * transition across namespaces, CCS_TRANSITION_CONTROL_INITIALIZE if executing
872+ * @program reinitializes domain transition within that namespace,
873+ * CCS_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
874+ * others otherwise.
875+ *
876+ * Caller holds ccs_read_lock().
877+ */
878+static enum ccs_transition_type ccs_transition_type
879+(const struct ccs_policy_namespace *ns, const struct ccs_path_info *domainname,
880+ const struct ccs_path_info *program)
881+{
882+ const char *last_name = ccs_last_word(domainname->name);
883+ enum ccs_transition_type type = CCS_TRANSITION_CONTROL_NO_RESET;
884+ while (type < CCS_MAX_TRANSITION_TYPE) {
885+ const struct list_head * const list =
886+ &ns->policy_list[CCS_ID_TRANSITION_CONTROL];
887+ if (!ccs_scan_transition(list, domainname, program, last_name,
888+ type)) {
889+ type++;
890+ continue;
891+ }
892+ if (type != CCS_TRANSITION_CONTROL_NO_RESET &&
893+ type != CCS_TRANSITION_CONTROL_NO_INITIALIZE)
894+ break;
895+ /*
896+ * Do not check for reset_domain if no_reset_domain matched.
897+ * Do not check for initialize_domain if no_initialize_domain
898+ * matched.
899+ */
900+ type++;
901+ type++;
902+ }
903+ return type;
904+}
905+
906+/**
907+ * ccs_find_next_domain - Find a domain.
908+ *
909+ * @ee: Pointer to "struct ccs_execve".
910+ *
911+ * Returns 0 on success, negative value otherwise.
912+ *
913+ * Caller holds ccs_read_lock().
914+ */
915+static int ccs_find_next_domain(struct ccs_execve *ee)
916+{
917+ struct ccs_request_info *r = &ee->r;
918+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
919+ const struct ccs_path_info *handler = ee->handler;
920+#endif
921+ struct ccs_domain_info *domain = NULL;
922+ struct ccs_domain_info * const old_domain = ccs_current_domain();
923+ struct linux_binprm *bprm = ee->bprm;
924+ struct ccs_security *task = ccs_current_security();
925+ const struct ccs_path_info *candidate;
926+ struct ccs_path_info exename;
927+ int retval;
928+ bool reject_on_transition_failure = false;
929+
930+ /* Get symlink's pathname of program. */
931+ retval = ccs_symlink_path(bprm->filename, &exename);
932+ if (retval < 0)
933+ return retval;
934+
935+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
936+ if (handler) {
937+ /* No permission check for execute handler. */
938+ candidate = &exename;
939+ if (ccs_pathcmp(candidate, handler)) {
940+ /* Failed to verify execute handler. */
941+ static u8 counter = 20;
942+ if (counter) {
943+ counter--;
944+ printk(KERN_WARNING "Failed to verify: %s\n",
945+ handler->name);
946+ }
947+ goto out;
948+ }
949+ } else
950+#endif
951+ {
952+ struct ccs_aggregator *ptr;
953+ struct list_head *list;
954+retry:
955+ /* Check 'aggregator' directive. */
956+ candidate = &exename;
957+ list = &old_domain->ns->policy_list[CCS_ID_AGGREGATOR];
958+ list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
959+ if (ptr->head.is_deleted ||
960+ !ccs_path_matches_pattern(candidate,
961+ ptr->original_name))
962+ continue;
963+ candidate = ptr->aggregated_name;
964+ break;
965+ }
966+
967+ /* Check execute permission. */
968+ retval = ccs_execute_permission(r, candidate);
969+ if (retval == CCS_RETRY_REQUEST)
970+ goto retry;
971+ if (retval < 0)
972+ goto out;
973+ /*
974+ * To be able to specify domainnames with wildcards, use the
975+ * pathname specified in the policy (which may contain
976+ * wildcard) rather than the pathname passed to execve()
977+ * (which never contains wildcard).
978+ */
979+ if (r->param.path.matched_path)
980+ candidate = r->param.path.matched_path;
981+ }
982+ /*
983+ * Check for domain transition preference if "file execute" matched.
984+ * If preference is given, make do_execve() fail if domain transition
985+ * has failed, for domain transition preference should be used with
986+ * destination domain defined.
987+ */
988+ if (r->ee->transition) {
989+ const char *domainname = r->ee->transition->name;
990+ reject_on_transition_failure = true;
991+ if (!strcmp(domainname, "keep"))
992+ goto force_keep_domain;
993+ if (!strcmp(domainname, "child"))
994+ goto force_child_domain;
995+ if (!strcmp(domainname, "reset"))
996+ goto force_reset_domain;
997+ if (!strcmp(domainname, "initialize"))
998+ goto force_initialize_domain;
999+ if (!strcmp(domainname, "parent")) {
1000+ char *cp;
1001+ strncpy(ee->tmp, old_domain->domainname->name,
1002+ CCS_EXEC_TMPSIZE - 1);
1003+ cp = strrchr(ee->tmp, ' ');
1004+ if (cp)
1005+ *cp = '\0';
1006+ } else if (*domainname == '<')
1007+ strncpy(ee->tmp, domainname, CCS_EXEC_TMPSIZE - 1);
1008+ else
1009+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
1010+ old_domain->domainname->name, domainname);
1011+ goto force_jump_domain;
1012+ }
1013+ /*
1014+ * No domain transition preference specified.
1015+ * Calculate domain to transit to.
1016+ */
1017+ switch (ccs_transition_type(old_domain->ns, old_domain->domainname,
1018+ candidate)) {
1019+ case CCS_TRANSITION_CONTROL_RESET:
1020+force_reset_domain:
1021+ /* Transit to the root of specified namespace. */
1022+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "<%s>",
1023+ candidate->name);
1024+ /*
1025+ * Make do_execve() fail if domain transition across namespaces
1026+ * has failed.
1027+ */
1028+ reject_on_transition_failure = true;
1029+ break;
1030+ case CCS_TRANSITION_CONTROL_INITIALIZE:
1031+force_initialize_domain:
1032+ /* Transit to the child of current namespace's root. */
1033+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
1034+ old_domain->ns->name, candidate->name);
1035+ break;
1036+ case CCS_TRANSITION_CONTROL_KEEP:
1037+force_keep_domain:
1038+ /* Keep current domain. */
1039+ domain = old_domain;
1040+ break;
1041+ default:
1042+ if (old_domain == &ccs_kernel_domain && !ccs_policy_loaded) {
1043+ /*
1044+ * Needn't to transit from kernel domain before
1045+ * starting /sbin/init. But transit from kernel domain
1046+ * if executing initializers because they might start
1047+ * before /sbin/init.
1048+ */
1049+ domain = old_domain;
1050+ break;
1051+ }
1052+force_child_domain:
1053+ /* Normal domain transition. */
1054+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
1055+ old_domain->domainname->name, candidate->name);
1056+ break;
1057+ }
1058+force_jump_domain:
1059+ /*
1060+ * Tell GC that I started execve().
1061+ * Also, tell open_exec() to check read permission.
1062+ */
1063+ task->ccs_flags |= CCS_TASK_IS_IN_EXECVE;
1064+ /*
1065+ * Make task->ccs_flags visible to GC before changing
1066+ * task->ccs_domain_info.
1067+ */
1068+ smp_wmb();
1069+ /*
1070+ * Proceed to the next domain in order to allow reaching via PID.
1071+ * It will be reverted if execve() failed. Reverting is not good.
1072+ * But it is better than being unable to reach via PID in interactive
1073+ * enforcing mode.
1074+ */
1075+ if (!domain)
1076+ domain = ccs_assign_domain(ee->tmp, true);
1077+ if (domain)
1078+ retval = 0;
1079+ else if (reject_on_transition_failure) {
1080+ printk(KERN_WARNING
1081+ "ERROR: Domain '%s' not ready.\n", ee->tmp);
1082+ retval = -ENOMEM;
1083+ } else if (r->mode == CCS_CONFIG_ENFORCING)
1084+ retval = -ENOMEM;
1085+ else {
1086+ retval = 0;
1087+ if (!old_domain->flags[CCS_DIF_TRANSITION_FAILED]) {
1088+ old_domain->flags[CCS_DIF_TRANSITION_FAILED] = true;
1089+ r->granted = false;
1090+ ccs_write_log(r, "%s",
1091+ ccs_dif[CCS_DIF_TRANSITION_FAILED]);
1092+ printk(KERN_WARNING
1093+ "ERROR: Domain '%s' not defined.\n", ee->tmp);
1094+ }
1095+ }
1096+out:
1097+ kfree(exename.name);
1098+ return retval;
1099+}
1100+
1101+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1102+
1103+/**
1104+ * ccs_unescape - Unescape escaped string.
1105+ *
1106+ * @dest: String to unescape.
1107+ *
1108+ * Returns nothing.
1109+ */
1110+static void ccs_unescape(unsigned char *dest)
1111+{
1112+ unsigned char *src = dest;
1113+ unsigned char c;
1114+ unsigned char d;
1115+ unsigned char e;
1116+ while (1) {
1117+ c = *src++;
1118+ if (!c)
1119+ break;
1120+ if (c != '\\') {
1121+ *dest++ = c;
1122+ continue;
1123+ }
1124+ c = *src++;
1125+ if (c == '\\') {
1126+ *dest++ = c;
1127+ continue;
1128+ }
1129+ if (c < '0' || c > '3')
1130+ break;
1131+ d = *src++;
1132+ if (d < '0' || d > '7')
1133+ break;
1134+ e = *src++;
1135+ if (e < '0' || e > '7')
1136+ break;
1137+ *dest++ = ((c - '0') << 6) + ((d - '0') << 3) + (e - '0');
1138+ }
1139+ *dest = '\0';
1140+}
1141+
1142+/**
1143+ * ccs_try_alt_exec - Try to start execute handler.
1144+ *
1145+ * @ee: Pointer to "struct ccs_execve".
1146+ *
1147+ * Returns 0 on success, negative value otherwise.
1148+ */
1149+static int ccs_try_alt_exec(struct ccs_execve *ee)
1150+{
1151+ /*
1152+ * Contents of modified bprm.
1153+ * The envp[] in original bprm is moved to argv[] so that
1154+ * the alternatively executed program won't be affected by
1155+ * some dangerous environment variables like LD_PRELOAD.
1156+ *
1157+ * modified bprm->argc
1158+ * = original bprm->argc + original bprm->envc + 7
1159+ * modified bprm->envc
1160+ * = 0
1161+ *
1162+ * modified bprm->argv[0]
1163+ * = the program's name specified by *_execute_handler
1164+ * modified bprm->argv[1]
1165+ * = ccs_current_domain()->domainname->name
1166+ * modified bprm->argv[2]
1167+ * = the current process's name
1168+ * modified bprm->argv[3]
1169+ * = the current process's information (e.g. uid/gid).
1170+ * modified bprm->argv[4]
1171+ * = original bprm->filename
1172+ * modified bprm->argv[5]
1173+ * = original bprm->argc in string expression
1174+ * modified bprm->argv[6]
1175+ * = original bprm->envc in string expression
1176+ * modified bprm->argv[7]
1177+ * = original bprm->argv[0]
1178+ * ...
1179+ * modified bprm->argv[bprm->argc + 6]
1180+ * = original bprm->argv[bprm->argc - 1]
1181+ * modified bprm->argv[bprm->argc + 7]
1182+ * = original bprm->envp[0]
1183+ * ...
1184+ * modified bprm->argv[bprm->envc + bprm->argc + 6]
1185+ * = original bprm->envp[bprm->envc - 1]
1186+ */
1187+ struct linux_binprm *bprm = ee->bprm;
1188+ struct file *filp;
1189+ int retval;
1190+ const int original_argc = bprm->argc;
1191+ const int original_envc = bprm->envc;
1192+
1193+ /* Close the requested program's dentry. */
1194+ ee->obj.path1.dentry = NULL;
1195+ ee->obj.path1.mnt = NULL;
1196+ ee->obj.stat_valid[CCS_PATH1] = false;
1197+ ee->obj.stat_valid[CCS_PATH1_PARENT] = false;
1198+ ee->obj.validate_done = false;
1199+ allow_write_access(bprm->file);
1200+ fput(bprm->file);
1201+ bprm->file = NULL;
1202+
1203+ /* Invalidate page dump cache. */
1204+ ee->dump.page = NULL;
1205+
1206+ /* Move envp[] to argv[] */
1207+ bprm->argc += bprm->envc;
1208+ bprm->envc = 0;
1209+
1210+ /* Set argv[6] */
1211+ {
1212+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%d", original_envc);
1213+ retval = ccs_copy_argv(ee->tmp, bprm);
1214+ if (retval < 0)
1215+ goto out;
1216+ }
1217+
1218+ /* Set argv[5] */
1219+ {
1220+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%d", original_argc);
1221+ retval = ccs_copy_argv(ee->tmp, bprm);
1222+ if (retval < 0)
1223+ goto out;
1224+ }
1225+
1226+ /* Set argv[4] */
1227+ {
1228+ retval = ccs_copy_argv(bprm->filename, bprm);
1229+ if (retval < 0)
1230+ goto out;
1231+ }
1232+
1233+ /* Set argv[3] */
1234+ {
1235+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1236+ /*
1237+ * Pass uid/gid seen from current user namespace, for these
1238+ * values are used by programs in current user namespace in
1239+ * order to decide whether to execve() or not (rather than by
1240+ * auditing daemon in init's user namespace).
1241+ */
1242+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1,
1243+ "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
1244+ "sgid=%d fsuid=%d fsgid=%d", ccs_sys_getpid(),
1245+ __kuid_val(current_uid()), __kgid_val(current_gid()),
1246+ __kuid_val(current_euid()),
1247+ __kgid_val(current_egid()),
1248+ __kuid_val(current_suid()),
1249+ __kgid_val(current_sgid()),
1250+ __kuid_val(current_fsuid()),
1251+ __kgid_val(current_fsgid()));
1252+#else
1253+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1,
1254+ "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
1255+ "sgid=%d fsuid=%d fsgid=%d", ccs_sys_getpid(),
1256+ current_uid(), current_gid(), current_euid(),
1257+ current_egid(), current_suid(), current_sgid(),
1258+ current_fsuid(), current_fsgid());
1259+#endif
1260+ retval = ccs_copy_argv(ee->tmp, bprm);
1261+ if (retval < 0)
1262+ goto out;
1263+ }
1264+
1265+ /* Set argv[2] */
1266+ {
1267+ char *exe = (char *) ccs_get_exe();
1268+ if (exe) {
1269+ retval = ccs_copy_argv(exe, bprm);
1270+ kfree(exe);
1271+ } else {
1272+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1273+ retval = ccs_copy_argv("<unknown>", bprm);
1274+#else
1275+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "<unknown>");
1276+ retval = ccs_copy_argv(ee->tmp, bprm);
1277+#endif
1278+ }
1279+ if (retval < 0)
1280+ goto out;
1281+ }
1282+
1283+ /* Set argv[1] */
1284+ {
1285+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1286+ retval = ccs_copy_argv(ccs_current_domain()->domainname->name,
1287+ bprm);
1288+#else
1289+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s",
1290+ ccs_current_domain()->domainname->name);
1291+ retval = ccs_copy_argv(ee->tmp, bprm);
1292+#endif
1293+ if (retval < 0)
1294+ goto out;
1295+ }
1296+
1297+ /* Set argv[0] */
1298+ {
1299+ struct path root;
1300+ char *cp;
1301+ int root_len;
1302+ int handler_len;
1303+ get_fs_root(current->fs, &root);
1304+ cp = ccs_realpath(&root);
1305+ path_put(&root);
1306+ if (!cp) {
1307+ retval = -ENOMEM;
1308+ goto out;
1309+ }
1310+ root_len = strlen(cp);
1311+ retval = strncmp(ee->handler->name, cp, root_len);
1312+ root_len--;
1313+ kfree(cp);
1314+ if (retval) {
1315+ retval = -ENOENT;
1316+ goto out;
1317+ }
1318+ handler_len = ee->handler->total_len + 1;
1319+ cp = kmalloc(handler_len, CCS_GFP_FLAGS);
1320+ if (!cp) {
1321+ retval = -ENOMEM;
1322+ goto out;
1323+ }
1324+ /* ee->handler_path is released by ccs_finish_execve(). */
1325+ ee->handler_path = cp;
1326+ /* Adjust root directory for open_exec(). */
1327+ memmove(cp, ee->handler->name + root_len,
1328+ handler_len - root_len);
1329+ ccs_unescape(cp);
1330+ retval = -ENOENT;
1331+ if (*cp != '/')
1332+ goto out;
1333+ retval = ccs_copy_argv(cp, bprm);
1334+ if (retval < 0)
1335+ goto out;
1336+ }
1337+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
1338+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1339+ bprm->argv_len = bprm->exec - bprm->p;
1340+#endif
1341+#endif
1342+
1343+ /*
1344+ * OK, now restart the process with execute handler program's dentry.
1345+ */
1346+ filp = open_exec(ee->handler_path);
1347+ if (IS_ERR(filp)) {
1348+ retval = PTR_ERR(filp);
1349+ goto out;
1350+ }
1351+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
1352+ ee->obj.path1 = filp->f_path;
1353+#else
1354+ ee->obj.path1.dentry = filp->f_dentry;
1355+ ee->obj.path1.mnt = filp->f_vfsmnt;
1356+#endif
1357+ bprm->file = filp;
1358+ bprm->filename = ee->handler_path;
1359+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1360+ bprm->interp = bprm->filename;
1361+#endif
1362+ retval = prepare_binprm(bprm);
1363+ if (retval < 0)
1364+ goto out;
1365+ ee->r.dont_sleep_on_enforce_error = true;
1366+ retval = ccs_find_next_domain(ee);
1367+ ee->r.dont_sleep_on_enforce_error = false;
1368+out:
1369+ return retval;
1370+}
1371+
1372+/**
1373+ * ccs_find_execute_handler - Find an execute handler.
1374+ *
1375+ * @ee: Pointer to "struct ccs_execve".
1376+ * @type: Type of execute handler.
1377+ *
1378+ * Returns true if found, false otherwise.
1379+ *
1380+ * Caller holds ccs_read_lock().
1381+ */
1382+static bool ccs_find_execute_handler(struct ccs_execve *ee, const u8 type)
1383+{
1384+ struct ccs_request_info *r = &ee->r;
1385+ /*
1386+ * To avoid infinite execute handler loop, don't use execute handler
1387+ * if the current process is marked as execute handler.
1388+ */
1389+ if (ccs_current_flags() & CCS_TASK_IS_EXECUTE_HANDLER)
1390+ return false;
1391+ r->param_type = type;
1392+ ccs_check_acl(r);
1393+ if (!r->granted)
1394+ return false;
1395+ ee->handler = container_of(r->matched_acl, struct ccs_handler_acl,
1396+ head)->handler;
1397+ ee->transition = r->matched_acl && r->matched_acl->cond &&
1398+ r->matched_acl->cond->exec_transit ?
1399+ r->matched_acl->cond->transit : NULL;
1400+ return true;
1401+}
1402+
1403+#endif
1404+
1405+#ifdef CONFIG_MMU
1406+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
1407+#define CCS_BPRM_MMU
1408+#elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR >= 3
1409+#define CCS_BPRM_MMU
1410+#elif defined(AX_MAJOR) && AX_MAJOR == 3 && defined(AX_MINOR) && AX_MINOR >= 2
1411+#define CCS_BPRM_MMU
1412+#endif
1413+#endif
1414+
1415+/**
1416+ * ccs_dump_page - Dump a page to buffer.
1417+ *
1418+ * @bprm: Pointer to "struct linux_binprm".
1419+ * @pos: Location to dump.
1420+ * @dump: Poiner to "struct ccs_page_dump".
1421+ *
1422+ * Returns true on success, false otherwise.
1423+ */
1424+bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
1425+ struct ccs_page_dump *dump)
1426+{
1427+ struct page *page;
1428+ /* dump->data is released by ccs_start_execve(). */
1429+ if (!dump->data) {
1430+ dump->data = kzalloc(PAGE_SIZE, CCS_GFP_FLAGS);
1431+ if (!dump->data)
1432+ return false;
1433+ }
1434+ /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
1435+#ifdef CCS_BPRM_MMU
1436+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
1437+ if (get_user_pages_remote(current, bprm->mm, pos, 1, FOLL_FORCE, &page,
1438+ NULL, NULL) <= 0)
1439+ return false;
1440+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
1441+ if (get_user_pages_remote(current, bprm->mm, pos, 1, FOLL_FORCE, &page,
1442+ NULL) <= 0)
1443+ return false;
1444+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 168) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
1445+ if (get_user_pages(current, bprm->mm, pos, 1, FOLL_FORCE, &page,
1446+ NULL) <= 0)
1447+ return false;
1448+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
1449+ if (get_user_pages_remote(current, bprm->mm, pos, 1, 0, 1, &page,
1450+ NULL) <= 0)
1451+ return false;
1452+#else
1453+ if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
1454+ return false;
1455+#endif
1456+#else
1457+ page = bprm->page[pos / PAGE_SIZE];
1458+#endif
1459+ if (page != dump->page) {
1460+ const unsigned int offset = pos % PAGE_SIZE;
1461+ /*
1462+ * Maybe kmap()/kunmap() should be used here.
1463+ * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
1464+ * So do I.
1465+ */
1466+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1467+ char *kaddr = kmap_atomic(page);
1468+#else
1469+ char *kaddr = kmap_atomic(page, KM_USER0);
1470+#endif
1471+ dump->page = page;
1472+ memcpy(dump->data + offset, kaddr + offset,
1473+ PAGE_SIZE - offset);
1474+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1475+ kunmap_atomic(kaddr);
1476+#else
1477+ kunmap_atomic(kaddr, KM_USER0);
1478+#endif
1479+ }
1480+ /* Same with put_arg_page(page) in fs/exec.c */
1481+#ifdef CCS_BPRM_MMU
1482+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1483+ put_user_page(page);
1484+#else
1485+ put_page(page);
1486+#endif
1487+#endif
1488+ return true;
1489+}
1490+
1491+/**
1492+ * ccs_start_execve - Prepare for execve() operation.
1493+ *
1494+ * @bprm: Pointer to "struct linux_binprm".
1495+ * @eep: Pointer to "struct ccs_execve *".
1496+ *
1497+ * Returns 0 on success, negative value otherwise.
1498+ */
1499+int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep)
1500+{
1501+ int retval;
1502+ struct ccs_security *task = ccs_current_security();
1503+ struct ccs_execve *ee;
1504+ int idx;
1505+ *eep = NULL;
1506+ ee = kzalloc(sizeof(*ee), CCS_GFP_FLAGS);
1507+ if (!ee)
1508+ return -ENOMEM;
1509+ ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
1510+ if (!ee->tmp) {
1511+ kfree(ee);
1512+ return -ENOMEM;
1513+ }
1514+ ccs_audit_alloc_execve(ee);
1515+ idx = ccs_read_lock();
1516+ /* ee->dump->data is allocated by ccs_dump_page(). */
1517+ ee->previous_domain = task->ccs_domain_info;
1518+ /* Clear manager flag. */
1519+ task->ccs_flags &= ~CCS_TASK_IS_MANAGER;
1520+ *eep = ee;
1521+ ccs_init_request_info(&ee->r, CCS_MAC_FILE_EXECUTE);
1522+ ee->r.ee = ee;
1523+ ee->bprm = bprm;
1524+ ee->r.obj = &ee->obj;
1525+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
1526+ ee->obj.path1 = bprm->file->f_path;
1527+#else
1528+ ee->obj.path1.dentry = bprm->file->f_dentry;
1529+ ee->obj.path1.mnt = bprm->file->f_vfsmnt;
1530+#endif
1531+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1532+ /*
1533+ * No need to call ccs_environ() for execute handler because envp[] is
1534+ * moved to argv[].
1535+ */
1536+ if (ccs_find_execute_handler(ee, CCS_TYPE_AUTO_EXECUTE_HANDLER)) {
1537+ retval = ccs_try_alt_exec(ee);
1538+ goto done;
1539+ }
1540+#endif
1541+ retval = ccs_find_next_domain(ee);
1542+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1543+ if (retval == -EPERM &&
1544+ ccs_find_execute_handler(ee, CCS_TYPE_DENIED_EXECUTE_HANDLER)) {
1545+ retval = ccs_try_alt_exec(ee);
1546+ goto done;
1547+ }
1548+#endif
1549+#ifdef CONFIG_CCSECURITY_MISC
1550+ if (!retval)
1551+ retval = ccs_environ(ee);
1552+#endif
1553+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1554+done:
1555+#endif
1556+ ccs_read_unlock(idx);
1557+ kfree(ee->tmp);
1558+ ee->tmp = NULL;
1559+ kfree(ee->dump.data);
1560+ ee->dump.data = NULL;
1561+ return retval;
1562+}
1563+
1564+/**
1565+ * ccs_finish_execve - Clean up execve() operation.
1566+ *
1567+ * @retval: Return code of an execve() operation.
1568+ * @ee: Pointer to "struct ccs_execve".
1569+ *
1570+ * Returns nothing.
1571+ */
1572+void ccs_finish_execve(int retval, struct ccs_execve *ee)
1573+{
1574+ struct ccs_security *task = ccs_current_security();
1575+ if (!ee)
1576+ return;
1577+ if (retval < 0) {
1578+ task->ccs_domain_info = ee->previous_domain;
1579+ /*
1580+ * Make task->ccs_domain_info visible to GC before changing
1581+ * task->ccs_flags.
1582+ */
1583+ smp_wmb();
1584+ } else {
1585+ /* Mark the current process as execute handler. */
1586+ if (ee->handler)
1587+ task->ccs_flags |= CCS_TASK_IS_EXECUTE_HANDLER;
1588+ /* Mark the current process as normal process. */
1589+ else
1590+ task->ccs_flags &= ~CCS_TASK_IS_EXECUTE_HANDLER;
1591+ }
1592+ /* Tell GC that I finished execve(). */
1593+ task->ccs_flags &= ~CCS_TASK_IS_IN_EXECVE;
1594+ ccs_audit_free_execve(ee, true);
1595+ kfree(ee->handler_path);
1596+ kfree(ee);
1597+}
1598+
1599+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
1600+
1601+/**
1602+ * __ccs_search_binary_handler - Main routine for do_execve().
1603+ *
1604+ * @bprm: Pointer to "struct linux_binprm".
1605+ *
1606+ * Returns 0 on success, negative value otherwise.
1607+ *
1608+ * Performs permission checks for do_execve() and domain transition.
1609+ * Domain transition by "struct ccs_domain_transition_control" and
1610+ * "auto_domain_transition=" parameter of "struct ccs_condition" are reverted
1611+ * if do_execve() failed.
1612+ * Garbage collector does not remove "struct ccs_domain_info" from
1613+ * ccs_domain_list nor kfree("struct ccs_domain_info") if the current thread is
1614+ * marked as CCS_TASK_IS_IN_EXECVE.
1615+ */
1616+static int __ccs_search_binary_handler(struct linux_binprm *bprm)
1617+{
1618+ struct ccs_execve *ee;
1619+ int retval;
1620+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
1621+ if (!ccs_policy_loaded)
1622+ ccsecurity_exports.load_policy(bprm->filename);
1623+#endif
1624+ retval = ccs_start_execve(bprm, &ee);
1625+ if (!retval)
1626+ retval = search_binary_handler(bprm);
1627+ ccs_finish_execve(retval, ee);
1628+ return retval;
1629+}
1630+
1631+#else
1632+
1633+/**
1634+ * __ccs_search_binary_handler - Main routine for do_execve().
1635+ *
1636+ * @bprm: Pointer to "struct linux_binprm".
1637+ * @regs: Pointer to "struct pt_regs".
1638+ *
1639+ * Returns 0 on success, negative value otherwise.
1640+ *
1641+ * Performs permission checks for do_execve() and domain transition.
1642+ * Domain transition by "struct ccs_domain_transition_control" and
1643+ * "auto_domain_transition=" parameter of "struct ccs_condition" are reverted
1644+ * if do_execve() failed.
1645+ * Garbage collector does not remove "struct ccs_domain_info" from
1646+ * ccs_domain_list nor kfree("struct ccs_domain_info") if the current thread is
1647+ * marked as CCS_TASK_IS_IN_EXECVE.
1648+ */
1649+static int __ccs_search_binary_handler(struct linux_binprm *bprm,
1650+ struct pt_regs *regs)
1651+{
1652+ struct ccs_execve *ee;
1653+ int retval;
1654+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
1655+ if (!ccs_policy_loaded)
1656+ ccsecurity_exports.load_policy(bprm->filename);
1657+#endif
1658+ retval = ccs_start_execve(bprm, &ee);
1659+ if (!retval)
1660+ retval = search_binary_handler(bprm, regs);
1661+ ccs_finish_execve(retval, ee);
1662+ return retval;
1663+}
1664+
1665+#endif
1666+
1667+/**
1668+ * ccs_permission_init - Register permission check hooks.
1669+ *
1670+ * Returns nothing.
1671+ */
1672+void __init ccs_permission_init(void)
1673+{
1674+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
1675+ ccsecurity_ops.save_open_mode = __ccs_save_open_mode;
1676+ ccsecurity_ops.clear_open_mode = __ccs_clear_open_mode;
1677+ ccsecurity_ops.open_permission = __ccs_open_permission;
1678+#else
1679+ ccsecurity_ops.open_permission = ccs_new_open_permission;
1680+#endif
1681+ ccsecurity_ops.fcntl_permission = __ccs_fcntl_permission;
1682+ ccsecurity_ops.ioctl_permission = __ccs_ioctl_permission;
1683+ ccsecurity_ops.chmod_permission = __ccs_chmod_permission;
1684+ ccsecurity_ops.chown_permission = __ccs_chown_permission;
1685+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
1686+ ccsecurity_ops.getattr_permission = __ccs_getattr_permission;
1687+#endif
1688+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1689+ ccsecurity_ops.pivot_root_permission = __ccs_pivot_root_permission;
1690+ ccsecurity_ops.chroot_permission = __ccs_chroot_permission;
1691+#else
1692+ ccsecurity_ops.pivot_root_permission = ccs_old_pivot_root_permission;
1693+ ccsecurity_ops.chroot_permission = ccs_old_chroot_permission;
1694+#endif
1695+ ccsecurity_ops.umount_permission = __ccs_umount_permission;
1696+ ccsecurity_ops.mknod_permission = __ccs_mknod_permission;
1697+ ccsecurity_ops.mkdir_permission = __ccs_mkdir_permission;
1698+ ccsecurity_ops.rmdir_permission = __ccs_rmdir_permission;
1699+ ccsecurity_ops.unlink_permission = __ccs_unlink_permission;
1700+ ccsecurity_ops.symlink_permission = __ccs_symlink_permission;
1701+ ccsecurity_ops.truncate_permission = __ccs_truncate_permission;
1702+ ccsecurity_ops.rename_permission = __ccs_rename_permission;
1703+ ccsecurity_ops.link_permission = __ccs_link_permission;
1704+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
1705+ ccsecurity_ops.open_exec_permission = __ccs_open_exec_permission;
1706+ ccsecurity_ops.uselib_permission = __ccs_uselib_permission;
1707+#endif
1708+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
1709+ ccsecurity_ops.parse_table = __ccs_parse_table;
1710+#endif
1711+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1712+ ccsecurity_ops.mount_permission = __ccs_mount_permission;
1713+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1714+ ccsecurity_ops.move_mount_permission = __ccs_move_mount_permission;
1715+#endif
1716+#else
1717+ ccsecurity_ops.mount_permission = ccs_old_mount_permission;
1718+#endif
1719+#ifdef CONFIG_CCSECURITY_CAPABILITY
1720+ ccsecurity_ops.socket_create_permission =
1721+ __ccs_socket_create_permission;
1722+#endif
1723+#ifdef CONFIG_CCSECURITY_NETWORK
1724+ ccsecurity_ops.socket_listen_permission =
1725+ __ccs_socket_listen_permission;
1726+ ccsecurity_ops.socket_connect_permission =
1727+ __ccs_socket_connect_permission;
1728+ ccsecurity_ops.socket_bind_permission = __ccs_socket_bind_permission;
1729+ ccsecurity_ops.socket_post_accept_permission =
1730+ __ccs_socket_post_accept_permission;
1731+ ccsecurity_ops.socket_sendmsg_permission =
1732+ __ccs_socket_sendmsg_permission;
1733+#endif
1734+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
1735+ ccsecurity_ops.socket_post_recvmsg_permission =
1736+ __ccs_socket_post_recvmsg_permission;
1737+#endif
1738+#ifdef CONFIG_CCSECURITY_IPC
1739+ ccsecurity_ops.kill_permission = ccs_signal_acl;
1740+ ccsecurity_ops.tgkill_permission = ccs_signal_acl0;
1741+ ccsecurity_ops.tkill_permission = ccs_signal_acl;
1742+ ccsecurity_ops.sigqueue_permission = ccs_signal_acl;
1743+ ccsecurity_ops.tgsigqueue_permission = ccs_signal_acl0;
1744+#endif
1745+#ifdef CONFIG_CCSECURITY_CAPABILITY
1746+ ccsecurity_ops.capable = __ccs_capable;
1747+ ccsecurity_ops.ptrace_permission = __ccs_ptrace_permission;
1748+#endif
1749+ ccsecurity_ops.search_binary_handler = __ccs_search_binary_handler;
1750+}
1751+
1752+/**
1753+ * ccs_kern_path - Wrapper for kern_path().
1754+ *
1755+ * @pathname: Pathname to resolve. Maybe NULL.
1756+ * @flags: Lookup flags.
1757+ * @path: Pointer to "struct path".
1758+ *
1759+ * Returns 0 on success, negative value otherwise.
1760+ */
1761+static int ccs_kern_path(const char *pathname, int flags, struct path *path)
1762+{
1763+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
1764+ if (!pathname || kern_path(pathname, flags, path))
1765+ return -ENOENT;
1766+#else
1767+ struct nameidata nd;
1768+ if (!pathname || path_lookup(pathname, flags, &nd))
1769+ return -ENOENT;
1770+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1771+ *path = nd.path;
1772+#else
1773+ path->dentry = nd.dentry;
1774+ path->mnt = nd.mnt;
1775+#endif
1776+#endif
1777+ return 0;
1778+}
1779+
1780+/**
1781+ * ccs_get_path - Get dentry/vfsmmount of a pathname.
1782+ *
1783+ * @pathname: The pathname to solve. Maybe NULL.
1784+ * @path: Pointer to "struct path".
1785+ *
1786+ * Returns 0 on success, negative value otherwise.
1787+ */
1788+static int ccs_get_path(const char *pathname, struct path *path)
1789+{
1790+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1791+ return ccs_kern_path(pathname, LOOKUP_FOLLOW, path);
1792+#else
1793+ return ccs_kern_path(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, path);
1794+#endif
1795+}
1796+
1797+/**
1798+ * ccs_symlink_path - Get symlink's pathname.
1799+ *
1800+ * @pathname: The pathname to solve. Maybe NULL.
1801+ * @name: Pointer to "struct ccs_path_info".
1802+ *
1803+ * Returns 0 on success, negative value otherwise.
1804+ *
1805+ * This function uses kzalloc(), so caller must kfree() if this function
1806+ * didn't return NULL.
1807+ */
1808+static int ccs_symlink_path(const char *pathname, struct ccs_path_info *name)
1809+{
1810+ char *buf;
1811+ struct path path;
1812+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1813+ if (ccs_kern_path(pathname, 0, &path))
1814+ return -ENOENT;
1815+#else
1816+ if (ccs_kern_path(pathname, LOOKUP_POSITIVE, &path))
1817+ return -ENOENT;
1818+#endif
1819+ buf = ccs_realpath(&path);
1820+ path_put(&path);
1821+ if (buf) {
1822+ name->name = buf;
1823+ ccs_fill_path_info(name);
1824+ return 0;
1825+ }
1826+ return -ENOMEM;
1827+}
1828+
1829+/**
1830+ * ccs_check_mount_acl - Check permission for path path path number operation.
1831+ *
1832+ * @r: Pointer to "struct ccs_request_info".
1833+ * @ptr: Pointer to "struct ccs_acl_info".
1834+ *
1835+ * Returns true if granted, false otherwise.
1836+ */
1837+static bool ccs_check_mount_acl(struct ccs_request_info *r,
1838+ const struct ccs_acl_info *ptr)
1839+{
1840+ const struct ccs_mount_acl *acl =
1841+ container_of(ptr, typeof(*acl), head);
1842+ return ccs_compare_number_union(r->param.mount.flags, &acl->flags) &&
1843+ ccs_compare_name_union(r->param.mount.type, &acl->fs_type) &&
1844+ ccs_compare_name_union(r->param.mount.dir, &acl->dir_name) &&
1845+ (!r->param.mount.need_dev ||
1846+ ccs_compare_name_union(r->param.mount.dev, &acl->dev_name));
1847+}
1848+
1849+/**
1850+ * ccs_mount_acl - Check permission for mount() operation.
1851+ *
1852+ * @r: Pointer to "struct ccs_request_info".
1853+ * @dev_name: Name of device file. Maybe NULL.
1854+ * @dir: Pointer to "struct path".
1855+ * @type: Name of filesystem type.
1856+ * @flags: Mount options.
1857+ *
1858+ * Returns 0 on success, negative value otherwise.
1859+ *
1860+ * Caller holds ccs_read_lock().
1861+ */
1862+static int ccs_mount_acl(struct ccs_request_info *r, const char *dev_name,
1863+ const struct path *dir, const char *type,
1864+ unsigned long flags)
1865+{
1866+ struct ccs_obj_info obj = { };
1867+ struct file_system_type *fstype = NULL;
1868+ const char *requested_type = NULL;
1869+ const char *requested_dir_name = NULL;
1870+ const char *requested_dev_name = NULL;
1871+ struct ccs_path_info rtype;
1872+ struct ccs_path_info rdev;
1873+ struct ccs_path_info rdir;
1874+ int need_dev = 0;
1875+ int error = -ENOMEM;
1876+ r->obj = &obj;
1877+
1878+ /* Get fstype. */
1879+ requested_type = ccs_encode(type);
1880+ if (!requested_type)
1881+ goto out;
1882+ rtype.name = requested_type;
1883+ ccs_fill_path_info(&rtype);
1884+
1885+ /* Get mount point. */
1886+ obj.path2 = *dir;
1887+ requested_dir_name = ccs_realpath(dir);
1888+ if (!requested_dir_name) {
1889+ error = -ENOMEM;
1890+ goto out;
1891+ }
1892+ rdir.name = requested_dir_name;
1893+ ccs_fill_path_info(&rdir);
1894+
1895+ /* Compare fs name. */
1896+ if (type == ccs_mounts[CCS_MOUNT_REMOUNT]) {
1897+ /* dev_name is ignored. */
1898+ } else if (type == ccs_mounts[CCS_MOUNT_MAKE_UNBINDABLE] ||
1899+ type == ccs_mounts[CCS_MOUNT_MAKE_PRIVATE] ||
1900+ type == ccs_mounts[CCS_MOUNT_MAKE_SLAVE] ||
1901+ type == ccs_mounts[CCS_MOUNT_MAKE_SHARED]) {
1902+ /* dev_name is ignored. */
1903+ } else if (type == ccs_mounts[CCS_MOUNT_BIND] ||
1904+ type == ccs_mounts[CCS_MOUNT_MOVE]) {
1905+ need_dev = -1; /* dev_name is a directory */
1906+ } else {
1907+ fstype = get_fs_type(type);
1908+ if (!fstype) {
1909+ error = -ENODEV;
1910+ goto out;
1911+ }
1912+ if (fstype->fs_flags & FS_REQUIRES_DEV)
1913+ /* dev_name is a block device file. */
1914+ need_dev = 1;
1915+ }
1916+ if (need_dev) {
1917+ /* Get mount point or device file. */
1918+ if (ccs_get_path(dev_name, &obj.path1)) {
1919+ error = -ENOENT;
1920+ goto out;
1921+ }
1922+ requested_dev_name = ccs_realpath(&obj.path1);
1923+ if (!requested_dev_name) {
1924+ error = -ENOENT;
1925+ goto out;
1926+ }
1927+ } else {
1928+ /* Map dev_name to "<NULL>" if no dev_name given. */
1929+ if (!dev_name)
1930+ dev_name = "<NULL>";
1931+ requested_dev_name = ccs_encode(dev_name);
1932+ if (!requested_dev_name) {
1933+ error = -ENOMEM;
1934+ goto out;
1935+ }
1936+ }
1937+ rdev.name = requested_dev_name;
1938+ ccs_fill_path_info(&rdev);
1939+ r->param_type = CCS_TYPE_MOUNT_ACL;
1940+ r->param.mount.need_dev = need_dev;
1941+ r->param.mount.dev = &rdev;
1942+ r->param.mount.dir = &rdir;
1943+ r->param.mount.type = &rtype;
1944+ r->param.mount.flags = flags;
1945+ error = ccs_check_acl(r);
1946+out:
1947+ kfree(requested_dev_name);
1948+ kfree(requested_dir_name);
1949+ if (fstype)
1950+ ccs_put_filesystem(fstype);
1951+ kfree(requested_type);
1952+ /* Drop refcount obtained by ccs_get_path(). */
1953+ if (obj.path1.dentry)
1954+ path_put(&obj.path1);
1955+ return error;
1956+}
1957+
1958+/**
1959+ * __ccs_mount_permission - Check permission for mount() operation.
1960+ *
1961+ * @dev_name: Name of device file. Maybe NULL.
1962+ * @path: Pointer to "struct path".
1963+ * @type: Name of filesystem type. Maybe NULL.
1964+ * @flags: Mount options.
1965+ * @data_page: Optional data. Maybe NULL.
1966+ *
1967+ * Returns 0 on success, negative value otherwise.
1968+ */
1969+static int __ccs_mount_permission(const char *dev_name,
1970+ const struct path *path, const char *type,
1971+ unsigned long flags, void *data_page)
1972+{
1973+ struct ccs_request_info r;
1974+ int error = 0;
1975+ int idx;
1976+ if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
1977+ flags &= ~MS_MGC_MSK;
1978+ if (flags & MS_REMOUNT) {
1979+ type = ccs_mounts[CCS_MOUNT_REMOUNT];
1980+ flags &= ~MS_REMOUNT;
1981+ } else if (flags & MS_BIND) {
1982+ type = ccs_mounts[CCS_MOUNT_BIND];
1983+ flags &= ~MS_BIND;
1984+ } else if (flags & MS_SHARED) {
1985+ if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
1986+ return -EINVAL;
1987+ type = ccs_mounts[CCS_MOUNT_MAKE_SHARED];
1988+ flags &= ~MS_SHARED;
1989+ } else if (flags & MS_PRIVATE) {
1990+ if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE))
1991+ return -EINVAL;
1992+ type = ccs_mounts[CCS_MOUNT_MAKE_PRIVATE];
1993+ flags &= ~MS_PRIVATE;
1994+ } else if (flags & MS_SLAVE) {
1995+ if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE))
1996+ return -EINVAL;
1997+ type = ccs_mounts[CCS_MOUNT_MAKE_SLAVE];
1998+ flags &= ~MS_SLAVE;
1999+ } else if (flags & MS_UNBINDABLE) {
2000+ if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE))
2001+ return -EINVAL;
2002+ type = ccs_mounts[CCS_MOUNT_MAKE_UNBINDABLE];
2003+ flags &= ~MS_UNBINDABLE;
2004+ } else if (flags & MS_MOVE) {
2005+ type = ccs_mounts[CCS_MOUNT_MOVE];
2006+ flags &= ~MS_MOVE;
2007+ }
2008+ if (!type)
2009+ type = "<NULL>";
2010+ idx = ccs_read_lock();
2011+ if (ccs_init_request_info(&r, CCS_MAC_FILE_MOUNT)
2012+ != CCS_CONFIG_DISABLED)
2013+ error = ccs_mount_acl(&r, dev_name, path, type, flags);
2014+ ccs_read_unlock(idx);
2015+ return error;
2016+}
2017+
2018+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
2019+
2020+/**
2021+ * ccs_old_mount_permission - Check permission for mount() operation.
2022+ *
2023+ * @dev_name: Name of device file.
2024+ * @nd: Pointer to "struct nameidata".
2025+ * @type: Name of filesystem type. Maybe NULL.
2026+ * @flags: Mount options.
2027+ * @data_page: Optional data. Maybe NULL.
2028+ *
2029+ * Returns 0 on success, negative value otherwise.
2030+ */
2031+static int ccs_old_mount_permission(const char *dev_name, struct nameidata *nd,
2032+ const char *type, unsigned long flags,
2033+ void *data_page)
2034+{
2035+ struct path path = { nd->mnt, nd->dentry };
2036+ return __ccs_mount_permission(dev_name, &path, type, flags, data_page);
2037+}
2038+
2039+#endif
2040+
2041+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
2042+/**
2043+ * __ccs_move_mount_permission - Check permission for move_mount() operation.
2044+ *
2045+ * @from_path: Pointer to "struct path".
2046+ * @to_path: Pointer to "struct path".
2047+ *
2048+ * Returns 0 on success, negative value otherwise.
2049+ */
2050+static int __ccs_move_mount_permission(const struct path *from_path,
2051+ const struct path *to_path)
2052+{
2053+ return -ENOSYS; /* For now. */
2054+}
2055+#endif
2056+
2057+/**
2058+ * ccs_compare_number_union - Check whether a value matches "struct ccs_number_union" or not.
2059+ *
2060+ * @value: Number to check.
2061+ * @ptr: Pointer to "struct ccs_number_union".
2062+ *
2063+ * Returns true if @value matches @ptr, false otherwise.
2064+ */
2065+static bool ccs_compare_number_union(const unsigned long value,
2066+ const struct ccs_number_union *ptr)
2067+{
2068+ if (ptr->group)
2069+ return ccs_number_matches_group(value, value, ptr->group);
2070+ return value >= ptr->values[0] && value <= ptr->values[1];
2071+}
2072+
2073+/**
2074+ * ccs_compare_name_union - Check whether a name matches "struct ccs_name_union" or not.
2075+ *
2076+ * @name: Pointer to "struct ccs_path_info".
2077+ * @ptr: Pointer to "struct ccs_name_union".
2078+ *
2079+ * Returns "struct ccs_path_info" if @name matches @ptr, NULL otherwise.
2080+ */
2081+static const struct ccs_path_info *ccs_compare_name_union
2082+(const struct ccs_path_info *name, const struct ccs_name_union *ptr)
2083+{
2084+ if (ptr->group)
2085+ return ccs_path_matches_group(name, ptr->group);
2086+ if (ccs_path_matches_pattern(name, ptr->filename))
2087+ return ptr->filename;
2088+ return NULL;
2089+}
2090+
2091+/**
2092+ * ccs_add_slash - Add trailing '/' if needed.
2093+ *
2094+ * @buf: Pointer to "struct ccs_path_info".
2095+ *
2096+ * Returns nothing.
2097+ *
2098+ * @buf must be generated by ccs_encode() because this function does not
2099+ * allocate memory for adding '/'.
2100+ */
2101+static void ccs_add_slash(struct ccs_path_info *buf)
2102+{
2103+ if (buf->is_dir)
2104+ return;
2105+ /* This is OK because ccs_encode() reserves space for appending "/". */
2106+ strcat((char *) buf->name, "/");
2107+ ccs_fill_path_info(buf);
2108+}
2109+
2110+/**
2111+ * ccs_get_realpath - Get realpath.
2112+ *
2113+ * @buf: Pointer to "struct ccs_path_info".
2114+ * @path: Pointer to "struct path". @path->mnt may be NULL.
2115+ *
2116+ * Returns true on success, false otherwise.
2117+ */
2118+static bool ccs_get_realpath(struct ccs_path_info *buf, struct path *path)
2119+{
2120+ buf->name = ccs_realpath(path);
2121+ if (buf->name) {
2122+ ccs_fill_path_info(buf);
2123+ return true;
2124+ }
2125+ return false;
2126+}
2127+
2128+/**
2129+ * ccs_check_path_acl - Check permission for path operation.
2130+ *
2131+ * @r: Pointer to "struct ccs_request_info".
2132+ * @ptr: Pointer to "struct ccs_acl_info".
2133+ *
2134+ * Returns true if granted, false otherwise.
2135+ *
2136+ * To be able to use wildcard for domain transition, this function sets
2137+ * matching entry on success. Since the caller holds ccs_read_lock(),
2138+ * it is safe to set matching entry.
2139+ */
2140+static bool ccs_check_path_acl(struct ccs_request_info *r,
2141+ const struct ccs_acl_info *ptr)
2142+{
2143+ const struct ccs_path_acl *acl = container_of(ptr, typeof(*acl), head);
2144+ if (ptr->perm & (1 << r->param.path.operation)) {
2145+ r->param.path.matched_path =
2146+ ccs_compare_name_union(r->param.path.filename,
2147+ &acl->name);
2148+ return r->param.path.matched_path != NULL;
2149+ }
2150+ return false;
2151+}
2152+
2153+/**
2154+ * ccs_check_path_number_acl - Check permission for path number operation.
2155+ *
2156+ * @r: Pointer to "struct ccs_request_info".
2157+ * @ptr: Pointer to "struct ccs_acl_info".
2158+ *
2159+ * Returns true if granted, false otherwise.
2160+ */
2161+static bool ccs_check_path_number_acl(struct ccs_request_info *r,
2162+ const struct ccs_acl_info *ptr)
2163+{
2164+ const struct ccs_path_number_acl *acl =
2165+ container_of(ptr, typeof(*acl), head);
2166+ return (ptr->perm & (1 << r->param.path_number.operation)) &&
2167+ ccs_compare_number_union(r->param.path_number.number,
2168+ &acl->number) &&
2169+ ccs_compare_name_union(r->param.path_number.filename,
2170+ &acl->name);
2171+}
2172+
2173+/**
2174+ * ccs_check_path2_acl - Check permission for path path operation.
2175+ *
2176+ * @r: Pointer to "struct ccs_request_info".
2177+ * @ptr: Pointer to "struct ccs_acl_info".
2178+ *
2179+ * Returns true if granted, false otherwise.
2180+ */
2181+static bool ccs_check_path2_acl(struct ccs_request_info *r,
2182+ const struct ccs_acl_info *ptr)
2183+{
2184+ const struct ccs_path2_acl *acl =
2185+ container_of(ptr, typeof(*acl), head);
2186+ return (ptr->perm & (1 << r->param.path2.operation)) &&
2187+ ccs_compare_name_union(r->param.path2.filename1, &acl->name1)
2188+ && ccs_compare_name_union(r->param.path2.filename2,
2189+ &acl->name2);
2190+}
2191+
2192+/**
2193+ * ccs_check_mkdev_acl - Check permission for path number number number operation.
2194+ *
2195+ * @r: Pointer to "struct ccs_request_info".
2196+ * @ptr: Pointer to "struct ccs_acl_info".
2197+ *
2198+ * Returns true if granted, false otherwise.
2199+ */
2200+static bool ccs_check_mkdev_acl(struct ccs_request_info *r,
2201+ const struct ccs_acl_info *ptr)
2202+{
2203+ const struct ccs_mkdev_acl *acl =
2204+ container_of(ptr, typeof(*acl), head);
2205+ return (ptr->perm & (1 << r->param.mkdev.operation)) &&
2206+ ccs_compare_number_union(r->param.mkdev.mode, &acl->mode) &&
2207+ ccs_compare_number_union(r->param.mkdev.major, &acl->major) &&
2208+ ccs_compare_number_union(r->param.mkdev.minor, &acl->minor) &&
2209+ ccs_compare_name_union(r->param.mkdev.filename, &acl->name);
2210+}
2211+
2212+/**
2213+ * ccs_path_permission - Check permission for path operation.
2214+ *
2215+ * @r: Pointer to "struct ccs_request_info".
2216+ * @operation: Type of operation.
2217+ * @filename: Filename to check.
2218+ *
2219+ * Returns 0 on success, negative value otherwise.
2220+ *
2221+ * Caller holds ccs_read_lock().
2222+ */
2223+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || !defined(CONFIG_SYSCTL_SYSCALL)
2224+static
2225+#endif
2226+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
2227+ const struct ccs_path_info *filename)
2228+{
2229+ r->type = ccs_p2mac[operation];
2230+ r->mode = ccs_get_mode(r->profile, r->type);
2231+ if (r->mode == CCS_CONFIG_DISABLED)
2232+ return 0;
2233+ r->param_type = CCS_TYPE_PATH_ACL;
2234+ r->param.path.filename = filename;
2235+ r->param.path.operation = operation;
2236+ return ccs_check_acl(r);
2237+}
2238+
2239+/**
2240+ * ccs_execute_permission - Check permission for execute operation.
2241+ *
2242+ * @r: Pointer to "struct ccs_request_info".
2243+ * @filename: Filename to check.
2244+ *
2245+ * Returns 0 on success, CCS_RETRY_REQUEST on retry, negative value otherwise.
2246+ *
2247+ * Caller holds ccs_read_lock().
2248+ */
2249+static int ccs_execute_permission(struct ccs_request_info *r,
2250+ const struct ccs_path_info *filename)
2251+{
2252+ int error;
2253+ /*
2254+ * Unlike other permission checks, this check is done regardless of
2255+ * profile mode settings in order to check for domain transition
2256+ * preference.
2257+ */
2258+ r->type = CCS_MAC_FILE_EXECUTE;
2259+ r->mode = ccs_get_mode(r->profile, r->type);
2260+ r->param_type = CCS_TYPE_PATH_ACL;
2261+ r->param.path.filename = filename;
2262+ r->param.path.operation = CCS_TYPE_EXECUTE;
2263+ error = ccs_check_acl(r);
2264+ r->ee->transition = r->matched_acl && r->matched_acl->cond &&
2265+ r->matched_acl->cond->exec_transit ?
2266+ r->matched_acl->cond->transit : NULL;
2267+ return error;
2268+}
2269+
2270+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
2271+
2272+/**
2273+ * __ccs_save_open_mode - Remember original flags passed to sys_open().
2274+ *
2275+ * @mode: Flags passed to sys_open().
2276+ *
2277+ * Returns nothing.
2278+ *
2279+ * TOMOYO does not check "file write" if open(path, O_TRUNC | O_RDONLY) was
2280+ * requested because write() is not permitted. Instead, TOMOYO checks
2281+ * "file truncate" if O_TRUNC is passed.
2282+ *
2283+ * TOMOYO does not check "file read" and "file write" if open(path, 3) was
2284+ * requested because read()/write() are not permitted. Instead, TOMOYO checks
2285+ * "file ioctl" when ioctl() is requested.
2286+ */
2287+static void __ccs_save_open_mode(int mode)
2288+{
2289+ if ((mode & 3) == 3)
2290+ ccs_current_security()->ccs_flags |= CCS_OPEN_FOR_IOCTL_ONLY;
2291+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 14)
2292+ /* O_TRUNC passes MAY_WRITE to ccs_open_permission(). */
2293+ else if (!(mode & 3) && (mode & O_TRUNC))
2294+ ccs_current_security()->ccs_flags |=
2295+ CCS_OPEN_FOR_READ_TRUNCATE;
2296+#endif
2297+}
2298+
2299+/**
2300+ * __ccs_clear_open_mode - Forget original flags passed to sys_open().
2301+ *
2302+ * Returns nothing.
2303+ */
2304+static void __ccs_clear_open_mode(void)
2305+{
2306+ ccs_current_security()->ccs_flags &= ~(CCS_OPEN_FOR_IOCTL_ONLY |
2307+ CCS_OPEN_FOR_READ_TRUNCATE);
2308+}
2309+
2310+#endif
2311+
2312+/**
2313+ * __ccs_open_permission - Check permission for "read" and "write".
2314+ *
2315+ * @dentry: Pointer to "struct dentry".
2316+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2317+ * @flag: Flags for open().
2318+ *
2319+ * Returns 0 on success, negative value otherwise.
2320+ */
2321+static int __ccs_open_permission(struct dentry *dentry, struct vfsmount *mnt,
2322+ const int flag)
2323+{
2324+ struct ccs_request_info r;
2325+ struct ccs_obj_info obj = {
2326+ .path1.dentry = dentry,
2327+ .path1.mnt = mnt,
2328+ };
2329+ const u32 ccs_flags = ccs_current_flags();
2330+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
2331+ const u8 acc_mode = (flag & 3) == 3 ? 0 : ACC_MODE(flag);
2332+#else
2333+ const u8 acc_mode = (ccs_flags & CCS_OPEN_FOR_IOCTL_ONLY) ? 0 :
2334+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 14)
2335+ (ccs_flags & CCS_OPEN_FOR_READ_TRUNCATE) ? 4 :
2336+#endif
2337+ ACC_MODE(flag);
2338+#endif
2339+ int error = 0;
2340+ struct ccs_path_info buf;
2341+ int idx;
2342+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
2343+ if (current->in_execve && !(ccs_flags & CCS_TASK_IS_IN_EXECVE))
2344+ return 0;
2345+#endif
2346+#ifndef CONFIG_CCSECURITY_FILE_READDIR
2347+ if (d_is_dir(dentry))
2348+ return 0;
2349+#endif
2350+ /* Sockets can't be opened by open(). */
2351+ if (S_ISSOCK(d_inode(dentry)->i_mode))
2352+ return 0;
2353+ buf.name = NULL;
2354+ r.mode = CCS_CONFIG_DISABLED;
2355+ idx = ccs_read_lock();
2356+ if (acc_mode && ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
2357+ != CCS_CONFIG_DISABLED) {
2358+ if (!ccs_get_realpath(&buf, &obj.path1)) {
2359+ error = -ENOMEM;
2360+ goto out;
2361+ }
2362+ r.obj = &obj;
2363+ if (acc_mode & MAY_READ)
2364+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
2365+ if (!error && (acc_mode & MAY_WRITE))
2366+ error = ccs_path_permission(&r, (flag & O_APPEND) ?
2367+ CCS_TYPE_APPEND :
2368+ CCS_TYPE_WRITE, &buf);
2369+ }
2370+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
2371+ if (!error && (flag & O_TRUNC) &&
2372+ ccs_init_request_info(&r, CCS_MAC_FILE_TRUNCATE)
2373+ != CCS_CONFIG_DISABLED) {
2374+ if (!buf.name && !ccs_get_realpath(&buf, &obj.path1)) {
2375+ error = -ENOMEM;
2376+ goto out;
2377+ }
2378+ r.obj = &obj;
2379+ error = ccs_path_permission(&r, CCS_TYPE_TRUNCATE, &buf);
2380+ }
2381+#endif
2382+out:
2383+ kfree(buf.name);
2384+ ccs_read_unlock(idx);
2385+ if (r.mode != CCS_CONFIG_ENFORCING)
2386+ error = 0;
2387+ return error;
2388+}
2389+
2390+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
2391+
2392+/**
2393+ * ccs_new_open_permission - Check permission for "read" and "write".
2394+ *
2395+ * @filp: Pointer to "struct file".
2396+ *
2397+ * Returns 0 on success, negative value otherwise.
2398+ */
2399+static int ccs_new_open_permission(struct file *filp)
2400+{
2401+ return __ccs_open_permission(filp->f_path.dentry, filp->f_path.mnt,
2402+ filp->f_flags);
2403+}
2404+
2405+#endif
2406+
2407+/**
2408+ * ccs_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "getattr", "chroot" and "unmount".
2409+ *
2410+ * @operation: Type of operation.
2411+ * @dentry: Pointer to "struct dentry".
2412+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2413+ * @target: Symlink's target if @operation is CCS_TYPE_SYMLINK,
2414+ * NULL otherwise.
2415+ *
2416+ * Returns 0 on success, negative value otherwise.
2417+ */
2418+static int ccs_path_perm(const u8 operation, struct dentry *dentry,
2419+ struct vfsmount *mnt, const char *target)
2420+{
2421+ struct ccs_request_info r;
2422+ struct ccs_obj_info obj = {
2423+ .path1.dentry = dentry,
2424+ .path1.mnt = mnt,
2425+ };
2426+ int error = 0;
2427+ struct ccs_path_info buf;
2428+ bool is_enforce = false;
2429+ struct ccs_path_info symlink_target;
2430+ int idx;
2431+ buf.name = NULL;
2432+ symlink_target.name = NULL;
2433+ idx = ccs_read_lock();
2434+ if (ccs_init_request_info(&r, ccs_p2mac[operation])
2435+ == CCS_CONFIG_DISABLED)
2436+ goto out;
2437+ is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
2438+ error = -ENOMEM;
2439+ if (!ccs_get_realpath(&buf, &obj.path1))
2440+ goto out;
2441+ r.obj = &obj;
2442+ switch (operation) {
2443+ case CCS_TYPE_RMDIR:
2444+ case CCS_TYPE_CHROOT:
2445+ ccs_add_slash(&buf);
2446+ break;
2447+ case CCS_TYPE_SYMLINK:
2448+ symlink_target.name = ccs_encode(target);
2449+ if (!symlink_target.name)
2450+ goto out;
2451+ ccs_fill_path_info(&symlink_target);
2452+ obj.symlink_target = &symlink_target;
2453+ break;
2454+ }
2455+ error = ccs_path_permission(&r, operation, &buf);
2456+ if (operation == CCS_TYPE_SYMLINK)
2457+ kfree(symlink_target.name);
2458+out:
2459+ kfree(buf.name);
2460+ ccs_read_unlock(idx);
2461+ if (!is_enforce)
2462+ error = 0;
2463+ return error;
2464+}
2465+
2466+/**
2467+ * ccs_mkdev_perm - Check permission for "mkblock" and "mkchar".
2468+ *
2469+ * @operation: Type of operation. (CCS_TYPE_MKCHAR or CCS_TYPE_MKBLOCK)
2470+ * @dentry: Pointer to "struct dentry".
2471+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2472+ * @mode: Create mode.
2473+ * @dev: Device number.
2474+ *
2475+ * Returns 0 on success, negative value otherwise.
2476+ */
2477+static int ccs_mkdev_perm(const u8 operation, struct dentry *dentry,
2478+ struct vfsmount *mnt, const unsigned int mode,
2479+ unsigned int dev)
2480+{
2481+ struct ccs_request_info r;
2482+ struct ccs_obj_info obj = {
2483+ .path1.dentry = dentry,
2484+ .path1.mnt = mnt,
2485+ };
2486+ int error = 0;
2487+ struct ccs_path_info buf;
2488+ bool is_enforce = false;
2489+ int idx;
2490+ idx = ccs_read_lock();
2491+ if (ccs_init_request_info(&r, ccs_pnnn2mac[operation])
2492+ == CCS_CONFIG_DISABLED)
2493+ goto out;
2494+ is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
2495+ error = -EPERM;
2496+ if (!capable(CAP_MKNOD))
2497+ goto out;
2498+ error = -ENOMEM;
2499+ if (!ccs_get_realpath(&buf, &obj.path1))
2500+ goto out;
2501+ r.obj = &obj;
2502+#ifdef CONFIG_SECURITY_PATH
2503+ dev = new_decode_dev(dev);
2504+#endif
2505+ r.param_type = CCS_TYPE_MKDEV_ACL;
2506+ r.param.mkdev.filename = &buf;
2507+ r.param.mkdev.operation = operation;
2508+ r.param.mkdev.mode = mode;
2509+ r.param.mkdev.major = MAJOR(dev);
2510+ r.param.mkdev.minor = MINOR(dev);
2511+ error = ccs_check_acl(&r);
2512+ kfree(buf.name);
2513+out:
2514+ ccs_read_unlock(idx);
2515+ if (!is_enforce)
2516+ error = 0;
2517+ return error;
2518+}
2519+
2520+/**
2521+ * ccs_path2_perm - Check permission for "rename", "link" and "pivot_root".
2522+ *
2523+ * @operation: Type of operation.
2524+ * @dentry1: Pointer to "struct dentry".
2525+ * @mnt1: Pointer to "struct vfsmount". Maybe NULL.
2526+ * @dentry2: Pointer to "struct dentry".
2527+ * @mnt2: Pointer to "struct vfsmount". Maybe NULL.
2528+ *
2529+ * Returns 0 on success, negative value otherwise.
2530+ */
2531+static int ccs_path2_perm(const u8 operation, struct dentry *dentry1,
2532+ struct vfsmount *mnt1, struct dentry *dentry2,
2533+ struct vfsmount *mnt2)
2534+{
2535+ struct ccs_request_info r;
2536+ int error = 0;
2537+ struct ccs_path_info buf1;
2538+ struct ccs_path_info buf2;
2539+ bool is_enforce = false;
2540+ struct ccs_obj_info obj = {
2541+ .path1.dentry = dentry1,
2542+ .path1.mnt = mnt1,
2543+ .path2.dentry = dentry2,
2544+ .path2.mnt = mnt2,
2545+ };
2546+ int idx;
2547+ buf1.name = NULL;
2548+ buf2.name = NULL;
2549+ idx = ccs_read_lock();
2550+ if (ccs_init_request_info(&r, ccs_pp2mac[operation])
2551+ == CCS_CONFIG_DISABLED)
2552+ goto out;
2553+ is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
2554+ error = -ENOMEM;
2555+ if (!ccs_get_realpath(&buf1, &obj.path1) ||
2556+ !ccs_get_realpath(&buf2, &obj.path2))
2557+ goto out;
2558+ switch (operation) {
2559+ case CCS_TYPE_RENAME:
2560+ case CCS_TYPE_LINK:
2561+ if (!d_is_dir(dentry1))
2562+ break;
2563+ /* fall through */
2564+ case CCS_TYPE_PIVOT_ROOT:
2565+ ccs_add_slash(&buf1);
2566+ ccs_add_slash(&buf2);
2567+ break;
2568+ }
2569+ r.obj = &obj;
2570+ r.param_type = CCS_TYPE_PATH2_ACL;
2571+ r.param.path2.operation = operation;
2572+ r.param.path2.filename1 = &buf1;
2573+ r.param.path2.filename2 = &buf2;
2574+ error = ccs_check_acl(&r);
2575+out:
2576+ kfree(buf1.name);
2577+ kfree(buf2.name);
2578+ ccs_read_unlock(idx);
2579+ if (!is_enforce)
2580+ error = 0;
2581+ return error;
2582+}
2583+
2584+/**
2585+ * ccs_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
2586+ *
2587+ * @type: Type of operation.
2588+ * @dentry: Pointer to "struct dentry".
2589+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2590+ * @number: Number.
2591+ *
2592+ * Returns 0 on success, negative value otherwise.
2593+ */
2594+static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
2595+ struct vfsmount *vfsmnt, unsigned long number)
2596+{
2597+ struct ccs_request_info r;
2598+ struct ccs_obj_info obj = {
2599+ .path1.dentry = dentry,
2600+ .path1.mnt = vfsmnt,
2601+ };
2602+ int error = 0;
2603+ struct ccs_path_info buf;
2604+ int idx;
2605+ if (!dentry)
2606+ return 0;
2607+ idx = ccs_read_lock();
2608+ if (ccs_init_request_info(&r, ccs_pn2mac[type]) == CCS_CONFIG_DISABLED)
2609+ goto out;
2610+ error = -ENOMEM;
2611+ if (!ccs_get_realpath(&buf, &obj.path1))
2612+ goto out;
2613+ r.obj = &obj;
2614+ if (type == CCS_TYPE_MKDIR)
2615+ ccs_add_slash(&buf);
2616+ r.param_type = CCS_TYPE_PATH_NUMBER_ACL;
2617+ r.param.path_number.operation = type;
2618+ r.param.path_number.filename = &buf;
2619+ r.param.path_number.number = number;
2620+ error = ccs_check_acl(&r);
2621+ kfree(buf.name);
2622+out:
2623+ ccs_read_unlock(idx);
2624+ if (r.mode != CCS_CONFIG_ENFORCING)
2625+ error = 0;
2626+ return error;
2627+}
2628+
2629+/**
2630+ * __ccs_ioctl_permission - Check permission for "ioctl".
2631+ *
2632+ * @filp: Pointer to "struct file".
2633+ * @cmd: Ioctl command number.
2634+ * @arg: Param for @cmd.
2635+ *
2636+ * Returns 0 on success, negative value otherwise.
2637+ */
2638+static int __ccs_ioctl_permission(struct file *filp, unsigned int cmd,
2639+ unsigned long arg)
2640+{
2641+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
2642+ return ccs_path_number_perm(CCS_TYPE_IOCTL, filp->f_path.dentry,
2643+ filp->f_path.mnt, cmd);
2644+#else
2645+ return ccs_path_number_perm(CCS_TYPE_IOCTL, filp->f_dentry,
2646+ filp->f_vfsmnt, cmd);
2647+#endif
2648+}
2649+
2650+/**
2651+ * __ccs_chmod_permission - Check permission for "chmod".
2652+ *
2653+ * @dentry: Pointer to "struct dentry".
2654+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2655+ * @mode: Mode.
2656+ *
2657+ * Returns 0 on success, negative value otherwise.
2658+ */
2659+static int __ccs_chmod_permission(struct dentry *dentry,
2660+ struct vfsmount *vfsmnt, mode_t mode)
2661+{
2662+ return ccs_path_number_perm(CCS_TYPE_CHMOD, dentry, vfsmnt,
2663+ mode & S_IALLUGO);
2664+}
2665+
2666+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
2667+
2668+/**
2669+ * __ccs_chown_permission - Check permission for "chown/chgrp".
2670+ *
2671+ * @dentry: Pointer to "struct dentry".
2672+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2673+ * @user: User ID.
2674+ * @group: Group ID.
2675+ *
2676+ * Returns 0 on success, negative value otherwise.
2677+ */
2678+static int __ccs_chown_permission(struct dentry *dentry,
2679+ struct vfsmount *vfsmnt, kuid_t user,
2680+ kgid_t group)
2681+{
2682+ int error = 0;
2683+ if (uid_valid(user))
2684+ error = ccs_path_number_perm(CCS_TYPE_CHOWN, dentry, vfsmnt,
2685+ from_kuid(&init_user_ns, user));
2686+ if (!error && gid_valid(group))
2687+ error = ccs_path_number_perm(CCS_TYPE_CHGRP, dentry, vfsmnt,
2688+ from_kgid(&init_user_ns, group));
2689+ return error;
2690+}
2691+
2692+#else
2693+
2694+/**
2695+ * __ccs_chown_permission - Check permission for "chown/chgrp".
2696+ *
2697+ * @dentry: Pointer to "struct dentry".
2698+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2699+ * @user: User ID.
2700+ * @group: Group ID.
2701+ *
2702+ * Returns 0 on success, negative value otherwise.
2703+ */
2704+static int __ccs_chown_permission(struct dentry *dentry,
2705+ struct vfsmount *vfsmnt, uid_t user,
2706+ gid_t group)
2707+{
2708+ int error = 0;
2709+ if (user == (uid_t) -1 && group == (gid_t) -1)
2710+ return 0;
2711+ if (user != (uid_t) -1)
2712+ error = ccs_path_number_perm(CCS_TYPE_CHOWN, dentry, vfsmnt,
2713+ user);
2714+ if (!error && group != (gid_t) -1)
2715+ error = ccs_path_number_perm(CCS_TYPE_CHGRP, dentry, vfsmnt,
2716+ group);
2717+ return error;
2718+}
2719+
2720+#endif
2721+
2722+/**
2723+ * __ccs_fcntl_permission - Check permission for changing O_APPEND flag.
2724+ *
2725+ * @file: Pointer to "struct file".
2726+ * @cmd: Command number.
2727+ * @arg: Value for @cmd.
2728+ *
2729+ * Returns 0 on success, negative value otherwise.
2730+ */
2731+static int __ccs_fcntl_permission(struct file *file, unsigned int cmd,
2732+ unsigned long arg)
2733+{
2734+ if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
2735+ return 0;
2736+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
2737+ return __ccs_open_permission(file->f_path.dentry, file->f_path.mnt,
2738+ O_WRONLY | (arg & O_APPEND));
2739+#elif defined(RHEL_MAJOR) && RHEL_MAJOR == 6
2740+ return __ccs_open_permission(file->f_dentry, file->f_vfsmnt,
2741+ O_WRONLY | (arg & O_APPEND));
2742+#else
2743+ return __ccs_open_permission(file->f_dentry, file->f_vfsmnt,
2744+ (O_WRONLY + 1) | (arg & O_APPEND));
2745+#endif
2746+}
2747+
2748+/**
2749+ * __ccs_pivot_root_permission - Check permission for pivot_root().
2750+ *
2751+ * @old_path: Pointer to "struct path".
2752+ * @new_path: Pointer to "struct path".
2753+ *
2754+ * Returns 0 on success, negative value otherwise.
2755+ */
2756+static int __ccs_pivot_root_permission(const struct path *old_path,
2757+ const struct path *new_path)
2758+{
2759+ return ccs_path2_perm(CCS_TYPE_PIVOT_ROOT, new_path->dentry,
2760+ new_path->mnt, old_path->dentry, old_path->mnt);
2761+}
2762+
2763+/**
2764+ * __ccs_chroot_permission - Check permission for chroot().
2765+ *
2766+ * @path: Pointer to "struct path".
2767+ *
2768+ * Returns 0 on success, negative value otherwise.
2769+ */
2770+static int __ccs_chroot_permission(const struct path *path)
2771+{
2772+ return ccs_path_perm(CCS_TYPE_CHROOT, path->dentry, path->mnt, NULL);
2773+}
2774+
2775+/**
2776+ * __ccs_umount_permission - Check permission for unmount.
2777+ *
2778+ * @mnt: Pointer to "struct vfsmount".
2779+ * @flags: Unused.
2780+ *
2781+ * Returns 0 on success, negative value otherwise.
2782+ */
2783+static int __ccs_umount_permission(struct vfsmount *mnt, int flags)
2784+{
2785+ return ccs_path_perm(CCS_TYPE_UMOUNT, mnt->mnt_root, mnt, NULL);
2786+}
2787+
2788+/**
2789+ * __ccs_mknod_permission - Check permission for vfs_mknod().
2790+ *
2791+ * @dentry: Pointer to "struct dentry".
2792+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2793+ * @mode: Device type and permission.
2794+ * @dev: Device number for block or character device.
2795+ *
2796+ * Returns 0 on success, negative value otherwise.
2797+ */
2798+static int __ccs_mknod_permission(struct dentry *dentry, struct vfsmount *mnt,
2799+ const unsigned int mode, unsigned int dev)
2800+{
2801+ int error = 0;
2802+ const unsigned int perm = mode & S_IALLUGO;
2803+ switch (mode & S_IFMT) {
2804+ case S_IFCHR:
2805+ error = ccs_mkdev_perm(CCS_TYPE_MKCHAR, dentry, mnt, perm,
2806+ dev);
2807+ break;
2808+ case S_IFBLK:
2809+ error = ccs_mkdev_perm(CCS_TYPE_MKBLOCK, dentry, mnt, perm,
2810+ dev);
2811+ break;
2812+ case S_IFIFO:
2813+ error = ccs_path_number_perm(CCS_TYPE_MKFIFO, dentry, mnt,
2814+ perm);
2815+ break;
2816+ case S_IFSOCK:
2817+ error = ccs_path_number_perm(CCS_TYPE_MKSOCK, dentry, mnt,
2818+ perm);
2819+ break;
2820+ case 0:
2821+ case S_IFREG:
2822+ error = ccs_path_number_perm(CCS_TYPE_CREATE, dentry, mnt,
2823+ perm);
2824+ break;
2825+ }
2826+ return error;
2827+}
2828+
2829+/**
2830+ * __ccs_mkdir_permission - Check permission for vfs_mkdir().
2831+ *
2832+ * @dentry: Pointer to "struct dentry".
2833+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2834+ * @mode: Create mode.
2835+ *
2836+ * Returns 0 on success, negative value otherwise.
2837+ */
2838+static int __ccs_mkdir_permission(struct dentry *dentry, struct vfsmount *mnt,
2839+ unsigned int mode)
2840+{
2841+ return ccs_path_number_perm(CCS_TYPE_MKDIR, dentry, mnt, mode);
2842+}
2843+
2844+/**
2845+ * __ccs_rmdir_permission - Check permission for vfs_rmdir().
2846+ *
2847+ * @dentry: Pointer to "struct dentry".
2848+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2849+ *
2850+ * Returns 0 on success, negative value otherwise.
2851+ */
2852+static int __ccs_rmdir_permission(struct dentry *dentry, struct vfsmount *mnt)
2853+{
2854+ return ccs_path_perm(CCS_TYPE_RMDIR, dentry, mnt, NULL);
2855+}
2856+
2857+/**
2858+ * __ccs_unlink_permission - Check permission for vfs_unlink().
2859+ *
2860+ * @dentry: Pointer to "struct dentry".
2861+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2862+ *
2863+ * Returns 0 on success, negative value otherwise.
2864+ */
2865+static int __ccs_unlink_permission(struct dentry *dentry, struct vfsmount *mnt)
2866+{
2867+ return ccs_path_perm(CCS_TYPE_UNLINK, dentry, mnt, NULL);
2868+}
2869+
2870+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
2871+
2872+/**
2873+ * __ccs_getattr_permission - Check permission for vfs_getattr().
2874+ *
2875+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2876+ * @dentry: Pointer to "struct dentry".
2877+ *
2878+ * Returns 0 on success, negative value otherwise.
2879+ */
2880+static int __ccs_getattr_permission(struct vfsmount *mnt,
2881+ struct dentry *dentry)
2882+{
2883+ /* It is not safe to call ccs_get_socket_name(). */
2884+ if (S_ISSOCK(d_inode(dentry)->i_mode))
2885+ return 0;
2886+ return ccs_path_perm(CCS_TYPE_GETATTR, dentry, mnt, NULL);
2887+}
2888+
2889+#endif
2890+
2891+/**
2892+ * __ccs_symlink_permission - Check permission for vfs_symlink().
2893+ *
2894+ * @dentry: Pointer to "struct dentry".
2895+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2896+ * @from: Content of symlink.
2897+ *
2898+ * Returns 0 on success, negative value otherwise.
2899+ */
2900+static int __ccs_symlink_permission(struct dentry *dentry,
2901+ struct vfsmount *mnt, const char *from)
2902+{
2903+ return ccs_path_perm(CCS_TYPE_SYMLINK, dentry, mnt, from);
2904+}
2905+
2906+/**
2907+ * __ccs_truncate_permission - Check permission for notify_change().
2908+ *
2909+ * @dentry: Pointer to "struct dentry".
2910+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2911+ *
2912+ * Returns 0 on success, negative value otherwise.
2913+ */
2914+static int __ccs_truncate_permission(struct dentry *dentry,
2915+ struct vfsmount *mnt)
2916+{
2917+ return ccs_path_perm(CCS_TYPE_TRUNCATE, dentry, mnt, NULL);
2918+}
2919+
2920+/**
2921+ * __ccs_rename_permission - Check permission for vfs_rename().
2922+ *
2923+ * @old_dentry: Pointer to "struct dentry".
2924+ * @new_dentry: Pointer to "struct dentry".
2925+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2926+ *
2927+ * Returns 0 on success, negative value otherwise.
2928+ */
2929+static int __ccs_rename_permission(struct dentry *old_dentry,
2930+ struct dentry *new_dentry,
2931+ struct vfsmount *mnt)
2932+{
2933+ return ccs_path2_perm(CCS_TYPE_RENAME, old_dentry, mnt, new_dentry,
2934+ mnt);
2935+}
2936+
2937+/**
2938+ * __ccs_link_permission - Check permission for vfs_link().
2939+ *
2940+ * @old_dentry: Pointer to "struct dentry".
2941+ * @new_dentry: Pointer to "struct dentry".
2942+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2943+ *
2944+ * Returns 0 on success, negative value otherwise.
2945+ */
2946+static int __ccs_link_permission(struct dentry *old_dentry,
2947+ struct dentry *new_dentry,
2948+ struct vfsmount *mnt)
2949+{
2950+ return ccs_path2_perm(CCS_TYPE_LINK, old_dentry, mnt, new_dentry, mnt);
2951+}
2952+
2953+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
2954+
2955+/**
2956+ * __ccs_open_exec_permission - Check permission for open_exec().
2957+ *
2958+ * @dentry: Pointer to "struct dentry".
2959+ * @mnt: Pointer to "struct vfsmount".
2960+ *
2961+ * Returns 0 on success, negative value otherwise.
2962+ */
2963+static int __ccs_open_exec_permission(struct dentry *dentry,
2964+ struct vfsmount *mnt)
2965+{
2966+ return (ccs_current_flags() & CCS_TASK_IS_IN_EXECVE) ?
2967+ __ccs_open_permission(dentry, mnt, O_RDONLY + 1) : 0;
2968+}
2969+
2970+/**
2971+ * __ccs_uselib_permission - Check permission for sys_uselib().
2972+ *
2973+ * @dentry: Pointer to "struct dentry".
2974+ * @mnt: Pointer to "struct vfsmount".
2975+ *
2976+ * Returns 0 on success, negative value otherwise.
2977+ */
2978+static int __ccs_uselib_permission(struct dentry *dentry, struct vfsmount *mnt)
2979+{
2980+ return __ccs_open_permission(dentry, mnt, O_RDONLY + 1);
2981+}
2982+
2983+#endif
2984+
2985+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
2986+
2987+/**
2988+ * __ccs_parse_table - Check permission for parse_table().
2989+ *
2990+ * @name: Pointer to "int __user".
2991+ * @nlen: Number of elements in @name.
2992+ * @oldval: Pointer to "void __user".
2993+ * @newval: Pointer to "void __user".
2994+ * @table: Pointer to "struct ctl_table".
2995+ *
2996+ * Returns 0 on success, negative value otherwise.
2997+ *
2998+ * Note that this function is racy because this function checks values in
2999+ * userspace memory which could be changed after permission check.
3000+ */
3001+static int __ccs_parse_table(int __user *name, int nlen, void __user *oldval,
3002+ void __user *newval, struct ctl_table *table)
3003+{
3004+ int n;
3005+ int error = -ENOMEM;
3006+ int op = 0;
3007+ struct ccs_path_info buf;
3008+ char *buffer = NULL;
3009+ struct ccs_request_info r;
3010+ int idx;
3011+ if (oldval)
3012+ op |= 004;
3013+ if (newval)
3014+ op |= 002;
3015+ if (!op) /* Neither read nor write */
3016+ return 0;
3017+ idx = ccs_read_lock();
3018+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
3019+ == CCS_CONFIG_DISABLED) {
3020+ error = 0;
3021+ goto out;
3022+ }
3023+ buffer = kmalloc(PAGE_SIZE, CCS_GFP_FLAGS);
3024+ if (!buffer)
3025+ goto out;
3026+ snprintf(buffer, PAGE_SIZE - 1, "proc:/sys");
3027+repeat:
3028+ if (!nlen) {
3029+ error = -ENOTDIR;
3030+ goto out;
3031+ }
3032+ if (get_user(n, name)) {
3033+ error = -EFAULT;
3034+ goto out;
3035+ }
3036+ for ( ; table->ctl_name
3037+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)
3038+ || table->procname
3039+#endif
3040+ ; table++) {
3041+ int pos;
3042+ const char *cp;
3043+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21)
3044+ if (n != table->ctl_name && table->ctl_name != CTL_ANY)
3045+ continue;
3046+#else
3047+ if (!n || n != table->ctl_name)
3048+ continue;
3049+#endif
3050+ pos = strlen(buffer);
3051+ cp = table->procname;
3052+ error = -ENOMEM;
3053+ if (cp) {
3054+ int len = strlen(cp);
3055+ if (len + 2 > PAGE_SIZE - 1)
3056+ goto out;
3057+ buffer[pos++] = '/';
3058+ memmove(buffer + pos, cp, len + 1);
3059+ } else {
3060+ /* Assume nobody assigns "=\$=" for procname. */
3061+ snprintf(buffer + pos, PAGE_SIZE - pos - 1,
3062+ "/=%d=", table->ctl_name);
3063+ if (!memchr(buffer, '\0', PAGE_SIZE - 2))
3064+ goto out;
3065+ }
3066+ if (!table->child)
3067+ goto no_child;
3068+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21)
3069+ if (!table->strategy)
3070+ goto no_strategy;
3071+ /* printk("sysctl='%s'\n", buffer); */
3072+ buf.name = ccs_encode(buffer);
3073+ if (!buf.name)
3074+ goto out;
3075+ ccs_fill_path_info(&buf);
3076+ if (op & MAY_READ)
3077+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
3078+ else
3079+ error = 0;
3080+ if (!error && (op & MAY_WRITE))
3081+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
3082+ kfree(buf.name);
3083+ if (error)
3084+ goto out;
3085+no_strategy:
3086+#endif
3087+ name++;
3088+ nlen--;
3089+ table = table->child;
3090+ goto repeat;
3091+no_child:
3092+ /* printk("sysctl='%s'\n", buffer); */
3093+ buf.name = ccs_encode(buffer);
3094+ if (!buf.name)
3095+ goto out;
3096+ ccs_fill_path_info(&buf);
3097+ if (op & MAY_READ)
3098+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
3099+ else
3100+ error = 0;
3101+ if (!error && (op & MAY_WRITE))
3102+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
3103+ kfree(buf.name);
3104+ goto out;
3105+ }
3106+ error = -ENOTDIR;
3107+out:
3108+ ccs_read_unlock(idx);
3109+ kfree(buffer);
3110+ return error;
3111+}
3112+
3113+#endif
3114+
3115+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
3116+
3117+/**
3118+ * ccs_old_pivot_root_permission - Check permission for pivot_root().
3119+ *
3120+ * @old_nd: Pointer to "struct nameidata".
3121+ * @new_nd: Pointer to "struct nameidata".
3122+ *
3123+ * Returns 0 on success, negative value otherwise.
3124+ */
3125+static int ccs_old_pivot_root_permission(struct nameidata *old_nd,
3126+ struct nameidata *new_nd)
3127+{
3128+ struct path old_path = { old_nd->mnt, old_nd->dentry };
3129+ struct path new_path = { new_nd->mnt, new_nd->dentry };
3130+ return __ccs_pivot_root_permission(&old_path, &new_path);
3131+}
3132+
3133+/**
3134+ * ccs_old_chroot_permission - Check permission for chroot().
3135+ *
3136+ * @nd: Pointer to "struct nameidata".
3137+ *
3138+ * Returns 0 on success, negative value otherwise.
3139+ */
3140+static int ccs_old_chroot_permission(struct nameidata *nd)
3141+{
3142+ struct path path = { nd->mnt, nd->dentry };
3143+ return __ccs_chroot_permission(&path);
3144+}
3145+
3146+#endif
3147+
3148+#ifdef CONFIG_CCSECURITY_NETWORK
3149+
3150+/**
3151+ * ccs_address_matches_group - Check whether the given address matches members of the given address group.
3152+ *
3153+ * @is_ipv6: True if @address is an IPv6 address.
3154+ * @address: An IPv4 or IPv6 address.
3155+ * @group: Pointer to "struct ccs_address_group".
3156+ *
3157+ * Returns true if @address matches addresses in @group group, false otherwise.
3158+ *
3159+ * Caller holds ccs_read_lock().
3160+ */
3161+static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
3162+ const struct ccs_group *group)
3163+{
3164+ struct ccs_address_group *member;
3165+ bool matched = false;
3166+ const u8 size = is_ipv6 ? 16 : 4;
3167+ list_for_each_entry_srcu(member, &group->member_list, head.list,
3168+ &ccs_ss) {
3169+ if (member->head.is_deleted)
3170+ continue;
3171+ if (member->address.is_ipv6 != is_ipv6)
3172+ continue;
3173+ if (memcmp(&member->address.ip[0], address, size) > 0 ||
3174+ memcmp(address, &member->address.ip[1], size) > 0)
3175+ continue;
3176+ matched = true;
3177+ break;
3178+ }
3179+ return matched;
3180+}
3181+
3182+/**
3183+ * ccs_check_inet_acl - Check permission for inet domain socket operation.
3184+ *
3185+ * @r: Pointer to "struct ccs_request_info".
3186+ * @ptr: Pointer to "struct ccs_acl_info".
3187+ *
3188+ * Returns true if granted, false otherwise.
3189+ */
3190+static bool ccs_check_inet_acl(struct ccs_request_info *r,
3191+ const struct ccs_acl_info *ptr)
3192+{
3193+ const struct ccs_inet_acl *acl = container_of(ptr, typeof(*acl), head);
3194+ const u8 size = r->param.inet_network.is_ipv6 ? 16 : 4;
3195+ if (!(ptr->perm & (1 << r->param.inet_network.operation)) ||
3196+ !ccs_compare_number_union(r->param.inet_network.port, &acl->port))
3197+ return false;
3198+ if (acl->address.group)
3199+ return ccs_address_matches_group(r->param.inet_network.is_ipv6,
3200+ r->param.inet_network.address,
3201+ acl->address.group);
3202+ return acl->address.is_ipv6 == r->param.inet_network.is_ipv6 &&
3203+ memcmp(&acl->address.ip[0],
3204+ r->param.inet_network.address, size) <= 0 &&
3205+ memcmp(r->param.inet_network.address,
3206+ &acl->address.ip[1], size) <= 0;
3207+}
3208+
3209+/**
3210+ * ccs_check_unix_acl - Check permission for unix domain socket operation.
3211+ *
3212+ * @r: Pointer to "struct ccs_request_info".
3213+ * @ptr: Pointer to "struct ccs_acl_info".
3214+ *
3215+ * Returns true if granted, false otherwise.
3216+ */
3217+static bool ccs_check_unix_acl(struct ccs_request_info *r,
3218+ const struct ccs_acl_info *ptr)
3219+{
3220+ const struct ccs_unix_acl *acl = container_of(ptr, typeof(*acl), head);
3221+ return (ptr->perm & (1 << r->param.unix_network.operation)) &&
3222+ ccs_compare_name_union(r->param.unix_network.address,
3223+ &acl->name);
3224+}
3225+
3226+/**
3227+ * ccs_inet_entry - Check permission for INET network operation.
3228+ *
3229+ * @address: Pointer to "struct ccs_addr_info".
3230+ *
3231+ * Returns 0 on success, negative value otherwise.
3232+ */
3233+static int ccs_inet_entry(const struct ccs_addr_info *address)
3234+{
3235+ const int idx = ccs_read_lock();
3236+ struct ccs_request_info r;
3237+ int error = 0;
3238+ const u8 type = ccs_inet2mac[address->protocol][address->operation];
3239+ if (type && ccs_init_request_info(&r, type) != CCS_CONFIG_DISABLED) {
3240+ r.param_type = CCS_TYPE_INET_ACL;
3241+ r.param.inet_network.protocol = address->protocol;
3242+ r.param.inet_network.operation = address->operation;
3243+ r.param.inet_network.is_ipv6 = address->inet.is_ipv6;
3244+ r.param.inet_network.address = address->inet.address;
3245+ r.param.inet_network.port = ntohs(address->inet.port);
3246+ r.dont_sleep_on_enforce_error =
3247+ address->operation == CCS_NETWORK_ACCEPT
3248+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
3249+ || address->operation == CCS_NETWORK_RECV
3250+#endif
3251+ ;
3252+ error = ccs_check_acl(&r);
3253+ }
3254+ ccs_read_unlock(idx);
3255+ return error;
3256+}
3257+
3258+/**
3259+ * ccs_check_inet_address - Check permission for inet domain socket's operation.
3260+ *
3261+ * @addr: Pointer to "struct sockaddr".
3262+ * @addr_len: Size of @addr.
3263+ * @port: Port number.
3264+ * @address: Pointer to "struct ccs_addr_info".
3265+ *
3266+ * Returns 0 on success, negative value otherwise.
3267+ */
3268+static int ccs_check_inet_address(const struct sockaddr *addr,
3269+ const unsigned int addr_len, const u16 port,
3270+ struct ccs_addr_info *address)
3271+{
3272+ struct ccs_inet_addr_info *i = &address->inet;
3273+ if (addr_len < sizeof(addr->sa_family))
3274+ goto skip;
3275+ switch (addr->sa_family) {
3276+ case AF_INET6:
3277+ if (addr_len < SIN6_LEN_RFC2133)
3278+ goto skip;
3279+ i->is_ipv6 = true;
3280+ i->address = (u32 *)
3281+ ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
3282+ i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
3283+ break;
3284+ case AF_INET:
3285+ if (addr_len < sizeof(struct sockaddr_in))
3286+ goto skip;
3287+ i->is_ipv6 = false;
3288+ i->address = (u32 *) &((struct sockaddr_in *) addr)->sin_addr;
3289+ i->port = ((struct sockaddr_in *) addr)->sin_port;
3290+ break;
3291+ default:
3292+ goto skip;
3293+ }
3294+ if (address->protocol == SOCK_RAW)
3295+ i->port = htons(port);
3296+ return ccs_inet_entry(address);
3297+skip:
3298+ return 0;
3299+}
3300+
3301+/**
3302+ * ccs_unix_entry - Check permission for UNIX network operation.
3303+ *
3304+ * @address: Pointer to "struct ccs_addr_info".
3305+ *
3306+ * Returns 0 on success, negative value otherwise.
3307+ */
3308+static int ccs_unix_entry(const struct ccs_addr_info *address)
3309+{
3310+ const int idx = ccs_read_lock();
3311+ struct ccs_request_info r;
3312+ int error = 0;
3313+ const u8 type = ccs_unix2mac[address->protocol][address->operation];
3314+ if (type && ccs_init_request_info(&r, type) != CCS_CONFIG_DISABLED) {
3315+ char

差分はサイズ制限により省略されました。全ての差分を見るためにはローカルクライアントを利用してください。

旧リポジトリブラウザで表示