• R/O
  • SSH
  • HTTPS

akari: Commit


Commit MetaInfo

Revision672 (tree)
Time2021-04-01 19:17:40
Authorkumaneko

Log Message

1.0.47

Change Summary

Incremental Difference

--- tags/patches/1.0.47/README (nonexistent)
+++ tags/patches/1.0.47/README (revision 672)
@@ -0,0 +1,383 @@
1+Notes for AKARI project
2+
3+AKARI is Access Keeping And Regulating Instrument for Linux 2.6 and later
4+kernels.
5+
6+You can use AKARI for analyzing your system's behavior (i.e. reports which
7+application accesses which resources like strace command does) and optionally
8+restricting your system's behavior (i.e. controls which application can
9+access which resources like TOMOYO/AppArmor does).
10+
11+AKARI is forked from TOMOYO 1.8 and made as a LKM (loadable kernel module)
12+so that you don't need to replace your kernels installed in your system.
13+
14+This patch is released under the GPLv2.
15+
16+Project URL: https://akari.osdn.jp/
17+
18+ChangeLog:
19+
20+Version 1.0 2010/10/10 First release.
21+
22+Version 1.0.1 2010/10/18 Minor update release.
23+
24+ Synchronize with TOMOYO revision 4069.
25+
26+ Fix off-by-two in ccs_check_unix_address().
27+
28+ Implement post accept() LSM hook.
29+
30+Version 1.0.2 2010/10/25 Minor update release.
31+
32+ Synchronize with TOMOYO revision 4090.
33+
34+ Add getattr() and readdir() checks.
35+
36+ Use "YYYY/MM/DD hh:mm:ss" format for /proc/ccs/ interface.
37+
38+ Do not automatically add / for umount().
39+
40+Version 1.0.3 2010/11/01 Minor update release.
41+
42+ Synchronize with TOMOYO revision 4104.
43+
44+ Fix pathname handling in ccs_unix_entry().
45+
46+Version 1.0.4 2010/11/11 Minor update release.
47+
48+ Synchronize with TOMOYO 1.8.0 release.
49+
50+ Add sysctl() check for 2.6.21 to 2.6.32 kernels.
51+
52+ Fix double new_decode_dev() bug for mknod().
53+
54+ Fix keyword typo.
55+
56+ Fix build failure on some kernels.
57+
58+ Changed pathname prefix priority.
59+
60+ Use hash table for faster scan.
61+
62+ Updated function comments.
63+
64+Version 1.0.5 2010/11/22 Minor update release.
65+
66+ Make ccs_domain_info/ccs_flags inheritable for 2.6.29 and later kernels.
67+
68+Version 1.0.6 2010/12/31 Minor update release.
69+
70+ Synchronize with TOMOYO revision 4280.
71+
72+ Use same interface for audit logs.
73+
74+ Split ccs_null_security into ccs_default_security and ccs_oom_security.
75+
76+Version 1.0.7 2011/01/21 Minor update release.
77+
78+ Synchronize with TOMOYO revision 4400.
79+
80+ Use filesystem name for unnamed devices when vfsmount is missing.
81+
82+Version 1.0.8 2011/02/07 Minor update release.
83+
84+ Synchronize with TOMOYO revision 4545.
85+
86+ Fix infinite loop bug when reading /proc/ccs/audit or /proc/ccs/query .
87+
88+Version 1.0.9 2011/02/14 Minor update release.
89+
90+ Fix missing permission check for interpreters in 2.6.30 and later kernels.
91+
92+Version 1.0.10 2011/02/15 Minor update release.
93+
94+ Fix missing permission check for interpreters in 2.6.23 and earlier kernels.
95+
96+ Fix wrong execute permission check and domain transition in 2.6.28 and earlier kernels.
97+
98+Version 1.0.11 2010/04/01 Minor update release.
99+
100+ Synchronize with TOMOYO 1.8.1 release.
101+
102+ Run garbage collector without waiting for /proc/ccs/ users.
103+
104+ Support built-in policy configuration.
105+
106+ Remove /proc/ccs/meminfo interface.
107+
108+ Pack policy when printing via /proc/ccs/ interface.
109+
110+ Fix conditional policy parsing.
111+
112+ Serialize updating profile's comment line.
113+
114+Version 1.0.12 2011/04/11 Minor update release.
115+
116+ Synchronize with TOMOYO revision 4874.
117+
118+ Fix fcntl(F_SETFL, O_APPEND) handling.
119+
120+Version 1.0.13 2011/05/05 Minor update release.
121+
122+ Synchronize with TOMOYO revision 4963.
123+
124+ Fix wrong profile number in audit logs for "misc env" permission.
125+
126+Version 1.0.14 2011/05/11 Minor update release.
127+
128+ Synchronize with TOMOYO revision 4978.
129+
130+ Fix wrong domainname validation.
131+
132+Version 1.0.15 2011/06/20 Minor update release.
133+
134+ Synchronize with TOMOYO 1.8.2 release.
135+
136+ Add policy namespace support.
137+
138+Version 1.0.16 2011/07/07 Minor update release.
139+
140+ Synchronize with TOMOYO revision 5235.
141+
142+ Remove /proc/ccs/.domain_status interface.
143+
144+Version 1.0.17 2011/07/13 Minor update release.
145+
146+ Synchronize with TOMOYO revision 5266.
147+
148+ Fix /proc/ccs/stat parser.
149+
150+ Accept "::" notation for IPv6 address.
151+
152+Version 1.0.18 2011/09/03 Minor update release.
153+
154+ Synchronize with TOMOYO revision 5401.
155+
156+ Avoid race when retrying "file execute" permission check.
157+
158+ Remove unneeded daemonize().
159+
160+ Fix load failure with !CONFIG_SMP && !CONFIG_DEBUG_SPINLOCK kernels.
161+
162+Version 1.0.19 2011/09/15 Minor update release.
163+
164+ Use akari/config.h for choosing build options.
165+
166+ Fix build error on CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER=y case.
167+
168+ Use lookup_mnt() rather than __put_namespace(). (2.6.0 to 2.6.2 kernels)
169+
170+ Fix unbalanced spin_lock()/spin_unlock() pair in lsm_pin().
171+ (2.6.15 to 2.6.35 kernels)
172+
173+ Fix "struct task_struct" leaks of tasks created before loading akari.ko .
174+ (2.6.28 and earlier kernels)
175+
176+ Use "struct task_struct"->pids[PIDTYPE_PID].pid instead of
177+ "struct task_struct" for associating with per "struct task_struct" variables
178+ (i.e. "struct ccs_security") in order to reduce amount of dead memory
179+ waiting for garbage collection. (2.6.29 and later kernels)
180+
181+ Add akari_test.ko for checking whether akari.ko seems to work or not.
182+
183+ Add SH and ARM architectures support. (Needs more testing.)
184+
185+Version 1.0.20 2011/09/29 Minor update release.
186+
187+ Synchronize with TOMOYO 1.8.3 release.
188+
189+ Allow specifying domain transition preference.
190+
191+ Simplify garbage collector.
192+
193+Version 1.0.21 2011/10/25 Minor update release.
194+
195+ Synchronize with TOMOYO revision 5569.
196+
197+ Fix incomplete read after seek.
198+
199+ Use query id for reaching target process's domain policy.
200+
201+ Fix quota counting.
202+
203+Version 1.0.22 2011/11/11 Minor update release.
204+
205+ Synchronize with TOMOYO revision 5625.
206+
207+ Optimize for object's size.
208+
209+Version 1.0.23 2011/11/18 Minor update release.
210+
211+ Synchronize with TOMOYO revision 5646.
212+
213+ Fix kernel config mapping error.
214+
215+Version 1.0.24 2011/12/13 Minor update release.
216+
217+ Synchronize with TOMOYO revision 5711.
218+
219+ Follow __d_path() behavior change. (Only 2.6.36 and later)
220+
221+Version 1.0.25 2012/02/29 Minor update release.
222+
223+ Synchronize with TOMOYO revision 5893.
224+
225+ Follow UMH_WAIT_PROC constant renumbering.
226+
227+ Fix mount flags checking order.
228+
229+Version 1.0.26 2012/04/01 Minor update release.
230+
231+ Synchronize with TOMOYO revision 5973.
232+
233+ Return appropriate value to poll().
234+
235+Version 1.0.27 2012/05/05 Minor update release.
236+
237+ Synchronize with TOMOYO revision 6035.
238+
239+ Readd RHEL_MINOR/AX_MINOR checks.
240+
241+ Accept manager programs which do not start with / .
242+
243+Version 1.0.28 2012/10/20 Security update release.
244+
245+ Fix kernel panic caused by double kfree() bug when "struct ccs_execve"
246+ pointer was by error duplicated at __ccs_alloc_task_security().
247+ This bug affects only 2.6.28 and earlier kernels.
248+
249+Version 1.0.29 2012/11/04 Minor update release.
250+
251+ Use dummy pointer as needed in order to make sure that security_bprm_free()
252+ (which is used for making the caller of do_execve() return to previous
253+ domain when do_execve() failed after domain transition) is always called.
254+ Without this fix, domain transition history on 2.6.28 and earlier kernels
255+ becomes inaccurate.
256+
257+Version 1.0.30 2013/02/14 Minor update release.
258+
259+ Commit a2a8474c "exec: do not sleep in TASK_TRACED under ->cred_guard_mutex"
260+ moved "current->in_execve = 1;" from before prepare_bprm_creds() to after
261+ prepare_bprm_creds(). It turned out that, as an unexpected bonus, we can use
262+ security_prepare_creds() as a hook for emulating security_bprm_free() hook.
263+
264+ I updated the logic for security_bprm_free() emulation, and now AKARI should
265+ be able to coexist with other AKARI-like LKM-based LSM implementations (e.g.
266+ CaitSith) on all kernel versions other than 2.6.29 and 2.6.30.
267+
268+Version 1.0.31 2015/01/12 Minor update release.
269+
270+ Synchronize with TOMOYO revision 6373.
271+
272+ Fix missing chmod(-1) check in Linux 3.1 and later kernels.
273+
274+ Fix potentially using bogus attributes when stat() fails.
275+
276+Version 1.0.32 2015/04/08 Minor update release.
277+
278+ Synchronize with TOMOYO revision 6388.
279+
280+ Fix incorrect readdir() permission check.
281+
282+Version 1.0.33 2015/04/21 Minor update release.
283+
284+ Synchronize with TOMOYO revision 6407.
285+
286+ Fix incorrect retry request check.
287+
288+Version 1.0.34 2015/05/05 Minor update release.
289+
290+ Synchronize with TOMOYO 1.8.4 release.
291+
292+ Support multiple use_group entries.
293+
294+Version 1.0.35 2015/11/11 Minor update release.
295+
296+ Synchronize with TOMOYO 1.8.5 release.
297+
298+ Use memory allocation flags used by TOMOYO 2.x.
299+
300+ Limit wildcard recursion depth.
301+
302+Version 1.0.36 2017/02/20 Minor update release.
303+
304+ Synchronize with TOMOYO revision 6553.
305+
306+ The bug fixed in TOMOYO's GC does not affect AKARI because
307+ AKARI always uses CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY.
308+
309+Version 1.0.37 2017/09/17 Minor update release.
310+
311+ Use smp_rmb() when waiting for hook readiness.
312+
313+Version 1.0.38 2018/04/01 Minor update release.
314+
315+ Synchronize with TOMOYO revision 6638.
316+
317+ Due to incorrect probe_kernel_write() usage, previously registered LSM
318+ hook (if any) was by error overwritten by this hook. This bug affects
319+ only 4.12 and later kernels.
320+
321+Version 1.0.39 2019/08/20 Minor update release.
322+
323+ Synchronize with TOMOYO 1.8.6 release.
324+
325+ Change pathname calculation for read-only filesystems.
326+
327+ Reject move_mount() system call for now.
328+
329+ Don't check open/getattr permission on sockets.
330+
331+Version 1.0.40 2019/12/25 Minor update release.
332+
333+ Synchronize with TOMOYO revision 6758.
334+
335+ Don't use nifty names on sockets.
336+
337+Version 1.0.41 2020/04/13 Minor update release.
338+
339+ Synchronize with TOMOYO revision 6785.
340+
341+ Fix wrong put_page() usage in ccs_dump_page().
342+
343+Version 1.0.42 2020/05/05 Minor update release.
344+
345+ Synchronize with TOMOYO 1.8.7 release.
346+
347+ Loosen domainname validation and pathname validation.
348+
349+Version 1.0.43 2020/08/08 Minor update release.
350+
351+ Synchronize with TOMOYO revision 6816.
352+
353+ Fix domain transition preference.
354+
355+Version 1.0.44 2020/08/20 Minor update release.
356+
357+ Synchronize with TOMOYO revision 6821.
358+
359+ Fix ccs_realpath() fallback.
360+
361+ Fix wrong ccs_search_binary_handler() mapping.
362+
363+Version 1.0.45 2020/11/11 Minor update release.
364+
365+ Synchronize with TOMOYO 1.8.8 release.
366+
367+ Fix LSM hook detection on ARM64.
368+
369+Version 1.0.46 2020/11/12 Minor update release.
370+
371+ Since ccsecurity_exports.load_policy is initialized to NULL in AKARI,
372+ calling ccsecurity_exports.load_policy() before ccs_permission_init() is
373+ called (changed in revision 654) caused kernel panic as soon as loading
374+ akari.ko module. Since AKARI directly calls ccs_load_policy(), there is
375+ no need to use ccsecurity_exports.load_policy().
376+
377+Version 1.0.47 2021/04/01 Minor update release.
378+
379+ Synchronize with TOMOYO 1.8.9 release.
380+
381+ Skip permission checks for fileless execution requests.
382+
383+ Fix ccs_kernel_service().
--- tags/patches/1.0.47/ccsecurity.h (nonexistent)
+++ tags/patches/1.0.47/ccsecurity.h (revision 672)
@@ -0,0 +1,973 @@
1+/*
2+ * include/linux/ccsecurity.h
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#ifndef _LINUX_CCSECURITY_H
10+#define _LINUX_CCSECURITY_H
11+
12+#include <linux/version.h>
13+
14+#ifndef __user
15+#define __user
16+#endif
17+
18+struct nameidata;
19+struct path;
20+struct dentry;
21+struct vfsmount;
22+struct linux_binprm;
23+struct pt_regs;
24+struct file;
25+struct ctl_table;
26+struct socket;
27+struct sockaddr;
28+struct sock;
29+struct sk_buff;
30+struct msghdr;
31+struct pid_namespace;
32+struct ccs_execve;
33+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
34+/*
35+ * Don't depend on prototype definition, for exec_binprm() is a static function
36+ * which is implicitly inlined by compiler.
37+ */
38+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
39+int search_binary_handler(struct linux_binprm *bprm);
40+#else
41+int search_binary_handler(struct linux_binprm *bprm, struct pt_regs *regs);
42+#endif
43+
44+#ifdef CONFIG_CCSECURITY
45+
46+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
47+/* Obtain prototype of __d_path(). */
48+#include <linux/dcache.h>
49+#endif
50+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
51+/* Obtain definition of kuid_t and kgid_t. */
52+#include <linux/uidgid.h>
53+#endif
54+
55+/* For exporting variables and functions. */
56+struct ccsecurity_exports {
57+ void (*load_policy) (const char *filename);
58+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
59+ char * (*d_absolute_path) (const struct path *, char *, int);
60+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
61+ typeof(__d_path) (*__d_path);
62+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
63+ spinlock_t *vfsmount_lock;
64+#endif
65+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
66+ struct task_struct * (*find_task_by_vpid) (pid_t nr);
67+ struct task_struct * (*find_task_by_pid_ns) (pid_t nr,
68+ struct pid_namespace *ns);
69+#endif
70+};
71+
72+/* For doing access control. */
73+struct ccsecurity_operations {
74+ void (*check_profile) (void);
75+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
76+ int (*chroot_permission) (const struct path *path);
77+ int (*pivot_root_permission) (const struct path *old_path,
78+ const struct path *new_path);
79+ int (*mount_permission) (const char *dev_name, const struct path *path,
80+ const char *type, unsigned long flags,
81+ void *data_page);
82+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
83+ int (*move_mount_permission) (const struct path *from_path,
84+ const struct path *to_path);
85+#endif
86+#else
87+ int (*chroot_permission) (struct nameidata *nd);
88+ int (*pivot_root_permission) (struct nameidata *old_nd,
89+ struct nameidata *new_nd);
90+ int (*mount_permission) (const char *dev_name, struct nameidata *nd,
91+ const char *type, unsigned long flags,
92+ void *data_page);
93+#endif
94+ int (*umount_permission) (struct vfsmount *mnt, int flags);
95+ _Bool (*lport_reserved) (const u16 port);
96+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
97+ void (*save_open_mode) (int mode);
98+ void (*clear_open_mode) (void);
99+ int (*open_permission) (struct dentry *dentry, struct vfsmount *mnt,
100+ const int flag);
101+#else
102+ int (*open_permission) (struct file *file);
103+#endif
104+ int (*ptrace_permission) (long request, long pid);
105+ int (*ioctl_permission) (struct file *filp, unsigned int cmd,
106+ unsigned long arg);
107+ int (*parse_table) (int __user *name, int nlen, void __user *oldval,
108+ void __user *newval, struct ctl_table *table);
109+ _Bool (*capable) (const u8 operation);
110+ int (*mknod_permission) (struct dentry *dentry, struct vfsmount *mnt,
111+ unsigned int mode, unsigned int dev);
112+ int (*mkdir_permission) (struct dentry *dentry, struct vfsmount *mnt,
113+ unsigned int mode);
114+ int (*rmdir_permission) (struct dentry *dentry, struct vfsmount *mnt);
115+ int (*unlink_permission) (struct dentry *dentry, struct vfsmount *mnt);
116+ int (*symlink_permission) (struct dentry *dentry, struct vfsmount *mnt,
117+ const char *from);
118+ int (*truncate_permission) (struct dentry *dentry,
119+ struct vfsmount *mnt);
120+ int (*rename_permission) (struct dentry *old_dentry,
121+ struct dentry *new_dentry,
122+ struct vfsmount *mnt);
123+ int (*link_permission) (struct dentry *old_dentry,
124+ struct dentry *new_dentry,
125+ struct vfsmount *mnt);
126+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
127+ int (*open_exec_permission) (struct dentry *dentry,
128+ struct vfsmount *mnt);
129+ int (*uselib_permission) (struct dentry *dentry, struct vfsmount *mnt);
130+#endif
131+ int (*fcntl_permission) (struct file *file, unsigned int cmd,
132+ unsigned long arg);
133+ int (*kill_permission) (pid_t pid, int sig);
134+ int (*tgkill_permission) (pid_t tgid, pid_t pid, int sig);
135+ int (*tkill_permission) (pid_t pid, int sig);
136+ int (*socket_create_permission) (int family, int type, int protocol);
137+ int (*socket_listen_permission) (struct socket *sock);
138+ int (*socket_connect_permission) (struct socket *sock,
139+ struct sockaddr *addr, int addr_len);
140+ int (*socket_bind_permission) (struct socket *sock,
141+ struct sockaddr *addr, int addr_len);
142+ int (*socket_post_accept_permission) (struct socket *sock,
143+ struct socket *newsock);
144+ int (*socket_sendmsg_permission) (struct socket *sock,
145+ struct msghdr *msg, int size);
146+ int (*socket_post_recvmsg_permission) (struct sock *sk,
147+ struct sk_buff *skb, int flags);
148+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
149+ int (*chown_permission) (struct dentry *dentry, struct vfsmount *mnt,
150+ kuid_t user, kgid_t group);
151+#else
152+ int (*chown_permission) (struct dentry *dentry, struct vfsmount *mnt,
153+ uid_t user, gid_t group);
154+#endif
155+ int (*chmod_permission) (struct dentry *dentry, struct vfsmount *mnt,
156+ mode_t mode);
157+ int (*getattr_permission) (struct vfsmount *mnt,
158+ struct dentry *dentry);
159+ int (*sigqueue_permission) (pid_t pid, int sig);
160+ int (*tgsigqueue_permission) (pid_t tgid, pid_t pid, int sig);
161+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
162+ int (*start_execve) (struct linux_binprm *bprm, struct ccs_execve **eep);
163+ void (*finish_execve) (int retval, struct ccs_execve *ep);
164+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
165+ int (*search_binary_handler) (struct linux_binprm *bprm);
166+#else
167+ int (*search_binary_handler) (struct linux_binprm *bprm,
168+ struct pt_regs *regs);
169+#endif
170+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
171+ int (*alloc_task_security) (const struct task_struct *task);
172+ void (*free_task_security) (const struct task_struct *task);
173+#endif
174+ _Bool disabled;
175+};
176+
177+extern struct ccsecurity_operations ccsecurity_ops;
178+
179+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
180+
181+static inline int ccs_chroot_permission(const struct path *path)
182+{
183+ int (*func) (const struct path *) = ccsecurity_ops.chroot_permission;
184+ return func ? func(path) : 0;
185+}
186+
187+static inline int ccs_pivot_root_permission(const struct path *old_path,
188+ const struct path *new_path)
189+{
190+ int (*func) (const struct path *, const struct path *)
191+ = ccsecurity_ops.pivot_root_permission;
192+ return func ? func(old_path, new_path) : 0;
193+}
194+
195+static inline int ccs_mount_permission(const char *dev_name,
196+ const struct path *path,
197+ const char *type, unsigned long flags,
198+ void *data_page)
199+{
200+ int (*func) (const char *, const struct path *, const char *,
201+ unsigned long, void *) = ccsecurity_ops.mount_permission;
202+ return func ? func(dev_name, path, type, flags, data_page) : 0;
203+}
204+
205+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
206+static inline int ccs_move_mount_permission(const struct path *from_path,
207+ const struct path *to_path)
208+{
209+ int (*func) (const struct path *, const struct path *) =
210+ ccsecurity_ops.move_mount_permission;
211+ return func ? func(from_path, to_path) : 0;
212+}
213+#endif
214+
215+#else
216+
217+static inline int ccs_chroot_permission(struct nameidata *nd)
218+{
219+ int (*func) (struct nameidata *) = ccsecurity_ops.chroot_permission;
220+ return func ? func(nd) : 0;
221+}
222+
223+static inline int ccs_pivot_root_permission(struct nameidata *old_nd,
224+ struct nameidata *new_nd)
225+{
226+ int (*func) (struct nameidata *, struct nameidata *)
227+ = ccsecurity_ops.pivot_root_permission;
228+ return func ? func(old_nd, new_nd) : 0;
229+}
230+
231+static inline int ccs_mount_permission(const char *dev_name,
232+ struct nameidata *nd, const char *type,
233+ unsigned long flags, void *data_page)
234+{
235+ int (*func) (const char *, struct nameidata *, const char *,
236+ unsigned long, void *) = ccsecurity_ops.mount_permission;
237+ return func ? func(dev_name, nd, type, flags, data_page) : 0;
238+}
239+
240+#endif
241+
242+static inline int ccs_umount_permission(struct vfsmount *mnt, int flags)
243+{
244+ int (*func) (struct vfsmount *, int)
245+ = ccsecurity_ops.umount_permission;
246+ return func ? func(mnt, flags) : 0;
247+}
248+
249+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
250+
251+static inline void ccs_save_open_mode(int mode)
252+{
253+ void (*func) (int) = ccsecurity_ops.save_open_mode;
254+ if (func)
255+ func(mode);
256+}
257+
258+static inline void ccs_clear_open_mode(void)
259+{
260+ void (*func) (void) = ccsecurity_ops.clear_open_mode;
261+ if (func)
262+ func();
263+}
264+
265+static inline int ccs_open_permission(struct dentry *dentry,
266+ struct vfsmount *mnt, const int flag)
267+{
268+ int (*func) (struct dentry *, struct vfsmount *, const int)
269+ = ccsecurity_ops.open_permission;
270+ return func ? func(dentry, mnt, flag) : 0;
271+}
272+
273+#else
274+
275+static inline int ccs_open_permission(struct file *filp)
276+{
277+ int (*func) (struct file *) = ccsecurity_ops.open_permission;
278+ return func ? func(filp) : 0;
279+}
280+
281+#endif
282+
283+static inline int ccs_fcntl_permission(struct file *file, unsigned int cmd,
284+ unsigned long arg)
285+{
286+ int (*func) (struct file *, unsigned int, unsigned long)
287+ = ccsecurity_ops.fcntl_permission;
288+ return func ? func(file, cmd, arg) : 0;
289+}
290+
291+static inline int ccs_ioctl_permission(struct file *filp, unsigned int cmd,
292+ unsigned long arg)
293+{
294+ int (*func) (struct file *, unsigned int, unsigned long)
295+ = ccsecurity_ops.ioctl_permission;
296+ return func ? func(filp, cmd, arg) : 0;
297+}
298+
299+static inline int ccs_parse_table(int __user *name, int nlen,
300+ void __user *oldval, void __user *newval,
301+ struct ctl_table *table)
302+{
303+ int (*func) (int __user *, int, void __user *, void __user *,
304+ struct ctl_table *) = ccsecurity_ops.parse_table;
305+ return func ? func(name, nlen, oldval, newval, table) : 0;
306+}
307+
308+static inline int ccs_mknod_permission(struct dentry *dentry,
309+ struct vfsmount *mnt, unsigned int mode,
310+ unsigned int dev)
311+{
312+ int (*func) (struct dentry *, struct vfsmount *, unsigned int,
313+ unsigned int) = ccsecurity_ops.mknod_permission;
314+ return func ? func(dentry, mnt, mode, dev) : 0;
315+}
316+
317+static inline int ccs_mkdir_permission(struct dentry *dentry,
318+ struct vfsmount *mnt, unsigned int mode)
319+{
320+ int (*func) (struct dentry *, struct vfsmount *, unsigned int)
321+ = ccsecurity_ops.mkdir_permission;
322+ return func ? func(dentry, mnt, mode) : 0;
323+}
324+
325+static inline int ccs_rmdir_permission(struct dentry *dentry,
326+ struct vfsmount *mnt)
327+{
328+ int (*func) (struct dentry *, struct vfsmount *)
329+ = ccsecurity_ops.rmdir_permission;
330+ return func ? func(dentry, mnt) : 0;
331+}
332+
333+static inline int ccs_unlink_permission(struct dentry *dentry,
334+ struct vfsmount *mnt)
335+{
336+ int (*func) (struct dentry *, struct vfsmount *)
337+ = ccsecurity_ops.unlink_permission;
338+ return func ? func(dentry, mnt) : 0;
339+}
340+
341+static inline int ccs_symlink_permission(struct dentry *dentry,
342+ struct vfsmount *mnt,
343+ const char *from)
344+{
345+ int (*func) (struct dentry *, struct vfsmount *, const char *)
346+ = ccsecurity_ops.symlink_permission;
347+ return func ? func(dentry, mnt, from) : 0;
348+}
349+
350+static inline int ccs_truncate_permission(struct dentry *dentry,
351+ struct vfsmount *mnt)
352+{
353+ int (*func) (struct dentry *, struct vfsmount *)
354+ = ccsecurity_ops.truncate_permission;
355+ return func ? func(dentry, mnt) : 0;
356+}
357+
358+static inline int ccs_rename_permission(struct dentry *old_dentry,
359+ struct dentry *new_dentry,
360+ struct vfsmount *mnt)
361+{
362+ int (*func) (struct dentry *, struct dentry *, struct vfsmount *)
363+ = ccsecurity_ops.rename_permission;
364+ return func ? func(old_dentry, new_dentry, mnt) : 0;
365+}
366+
367+static inline int ccs_link_permission(struct dentry *old_dentry,
368+ struct dentry *new_dentry,
369+ struct vfsmount *mnt)
370+{
371+ int (*func) (struct dentry *, struct dentry *, struct vfsmount *)
372+ = ccsecurity_ops.link_permission;
373+ return func ? func(old_dentry, new_dentry, mnt) : 0;
374+}
375+
376+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
377+
378+static inline int ccs_open_exec_permission(struct dentry *dentry,
379+ struct vfsmount *mnt)
380+{
381+ int (*func) (struct dentry *, struct vfsmount *)
382+ = ccsecurity_ops.open_exec_permission;
383+ return func ? func(dentry, mnt) : 0;
384+}
385+
386+static inline int ccs_uselib_permission(struct dentry *dentry,
387+ struct vfsmount *mnt)
388+{
389+ int (*func) (struct dentry *, struct vfsmount *)
390+ = ccsecurity_ops.uselib_permission;
391+ return func ? func(dentry, mnt) : 0;
392+}
393+
394+#endif
395+
396+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
397+
398+static inline int ccs_chown_permission(struct dentry *dentry,
399+ struct vfsmount *mnt, kuid_t user,
400+ kgid_t group)
401+{
402+ int (*func) (struct dentry *, struct vfsmount *, kuid_t, kgid_t)
403+ = ccsecurity_ops.chown_permission;
404+ return func ? func(dentry, mnt, user, group) : 0;
405+}
406+
407+#else
408+
409+static inline int ccs_chown_permission(struct dentry *dentry,
410+ struct vfsmount *mnt, uid_t user,
411+ gid_t group)
412+{
413+ int (*func) (struct dentry *, struct vfsmount *, uid_t, gid_t)
414+ = ccsecurity_ops.chown_permission;
415+ return func ? func(dentry, mnt, user, group) : 0;
416+}
417+
418+#endif
419+
420+static inline int ccs_chmod_permission(struct dentry *dentry,
421+ struct vfsmount *mnt, mode_t mode)
422+{
423+ int (*func) (struct dentry *, struct vfsmount *, mode_t)
424+ = ccsecurity_ops.chmod_permission;
425+ return func ? func(dentry, mnt, mode) : 0;
426+}
427+
428+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
429+
430+/* Define as a macro here, for exec_binprm() is a static function. */
431+#define ccs_exec_binprm(bprm) \
432+({ \
433+ struct ccs_execve *ee = NULL; \
434+ void (*func) (int, struct ccs_execve *); \
435+ int retval = ccsecurity_ops.start_execve(bprm, &ee); \
436+ if (!retval) \
437+ retval = exec_binprm(bprm); \
438+ func = ccsecurity_ops.finish_execve; \
439+ if (func) \
440+ func(retval, ee); \
441+ retval; \
442+})
443+
444+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
445+
446+static inline int ccs_search_binary_handler(struct linux_binprm *bprm)
447+{
448+ return ccsecurity_ops.search_binary_handler(bprm);
449+}
450+
451+#else
452+
453+static inline int ccs_search_binary_handler(struct linux_binprm *bprm,
454+ struct pt_regs *regs)
455+{
456+ return ccsecurity_ops.search_binary_handler(bprm, regs);
457+}
458+
459+#endif
460+
461+#else
462+
463+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
464+
465+static inline int ccs_chroot_permission(const struct path *path)
466+{
467+ return 0;
468+}
469+
470+static inline int ccs_pivot_root_permission(const struct path *old_path,
471+ const struct path *new_path)
472+{
473+ return 0;
474+}
475+
476+static inline int ccs_mount_permission(const char *dev_name,
477+ const struct path *path,
478+ const char *type, unsigned long flags,
479+ void *data_page)
480+{
481+ return 0;
482+}
483+
484+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
485+static inline int ccs_move_mount_permission(const struct path *from_path,
486+ const struct path *to_path)
487+{
488+ return 0;
489+}
490+#endif
491+
492+#else
493+
494+static inline int ccs_chroot_permission(struct nameidata *nd)
495+{
496+ return 0;
497+}
498+
499+static inline int ccs_pivot_root_permission(struct nameidata *old_nd,
500+ struct nameidata *new_nd)
501+{
502+ return 0;
503+}
504+
505+static inline int ccs_mount_permission(const char *dev_name,
506+ struct nameidata *nd, const char *type,
507+ unsigned long flags, void *data_page)
508+{
509+ return 0;
510+}
511+
512+#endif
513+
514+static inline int ccs_umount_permission(struct vfsmount *mnt, int flags)
515+{
516+ return 0;
517+}
518+
519+static inline void ccs_save_open_mode(int mode)
520+{
521+}
522+
523+static inline void ccs_clear_open_mode(void)
524+{
525+}
526+
527+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
528+
529+static inline int ccs_open_permission(struct dentry *dentry,
530+ struct vfsmount *mnt, const int flag)
531+{
532+ return 0;
533+}
534+
535+#else
536+
537+static inline int ccs_open_permission(struct file *filp)
538+{
539+ return 0;
540+}
541+
542+#endif
543+
544+static inline int ccs_ioctl_permission(struct file *filp, unsigned int cmd,
545+ unsigned long arg)
546+{
547+ return 0;
548+}
549+
550+static inline int ccs_parse_table(int __user *name, int nlen,
551+ void __user *oldval, void __user *newval,
552+ struct ctl_table *table)
553+{
554+ return 0;
555+}
556+
557+static inline int ccs_mknod_permission(struct dentry *dentry,
558+ struct vfsmount *mnt, unsigned int mode,
559+ unsigned int dev)
560+{
561+ return 0;
562+}
563+
564+static inline int ccs_mkdir_permission(struct dentry *dentry,
565+ struct vfsmount *mnt, unsigned int mode)
566+{
567+ return 0;
568+}
569+
570+static inline int ccs_rmdir_permission(struct dentry *dentry,
571+ struct vfsmount *mnt)
572+{
573+ return 0;
574+}
575+
576+static inline int ccs_unlink_permission(struct dentry *dentry,
577+ struct vfsmount *mnt)
578+{
579+ return 0;
580+}
581+
582+static inline int ccs_symlink_permission(struct dentry *dentry,
583+ struct vfsmount *mnt,
584+ const char *from)
585+{
586+ return 0;
587+}
588+
589+static inline int ccs_truncate_permission(struct dentry *dentry,
590+ struct vfsmount *mnt)
591+{
592+ return 0;
593+}
594+
595+static inline int ccs_rename_permission(struct dentry *old_dentry,
596+ struct dentry *new_dentry,
597+ struct vfsmount *mnt)
598+{
599+ return 0;
600+}
601+
602+static inline int ccs_link_permission(struct dentry *old_dentry,
603+ struct dentry *new_dentry,
604+ struct vfsmount *mnt)
605+{
606+ return 0;
607+}
608+
609+static inline int ccs_open_exec_permission(struct dentry *dentry,
610+ struct vfsmount *mnt)
611+{
612+ return 0;
613+}
614+
615+static inline int ccs_uselib_permission(struct dentry *dentry,
616+ struct vfsmount *mnt)
617+{
618+ return 0;
619+}
620+
621+static inline int ccs_fcntl_permission(struct file *file, unsigned int cmd,
622+ unsigned long arg)
623+{
624+ return 0;
625+}
626+
627+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
628+
629+static inline int ccs_chown_permission(struct dentry *dentry,
630+ struct vfsmount *mnt, kuid_t user,
631+ kgid_t group)
632+{
633+ return 0;
634+}
635+
636+#else
637+
638+static inline int ccs_chown_permission(struct dentry *dentry,
639+ struct vfsmount *mnt, uid_t user,
640+ gid_t group)
641+{
642+ return 0;
643+}
644+
645+#endif
646+
647+static inline int ccs_chmod_permission(struct dentry *dentry,
648+ struct vfsmount *mnt, mode_t mode)
649+{
650+ return 0;
651+}
652+
653+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
654+
655+/* Define as a macro here, for exec_binprm() is a static function. */
656+#define ccs_exec_binprm(bprm) exec_binprm(bprm)
657+
658+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
659+
660+static inline int ccs_search_binary_handler(struct linux_binprm *bprm)
661+{
662+ return search_binary_handler(bprm);
663+}
664+
665+#else
666+
667+static inline int ccs_search_binary_handler(struct linux_binprm *bprm,
668+ struct pt_regs *regs)
669+{
670+ return search_binary_handler(bprm, regs);
671+}
672+
673+#endif
674+
675+#endif
676+
677+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
678+
679+static inline int ccs_alloc_task_security(const struct task_struct *task)
680+{
681+ int (*func) (const struct task_struct *)
682+ = ccsecurity_ops.alloc_task_security;
683+ return func ? func(task) : 0;
684+}
685+
686+static inline void ccs_free_task_security(const struct task_struct *task)
687+{
688+ void (*func) (const struct task_struct *)
689+ = ccsecurity_ops.free_task_security;
690+ if (func)
691+ func(task);
692+}
693+
694+#else
695+
696+static inline int ccs_alloc_task_security(const struct task_struct *task)
697+{
698+ return 0;
699+}
700+
701+static inline void ccs_free_task_security(const struct task_struct *task)
702+{
703+}
704+
705+#endif
706+
707+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
708+
709+static inline int ccs_getattr_permission(struct vfsmount *mnt,
710+ struct dentry *dentry)
711+{
712+ int (*func) (struct vfsmount *, struct dentry *)
713+ = ccsecurity_ops.getattr_permission;
714+ return func ? func(mnt, dentry) : 0;
715+}
716+
717+#else
718+
719+static inline int ccs_getattr_permission(struct vfsmount *mnt,
720+ struct dentry *dentry)
721+{
722+ return 0;
723+}
724+
725+#endif
726+
727+#ifdef CONFIG_CCSECURITY_NETWORK
728+
729+static inline int ccs_socket_listen_permission(struct socket *sock)
730+{
731+ int (*func) (struct socket *)
732+ = ccsecurity_ops.socket_listen_permission;
733+ return func ? func(sock) : 0;
734+}
735+
736+static inline int ccs_socket_connect_permission(struct socket *sock,
737+ struct sockaddr *addr,
738+ int addr_len)
739+{
740+ int (*func) (struct socket *, struct sockaddr *, int)
741+ = ccsecurity_ops.socket_connect_permission;
742+ return func ? func(sock, addr, addr_len) : 0;
743+}
744+
745+static inline int ccs_socket_bind_permission(struct socket *sock,
746+ struct sockaddr *addr,
747+ int addr_len)
748+{
749+ int (*func) (struct socket *, struct sockaddr *, int)
750+ = ccsecurity_ops.socket_bind_permission;
751+ return func ? func(sock, addr, addr_len) : 0;
752+}
753+
754+static inline int ccs_socket_post_accept_permission(struct socket *sock,
755+ struct socket *newsock)
756+{
757+ int (*func) (struct socket *, struct socket *)
758+ = ccsecurity_ops.socket_post_accept_permission;
759+ return func ? func(sock, newsock) : 0;
760+}
761+
762+static inline int ccs_socket_sendmsg_permission(struct socket *sock,
763+ struct msghdr *msg,
764+ int size)
765+{
766+ int (*func) (struct socket *, struct msghdr *, int)
767+ = ccsecurity_ops.socket_sendmsg_permission;
768+ return func ? func(sock, msg, size) : 0;
769+}
770+
771+#else
772+
773+static inline int ccs_socket_listen_permission(struct socket *sock)
774+{
775+ return 0;
776+}
777+
778+static inline int ccs_socket_connect_permission(struct socket *sock,
779+ struct sockaddr *addr,
780+ int addr_len)
781+{
782+ return 0;
783+}
784+
785+static inline int ccs_socket_bind_permission(struct socket *sock,
786+ struct sockaddr *addr,
787+ int addr_len)
788+{
789+ return 0;
790+}
791+
792+static inline int ccs_socket_post_accept_permission(struct socket *sock,
793+ struct socket *newsock)
794+{
795+ return 0;
796+}
797+
798+static inline int ccs_socket_sendmsg_permission(struct socket *sock,
799+ struct msghdr *msg,
800+ int size)
801+{
802+ return 0;
803+}
804+
805+#endif
806+
807+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
808+
809+static inline int ccs_socket_post_recvmsg_permission(struct sock *sk,
810+ struct sk_buff *skb,
811+ int flags)
812+{
813+ int (*func) (struct sock *, struct sk_buff *, int)
814+ = ccsecurity_ops.socket_post_recvmsg_permission;
815+ return func ? func(sk, skb, flags) : 0;
816+}
817+
818+#else
819+
820+static inline int ccs_socket_post_recvmsg_permission(struct sock *sk,
821+ struct sk_buff *skb,
822+ int flags)
823+{
824+ return 0;
825+}
826+
827+#endif
828+
829+#ifdef CONFIG_CCSECURITY_PORTRESERVE
830+
831+static inline _Bool ccs_lport_reserved(const u16 port)
832+{
833+ _Bool (*func) (const u16) = ccsecurity_ops.lport_reserved;
834+ return func ? func(port) : 0;
835+}
836+
837+#else
838+
839+static inline _Bool ccs_lport_reserved(const u16 port)
840+{
841+ return 0;
842+}
843+
844+#endif
845+
846+#ifdef CONFIG_CCSECURITY_CAPABILITY
847+
848+static inline _Bool ccs_capable(const u8 operation)
849+{
850+ _Bool (*func) (const u8) = ccsecurity_ops.capable;
851+ return func ? func(operation) : 1;
852+}
853+
854+static inline int ccs_socket_create_permission(int family, int type,
855+ int protocol)
856+{
857+ int (*func) (int, int, int) = ccsecurity_ops.socket_create_permission;
858+ return func ? func(family, type, protocol) : 0;
859+}
860+
861+static inline int ccs_ptrace_permission(long request, long pid)
862+{
863+ int (*func) (long, long) = ccsecurity_ops.ptrace_permission;
864+ return func ? func(request, pid) : 0;
865+}
866+
867+#else
868+
869+static inline _Bool ccs_capable(const u8 operation)
870+{
871+ return 1;
872+}
873+
874+static inline int ccs_socket_create_permission(int family, int type,
875+ int protocol)
876+{
877+ return 0;
878+}
879+
880+static inline int ccs_ptrace_permission(long request, long pid)
881+{
882+ return 0;
883+}
884+
885+#endif
886+
887+#ifdef CONFIG_CCSECURITY_IPC
888+
889+static inline int ccs_kill_permission(pid_t pid, int sig)
890+{
891+ int (*func) (pid_t, int) = ccsecurity_ops.kill_permission;
892+ return func ? func(pid, sig) : 0;
893+}
894+
895+static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
896+{
897+ int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgkill_permission;
898+ return func ? func(tgid, pid, sig) : 0;
899+}
900+
901+static inline int ccs_tkill_permission(pid_t pid, int sig)
902+{
903+ int (*func) (pid_t, int) = ccsecurity_ops.tkill_permission;
904+ return func ? func(pid, sig) : 0;
905+}
906+
907+static inline int ccs_sigqueue_permission(pid_t pid, int sig)
908+{
909+ int (*func) (pid_t, int) = ccsecurity_ops.sigqueue_permission;
910+ return func ? func(pid, sig) : 0;
911+}
912+
913+static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
914+{
915+ int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgsigqueue_permission;
916+ return func ? func(tgid, pid, sig) : 0;
917+}
918+
919+#else
920+
921+static inline int ccs_kill_permission(pid_t pid, int sig)
922+{
923+ return 0;
924+}
925+
926+static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
927+{
928+ return 0;
929+}
930+
931+static inline int ccs_tkill_permission(pid_t pid, int sig)
932+{
933+ return 0;
934+}
935+
936+static inline int ccs_sigqueue_permission(pid_t pid, int sig)
937+{
938+ return 0;
939+}
940+
941+static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
942+{
943+ return 0;
944+}
945+
946+#endif
947+
948+/* Index numbers for Capability Controls. */
949+enum ccs_capability_acl_index {
950+ /* socket(PF_ROUTE, *, *) */
951+ CCS_USE_ROUTE_SOCKET,
952+ /* socket(PF_PACKET, *, *) */
953+ CCS_USE_PACKET_SOCKET,
954+ /* sys_reboot() */
955+ CCS_SYS_REBOOT,
956+ /* sys_vhangup() */
957+ CCS_SYS_VHANGUP,
958+ /* do_settimeofday(), sys_adjtimex() */
959+ CCS_SYS_SETTIME,
960+ /* sys_nice(), sys_setpriority() */
961+ CCS_SYS_NICE,
962+ /* sys_sethostname(), sys_setdomainname() */
963+ CCS_SYS_SETHOSTNAME,
964+ /* sys_create_module(), sys_init_module(), sys_delete_module() */
965+ CCS_USE_KERNEL_MODULE,
966+ /* sys_kexec_load() */
967+ CCS_SYS_KEXEC_LOAD,
968+ /* sys_ptrace() */
969+ CCS_SYS_PTRACE,
970+ CCS_MAX_CAPABILITY_INDEX
971+};
972+
973+#endif
--- tags/patches/1.0.47/gc.c (nonexistent)
+++ tags/patches/1.0.47/gc.c (revision 672)
@@ -0,0 +1,1054 @@
1+/*
2+ * security/ccsecurity/gc.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#include "internal.h"
10+
11+/***** SECTION1: Constants definition *****/
12+
13+/* For compatibility with older kernels. */
14+#ifndef for_each_process
15+#define for_each_process for_each_task
16+#endif
17+
18+/* The list for "struct ccs_io_buffer". */
19+static LIST_HEAD(ccs_io_buffer_list);
20+/* Lock for protecting ccs_io_buffer_list. */
21+static DEFINE_SPINLOCK(ccs_io_buffer_list_lock);
22+
23+/***** SECTION2: Structure definition *****/
24+
25+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
26+
27+/*
28+ * Lock for syscall users.
29+ *
30+ * This lock is used for protecting single SRCU section for 2.6.18 and
31+ * earlier kernels because they don't have SRCU support.
32+ */
33+struct ccs_lock_struct {
34+ int counter_idx; /* Currently active index (0 or 1). */
35+ int counter[2]; /* Current users. Protected by ccs_counter_lock. */
36+};
37+
38+#endif
39+
40+/***** SECTION3: Prototype definition section *****/
41+
42+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
43+int ccs_lock(void);
44+#endif
45+void ccs_del_acl(struct list_head *element);
46+void ccs_del_condition(struct list_head *element);
47+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register);
48+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
49+void ccs_unlock(const int idx);
50+#endif
51+
52+static bool ccs_domain_used_by_task(struct ccs_domain_info *domain);
53+static bool ccs_name_used_by_io_buffer(const char *string, const size_t size);
54+static bool ccs_struct_used_by_io_buffer(const struct list_head *element);
55+static int ccs_gc_thread(void *unused);
56+static void ccs_collect_acl(struct list_head *list);
57+static void ccs_collect_entry(void);
58+static void ccs_collect_member(const enum ccs_policy_id id,
59+ struct list_head *member_list);
60+static void ccs_memory_free(const void *ptr, const enum ccs_policy_id type);
61+static void ccs_put_name_union(struct ccs_name_union *ptr);
62+static void ccs_put_number_union(struct ccs_number_union *ptr);
63+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
64+static void ccs_synchronize_counter(void);
65+#endif
66+static void ccs_try_to_gc(const enum ccs_policy_id type,
67+ struct list_head *element);
68+
69+/***** SECTION4: Standalone functions section *****/
70+
71+/***** SECTION5: Variables definition section *****/
72+
73+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
74+
75+/*
76+ * Lock for syscall users.
77+ *
78+ * This lock is held for only protecting single SRCU section.
79+ */
80+struct srcu_struct ccs_ss;
81+
82+#else
83+
84+static struct ccs_lock_struct ccs_counter;
85+/* Lock for protecting ccs_counter. */
86+static DEFINE_SPINLOCK(ccs_counter_lock);
87+
88+#endif
89+
90+/***** SECTION6: Dependent functions section *****/
91+
92+/**
93+ * ccs_memory_free - Free memory for elements.
94+ *
95+ * @ptr: Pointer to allocated memory.
96+ * @type: One of values in "enum ccs_policy_id".
97+ *
98+ * Returns nothing.
99+ *
100+ * Caller holds ccs_policy_lock mutex.
101+ */
102+static void ccs_memory_free(const void *ptr, const enum ccs_policy_id type)
103+{
104+ /* Size of an element. */
105+ static const u8 e[CCS_MAX_POLICY] = {
106+#ifdef CONFIG_CCSECURITY_PORTRESERVE
107+ [CCS_ID_RESERVEDPORT] = sizeof(struct ccs_reserved),
108+#endif
109+ [CCS_ID_GROUP] = sizeof(struct ccs_group),
110+#ifdef CONFIG_CCSECURITY_NETWORK
111+ [CCS_ID_ADDRESS_GROUP] = sizeof(struct ccs_address_group),
112+#endif
113+ [CCS_ID_PATH_GROUP] = sizeof(struct ccs_path_group),
114+ [CCS_ID_NUMBER_GROUP] = sizeof(struct ccs_number_group),
115+ [CCS_ID_AGGREGATOR] = sizeof(struct ccs_aggregator),
116+ [CCS_ID_TRANSITION_CONTROL]
117+ = sizeof(struct ccs_transition_control),
118+ [CCS_ID_MANAGER] = sizeof(struct ccs_manager),
119+ /* [CCS_ID_CONDITION] = "struct ccs_condition"->size, */
120+ /* [CCS_ID_NAME] = "struct ccs_name"->size, */
121+ /* [CCS_ID_ACL] = a["struct ccs_acl_info"->type], */
122+ [CCS_ID_DOMAIN] = sizeof(struct ccs_domain_info),
123+ };
124+ /* Size of a domain ACL element. */
125+ static const u8 a[] = {
126+ [CCS_TYPE_PATH_ACL] = sizeof(struct ccs_path_acl),
127+ [CCS_TYPE_PATH2_ACL] = sizeof(struct ccs_path2_acl),
128+ [CCS_TYPE_PATH_NUMBER_ACL]
129+ = sizeof(struct ccs_path_number_acl),
130+ [CCS_TYPE_MKDEV_ACL] = sizeof(struct ccs_mkdev_acl),
131+ [CCS_TYPE_MOUNT_ACL] = sizeof(struct ccs_mount_acl),
132+#ifdef CONFIG_CCSECURITY_NETWORK
133+ [CCS_TYPE_INET_ACL] = sizeof(struct ccs_inet_acl),
134+ [CCS_TYPE_UNIX_ACL] = sizeof(struct ccs_unix_acl),
135+#endif
136+#ifdef CONFIG_CCSECURITY_MISC
137+ [CCS_TYPE_ENV_ACL] = sizeof(struct ccs_env_acl),
138+#endif
139+#ifdef CONFIG_CCSECURITY_CAPABILITY
140+ [CCS_TYPE_CAPABILITY_ACL] = sizeof(struct ccs_capability_acl),
141+#endif
142+#ifdef CONFIG_CCSECURITY_IPC
143+ [CCS_TYPE_SIGNAL_ACL] = sizeof(struct ccs_signal_acl),
144+#endif
145+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
146+ [CCS_TYPE_AUTO_EXECUTE_HANDLER]
147+ = sizeof(struct ccs_handler_acl),
148+ [CCS_TYPE_DENIED_EXECUTE_HANDLER]
149+ = sizeof(struct ccs_handler_acl),
150+#endif
151+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
152+ [CCS_TYPE_AUTO_TASK_ACL] = sizeof(struct ccs_task_acl),
153+ [CCS_TYPE_MANUAL_TASK_ACL] = sizeof(struct ccs_task_acl),
154+#endif
155+ };
156+ size_t size;
157+ if (type == CCS_ID_ACL)
158+ size = a[container_of(ptr, typeof(struct ccs_acl_info),
159+ list)->type];
160+ else if (type == CCS_ID_NAME)
161+ size = container_of(ptr, typeof(struct ccs_name),
162+ head.list)->size;
163+ else if (type == CCS_ID_CONDITION)
164+ size = container_of(ptr, typeof(struct ccs_condition),
165+ head.list)->size;
166+ else
167+ size = e[type];
168+ ccs_memory_used[CCS_MEMORY_POLICY] -= ccs_round2(size);
169+ kfree(ptr);
170+}
171+
172+/**
173+ * ccs_put_name_union - Drop reference on "struct ccs_name_union".
174+ *
175+ * @ptr: Pointer to "struct ccs_name_union".
176+ *
177+ * Returns nothing.
178+ */
179+static void ccs_put_name_union(struct ccs_name_union *ptr)
180+{
181+ ccs_put_group(ptr->group);
182+ ccs_put_name(ptr->filename);
183+}
184+
185+/**
186+ * ccs_put_number_union - Drop reference on "struct ccs_number_union".
187+ *
188+ * @ptr: Pointer to "struct ccs_number_union".
189+ *
190+ * Returns nothing.
191+ */
192+static void ccs_put_number_union(struct ccs_number_union *ptr)
193+{
194+ ccs_put_group(ptr->group);
195+}
196+
197+/**
198+ * ccs_struct_used_by_io_buffer - Check whether the list element is used by /proc/ccs/ users or not.
199+ *
200+ * @element: Pointer to "struct list_head".
201+ *
202+ * Returns true if @element is used by /proc/ccs/ users, false otherwise.
203+ */
204+static bool ccs_struct_used_by_io_buffer(const struct list_head *element)
205+{
206+ struct ccs_io_buffer *head;
207+ bool in_use = false;
208+ spin_lock(&ccs_io_buffer_list_lock);
209+ list_for_each_entry(head, &ccs_io_buffer_list, list) {
210+ head->users++;
211+ spin_unlock(&ccs_io_buffer_list_lock);
212+ mutex_lock(&head->io_sem);
213+ if (head->r.domain == element || head->r.group == element ||
214+ head->r.acl == element || &head->w.domain->list == element)
215+ in_use = true;
216+ mutex_unlock(&head->io_sem);
217+ spin_lock(&ccs_io_buffer_list_lock);
218+ head->users--;
219+ if (in_use)
220+ break;
221+ }
222+ spin_unlock(&ccs_io_buffer_list_lock);
223+ return in_use;
224+}
225+
226+/**
227+ * ccs_name_used_by_io_buffer - Check whether the string is used by /proc/ccs/ users or not.
228+ *
229+ * @string: String to check.
230+ * @size: Memory allocated for @string .
231+ *
232+ * Returns true if @string is used by /proc/ccs/ users, false otherwise.
233+ */
234+static bool ccs_name_used_by_io_buffer(const char *string, const size_t size)
235+{
236+ struct ccs_io_buffer *head;
237+ bool in_use = false;
238+ spin_lock(&ccs_io_buffer_list_lock);
239+ list_for_each_entry(head, &ccs_io_buffer_list, list) {
240+ int i;
241+ head->users++;
242+ spin_unlock(&ccs_io_buffer_list_lock);
243+ mutex_lock(&head->io_sem);
244+ for (i = 0; i < CCS_MAX_IO_READ_QUEUE; i++) {
245+ const char *w = head->r.w[i];
246+ if (w < string || w > string + size)
247+ continue;
248+ in_use = true;
249+ break;
250+ }
251+ mutex_unlock(&head->io_sem);
252+ spin_lock(&ccs_io_buffer_list_lock);
253+ head->users--;
254+ if (in_use)
255+ break;
256+ }
257+ spin_unlock(&ccs_io_buffer_list_lock);
258+ return in_use;
259+}
260+
261+/**
262+ * ccs_del_transition_control - Delete members in "struct ccs_transition_control".
263+ *
264+ * @element: Pointer to "struct list_head".
265+ *
266+ * Returns nothing.
267+ */
268+static inline void ccs_del_transition_control(struct list_head *element)
269+{
270+ struct ccs_transition_control *ptr =
271+ container_of(element, typeof(*ptr), head.list);
272+ ccs_put_name(ptr->domainname);
273+ ccs_put_name(ptr->program);
274+}
275+
276+/**
277+ * ccs_del_aggregator - Delete members in "struct ccs_aggregator".
278+ *
279+ * @element: Pointer to "struct list_head".
280+ *
281+ * Returns nothing.
282+ */
283+static inline void ccs_del_aggregator(struct list_head *element)
284+{
285+ struct ccs_aggregator *ptr =
286+ container_of(element, typeof(*ptr), head.list);
287+ ccs_put_name(ptr->original_name);
288+ ccs_put_name(ptr->aggregated_name);
289+}
290+
291+/**
292+ * ccs_del_manager - Delete members in "struct ccs_manager".
293+ *
294+ * @element: Pointer to "struct list_head".
295+ *
296+ * Returns nothing.
297+ */
298+static inline void ccs_del_manager(struct list_head *element)
299+{
300+ struct ccs_manager *ptr =
301+ container_of(element, typeof(*ptr), head.list);
302+ ccs_put_name(ptr->manager);
303+}
304+
305+/**
306+ * ccs_domain_used_by_task - Check whether the given pointer is referenced by a task.
307+ *
308+ * @domain: Pointer to "struct ccs_domain_info".
309+ *
310+ * Returns true if @domain is in use, false otherwise.
311+ */
312+static bool ccs_domain_used_by_task(struct ccs_domain_info *domain)
313+{
314+ bool in_use = false;
315+ /*
316+ * Don't delete this domain if somebody is doing execve().
317+ *
318+ * Since ccs_finish_execve() first reverts ccs_domain_info and then
319+ * updates ccs_flags, we need smp_rmb() to make sure that GC first
320+ * checks ccs_flags and then checks ccs_domain_info.
321+ */
322+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
323+ int idx;
324+ rcu_read_lock();
325+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++) {
326+ struct ccs_security *ptr;
327+ struct list_head *list = &ccs_task_security_list[idx];
328+ list_for_each_entry_rcu(ptr, list, list) {
329+ if (!(ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
330+ smp_rmb(); /* Avoid out of order execution. */
331+ if (ptr->ccs_domain_info != domain)
332+ continue;
333+ }
334+ in_use = true;
335+ goto out;
336+ }
337+ }
338+ in_use = ccs_used_by_cred(domain);
339+out:
340+ rcu_read_unlock();
341+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) || defined(for_each_process_thread)
342+ struct task_struct *g;
343+ struct task_struct *t;
344+ rcu_read_lock();
345+ for_each_process_thread(g, t) {
346+ if (!(t->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
347+ smp_rmb(); /* Avoid out of order execution. */
348+ if (t->ccs_domain_info != domain)
349+ continue;
350+ }
351+ in_use = true;
352+ goto out;
353+ }
354+out:
355+ rcu_read_unlock();
356+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
357+ struct task_struct *g;
358+ struct task_struct *t;
359+ rcu_read_lock();
360+ read_lock(&tasklist_lock);
361+ do_each_thread(g, t) {
362+ if (!(t->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
363+ smp_rmb(); /* Avoid out of order execution. */
364+ if (t->ccs_domain_info != domain)
365+ continue;
366+ }
367+ in_use = true;
368+ goto out;
369+ } while_each_thread(g, t);
370+out:
371+ read_unlock(&tasklist_lock);
372+ rcu_read_unlock();
373+#else
374+ struct task_struct *p;
375+ read_lock(&tasklist_lock);
376+ for_each_process(p) {
377+ if (!(p->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
378+ smp_rmb(); /* Avoid out of order execution. */
379+ if (p->ccs_domain_info != domain)
380+ continue;
381+ }
382+ in_use = true;
383+ break;
384+ }
385+ read_unlock(&tasklist_lock);
386+#endif
387+ return in_use;
388+}
389+
390+/**
391+ * ccs_del_acl - Delete members in "struct ccs_acl_info".
392+ *
393+ * @element: Pointer to "struct list_head".
394+ *
395+ * Returns nothing.
396+ */
397+void ccs_del_acl(struct list_head *element)
398+{
399+ struct ccs_acl_info *acl = container_of(element, typeof(*acl), list);
400+ ccs_put_condition(acl->cond);
401+ switch (acl->type) {
402+ case CCS_TYPE_PATH_ACL:
403+ {
404+ struct ccs_path_acl *entry =
405+ container_of(acl, typeof(*entry), head);
406+ ccs_put_name_union(&entry->name);
407+ }
408+ break;
409+ case CCS_TYPE_PATH2_ACL:
410+ {
411+ struct ccs_path2_acl *entry =
412+ container_of(acl, typeof(*entry), head);
413+ ccs_put_name_union(&entry->name1);
414+ ccs_put_name_union(&entry->name2);
415+ }
416+ break;
417+ case CCS_TYPE_PATH_NUMBER_ACL:
418+ {
419+ struct ccs_path_number_acl *entry =
420+ container_of(acl, typeof(*entry), head);
421+ ccs_put_name_union(&entry->name);
422+ ccs_put_number_union(&entry->number);
423+ }
424+ break;
425+ case CCS_TYPE_MKDEV_ACL:
426+ {
427+ struct ccs_mkdev_acl *entry =
428+ container_of(acl, typeof(*entry), head);
429+ ccs_put_name_union(&entry->name);
430+ ccs_put_number_union(&entry->mode);
431+ ccs_put_number_union(&entry->major);
432+ ccs_put_number_union(&entry->minor);
433+ }
434+ break;
435+ case CCS_TYPE_MOUNT_ACL:
436+ {
437+ struct ccs_mount_acl *entry =
438+ container_of(acl, typeof(*entry), head);
439+ ccs_put_name_union(&entry->dev_name);
440+ ccs_put_name_union(&entry->dir_name);
441+ ccs_put_name_union(&entry->fs_type);
442+ ccs_put_number_union(&entry->flags);
443+ }
444+ break;
445+#ifdef CONFIG_CCSECURITY_NETWORK
446+ case CCS_TYPE_INET_ACL:
447+ {
448+ struct ccs_inet_acl *entry =
449+ container_of(acl, typeof(*entry), head);
450+ ccs_put_group(entry->address.group);
451+ ccs_put_number_union(&entry->port);
452+ }
453+ break;
454+ case CCS_TYPE_UNIX_ACL:
455+ {
456+ struct ccs_unix_acl *entry =
457+ container_of(acl, typeof(*entry), head);
458+ ccs_put_name_union(&entry->name);
459+ }
460+ break;
461+#endif
462+#ifdef CONFIG_CCSECURITY_MISC
463+ case CCS_TYPE_ENV_ACL:
464+ {
465+ struct ccs_env_acl *entry =
466+ container_of(acl, typeof(*entry), head);
467+ ccs_put_name(entry->env);
468+ }
469+ break;
470+#endif
471+#ifdef CONFIG_CCSECURITY_CAPABILITY
472+ case CCS_TYPE_CAPABILITY_ACL:
473+ {
474+ /* Nothing to do. */
475+ }
476+ break;
477+#endif
478+#ifdef CONFIG_CCSECURITY_IPC
479+ case CCS_TYPE_SIGNAL_ACL:
480+ {
481+ struct ccs_signal_acl *entry =
482+ container_of(acl, typeof(*entry), head);
483+ ccs_put_number_union(&entry->sig);
484+ ccs_put_name(entry->domainname);
485+ }
486+ break;
487+#endif
488+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
489+ case CCS_TYPE_AUTO_EXECUTE_HANDLER:
490+ case CCS_TYPE_DENIED_EXECUTE_HANDLER:
491+ {
492+ struct ccs_handler_acl *entry =
493+ container_of(acl, typeof(*entry), head);
494+ ccs_put_name(entry->handler);
495+ }
496+ break;
497+#endif
498+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
499+ case CCS_TYPE_AUTO_TASK_ACL:
500+ case CCS_TYPE_MANUAL_TASK_ACL:
501+ {
502+ struct ccs_task_acl *entry =
503+ container_of(acl, typeof(*entry), head);
504+ ccs_put_name(entry->domainname);
505+ }
506+ break;
507+#endif
508+ }
509+}
510+
511+/**
512+ * ccs_del_domain - Delete members in "struct ccs_domain_info".
513+ *
514+ * @element: Pointer to "struct list_head".
515+ *
516+ * Returns nothing.
517+ *
518+ * Caller holds ccs_policy_lock mutex.
519+ */
520+static inline void ccs_del_domain(struct list_head *element)
521+{
522+ struct ccs_domain_info *domain =
523+ container_of(element, typeof(*domain), list);
524+ struct ccs_acl_info *acl;
525+ struct ccs_acl_info *tmp;
526+ /*
527+ * Since this domain is referenced from neither "struct ccs_io_buffer"
528+ * nor "struct task_struct", we can delete elements without checking
529+ * for is_deleted flag.
530+ */
531+ list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
532+ ccs_del_acl(&acl->list);
533+ ccs_memory_free(acl, CCS_ID_ACL);
534+ }
535+ ccs_put_name(domain->domainname);
536+}
537+
538+/**
539+ * ccs_del_path_group - Delete members in "struct ccs_path_group".
540+ *
541+ * @element: Pointer to "struct list_head".
542+ *
543+ * Returns nothing.
544+ */
545+static inline void ccs_del_path_group(struct list_head *element)
546+{
547+ struct ccs_path_group *member =
548+ container_of(element, typeof(*member), head.list);
549+ ccs_put_name(member->member_name);
550+}
551+
552+/**
553+ * ccs_del_group - Delete "struct ccs_group".
554+ *
555+ * @element: Pointer to "struct list_head".
556+ *
557+ * Returns nothing.
558+ */
559+static inline void ccs_del_group(struct list_head *element)
560+{
561+ struct ccs_group *group =
562+ container_of(element, typeof(*group), head.list);
563+ ccs_put_name(group->group_name);
564+}
565+
566+/**
567+ * ccs_del_address_group - Delete members in "struct ccs_address_group".
568+ *
569+ * @element: Pointer to "struct list_head".
570+ *
571+ * Returns nothing.
572+ */
573+static inline void ccs_del_address_group(struct list_head *element)
574+{
575+ /* Nothing to do. */
576+}
577+
578+/**
579+ * ccs_del_number_group - Delete members in "struct ccs_number_group".
580+ *
581+ * @element: Pointer to "struct list_head".
582+ *
583+ * Returns nothing.
584+ */
585+static inline void ccs_del_number_group(struct list_head *element)
586+{
587+ /* Nothing to do. */
588+}
589+
590+/**
591+ * ccs_del_reservedport - Delete members in "struct ccs_reserved".
592+ *
593+ * @element: Pointer to "struct list_head".
594+ *
595+ * Returns nothing.
596+ */
597+static inline void ccs_del_reservedport(struct list_head *element)
598+{
599+ /* Nothing to do. */
600+}
601+
602+/**
603+ * ccs_del_condition - Delete members in "struct ccs_condition".
604+ *
605+ * @element: Pointer to "struct list_head".
606+ *
607+ * Returns nothing.
608+ */
609+void ccs_del_condition(struct list_head *element)
610+{
611+ struct ccs_condition *cond = container_of(element, typeof(*cond),
612+ head.list);
613+ const u16 condc = cond->condc;
614+ const u16 numbers_count = cond->numbers_count;
615+ const u16 names_count = cond->names_count;
616+ const u16 argc = cond->argc;
617+ const u16 envc = cond->envc;
618+ unsigned int i;
619+ const struct ccs_condition_element *condp
620+ = (const struct ccs_condition_element *) (cond + 1);
621+ struct ccs_number_union *numbers_p
622+ = (struct ccs_number_union *) (condp + condc);
623+ struct ccs_name_union *names_p
624+ = (struct ccs_name_union *) (numbers_p + numbers_count);
625+ const struct ccs_argv *argv
626+ = (const struct ccs_argv *) (names_p + names_count);
627+ const struct ccs_envp *envp
628+ = (const struct ccs_envp *) (argv + argc);
629+ for (i = 0; i < numbers_count; i++)
630+ ccs_put_number_union(numbers_p++);
631+ for (i = 0; i < names_count; i++)
632+ ccs_put_name_union(names_p++);
633+ for (i = 0; i < argc; argv++, i++)
634+ ccs_put_name(argv->value);
635+ for (i = 0; i < envc; envp++, i++) {
636+ ccs_put_name(envp->name);
637+ ccs_put_name(envp->value);
638+ }
639+ ccs_put_name(cond->transit);
640+}
641+
642+/**
643+ * ccs_del_name - Delete members in "struct ccs_name".
644+ *
645+ * @element: Pointer to "struct list_head".
646+ *
647+ * Returns nothing.
648+ */
649+static inline void ccs_del_name(struct list_head *element)
650+{
651+ /* Nothing to do. */
652+}
653+
654+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
655+
656+/**
657+ * ccs_lock - Alternative for srcu_read_lock().
658+ *
659+ * Returns index number which has to be passed to ccs_unlock().
660+ */
661+int ccs_lock(void)
662+{
663+ int idx;
664+ spin_lock(&ccs_counter_lock);
665+ idx = ccs_counter.counter_idx;
666+ ccs_counter.counter[idx]++;
667+ spin_unlock(&ccs_counter_lock);
668+ return idx;
669+}
670+
671+/**
672+ * ccs_unlock - Alternative for srcu_read_unlock().
673+ *
674+ * @idx: Index number returned by ccs_lock().
675+ *
676+ * Returns nothing.
677+ */
678+void ccs_unlock(const int idx)
679+{
680+ spin_lock(&ccs_counter_lock);
681+ ccs_counter.counter[idx]--;
682+ spin_unlock(&ccs_counter_lock);
683+}
684+
685+/**
686+ * ccs_synchronize_counter - Alternative for synchronize_srcu().
687+ *
688+ * Returns nothing.
689+ */
690+static void ccs_synchronize_counter(void)
691+{
692+ int idx;
693+ int v;
694+ /*
695+ * Change currently active counter's index. Make it visible to other
696+ * threads by doing it with ccs_counter_lock held.
697+ * This function is called by garbage collector thread, and the garbage
698+ * collector thread is exclusive. Therefore, it is guaranteed that
699+ * SRCU grace period has expired when returning from this function.
700+ */
701+ spin_lock(&ccs_counter_lock);
702+ idx = ccs_counter.counter_idx;
703+ ccs_counter.counter_idx ^= 1;
704+ v = ccs_counter.counter[idx];
705+ spin_unlock(&ccs_counter_lock);
706+ /* Wait for previously active counter to become 0. */
707+ while (v) {
708+ ssleep(1);
709+ spin_lock(&ccs_counter_lock);
710+ v = ccs_counter.counter[idx];
711+ spin_unlock(&ccs_counter_lock);
712+ }
713+}
714+
715+#endif
716+
717+/**
718+ * ccs_try_to_gc - Try to kfree() an entry.
719+ *
720+ * @type: One of values in "enum ccs_policy_id".
721+ * @element: Pointer to "struct list_head".
722+ *
723+ * Returns nothing.
724+ *
725+ * Caller holds ccs_policy_lock mutex.
726+ */
727+static void ccs_try_to_gc(const enum ccs_policy_id type,
728+ struct list_head *element)
729+{
730+ /*
731+ * __list_del_entry() guarantees that the list element became no longer
732+ * reachable from the list which the element was originally on (e.g.
733+ * ccs_domain_list). Also, synchronize_srcu() guarantees that the list
734+ * element became no longer referenced by syscall users.
735+ */
736+ __list_del_entry(element);
737+ mutex_unlock(&ccs_policy_lock);
738+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
739+ synchronize_srcu(&ccs_ss);
740+#else
741+ ccs_synchronize_counter();
742+#endif
743+ /*
744+ * However, there are two users which may still be using the list
745+ * element. We need to defer until both users forget this element.
746+ *
747+ * Don't kfree() until "struct ccs_io_buffer"->r.{domain,group,acl} and
748+ * "struct ccs_io_buffer"->w.domain forget this element.
749+ */
750+ if (ccs_struct_used_by_io_buffer(element))
751+ goto reinject;
752+ switch (type) {
753+ case CCS_ID_TRANSITION_CONTROL:
754+ ccs_del_transition_control(element);
755+ break;
756+ case CCS_ID_MANAGER:
757+ ccs_del_manager(element);
758+ break;
759+ case CCS_ID_AGGREGATOR:
760+ ccs_del_aggregator(element);
761+ break;
762+ case CCS_ID_GROUP:
763+ ccs_del_group(element);
764+ break;
765+ case CCS_ID_PATH_GROUP:
766+ ccs_del_path_group(element);
767+ break;
768+#ifdef CONFIG_CCSECURITY_NETWORK
769+ case CCS_ID_ADDRESS_GROUP:
770+ ccs_del_address_group(element);
771+ break;
772+#endif
773+ case CCS_ID_NUMBER_GROUP:
774+ ccs_del_number_group(element);
775+ break;
776+#ifdef CONFIG_CCSECURITY_PORTRESERVE
777+ case CCS_ID_RESERVEDPORT:
778+ ccs_del_reservedport(element);
779+ break;
780+#endif
781+ case CCS_ID_CONDITION:
782+ ccs_del_condition(element);
783+ break;
784+ case CCS_ID_NAME:
785+ /*
786+ * Don't kfree() until all "struct ccs_io_buffer"->r.w[] forget
787+ * this element.
788+ */
789+ if (ccs_name_used_by_io_buffer
790+ (container_of(element, typeof(struct ccs_name),
791+ head.list)->entry.name,
792+ container_of(element, typeof(struct ccs_name),
793+ head.list)->size))
794+ goto reinject;
795+ ccs_del_name(element);
796+ break;
797+ case CCS_ID_ACL:
798+ ccs_del_acl(element);
799+ break;
800+ case CCS_ID_DOMAIN:
801+ /*
802+ * Don't kfree() until all "struct task_struct" forget this
803+ * element.
804+ */
805+ if (ccs_domain_used_by_task
806+ (container_of(element, typeof(struct ccs_domain_info),
807+ list)))
808+ goto reinject;
809+ break;
810+ case CCS_MAX_POLICY:
811+ break;
812+ }
813+ mutex_lock(&ccs_policy_lock);
814+ if (type == CCS_ID_DOMAIN)
815+ ccs_del_domain(element);
816+ ccs_memory_free(element, type);
817+ return;
818+reinject:
819+ /*
820+ * We can safely reinject this element here because
821+ * (1) Appending list elements and removing list elements are protected
822+ * by ccs_policy_lock mutex.
823+ * (2) Only this function removes list elements and this function is
824+ * exclusively executed by ccs_gc_mutex mutex.
825+ * are true.
826+ */
827+ mutex_lock(&ccs_policy_lock);
828+ list_add_rcu(element, element->prev);
829+}
830+
831+/**
832+ * ccs_collect_member - Delete elements with "struct ccs_acl_head".
833+ *
834+ * @id: One of values in "enum ccs_policy_id".
835+ * @member_list: Pointer to "struct list_head".
836+ *
837+ * Returns nothing.
838+ *
839+ * Caller holds ccs_policy_lock mutex.
840+ */
841+static void ccs_collect_member(const enum ccs_policy_id id,
842+ struct list_head *member_list)
843+{
844+ struct ccs_acl_head *member;
845+ struct ccs_acl_head *tmp;
846+ list_for_each_entry_safe(member, tmp, member_list, list) {
847+ if (!member->is_deleted)
848+ continue;
849+ member->is_deleted = CCS_GC_IN_PROGRESS;
850+ ccs_try_to_gc(id, &member->list);
851+ }
852+}
853+
854+/**
855+ * ccs_collect_acl - Delete elements in "struct ccs_domain_info".
856+ *
857+ * @list: Pointer to "struct list_head".
858+ *
859+ * Returns nothing.
860+ *
861+ * Caller holds ccs_policy_lock mutex.
862+ */
863+static void ccs_collect_acl(struct list_head *list)
864+{
865+ struct ccs_acl_info *acl;
866+ struct ccs_acl_info *tmp;
867+ list_for_each_entry_safe(acl, tmp, list, list) {
868+ if (!acl->is_deleted)
869+ continue;
870+ acl->is_deleted = CCS_GC_IN_PROGRESS;
871+ ccs_try_to_gc(CCS_ID_ACL, &acl->list);
872+ }
873+}
874+
875+/**
876+ * ccs_collect_entry - Try to kfree() deleted elements.
877+ *
878+ * Returns nothing.
879+ */
880+static void ccs_collect_entry(void)
881+{
882+ int i;
883+ enum ccs_policy_id id;
884+ struct ccs_policy_namespace *ns;
885+ mutex_lock(&ccs_policy_lock);
886+ {
887+ struct ccs_domain_info *domain;
888+ struct ccs_domain_info *tmp;
889+ list_for_each_entry_safe(domain, tmp, &ccs_domain_list, list) {
890+ ccs_collect_acl(&domain->acl_info_list);
891+ if (!domain->is_deleted ||
892+ ccs_domain_used_by_task(domain))
893+ continue;
894+ ccs_try_to_gc(CCS_ID_DOMAIN, &domain->list);
895+ }
896+ }
897+ list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
898+ for (id = 0; id < CCS_MAX_POLICY; id++)
899+ ccs_collect_member(id, &ns->policy_list[id]);
900+ for (i = 0; i < CCS_MAX_ACL_GROUPS; i++)
901+ ccs_collect_acl(&ns->acl_group[i]);
902+ }
903+ {
904+ struct ccs_shared_acl_head *ptr;
905+ struct ccs_shared_acl_head *tmp;
906+ list_for_each_entry_safe(ptr, tmp, &ccs_condition_list, list) {
907+ if (atomic_read(&ptr->users) > 0)
908+ continue;
909+ atomic_set(&ptr->users, CCS_GC_IN_PROGRESS);
910+ ccs_try_to_gc(CCS_ID_CONDITION, &ptr->list);
911+ }
912+ }
913+ list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
914+ for (i = 0; i < CCS_MAX_GROUP; i++) {
915+ struct list_head *list = &ns->group_list[i];
916+ struct ccs_group *group;
917+ struct ccs_group *tmp;
918+ switch (i) {
919+ case 0:
920+ id = CCS_ID_PATH_GROUP;
921+ break;
922+ case 1:
923+ id = CCS_ID_NUMBER_GROUP;
924+ break;
925+ default:
926+#ifdef CONFIG_CCSECURITY_NETWORK
927+ id = CCS_ID_ADDRESS_GROUP;
928+#else
929+ continue;
930+#endif
931+ break;
932+ }
933+ list_for_each_entry_safe(group, tmp, list, head.list) {
934+ ccs_collect_member(id, &group->member_list);
935+ if (!list_empty(&group->member_list) ||
936+ atomic_read(&group->head.users) > 0)
937+ continue;
938+ atomic_set(&group->head.users,
939+ CCS_GC_IN_PROGRESS);
940+ ccs_try_to_gc(CCS_ID_GROUP, &group->head.list);
941+ }
942+ }
943+ }
944+ for (i = 0; i < CCS_MAX_HASH; i++) {
945+ struct list_head *list = &ccs_name_list[i];
946+ struct ccs_shared_acl_head *ptr;
947+ struct ccs_shared_acl_head *tmp;
948+ list_for_each_entry_safe(ptr, tmp, list, list) {
949+ if (atomic_read(&ptr->users) > 0)
950+ continue;
951+ atomic_set(&ptr->users, CCS_GC_IN_PROGRESS);
952+ ccs_try_to_gc(CCS_ID_NAME, &ptr->list);
953+ }
954+ }
955+ mutex_unlock(&ccs_policy_lock);
956+}
957+
958+/**
959+ * ccs_gc_thread - Garbage collector thread function.
960+ *
961+ * @unused: Unused.
962+ *
963+ * Returns 0.
964+ */
965+static int ccs_gc_thread(void *unused)
966+{
967+ /* Garbage collector thread is exclusive. */
968+ static DEFINE_MUTEX(ccs_gc_mutex);
969+ if (!mutex_trylock(&ccs_gc_mutex))
970+ goto out;
971+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
972+ /* daemonize() not needed. */
973+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
974+ daemonize("GC for CCS");
975+#else
976+ daemonize();
977+ reparent_to_init();
978+#if defined(TASK_DEAD)
979+ {
980+ struct task_struct *task = current;
981+ spin_lock_irq(&task->sighand->siglock);
982+ siginitsetinv(&task->blocked, 0);
983+ recalc_sigpending();
984+ spin_unlock_irq(&task->sighand->siglock);
985+ }
986+#else
987+ {
988+ struct task_struct *task = current;
989+ spin_lock_irq(&task->sigmask_lock);
990+ siginitsetinv(&task->blocked, 0);
991+ recalc_sigpending(task);
992+ spin_unlock_irq(&task->sigmask_lock);
993+ }
994+#endif
995+ snprintf(current->comm, sizeof(current->comm) - 1, "GC for CCS");
996+#endif
997+ ccs_collect_entry();
998+ {
999+ struct ccs_io_buffer *head;
1000+ struct ccs_io_buffer *tmp;
1001+ spin_lock(&ccs_io_buffer_list_lock);
1002+ list_for_each_entry_safe(head, tmp, &ccs_io_buffer_list,
1003+ list) {
1004+ if (head->users)
1005+ continue;
1006+ list_del(&head->list);
1007+ kfree(head->read_buf);
1008+ kfree(head->write_buf);
1009+ kfree(head);
1010+ }
1011+ spin_unlock(&ccs_io_buffer_list_lock);
1012+ }
1013+ mutex_unlock(&ccs_gc_mutex);
1014+out:
1015+ /* This acts as do_exit(0). */
1016+ return 0;
1017+}
1018+
1019+/**
1020+ * ccs_notify_gc - Register/unregister /proc/ccs/ users.
1021+ *
1022+ * @head: Pointer to "struct ccs_io_buffer".
1023+ * @is_register: True if register, false if unregister.
1024+ *
1025+ * Returns nothing.
1026+ */
1027+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register)
1028+{
1029+ bool is_write = false;
1030+ spin_lock(&ccs_io_buffer_list_lock);
1031+ if (is_register) {
1032+ head->users = 1;
1033+ list_add(&head->list, &ccs_io_buffer_list);
1034+ } else {
1035+ is_write = head->write_buf != NULL;
1036+ if (!--head->users) {
1037+ list_del(&head->list);
1038+ kfree(head->read_buf);
1039+ kfree(head->write_buf);
1040+ kfree(head);
1041+ }
1042+ }
1043+ spin_unlock(&ccs_io_buffer_list_lock);
1044+ if (is_write) {
1045+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
1046+ struct task_struct *task = kthread_create(ccs_gc_thread, NULL,
1047+ "GC for CCS");
1048+ if (!IS_ERR(task))
1049+ wake_up_process(task);
1050+#else
1051+ kernel_thread(ccs_gc_thread, NULL, 0);
1052+#endif
1053+ }
1054+}
--- tags/patches/1.0.47/internal.h (nonexistent)
+++ tags/patches/1.0.47/internal.h (revision 672)
@@ -0,0 +1,2168 @@
1+/*
2+ * security/ccsecurity/internal.h
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#ifndef _SECURITY_CCSECURITY_INTERNAL_H
10+#define _SECURITY_CCSECURITY_INTERNAL_H
11+
12+#include <linux/version.h>
13+#include <linux/types.h>
14+#include <linux/kernel.h>
15+#include <linux/string.h>
16+#include <linux/mm.h>
17+#include <linux/utime.h>
18+#include <linux/file.h>
19+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
20+#include <linux/smp_lock.h>
21+#endif
22+#include <linux/module.h>
23+#include <linux/init.h>
24+#include <linux/slab.h>
25+#include <linux/highmem.h>
26+#include <linux/poll.h>
27+#include <linux/binfmts.h>
28+#include <linux/delay.h>
29+#include <linux/sched.h>
30+#include <linux/dcache.h>
31+#include <linux/mount.h>
32+#include <linux/net.h>
33+#include <linux/inet.h>
34+#include <linux/in.h>
35+#include <linux/in6.h>
36+#include <linux/un.h>
37+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
38+#include <linux/fs.h>
39+#endif
40+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
41+#include <linux/namei.h>
42+#endif
43+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
44+#include <linux/fs_struct.h>
45+#endif
46+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
47+#include <linux/namespace.h>
48+#endif
49+#include <linux/proc_fs.h>
50+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) || defined(RHEL_MAJOR)
51+#include <linux/hash.h>
52+#endif
53+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
54+#include <linux/sysctl.h>
55+#endif
56+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 6)
57+#include <linux/kthread.h>
58+#endif
59+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
60+#include <linux/magic.h>
61+#endif
62+#include <stdarg.h>
63+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
64+#include <linux/uaccess.h>
65+#else
66+#include <asm/uaccess.h>
67+#endif
68+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
69+#include <linux/sched/signal.h>
70+#endif
71+#include <net/sock.h>
72+#include <net/af_unix.h>
73+#include <net/ip.h>
74+#include <net/ipv6.h>
75+#include <net/udp.h>
76+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
77+#include <uapi/linux/mount.h>
78+#endif
79+
80+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
81+#define sk_family family
82+#define sk_protocol protocol
83+#define sk_type type
84+#endif
85+
86+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
87+
88+/* Structure for holding "struct vfsmount *" and "struct dentry *". */
89+struct path {
90+ struct vfsmount *mnt;
91+ struct dentry *dentry;
92+};
93+
94+#endif
95+
96+#ifndef __printf
97+#define __printf(a,b) __attribute__((format(printf,a,b)))
98+#endif
99+#ifndef __packed
100+#define __packed __attribute__((__packed__))
101+#endif
102+#ifndef bool
103+#define bool _Bool
104+#endif
105+#ifndef false
106+#define false 0
107+#endif
108+#ifndef true
109+#define true 1
110+#endif
111+
112+#ifndef __user
113+#define __user
114+#endif
115+
116+#ifndef current_uid
117+#define current_uid() (current->uid)
118+#endif
119+#ifndef current_gid
120+#define current_gid() (current->gid)
121+#endif
122+#ifndef current_euid
123+#define current_euid() (current->euid)
124+#endif
125+#ifndef current_egid
126+#define current_egid() (current->egid)
127+#endif
128+#ifndef current_suid
129+#define current_suid() (current->suid)
130+#endif
131+#ifndef current_sgid
132+#define current_sgid() (current->sgid)
133+#endif
134+#ifndef current_fsuid
135+#define current_fsuid() (current->fsuid)
136+#endif
137+#ifndef current_fsgid
138+#define current_fsgid() (current->fsgid)
139+#endif
140+
141+#ifndef DEFINE_SPINLOCK
142+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
143+#endif
144+
145+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
146+#define mutex semaphore
147+#define mutex_init(mutex) init_MUTEX(mutex)
148+#define mutex_unlock(mutex) up(mutex)
149+#define mutex_lock(mutex) down(mutex)
150+#define mutex_lock_interruptible(mutex) down_interruptible(mutex)
151+#define mutex_trylock(mutex) (!down_trylock(mutex))
152+#define DEFINE_MUTEX(mutexname) DECLARE_MUTEX(mutexname)
153+#endif
154+
155+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
156+#define MS_UNBINDABLE (1<<17) /* change to unbindable */
157+#define MS_PRIVATE (1<<18) /* change to private */
158+#define MS_SLAVE (1<<19) /* change to slave */
159+#define MS_SHARED (1<<20) /* change to shared */
160+#endif
161+
162+#ifndef container_of
163+#define container_of(ptr, type, member) ({ \
164+ const typeof(((type *)0)->member) *__mptr = (ptr); \
165+ (type *)((char *)__mptr - offsetof(type, member)); })
166+#endif
167+
168+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
169+#define smp_read_barrier_depends smp_rmb
170+#endif
171+
172+#ifndef ACCESS_ONCE
173+#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
174+#endif
175+
176+#ifndef rcu_dereference
177+#define rcu_dereference(p) ({ \
178+ typeof(p) _________p1 = ACCESS_ONCE(p); \
179+ smp_read_barrier_depends(); /* see RCU */ \
180+ (_________p1); \
181+ })
182+#endif
183+
184+#ifndef rcu_assign_pointer
185+#define rcu_assign_pointer(p, v) \
186+ ({ \
187+ if (!__builtin_constant_p(v) || \
188+ ((v) != NULL)) \
189+ smp_wmb(); /* see RCU */ \
190+ (p) = (v); \
191+ })
192+#endif
193+
194+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
195+#define f_vfsmnt f_path.mnt
196+#endif
197+
198+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
199+
200+/**
201+ * kzalloc() - Allocate memory. The memory is set to zero.
202+ *
203+ * @size: Size to allocate.
204+ * @flags: GFP flags.
205+ *
206+ * Returns pointer to allocated memory on success, NULL otherwise.
207+ *
208+ * This is for compatibility with older kernels.
209+ *
210+ * Since several distributions backported kzalloc(), I define it as a macro
211+ * rather than an inlined function in order to avoid multiple definition error.
212+ */
213+#define kzalloc(size, flags) ({ \
214+ void *ret = kmalloc((size), (flags)); \
215+ if (ret) \
216+ memset(ret, 0, (size)); \
217+ ret; })
218+
219+#endif
220+
221+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
222+
223+/**
224+ * path_put - Drop reference on "struct path".
225+ *
226+ * @path: Pointer to "struct path".
227+ *
228+ * Returns nothing.
229+ *
230+ * This is for compatibility with older kernels.
231+ */
232+static inline void path_put(struct path *path)
233+{
234+ dput(path->dentry);
235+ mntput(path->mnt);
236+}
237+
238+#endif
239+
240+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
241+
242+/**
243+ * __list_add_rcu - Insert a new entry between two known consecutive entries.
244+ *
245+ * @new: Pointer to "struct list_head".
246+ * @prev: Pointer to "struct list_head".
247+ * @next: Pointer to "struct list_head".
248+ *
249+ * Returns nothing.
250+ *
251+ * This is for compatibility with older kernels.
252+ */
253+static inline void __list_add_rcu(struct list_head *new,
254+ struct list_head *prev,
255+ struct list_head *next)
256+{
257+ new->next = next;
258+ new->prev = prev;
259+ rcu_assign_pointer(prev->next, new);
260+ next->prev = new;
261+}
262+
263+/**
264+ * list_add_tail_rcu - Add a new entry to rcu-protected list.
265+ *
266+ * @new: Pointer to "struct list_head".
267+ * @head: Pointer to "struct list_head".
268+ *
269+ * Returns nothing.
270+ *
271+ * This is for compatibility with older kernels.
272+ */
273+static inline void list_add_tail_rcu(struct list_head *new,
274+ struct list_head *head)
275+{
276+ __list_add_rcu(new, head->prev, head);
277+}
278+
279+/**
280+ * list_add_rcu - Add a new entry to rcu-protected list.
281+ *
282+ * @new: Pointer to "struct list_head".
283+ * @head: Pointer to "struct list_head".
284+ *
285+ * Returns nothing.
286+ *
287+ * This is for compatibility with older kernels.
288+ */
289+static inline void list_add_rcu(struct list_head *new, struct list_head *head)
290+{
291+ __list_add_rcu(new, head, head->next);
292+}
293+
294+#endif
295+
296+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
297+
298+/**
299+ * __list_del_entry - Deletes entry from list without re-initialization.
300+ *
301+ * @entry: Pointer to "struct list_head".
302+ *
303+ * Returns nothing.
304+ *
305+ * This is for compatibility with older kernels.
306+ */
307+static inline void __list_del_entry(struct list_head *entry)
308+{
309+ __list_del(entry->prev, entry->next);
310+}
311+
312+#endif
313+
314+#ifndef list_for_each_entry_safe
315+
316+/**
317+ * list_for_each_entry_safe - Iterate over list of given type safe against removal of list entry.
318+ *
319+ * @pos: The "type *" to use as a loop cursor.
320+ * @n: Another "type *" to use as temporary storage.
321+ * @head: Pointer to "struct list_head".
322+ * @member: The name of the list_struct within the struct.
323+ *
324+ * This is for compatibility with older kernels.
325+ */
326+#define list_for_each_entry_safe(pos, n, head, member) \
327+ for (pos = list_entry((head)->next, typeof(*pos), member), \
328+ n = list_entry(pos->member.next, typeof(*pos), member); \
329+ &pos->member != (head); \
330+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
331+
332+#endif
333+
334+#ifndef srcu_dereference
335+
336+/**
337+ * srcu_dereference - Fetch SRCU-protected pointer with checking.
338+ *
339+ * @p: The pointer to read, prior to dereferencing.
340+ * @ss: Pointer to "struct srcu_struct".
341+ *
342+ * Returns @p.
343+ *
344+ * This is for compatibility with older kernels.
345+ */
346+#define srcu_dereference(p, ss) rcu_dereference(p)
347+
348+#endif
349+
350+#ifndef list_for_each_entry_srcu
351+
352+/**
353+ * list_for_each_entry_srcu - Iterate over rcu list of given type.
354+ *
355+ * @pos: The type * to use as a loop cursor.
356+ * @head: The head for your list.
357+ * @member: The name of the list_struct within the struct.
358+ * @ss: Pointer to "struct srcu_struct".
359+ *
360+ * As of 2.6.36, this macro is not provided because only TOMOYO wants it.
361+ */
362+#define list_for_each_entry_srcu(pos, head, member, ss) \
363+ for (pos = list_entry(srcu_dereference((head)->next, ss), \
364+ typeof(*pos), member); \
365+ prefetch(pos->member.next), &pos->member != (head); \
366+ pos = list_entry(srcu_dereference(pos->member.next, ss), \
367+ typeof(*pos), member))
368+
369+#endif
370+
371+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 30) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9))
372+
373+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 4, 21)
374+#undef ssleep
375+#endif
376+
377+#ifndef ssleep
378+
379+/**
380+ * ssleep - Sleep for specified seconds.
381+ *
382+ * @secs: Seconds to sleep.
383+ *
384+ * Returns nothing.
385+ *
386+ * This is for compatibility with older kernels.
387+ *
388+ * Since several distributions backported ssleep(), I define it as a macro
389+ * rather than an inlined function in order to avoid multiple definition error.
390+ */
391+#define ssleep(secs) { \
392+ set_current_state(TASK_UNINTERRUPTIBLE); \
393+ schedule_timeout((HZ * secs) + 1); \
394+ }
395+
396+#endif
397+
398+#endif
399+
400+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
401+
402+/**
403+ * from_kuid - Convert kuid_t to uid_t.
404+ *
405+ * @ns: Unused.
406+ * @uid: kuid_t value.
407+ *
408+ * Returns uid seen from init's user namespace.
409+ */
410+#define from_kuid(ns, uid) (uid)
411+
412+/**
413+ * from_kgid - Convert kgid_t to gid_t.
414+ *
415+ * @ns: Unused.
416+ * @gid: kgid_t value.
417+ *
418+ * Returns gid seen from init's user namespace.
419+ */
420+#define from_kgid(ns, gid) (gid)
421+
422+/**
423+ * uid_eq - Check whether the uids are equals or not.
424+ *
425+ * @left: Uid seen from current user namespace.
426+ * @right: Uid seen from current user namespace.
427+ *
428+ * Returns true if uid is root in init's user namespace, false otherwise.
429+ */
430+#define uid_eq(left, right) ((left) == (right))
431+#define GLOBAL_ROOT_UID 0
432+
433+#endif
434+
435+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
436+#define d_backing_inode(upper) (upper)->d_inode
437+#endif
438+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
439+#define d_is_dir(dentry) ({ struct inode *inode = d_backing_inode(dentry); \
440+ inode && S_ISDIR(inode->i_mode); })
441+#endif
442+
443+/*
444+ * TOMOYO specific part start.
445+ */
446+
447+/* Clear TOMOYO 1.8 config. */
448+#undef CONFIG_CCSECURITY
449+#undef CONFIG_CCSECURITY_LKM
450+#undef CONFIG_CCSECURITY_DISABLE_BY_DEFAULT
451+#undef CONFIG_CCSECURITY_MAX_AUDIT_LOG
452+#undef CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY
453+#undef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
454+#undef CONFIG_CCSECURITY_POLICY_LOADER
455+#undef CONFIG_CCSECURITY_ACTIVATION_TRIGGER
456+#undef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
457+#undef CONFIG_CCSECURITY_FILE_READDIR
458+#undef CONFIG_CCSECURITY_FILE_GETATTR
459+#undef CONFIG_CCSECURITY_NETWORK
460+#undef CONFIG_CCSECURITY_NETWORK_RECVMSG
461+#undef CONFIG_CCSECURITY_CAPABILITY
462+#undef CONFIG_CCSECURITY_IPC
463+#undef CONFIG_CCSECURITY_MISC
464+#undef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
465+#undef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
466+#undef CONFIG_CCSECURITY_PORTRESERVE
467+/* Define AKARI 1.0 config. */
468+#include "config.h"
469+#ifndef CONFIG_CCSECURITY
470+#define CONFIG_CCSECURITY
471+#endif
472+#ifndef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
473+#define CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
474+#endif
475+#ifndef CONFIG_CCSECURITY_MAX_AUDIT_LOG
476+#define CONFIG_CCSECURITY_MAX_AUDIT_LOG 1024
477+#endif
478+#ifndef CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY
479+#define CONFIG_CCSECURITY_MAX_ACCEPT_ENTRY 2048
480+#endif
481+#ifndef CONFIG_CCSECURITY_POLICY_LOADER
482+#define CONFIG_CCSECURITY_POLICY_LOADER "/sbin/ccs-init"
483+#endif
484+#ifndef CONFIG_CCSECURITY_ACTIVATION_TRIGGER
485+#define CONFIG_CCSECURITY_ACTIVATION_TRIGGER "/sbin/init"
486+#endif
487+#include "ccsecurity.h"
488+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
489+#error This module supports only 2.6.0 and later kernels.
490+#endif
491+#ifndef CONFIG_SECURITY
492+#error You must choose CONFIG_SECURITY=y for building this module.
493+#endif
494+#ifndef CONFIG_KALLSYMS
495+#error You must choose CONFIG_KALLSYMS=y for building this module.
496+#endif
497+#ifndef CONFIG_PROC_FS
498+#error You must choose CONFIG_PROC_FS=y for building this module.
499+#endif
500+#ifndef CONFIG_MODULES
501+#error You must choose CONFIG_MODULES=y for building this module.
502+#endif
503+
504+/* Enumeration definition for internal use. */
505+
506+/* Index numbers for Access Controls. */
507+enum ccs_acl_entry_type_index {
508+ CCS_TYPE_PATH_ACL,
509+ CCS_TYPE_PATH2_ACL,
510+ CCS_TYPE_PATH_NUMBER_ACL,
511+ CCS_TYPE_MKDEV_ACL,
512+ CCS_TYPE_MOUNT_ACL,
513+#ifdef CONFIG_CCSECURITY_MISC
514+ CCS_TYPE_ENV_ACL,
515+#endif
516+#ifdef CONFIG_CCSECURITY_CAPABILITY
517+ CCS_TYPE_CAPABILITY_ACL,
518+#endif
519+#ifdef CONFIG_CCSECURITY_NETWORK
520+ CCS_TYPE_INET_ACL,
521+ CCS_TYPE_UNIX_ACL,
522+#endif
523+#ifdef CONFIG_CCSECURITY_IPC
524+ CCS_TYPE_SIGNAL_ACL,
525+#endif
526+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
527+ CCS_TYPE_AUTO_EXECUTE_HANDLER,
528+ CCS_TYPE_DENIED_EXECUTE_HANDLER,
529+#endif
530+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
531+ CCS_TYPE_AUTO_TASK_ACL,
532+ CCS_TYPE_MANUAL_TASK_ACL,
533+#endif
534+};
535+
536+/* Index numbers for "struct ccs_condition". */
537+enum ccs_conditions_index {
538+ CCS_TASK_UID, /* current_uid() */
539+ CCS_TASK_EUID, /* current_euid() */
540+ CCS_TASK_SUID, /* current_suid() */
541+ CCS_TASK_FSUID, /* current_fsuid() */
542+ CCS_TASK_GID, /* current_gid() */
543+ CCS_TASK_EGID, /* current_egid() */
544+ CCS_TASK_SGID, /* current_sgid() */
545+ CCS_TASK_FSGID, /* current_fsgid() */
546+ CCS_TASK_PID, /* sys_getpid() */
547+ CCS_TASK_PPID, /* sys_getppid() */
548+ CCS_EXEC_ARGC, /* "struct linux_binprm *"->argc */
549+ CCS_EXEC_ENVC, /* "struct linux_binprm *"->envc */
550+ CCS_TYPE_IS_SOCKET, /* S_IFSOCK */
551+ CCS_TYPE_IS_SYMLINK, /* S_IFLNK */
552+ CCS_TYPE_IS_FILE, /* S_IFREG */
553+ CCS_TYPE_IS_BLOCK_DEV, /* S_IFBLK */
554+ CCS_TYPE_IS_DIRECTORY, /* S_IFDIR */
555+ CCS_TYPE_IS_CHAR_DEV, /* S_IFCHR */
556+ CCS_TYPE_IS_FIFO, /* S_IFIFO */
557+ CCS_MODE_SETUID, /* S_ISUID */
558+ CCS_MODE_SETGID, /* S_ISGID */
559+ CCS_MODE_STICKY, /* S_ISVTX */
560+ CCS_MODE_OWNER_READ, /* S_IRUSR */
561+ CCS_MODE_OWNER_WRITE, /* S_IWUSR */
562+ CCS_MODE_OWNER_EXECUTE, /* S_IXUSR */
563+ CCS_MODE_GROUP_READ, /* S_IRGRP */
564+ CCS_MODE_GROUP_WRITE, /* S_IWGRP */
565+ CCS_MODE_GROUP_EXECUTE, /* S_IXGRP */
566+ CCS_MODE_OTHERS_READ, /* S_IROTH */
567+ CCS_MODE_OTHERS_WRITE, /* S_IWOTH */
568+ CCS_MODE_OTHERS_EXECUTE, /* S_IXOTH */
569+ CCS_TASK_TYPE, /* ((u8) task->ccs_flags) &
570+ CCS_TASK_IS_EXECUTE_HANDLER */
571+ CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
572+ CCS_EXEC_REALPATH,
573+ CCS_SYMLINK_TARGET,
574+ CCS_PATH1_UID,
575+ CCS_PATH1_GID,
576+ CCS_PATH1_INO,
577+ CCS_PATH1_MAJOR,
578+ CCS_PATH1_MINOR,
579+ CCS_PATH1_PERM,
580+ CCS_PATH1_TYPE,
581+ CCS_PATH1_DEV_MAJOR,
582+ CCS_PATH1_DEV_MINOR,
583+ CCS_PATH2_UID,
584+ CCS_PATH2_GID,
585+ CCS_PATH2_INO,
586+ CCS_PATH2_MAJOR,
587+ CCS_PATH2_MINOR,
588+ CCS_PATH2_PERM,
589+ CCS_PATH2_TYPE,
590+ CCS_PATH2_DEV_MAJOR,
591+ CCS_PATH2_DEV_MINOR,
592+ CCS_PATH1_PARENT_UID,
593+ CCS_PATH1_PARENT_GID,
594+ CCS_PATH1_PARENT_INO,
595+ CCS_PATH1_PARENT_PERM,
596+ CCS_PATH2_PARENT_UID,
597+ CCS_PATH2_PARENT_GID,
598+ CCS_PATH2_PARENT_INO,
599+ CCS_PATH2_PARENT_PERM,
600+ CCS_MAX_CONDITION_KEYWORD,
601+ CCS_NUMBER_UNION,
602+ CCS_NAME_UNION,
603+ CCS_ARGV_ENTRY,
604+ CCS_ENVP_ENTRY,
605+};
606+
607+/* Index numbers for domain's attributes. */
608+enum ccs_domain_info_flags_index {
609+ /* Quota warnning flag. */
610+ CCS_DIF_QUOTA_WARNED,
611+ /*
612+ * This domain was unable to create a new domain at
613+ * ccs_find_next_domain() because the name of the domain to be created
614+ * was too long or it could not allocate memory.
615+ * More than one process continued execve() without domain transition.
616+ */
617+ CCS_DIF_TRANSITION_FAILED,
618+ CCS_MAX_DOMAIN_INFO_FLAGS
619+};
620+
621+/* Index numbers for audit type. */
622+enum ccs_grant_log {
623+ /* Follow profile's configuration. */
624+ CCS_GRANTLOG_AUTO,
625+ /* Do not generate grant log. */
626+ CCS_GRANTLOG_NO,
627+ /* Generate grant_log. */
628+ CCS_GRANTLOG_YES,
629+};
630+
631+/* Index numbers for group entries. */
632+enum ccs_group_id {
633+ CCS_PATH_GROUP,
634+ CCS_NUMBER_GROUP,
635+#ifdef CONFIG_CCSECURITY_NETWORK
636+ CCS_ADDRESS_GROUP,
637+#endif
638+ CCS_MAX_GROUP
639+};
640+
641+/* Index numbers for category of functionality. */
642+enum ccs_mac_category_index {
643+ CCS_MAC_CATEGORY_FILE,
644+#ifdef CONFIG_CCSECURITY_NETWORK
645+ CCS_MAC_CATEGORY_NETWORK,
646+#endif
647+#ifdef CONFIG_CCSECURITY_MISC
648+ CCS_MAC_CATEGORY_MISC,
649+#endif
650+#ifdef CONFIG_CCSECURITY_IPC
651+ CCS_MAC_CATEGORY_IPC,
652+#endif
653+#ifdef CONFIG_CCSECURITY_CAPABILITY
654+ CCS_MAC_CATEGORY_CAPABILITY,
655+#endif
656+ CCS_MAX_MAC_CATEGORY_INDEX
657+};
658+
659+/* Index numbers for functionality. */
660+enum ccs_mac_index {
661+ CCS_MAC_FILE_EXECUTE,
662+ CCS_MAC_FILE_OPEN,
663+ CCS_MAC_FILE_CREATE,
664+ CCS_MAC_FILE_UNLINK,
665+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
666+ CCS_MAC_FILE_GETATTR,
667+#endif
668+ CCS_MAC_FILE_MKDIR,
669+ CCS_MAC_FILE_RMDIR,
670+ CCS_MAC_FILE_MKFIFO,
671+ CCS_MAC_FILE_MKSOCK,
672+ CCS_MAC_FILE_TRUNCATE,
673+ CCS_MAC_FILE_SYMLINK,
674+ CCS_MAC_FILE_MKBLOCK,
675+ CCS_MAC_FILE_MKCHAR,
676+ CCS_MAC_FILE_LINK,
677+ CCS_MAC_FILE_RENAME,
678+ CCS_MAC_FILE_CHMOD,
679+ CCS_MAC_FILE_CHOWN,
680+ CCS_MAC_FILE_CHGRP,
681+ CCS_MAC_FILE_IOCTL,
682+ CCS_MAC_FILE_CHROOT,
683+ CCS_MAC_FILE_MOUNT,
684+ CCS_MAC_FILE_UMOUNT,
685+ CCS_MAC_FILE_PIVOT_ROOT,
686+#ifdef CONFIG_CCSECURITY_NETWORK
687+ CCS_MAC_NETWORK_INET_STREAM_BIND,
688+ CCS_MAC_NETWORK_INET_STREAM_LISTEN,
689+ CCS_MAC_NETWORK_INET_STREAM_CONNECT,
690+ CCS_MAC_NETWORK_INET_STREAM_ACCEPT,
691+ CCS_MAC_NETWORK_INET_DGRAM_BIND,
692+ CCS_MAC_NETWORK_INET_DGRAM_SEND,
693+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
694+ CCS_MAC_NETWORK_INET_DGRAM_RECV,
695+#endif
696+ CCS_MAC_NETWORK_INET_RAW_BIND,
697+ CCS_MAC_NETWORK_INET_RAW_SEND,
698+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
699+ CCS_MAC_NETWORK_INET_RAW_RECV,
700+#endif
701+ CCS_MAC_NETWORK_UNIX_STREAM_BIND,
702+ CCS_MAC_NETWORK_UNIX_STREAM_LISTEN,
703+ CCS_MAC_NETWORK_UNIX_STREAM_CONNECT,
704+ CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT,
705+ CCS_MAC_NETWORK_UNIX_DGRAM_BIND,
706+ CCS_MAC_NETWORK_UNIX_DGRAM_SEND,
707+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
708+ CCS_MAC_NETWORK_UNIX_DGRAM_RECV,
709+#endif
710+ CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND,
711+ CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
712+ CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
713+ CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
714+#endif
715+#ifdef CONFIG_CCSECURITY_MISC
716+ CCS_MAC_ENVIRON,
717+#endif
718+#ifdef CONFIG_CCSECURITY_IPC
719+ CCS_MAC_SIGNAL,
720+#endif
721+#ifdef CONFIG_CCSECURITY_CAPABILITY
722+ CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
723+ CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
724+ CCS_MAC_CAPABILITY_SYS_REBOOT,
725+ CCS_MAC_CAPABILITY_SYS_VHANGUP,
726+ CCS_MAC_CAPABILITY_SYS_SETTIME,
727+ CCS_MAC_CAPABILITY_SYS_NICE,
728+ CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
729+ CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
730+ CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
731+ CCS_MAC_CAPABILITY_SYS_PTRACE,
732+#endif
733+ CCS_MAX_MAC_INDEX
734+};
735+
736+/* Index numbers for /proc/ccs/stat interface. */
737+enum ccs_memory_stat_type {
738+ CCS_MEMORY_POLICY,
739+ CCS_MEMORY_AUDIT,
740+ CCS_MEMORY_QUERY,
741+ CCS_MAX_MEMORY_STAT
742+};
743+
744+/* Index numbers for access controls with one pathname and three numbers. */
745+enum ccs_mkdev_acl_index {
746+ CCS_TYPE_MKBLOCK,
747+ CCS_TYPE_MKCHAR,
748+ CCS_MAX_MKDEV_OPERATION
749+};
750+
751+/* Index numbers for operation mode. */
752+enum ccs_mode_value {
753+ CCS_CONFIG_DISABLED,
754+ CCS_CONFIG_LEARNING,
755+ CCS_CONFIG_PERMISSIVE,
756+ CCS_CONFIG_ENFORCING,
757+ CCS_CONFIG_MAX_MODE,
758+ CCS_CONFIG_WANT_REJECT_LOG = 64,
759+ CCS_CONFIG_WANT_GRANT_LOG = 128,
760+ CCS_CONFIG_USE_DEFAULT = 255,
761+};
762+
763+/* Index numbers for socket operations. */
764+enum ccs_network_acl_index {
765+ CCS_NETWORK_BIND, /* bind() operation. */
766+ CCS_NETWORK_LISTEN, /* listen() operation. */
767+ CCS_NETWORK_CONNECT, /* connect() operation. */
768+ CCS_NETWORK_ACCEPT, /* accept() operation. */
769+ CCS_NETWORK_SEND, /* send() operation. */
770+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
771+ CCS_NETWORK_RECV, /* recv() operation. */
772+#endif
773+ CCS_MAX_NETWORK_OPERATION
774+};
775+
776+/* Index numbers for access controls with two pathnames. */
777+enum ccs_path2_acl_index {
778+ CCS_TYPE_LINK,
779+ CCS_TYPE_RENAME,
780+ CCS_TYPE_PIVOT_ROOT,
781+ CCS_MAX_PATH2_OPERATION
782+};
783+
784+/* Index numbers for access controls with one pathname. */
785+enum ccs_path_acl_index {
786+ CCS_TYPE_EXECUTE,
787+ CCS_TYPE_READ,
788+ CCS_TYPE_WRITE,
789+ CCS_TYPE_APPEND,
790+ CCS_TYPE_UNLINK,
791+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
792+ CCS_TYPE_GETATTR,
793+#endif
794+ CCS_TYPE_RMDIR,
795+ CCS_TYPE_TRUNCATE,
796+ CCS_TYPE_SYMLINK,
797+ CCS_TYPE_CHROOT,
798+ CCS_TYPE_UMOUNT,
799+ CCS_MAX_PATH_OPERATION
800+};
801+
802+/* Index numbers for access controls with one pathname and one number. */
803+enum ccs_path_number_acl_index {
804+ CCS_TYPE_CREATE,
805+ CCS_TYPE_MKDIR,
806+ CCS_TYPE_MKFIFO,
807+ CCS_TYPE_MKSOCK,
808+ CCS_TYPE_IOCTL,
809+ CCS_TYPE_CHMOD,
810+ CCS_TYPE_CHOWN,
811+ CCS_TYPE_CHGRP,
812+ CCS_MAX_PATH_NUMBER_OPERATION
813+};
814+
815+/* Index numbers for stat(). */
816+enum ccs_path_stat_index {
817+ /* Do not change this order. */
818+ CCS_PATH1,
819+ CCS_PATH1_PARENT,
820+ CCS_PATH2,
821+ CCS_PATH2_PARENT,
822+ CCS_MAX_PATH_STAT
823+};
824+
825+/* Index numbers for entry type. */
826+enum ccs_policy_id {
827+#ifdef CONFIG_CCSECURITY_PORTRESERVE
828+ CCS_ID_RESERVEDPORT,
829+#endif
830+ CCS_ID_GROUP,
831+#ifdef CONFIG_CCSECURITY_NETWORK
832+ CCS_ID_ADDRESS_GROUP,
833+#endif
834+ CCS_ID_PATH_GROUP,
835+ CCS_ID_NUMBER_GROUP,
836+ CCS_ID_AGGREGATOR,
837+ CCS_ID_TRANSITION_CONTROL,
838+ CCS_ID_MANAGER,
839+ CCS_ID_CONDITION,
840+ CCS_ID_NAME,
841+ CCS_ID_ACL,
842+ CCS_ID_DOMAIN,
843+ CCS_MAX_POLICY
844+};
845+
846+/* Index numbers for /proc/ccs/stat interface. */
847+enum ccs_policy_stat_type {
848+ /* Do not change this order. */
849+ CCS_STAT_POLICY_UPDATES,
850+ CCS_STAT_POLICY_LEARNING, /* == CCS_CONFIG_LEARNING */
851+ CCS_STAT_POLICY_PERMISSIVE, /* == CCS_CONFIG_PERMISSIVE */
852+ CCS_STAT_POLICY_ENFORCING, /* == CCS_CONFIG_ENFORCING */
853+ CCS_MAX_POLICY_STAT
854+};
855+
856+/* Index numbers for profile's PREFERENCE values. */
857+enum ccs_pref_index {
858+ CCS_PREF_MAX_AUDIT_LOG,
859+ CCS_PREF_MAX_LEARNING_ENTRY,
860+ CCS_PREF_ENFORCING_PENALTY,
861+ CCS_MAX_PREF
862+};
863+
864+/* Index numbers for /proc/ccs/ interfaces. */
865+enum ccs_proc_interface_index {
866+ CCS_DOMAIN_POLICY,
867+ CCS_EXCEPTION_POLICY,
868+ CCS_PROCESS_STATUS,
869+ CCS_STAT,
870+ CCS_AUDIT,
871+ CCS_VERSION,
872+ CCS_PROFILE,
873+ CCS_QUERY,
874+ CCS_MANAGER,
875+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
876+ CCS_EXECUTE_HANDLER,
877+#endif
878+};
879+
880+/* Index numbers for special mount operations. */
881+enum ccs_special_mount {
882+ CCS_MOUNT_BIND, /* mount --bind /source /dest */
883+ CCS_MOUNT_MOVE, /* mount --move /old /new */
884+ CCS_MOUNT_REMOUNT, /* mount -o remount /dir */
885+ CCS_MOUNT_MAKE_UNBINDABLE, /* mount --make-unbindable /dir */
886+ CCS_MOUNT_MAKE_PRIVATE, /* mount --make-private /dir */
887+ CCS_MOUNT_MAKE_SLAVE, /* mount --make-slave /dir */
888+ CCS_MOUNT_MAKE_SHARED, /* mount --make-shared /dir */
889+ CCS_MAX_SPECIAL_MOUNT
890+};
891+
892+/* Index numbers for domain transition control keywords. */
893+enum ccs_transition_type {
894+ /* Do not change this order, */
895+ CCS_TRANSITION_CONTROL_NO_RESET,
896+ CCS_TRANSITION_CONTROL_RESET,
897+ CCS_TRANSITION_CONTROL_NO_INITIALIZE,
898+ CCS_TRANSITION_CONTROL_INITIALIZE,
899+ CCS_TRANSITION_CONTROL_NO_KEEP,
900+ CCS_TRANSITION_CONTROL_KEEP,
901+ CCS_MAX_TRANSITION_TYPE
902+};
903+
904+/* Index numbers for type of numeric values. */
905+enum ccs_value_type {
906+ CCS_VALUE_TYPE_INVALID,
907+ CCS_VALUE_TYPE_DECIMAL,
908+ CCS_VALUE_TYPE_OCTAL,
909+ CCS_VALUE_TYPE_HEXADECIMAL,
910+};
911+
912+/* Constants definition for internal use. */
913+
914+/*
915+ * TOMOYO uses this hash only when appending a string into the string table.
916+ * Frequency of appending strings is very low. So we don't need large (e.g.
917+ * 64k) hash size. 256 will be sufficient.
918+ */
919+#define CCS_HASH_BITS 8
920+#define CCS_MAX_HASH (1u << CCS_HASH_BITS)
921+
922+/*
923+ * TOMOYO checks only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET.
924+ * Therefore, we don't need SOCK_MAX.
925+ */
926+#define CCS_SOCK_MAX 6
927+
928+/* Size of temporary buffer for execve() operation. */
929+#define CCS_EXEC_TMPSIZE 4096
930+
931+/* Garbage collector is trying to kfree() this element. */
932+#define CCS_GC_IN_PROGRESS -1
933+
934+/* Profile number is an integer between 0 and 255. */
935+#define CCS_MAX_PROFILES 256
936+
937+/* Group number is an integer between 0 and 255. */
938+#define CCS_MAX_ACL_GROUPS 256
939+
940+/* Current thread is doing open(O_RDONLY | O_TRUNC) ? */
941+#define CCS_OPEN_FOR_READ_TRUNCATE 1
942+/* Current thread is doing open(3) ? */
943+#define CCS_OPEN_FOR_IOCTL_ONLY 2
944+/* Current thread is doing do_execve() ? */
945+#define CCS_TASK_IS_IN_EXECVE 4
946+/* Current thread is running as an execute handler program? */
947+#define CCS_TASK_IS_EXECUTE_HANDLER 8
948+/* Current thread is allowed to modify policy via /proc/ccs/ interface? */
949+#define CCS_TASK_IS_MANAGER 16
950+
951+/*
952+ * Retry this request. Returned by ccs_supervisor() if policy violation has
953+ * occurred in enforcing mode and the userspace daemon decided to retry.
954+ *
955+ * We must choose a positive value in order to distinguish "granted" (which is
956+ * 0) and "rejected" (which is a negative value) and "retry".
957+ */
958+#define CCS_RETRY_REQUEST 1
959+
960+/* The gfp flags used by TOMOYO. */
961+#define CCS_GFP_FLAGS GFP_NOFS
962+
963+/* Size of read buffer for /proc/ccs/ interface. */
964+#define CCS_MAX_IO_READ_QUEUE 64
965+
966+/* Structure definition for internal use. */
967+
968+/* Common header for holding ACL entries. */
969+struct ccs_acl_head {
970+ struct list_head list;
971+ s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
972+} __packed;
973+
974+/* Common header for shared entries. */
975+struct ccs_shared_acl_head {
976+ struct list_head list;
977+ atomic_t users;
978+} __packed;
979+
980+/* Common header for individual entries. */
981+struct ccs_acl_info {
982+ struct list_head list;
983+ struct ccs_condition *cond; /* Maybe NULL. */
984+ s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
985+ u8 type; /* One of values in "enum ccs_acl_entry_type_index". */
986+ u16 perm;
987+} __packed;
988+
989+/* Structure for holding a word. */
990+struct ccs_name_union {
991+ /* Either @filename or @group is NULL. */
992+ const struct ccs_path_info *filename;
993+ struct ccs_group *group;
994+};
995+
996+/* Structure for holding a number. */
997+struct ccs_number_union {
998+ unsigned long values[2];
999+ struct ccs_group *group; /* Maybe NULL. */
1000+ /* One of values in "enum ccs_value_type". */
1001+ u8 value_type[2];
1002+};
1003+
1004+/* Structure for holding an IP address. */
1005+struct ccs_ipaddr_union {
1006+ struct in6_addr ip[2]; /* Big endian. */
1007+ struct ccs_group *group; /* Pointer to address group. */
1008+ bool is_ipv6; /* Valid only if @group == NULL. */
1009+};
1010+
1011+/* Structure for "path_group"/"number_group"/"address_group" directive. */
1012+struct ccs_group {
1013+ struct ccs_shared_acl_head head;
1014+ /* Name of group (without leading '@'). */
1015+ const struct ccs_path_info *group_name;
1016+ /*
1017+ * List of "struct ccs_path_group" or "struct ccs_number_group" or
1018+ * "struct ccs_address_group".
1019+ */
1020+ struct list_head member_list;
1021+};
1022+
1023+/* Structure for "path_group" directive. */
1024+struct ccs_path_group {
1025+ struct ccs_acl_head head;
1026+ const struct ccs_path_info *member_name;
1027+};
1028+
1029+/* Structure for "number_group" directive. */
1030+struct ccs_number_group {
1031+ struct ccs_acl_head head;
1032+ struct ccs_number_union number;
1033+};
1034+
1035+/* Structure for "address_group" directive. */
1036+struct ccs_address_group {
1037+ struct ccs_acl_head head;
1038+ /* Structure for holding an IP address. */
1039+ struct ccs_ipaddr_union address;
1040+};
1041+
1042+/* Subset of "struct stat". Used by conditional ACL and audit logs. */
1043+struct ccs_mini_stat {
1044+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1045+ kuid_t uid;
1046+ kgid_t gid;
1047+#else
1048+ uid_t uid;
1049+ gid_t gid;
1050+#endif
1051+ ino_t ino;
1052+ umode_t mode;
1053+ dev_t dev;
1054+ dev_t rdev;
1055+};
1056+
1057+/* Structure for dumping argv[] and envp[] of "struct linux_binprm". */
1058+struct ccs_page_dump {
1059+ struct page *page; /* Previously dumped page. */
1060+ char *data; /* Contents of "page". Size is PAGE_SIZE. */
1061+};
1062+
1063+/* Structure for attribute checks in addition to pathname checks. */
1064+struct ccs_obj_info {
1065+ /* True if ccs_get_attributes() was already called, false otherwise. */
1066+ bool validate_done;
1067+ /* True if @stat[] is valid. */
1068+ bool stat_valid[CCS_MAX_PATH_STAT];
1069+ /* First pathname. Initialized with { NULL, NULL } if no path. */
1070+ struct path path1;
1071+ /* Second pathname. Initialized with { NULL, NULL } if no path. */
1072+ struct path path2;
1073+ /*
1074+ * Information on @path1, @path1's parent directory, @path2, @path2's
1075+ * parent directory.
1076+ */
1077+ struct ccs_mini_stat stat[CCS_MAX_PATH_STAT];
1078+ /*
1079+ * Content of symbolic link to be created. NULL for operations other
1080+ * than symlink().
1081+ */
1082+ struct ccs_path_info *symlink_target;
1083+};
1084+
1085+/* Structure for entries which follows "struct ccs_condition". */
1086+struct ccs_condition_element {
1087+ /*
1088+ * Left hand operand. A "struct ccs_argv" for CCS_ARGV_ENTRY, a
1089+ * "struct ccs_envp" for CCS_ENVP_ENTRY is attached to the tail
1090+ * of the array of this struct.
1091+ */
1092+ u8 left;
1093+ /*
1094+ * Right hand operand. A "struct ccs_number_union" for
1095+ * CCS_NUMBER_UNION, a "struct ccs_name_union" for CCS_NAME_UNION is
1096+ * attached to the tail of the array of this struct.
1097+ */
1098+ u8 right;
1099+ /* Equation operator. True if equals or overlaps, false otherwise. */
1100+ bool equals;
1101+};
1102+
1103+/* Structure for optional arguments. */
1104+struct ccs_condition {
1105+ struct ccs_shared_acl_head head;
1106+ u32 size; /* Memory size allocated for this entry. */
1107+ u16 condc; /* Number of conditions in this struct. */
1108+ u16 numbers_count; /* Number of "struct ccs_number_union values". */
1109+ u16 names_count; /* Number of "struct ccs_name_union names". */
1110+ u16 argc; /* Number of "struct ccs_argv". */
1111+ u16 envc; /* Number of "struct ccs_envp". */
1112+ u8 grant_log; /* One of values in "enum ccs_grant_log". */
1113+ bool exec_transit; /* True if transit is for "file execute". */
1114+ const struct ccs_path_info *transit; /* Maybe NULL. */
1115+ /*
1116+ * struct ccs_condition_element condition[condc];
1117+ * struct ccs_number_union values[numbers_count];
1118+ * struct ccs_name_union names[names_count];
1119+ * struct ccs_argv argv[argc];
1120+ * struct ccs_envp envp[envc];
1121+ */
1122+};
1123+
1124+struct ccs_execve;
1125+struct ccs_policy_namespace;
1126+
1127+/* Structure for request info. */
1128+struct ccs_request_info {
1129+ /*
1130+ * For holding parameters specific to operations which deal files.
1131+ * NULL if not dealing files.
1132+ */
1133+ struct ccs_obj_info *obj;
1134+ /*
1135+ * For holding parameters specific to execve() request.
1136+ * NULL if not dealing do_execve().
1137+ */
1138+ struct ccs_execve *ee;
1139+ /*
1140+ * For holding parameters.
1141+ * Pointers in this union are not NULL except path->matched_path.
1142+ */
1143+ union {
1144+ struct {
1145+ const struct ccs_path_info *filename;
1146+ /*
1147+ * For using wildcards at ccs_find_next_domain().
1148+ *
1149+ * The matched_acl cannot be used because it may refer
1150+ * a "struct ccs_path_acl" with ->is_group == true.
1151+ * We want to use exact "struct ccs_path_info" rather
1152+ * than "struct ccs_path_acl".
1153+ */
1154+ const struct ccs_path_info *matched_path;
1155+ /* One of values in "enum ccs_path_acl_index". */
1156+ u8 operation;
1157+ } path;
1158+ struct {
1159+ const struct ccs_path_info *filename1;
1160+ const struct ccs_path_info *filename2;
1161+ /* One of values in "enum ccs_path2_acl_index". */
1162+ u8 operation;
1163+ } path2;
1164+ struct {
1165+ const struct ccs_path_info *filename;
1166+ unsigned int mode;
1167+ unsigned int major;
1168+ unsigned int minor;
1169+ /* One of values in "enum ccs_mkdev_acl_index". */
1170+ u8 operation;
1171+ } mkdev;
1172+ struct {
1173+ const struct ccs_path_info *filename;
1174+ unsigned long number;
1175+ /*
1176+ * One of values in "enum ccs_path_number_acl_index".
1177+ */
1178+ u8 operation;
1179+ } path_number;
1180+#ifdef CONFIG_CCSECURITY_NETWORK
1181+ struct {
1182+ const u32 *address; /* Big endian. */
1183+ u16 port; /* Host endian. */
1184+ /* One of values smaller than CCS_SOCK_MAX. */
1185+ u8 protocol;
1186+ /* One of values in "enum ccs_network_acl_index". */
1187+ u8 operation;
1188+ bool is_ipv6;
1189+ } inet_network;
1190+ struct {
1191+ const struct ccs_path_info *address;
1192+ /* One of values smaller than CCS_SOCK_MAX. */
1193+ u8 protocol;
1194+ /* One of values in "enum ccs_network_acl_index". */
1195+ u8 operation;
1196+ } unix_network;
1197+#endif
1198+#ifdef CONFIG_CCSECURITY_MISC
1199+ struct {
1200+ const struct ccs_path_info *name;
1201+ } environ;
1202+#endif
1203+#ifdef CONFIG_CCSECURITY_CAPABILITY
1204+ struct {
1205+ /* One of values in "enum ccs_capability_acl_index". */
1206+ u8 operation;
1207+ } capability;
1208+#endif
1209+#ifdef CONFIG_CCSECURITY_IPC
1210+ struct {
1211+ const char *dest_pattern;
1212+ int sig;
1213+ } signal;
1214+#endif
1215+ struct {
1216+ const struct ccs_path_info *type;
1217+ const struct ccs_path_info *dir;
1218+ const struct ccs_path_info *dev;
1219+ unsigned long flags;
1220+ int need_dev;
1221+ } mount;
1222+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
1223+ struct {
1224+ const struct ccs_path_info *domainname;
1225+ } task;
1226+#endif
1227+ } param;
1228+ /*
1229+ * For updating current->ccs_domain_info at ccs_update_task_domain().
1230+ * Initialized to NULL at ccs_init_request_info().
1231+ * Matching "struct ccs_acl_info" is copied if access request was
1232+ * granted. Re-initialized to NULL at ccs_update_task_domain().
1233+ */
1234+ struct ccs_acl_info *matched_acl;
1235+ u8 param_type; /* One of values in "enum ccs_acl_entry_type_index". */
1236+ bool granted; /* True if granted, false otherwise. */
1237+ /* True if current thread should not be carried sleep penalty. */
1238+ bool dont_sleep_on_enforce_error;
1239+ /*
1240+ * For counting number of retries made for this request.
1241+ * This counter is incremented whenever ccs_supervisor() returned
1242+ * CCS_RETRY_REQUEST.
1243+ */
1244+ u8 retry;
1245+ /*
1246+ * For holding profile number used for this request.
1247+ * One of values between 0 and CCS_MAX_PROFILES - 1.
1248+ */
1249+ u8 profile;
1250+ /*
1251+ * For holding operation mode used for this request.
1252+ * One of CCS_CONFIG_DISABLED, CCS_CONFIG_LEARNING,
1253+ * CCS_CONFIG_PERMISSIVE, CCS_CONFIG_ENFORCING.
1254+ */
1255+ u8 mode;
1256+ /*
1257+ * For holding operation index used for this request.
1258+ * Used by ccs_init_request_info() / ccs_get_mode() /
1259+ * ccs_write_log(). One of values in "enum ccs_mac_index".
1260+ */
1261+ u8 type;
1262+};
1263+
1264+/* Structure for holding a token. */
1265+struct ccs_path_info {
1266+ const char *name;
1267+ u32 hash; /* = full_name_hash(name, strlen(name)) */
1268+ u16 total_len; /* = strlen(name) */
1269+ u16 const_len; /* = ccs_const_part_length(name) */
1270+ bool is_dir; /* = ccs_strendswith(name, "/") */
1271+ bool is_patterned; /* = const_len < total_len */
1272+};
1273+
1274+/* Structure for execve() operation. */
1275+struct ccs_execve {
1276+ struct ccs_request_info r;
1277+ struct ccs_obj_info obj;
1278+ struct linux_binprm *bprm;
1279+ struct ccs_domain_info *previous_domain;
1280+ const struct ccs_path_info *transition;
1281+ /* For execute_handler */
1282+ const struct ccs_path_info *handler;
1283+ char *handler_path; /* = kstrdup(handler->name, CCS_GFP_FLAGS) */
1284+ /* For dumping argv[] and envp[]. */
1285+ struct ccs_page_dump dump;
1286+ /* For temporary use. */
1287+ char *tmp; /* Size is CCS_EXEC_TMPSIZE bytes */
1288+};
1289+
1290+/* Structure for domain information. */
1291+struct ccs_domain_info {
1292+ struct list_head list;
1293+ struct list_head acl_info_list;
1294+ /* Name of this domain. Never NULL. */
1295+ const struct ccs_path_info *domainname;
1296+ /* Namespace for this domain. Never NULL. */
1297+ struct ccs_policy_namespace *ns;
1298+ /* Group numbers to use. */
1299+ unsigned long group[CCS_MAX_ACL_GROUPS / BITS_PER_LONG];
1300+ u8 profile; /* Profile number to use. */
1301+ bool is_deleted; /* Delete flag. */
1302+ bool flags[CCS_MAX_DOMAIN_INFO_FLAGS];
1303+};
1304+
1305+/*
1306+ * Structure for "reset_domain"/"no_reset_domain"/"initialize_domain"/
1307+ * "no_initialize_domain"/"keep_domain"/"no_keep_domain" keyword.
1308+ */
1309+struct ccs_transition_control {
1310+ struct ccs_acl_head head;
1311+ u8 type; /* One of values in "enum ccs_transition_type" */
1312+ bool is_last_name; /* True if the domainname is ccs_last_word(). */
1313+ const struct ccs_path_info *domainname; /* Maybe NULL */
1314+ const struct ccs_path_info *program; /* Maybe NULL */
1315+};
1316+
1317+/* Structure for "aggregator" keyword. */
1318+struct ccs_aggregator {
1319+ struct ccs_acl_head head;
1320+ const struct ccs_path_info *original_name;
1321+ const struct ccs_path_info *aggregated_name;
1322+};
1323+
1324+/* Structure for "deny_autobind" keyword. */
1325+struct ccs_reserved {
1326+ struct ccs_acl_head head;
1327+ struct ccs_number_union port;
1328+};
1329+
1330+/* Structure for policy manager. */
1331+struct ccs_manager {
1332+ struct ccs_acl_head head;
1333+ /* A path to program or a domainname. */
1334+ const struct ccs_path_info *manager;
1335+};
1336+
1337+/* Structure for argv[]. */
1338+struct ccs_argv {
1339+ unsigned long index;
1340+ const struct ccs_path_info *value;
1341+ bool is_not;
1342+};
1343+
1344+/* Structure for envp[]. */
1345+struct ccs_envp {
1346+ const struct ccs_path_info *name;
1347+ const struct ccs_path_info *value;
1348+ bool is_not;
1349+};
1350+
1351+/*
1352+ * Structure for "task auto_execute_handler" and "task denied_execute_handler"
1353+ * directive.
1354+ *
1355+ * If "task auto_execute_handler" directive exists and the current process is
1356+ * not an execute handler, all execve() requests are replaced by execve()
1357+ * requests of a program specified by "task auto_execute_handler" directive.
1358+ * If the current process is an execute handler, "task auto_execute_handler"
1359+ * and "task denied_execute_handler" directives are ignored.
1360+ * The program specified by "task execute_handler" validates execve()
1361+ * parameters and executes the original execve() requests if appropriate.
1362+ *
1363+ * "task denied_execute_handler" directive is used only when execve() request
1364+ * was rejected in enforcing mode (i.e. CONFIG::file::execute={ mode=enforcing
1365+ * }). The program specified by "task denied_execute_handler" does whatever it
1366+ * wants to do (e.g. silently terminate, change firewall settings, redirect the
1367+ * user to honey pot etc.).
1368+ */
1369+struct ccs_handler_acl {
1370+ struct ccs_acl_info head; /* type = CCS_TYPE_*_EXECUTE_HANDLER */
1371+ const struct ccs_path_info *handler; /* Pointer to single pathname. */
1372+};
1373+
1374+/*
1375+ * Structure for "task auto_domain_transition" and
1376+ * "task manual_domain_transition" directive.
1377+ */
1378+struct ccs_task_acl {
1379+ struct ccs_acl_info head; /* type = CCS_TYPE_*_TASK_ACL */
1380+ /* Pointer to domainname. */
1381+ const struct ccs_path_info *domainname;
1382+};
1383+
1384+/*
1385+ * Structure for "file execute", "file read", "file write", "file append",
1386+ * "file unlink", "file getattr", "file rmdir", "file truncate",
1387+ * "file symlink", "file chroot" and "file unmount" directive.
1388+ */
1389+struct ccs_path_acl {
1390+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
1391+ struct ccs_name_union name;
1392+};
1393+
1394+/*
1395+ * Structure for "file rename", "file link" and "file pivot_root" directive.
1396+ */
1397+struct ccs_path2_acl {
1398+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
1399+ struct ccs_name_union name1;
1400+ struct ccs_name_union name2;
1401+};
1402+
1403+/*
1404+ * Structure for "file create", "file mkdir", "file mkfifo", "file mksock",
1405+ * "file ioctl", "file chmod", "file chown" and "file chgrp" directive.
1406+ */
1407+struct ccs_path_number_acl {
1408+ struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */
1409+ struct ccs_name_union name;
1410+ struct ccs_number_union number;
1411+};
1412+
1413+/* Structure for "file mkblock" and "file mkchar" directive. */
1414+struct ccs_mkdev_acl {
1415+ struct ccs_acl_info head; /* type = CCS_TYPE_MKDEV_ACL */
1416+ struct ccs_name_union name;
1417+ struct ccs_number_union mode;
1418+ struct ccs_number_union major;
1419+ struct ccs_number_union minor;
1420+};
1421+
1422+/* Structure for "file mount" directive. */
1423+struct ccs_mount_acl {
1424+ struct ccs_acl_info head; /* type = CCS_TYPE_MOUNT_ACL */
1425+ struct ccs_name_union dev_name;
1426+ struct ccs_name_union dir_name;
1427+ struct ccs_name_union fs_type;
1428+ struct ccs_number_union flags;
1429+};
1430+
1431+/* Structure for "misc env" directive in domain policy. */
1432+struct ccs_env_acl {
1433+ struct ccs_acl_info head; /* type = CCS_TYPE_ENV_ACL */
1434+ const struct ccs_path_info *env; /* environment variable */
1435+};
1436+
1437+/* Structure for "capability" directive. */
1438+struct ccs_capability_acl {
1439+ struct ccs_acl_info head; /* type = CCS_TYPE_CAPABILITY_ACL */
1440+ u8 operation; /* One of values in "enum ccs_capability_acl_index". */
1441+};
1442+
1443+/* Structure for "ipc signal" directive. */
1444+struct ccs_signal_acl {
1445+ struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */
1446+ struct ccs_number_union sig;
1447+ /* Pointer to destination pattern. */
1448+ const struct ccs_path_info *domainname;
1449+};
1450+
1451+/* Structure for "network inet" directive. */
1452+struct ccs_inet_acl {
1453+ struct ccs_acl_info head; /* type = CCS_TYPE_INET_ACL */
1454+ u8 protocol;
1455+ struct ccs_ipaddr_union address;
1456+ struct ccs_number_union port;
1457+};
1458+
1459+/* Structure for "network unix" directive. */
1460+struct ccs_unix_acl {
1461+ struct ccs_acl_info head; /* type = CCS_TYPE_UNIX_ACL */
1462+ u8 protocol;
1463+ struct ccs_name_union name;
1464+};
1465+
1466+/* Structure for holding string data. */
1467+struct ccs_name {
1468+ struct ccs_shared_acl_head head;
1469+ int size; /* Memory size allocated for this entry. */
1470+ struct ccs_path_info entry;
1471+};
1472+
1473+/* Structure for holding a line from /proc/ccs/ interface. */
1474+struct ccs_acl_param {
1475+ char *data; /* Unprocessed data. */
1476+ struct list_head *list; /* List to add or remove. */
1477+ struct ccs_policy_namespace *ns; /* Namespace to use. */
1478+ bool is_delete; /* True if it is a delete request. */
1479+ union ccs_acl_union {
1480+ struct ccs_acl_info acl_info;
1481+ struct ccs_handler_acl handler_acl;
1482+ struct ccs_task_acl task_acl;
1483+ struct ccs_path_acl path_acl;
1484+ struct ccs_path2_acl path2_acl;
1485+ struct ccs_path_number_acl path_number_acl;
1486+ struct ccs_mkdev_acl mkdev_acl;
1487+ struct ccs_mount_acl mount_acl;
1488+ struct ccs_env_acl env_acl;
1489+ struct ccs_capability_acl capability_acl;
1490+ struct ccs_signal_acl signal_acl;
1491+ struct ccs_inet_acl inet_acl;
1492+ struct ccs_unix_acl unix_acl;
1493+ /**/
1494+ struct ccs_acl_head acl_head;
1495+ struct ccs_transition_control transition_control;
1496+ struct ccs_aggregator aggregator;
1497+ struct ccs_reserved reserved;
1498+ struct ccs_manager manager;
1499+ struct ccs_path_group path_group;
1500+ struct ccs_number_group number_group;
1501+ struct ccs_address_group address_group;
1502+ } e;
1503+};
1504+
1505+/* Structure for reading/writing policy via /proc/ccs/ interfaces. */
1506+struct ccs_io_buffer {
1507+ /* Exclusive lock for this structure. */
1508+ struct mutex io_sem;
1509+ char __user *read_user_buf;
1510+ size_t read_user_buf_avail;
1511+ struct {
1512+ struct list_head *ns;
1513+ struct list_head *domain;
1514+ struct list_head *group;
1515+ struct list_head *acl;
1516+ size_t avail;
1517+ unsigned int step;
1518+ unsigned int query_index;
1519+ u16 index;
1520+ u16 cond_index;
1521+ u8 acl_group_index;
1522+ u8 cond_step;
1523+ u8 bit;
1524+ u8 w_pos;
1525+ bool eof;
1526+ bool print_this_domain_only;
1527+ bool print_transition_related_only;
1528+ bool print_cond_part;
1529+ const char *w[CCS_MAX_IO_READ_QUEUE];
1530+ } r;
1531+ struct {
1532+ struct ccs_policy_namespace *ns;
1533+ struct ccs_domain_info *domain;
1534+ size_t avail;
1535+ bool is_delete;
1536+ } w;
1537+ /* Buffer for reading. */
1538+ char *read_buf;
1539+ /* Size of read buffer. */
1540+ size_t readbuf_size;
1541+ /* Buffer for writing. */
1542+ char *write_buf;
1543+ /* Size of write buffer. */
1544+ size_t writebuf_size;
1545+ /* Type of interface. */
1546+ enum ccs_proc_interface_index type;
1547+ /* Users counter protected by ccs_io_buffer_list_lock. */
1548+ u8 users;
1549+ /* List for telling GC not to kfree() elements. */
1550+ struct list_head list;
1551+};
1552+
1553+/* Structure for /proc/ccs/profile interface. */
1554+struct ccs_profile {
1555+ const struct ccs_path_info *comment;
1556+ u8 default_config;
1557+ u8 config[CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX];
1558+ unsigned int pref[CCS_MAX_PREF];
1559+};
1560+
1561+/* Structure for representing YYYY/MM/DD hh/mm/ss. */
1562+struct ccs_time {
1563+ u16 year;
1564+ u8 month;
1565+ u8 day;
1566+ u8 hour;
1567+ u8 min;
1568+ u8 sec;
1569+};
1570+
1571+/* Structure for policy namespace. */
1572+struct ccs_policy_namespace {
1573+ /* Profile table. Memory is allocated as needed. */
1574+ struct ccs_profile *profile_ptr[CCS_MAX_PROFILES];
1575+ /* List of "struct ccs_group". */
1576+ struct list_head group_list[CCS_MAX_GROUP];
1577+ /* List of policy. */
1578+ struct list_head policy_list[CCS_MAX_POLICY];
1579+ /* The global ACL referred by "use_group" keyword. */
1580+ struct list_head acl_group[CCS_MAX_ACL_GROUPS];
1581+ /* List for connecting to ccs_namespace_list list. */
1582+ struct list_head namespace_list;
1583+ /* Profile version. Currently only 20200505 is supported. */
1584+ unsigned int profile_version;
1585+ /* Name of this namespace (e.g. "<kernel>", "</usr/sbin/httpd>" ). */
1586+ const char *name;
1587+};
1588+
1589+/* Prototype definition for "struct ccsecurity_operations". */
1590+
1591+void __init ccs_permission_init(void);
1592+void __init ccs_mm_init(void);
1593+
1594+/* Prototype definition for internal use. */
1595+
1596+bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
1597+ struct ccs_page_dump *dump);
1598+bool ccs_memory_ok(const void *ptr, const unsigned int size);
1599+char *ccs_encode(const char *str);
1600+char *ccs_encode2(const char *str, int str_len);
1601+char *ccs_realpath(const struct path *path);
1602+const char *ccs_get_exe(void);
1603+const struct ccs_path_info *ccs_get_name(const char *name);
1604+int ccs_audit_log(struct ccs_request_info *r);
1605+int ccs_check_acl(struct ccs_request_info *r);
1606+int ccs_init_request_info(struct ccs_request_info *r, const u8 index);
1607+struct ccs_domain_info *ccs_assign_domain(const char *domainname,
1608+ const bool transit);
1609+u8 ccs_get_config(const u8 profile, const u8 index);
1610+void *ccs_commit_ok(void *data, const unsigned int size);
1611+void ccs_del_acl(struct list_head *element);
1612+void ccs_del_condition(struct list_head *element);
1613+void ccs_fill_path_info(struct ccs_path_info *ptr);
1614+void ccs_get_attributes(struct ccs_obj_info *obj);
1615+void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register);
1616+void ccs_transition_failed(const char *domainname);
1617+void ccs_warn_oom(const char *function);
1618+void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...)
1619+ __printf(2, 3);
1620+
1621+/* Variable definition for internal use. */
1622+
1623+extern bool ccs_policy_loaded;
1624+extern const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS];
1625+extern const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX];
1626+extern const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION];
1627+extern const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION];
1628+extern const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION];
1629+extern struct ccs_domain_info ccs_kernel_domain;
1630+extern struct list_head ccs_condition_list;
1631+extern struct list_head ccs_domain_list;
1632+extern struct list_head ccs_name_list[CCS_MAX_HASH];
1633+extern struct list_head ccs_namespace_list;
1634+extern struct mutex ccs_policy_lock;
1635+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1636+extern struct srcu_struct ccs_ss;
1637+#endif
1638+extern unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT];
1639+extern unsigned int ccs_memory_used[CCS_MAX_MEMORY_STAT];
1640+
1641+/* Inlined functions for internal use. */
1642+
1643+/**
1644+ * ccs_pathcmp - strcmp() for "struct ccs_path_info" structure.
1645+ *
1646+ * @a: Pointer to "struct ccs_path_info".
1647+ * @b: Pointer to "struct ccs_path_info".
1648+ *
1649+ * Returns true if @a != @b, false otherwise.
1650+ */
1651+static inline bool ccs_pathcmp(const struct ccs_path_info *a,
1652+ const struct ccs_path_info *b)
1653+{
1654+ return a->hash != b->hash || strcmp(a->name, b->name);
1655+}
1656+
1657+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1658+
1659+/**
1660+ * ccs_read_lock - Take lock for protecting policy.
1661+ *
1662+ * Returns index number for ccs_read_unlock().
1663+ */
1664+static inline int ccs_read_lock(void)
1665+{
1666+ return srcu_read_lock(&ccs_ss);
1667+}
1668+
1669+/**
1670+ * ccs_read_unlock - Release lock for protecting policy.
1671+ *
1672+ * @idx: Index number returned by ccs_read_lock().
1673+ *
1674+ * Returns nothing.
1675+ */
1676+static inline void ccs_read_unlock(const int idx)
1677+{
1678+ srcu_read_unlock(&ccs_ss, idx);
1679+}
1680+
1681+#else
1682+
1683+int ccs_lock(void);
1684+void ccs_unlock(const int idx);
1685+
1686+/**
1687+ * ccs_read_lock - Take lock for protecting policy.
1688+ *
1689+ * Returns index number for ccs_read_unlock().
1690+ */
1691+static inline int ccs_read_lock(void)
1692+{
1693+ return ccs_lock();
1694+}
1695+
1696+/**
1697+ * ccs_read_unlock - Release lock for protecting policy.
1698+ *
1699+ * @idx: Index number returned by ccs_read_lock().
1700+ *
1701+ * Returns nothing.
1702+ */
1703+static inline void ccs_read_unlock(const int idx)
1704+{
1705+ ccs_unlock(idx);
1706+}
1707+
1708+#endif
1709+
1710+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
1711+
1712+/**
1713+ * ccs_tasklist_lock - Take lock for reading list of "struct task_struct".
1714+ *
1715+ * Returns nothing.
1716+ */
1717+static inline void ccs_tasklist_lock(void)
1718+{
1719+ rcu_read_lock();
1720+}
1721+
1722+/**
1723+ * ccs_tasklist_unlock - Release lock for reading list of "struct task_struct".
1724+ *
1725+ * Returns nothing.
1726+ */
1727+static inline void ccs_tasklist_unlock(void)
1728+{
1729+ rcu_read_unlock();
1730+}
1731+
1732+#else
1733+
1734+/**
1735+ * ccs_tasklist_lock - Take lock for reading list of "struct task_struct".
1736+ *
1737+ * Returns nothing.
1738+ */
1739+static inline void ccs_tasklist_lock(void)
1740+{
1741+ read_lock(&tasklist_lock);
1742+}
1743+
1744+/**
1745+ * ccs_tasklist_unlock - Release lock for reading list of "struct task_struct".
1746+ *
1747+ * Returns nothing.
1748+ */
1749+static inline void ccs_tasklist_unlock(void)
1750+{
1751+ read_unlock(&tasklist_lock);
1752+}
1753+
1754+#endif
1755+
1756+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1757+
1758+/**
1759+ * ccs_sys_getppid - Copy of getppid().
1760+ *
1761+ * Returns parent process's PID.
1762+ *
1763+ * Alpha does not have getppid() defined. To be able to build this module on
1764+ * Alpha, I have to copy getppid() from kernel/timer.c.
1765+ */
1766+static inline pid_t ccs_sys_getppid(void)
1767+{
1768+ pid_t pid;
1769+ rcu_read_lock();
1770+ pid = task_tgid_vnr(rcu_dereference(current->real_parent));
1771+ rcu_read_unlock();
1772+ return pid;
1773+}
1774+
1775+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1776+
1777+/**
1778+ * ccs_sys_getppid - Copy of getppid().
1779+ *
1780+ * Returns parent process's PID.
1781+ *
1782+ * This function was rewritten to use RCU in 2.6.16.34. However, distributors
1783+ * which use earlier kernels (e.g. 2.6.8/2.6.9) did not backport the bugfix.
1784+ * Therefore, I'm using code for 2.6.16.34 for earlier kernels.
1785+ */
1786+static inline pid_t ccs_sys_getppid(void)
1787+{
1788+ pid_t pid;
1789+ rcu_read_lock();
1790+#if (defined(RHEL_MAJOR) && RHEL_MAJOR == 5) || (defined(AX_MAJOR) && AX_MAJOR == 3)
1791+ pid = rcu_dereference(current->parent)->tgid;
1792+#elif defined(CONFIG_UTRACE)
1793+ /*
1794+ * RHEL 5.0 kernel does not have RHEL_MAJOR/RHEL_MINOR defined.
1795+ * Assume RHEL 5.0 if CONFIG_UTRACE is defined.
1796+ */
1797+ pid = rcu_dereference(current->parent)->tgid;
1798+#else
1799+ pid = rcu_dereference(current->real_parent)->tgid;
1800+#endif
1801+ rcu_read_unlock();
1802+ return pid;
1803+}
1804+
1805+#else
1806+
1807+/**
1808+ * ccs_sys_getppid - Copy of getppid().
1809+ *
1810+ * Returns parent process's PID.
1811+ *
1812+ * I can't use code for 2.6.16.34 for 2.4 kernels because 2.4 kernels does not
1813+ * have RCU. Therefore, I'm using pessimistic lock (i.e. tasklist_lock
1814+ * spinlock).
1815+ */
1816+static inline pid_t ccs_sys_getppid(void)
1817+{
1818+ pid_t pid;
1819+ read_lock(&tasklist_lock);
1820+#ifdef TASK_DEAD
1821+ pid = current->group_leader->real_parent->tgid;
1822+#else
1823+ pid = current->p_opptr->pid;
1824+#endif
1825+ read_unlock(&tasklist_lock);
1826+ return pid;
1827+}
1828+
1829+#endif
1830+
1831+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1832+
1833+/**
1834+ * ccs_sys_getpid - Copy of getpid().
1835+ *
1836+ * Returns current thread's PID.
1837+ *
1838+ * Alpha does not have getpid() defined. To be able to build this module on
1839+ * Alpha, I have to copy getpid() from kernel/timer.c.
1840+ */
1841+static inline pid_t ccs_sys_getpid(void)
1842+{
1843+ return task_tgid_vnr(current);
1844+}
1845+
1846+#else
1847+
1848+/**
1849+ * ccs_sys_getpid - Copy of getpid().
1850+ *
1851+ * Returns current thread's PID.
1852+ */
1853+static inline pid_t ccs_sys_getpid(void)
1854+{
1855+ return current->tgid;
1856+}
1857+
1858+#endif
1859+
1860+/**
1861+ * ccs_get_mode - Get mode for specified functionality.
1862+ *
1863+ * @profile: Profile number.
1864+ * @index: Functionality number.
1865+ *
1866+ * Returns mode.
1867+ */
1868+static inline u8 ccs_get_mode(const u8 profile, const u8 index)
1869+{
1870+ return ccs_get_config(profile, index) & (CCS_CONFIG_MAX_MODE - 1);
1871+}
1872+
1873+#if defined(CONFIG_SLOB)
1874+
1875+/**
1876+ * ccs_round2 - Round up to power of 2 for calculating memory usage.
1877+ *
1878+ * @size: Size to be rounded up.
1879+ *
1880+ * Returns @size.
1881+ *
1882+ * Since SLOB does not round up, this function simply returns @size.
1883+ */
1884+static inline int ccs_round2(size_t size)
1885+{
1886+ return size;
1887+}
1888+
1889+#else
1890+
1891+/**
1892+ * ccs_round2 - Round up to power of 2 for calculating memory usage.
1893+ *
1894+ * @size: Size to be rounded up.
1895+ *
1896+ * Returns rounded size.
1897+ *
1898+ * Strictly speaking, SLAB may be able to allocate (e.g.) 96 bytes instead of
1899+ * (e.g.) 128 bytes.
1900+ */
1901+static inline int ccs_round2(size_t size)
1902+{
1903+#if PAGE_SIZE == 4096
1904+ size_t bsize = 32;
1905+#else
1906+ size_t bsize = 64;
1907+#endif
1908+ if (!size)
1909+ return 0;
1910+ while (size > bsize)
1911+ bsize <<= 1;
1912+ return bsize;
1913+}
1914+
1915+#endif
1916+
1917+/**
1918+ * ccs_put_condition - Drop reference on "struct ccs_condition".
1919+ *
1920+ * @cond: Pointer to "struct ccs_condition". Maybe NULL.
1921+ *
1922+ * Returns nothing.
1923+ */
1924+static inline void ccs_put_condition(struct ccs_condition *cond)
1925+{
1926+ if (cond)
1927+ atomic_dec(&cond->head.users);
1928+}
1929+
1930+/**
1931+ * ccs_put_group - Drop reference on "struct ccs_group".
1932+ *
1933+ * @group: Pointer to "struct ccs_group". Maybe NULL.
1934+ *
1935+ * Returns nothing.
1936+ */
1937+static inline void ccs_put_group(struct ccs_group *group)
1938+{
1939+ if (group)
1940+ atomic_dec(&group->head.users);
1941+}
1942+
1943+/**
1944+ * ccs_put_name - Drop reference on "struct ccs_name".
1945+ *
1946+ * @name: Pointer to "struct ccs_path_info". Maybe NULL.
1947+ *
1948+ * Returns nothing.
1949+ */
1950+static inline void ccs_put_name(const struct ccs_path_info *name)
1951+{
1952+ if (name)
1953+ atomic_dec(&container_of(name, struct ccs_name, entry)->
1954+ head.users);
1955+}
1956+
1957+/* For importing variables and functions. */
1958+extern struct ccsecurity_exports ccsecurity_exports;
1959+
1960+#ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
1961+
1962+/*
1963+ * Structure for holding "struct ccs_domain_info *" and "struct ccs_execve *"
1964+ * and "u32 ccs_flags" for each "struct task_struct".
1965+ *
1966+ * "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct"
1967+ * are maintained outside that "struct task_struct". Therefore, ccs_security
1968+ * != task_struct . This keeps KABI for distributor's prebuilt kernels but
1969+ * entails slow access.
1970+ *
1971+ * Memory for this structure is allocated when current thread tries to access
1972+ * it. Therefore, if memory allocation failed, current thread will be killed by
1973+ * SIGKILL. Note that if current->pid == 1, sending SIGKILL won't work.
1974+ */
1975+struct ccs_security {
1976+ struct list_head list;
1977+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29) || LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1978+ const struct task_struct *task;
1979+#else
1980+ struct pid *pid; /* Maybe NULL. */
1981+ const struct cred *cred; /* Maybe NULL. */
1982+#endif
1983+ struct ccs_domain_info *ccs_domain_info;
1984+ u32 ccs_flags;
1985+ struct ccs_execve *ee; /* Maybe NULL. */
1986+ struct rcu_head rcu;
1987+};
1988+
1989+void __init ccs_main_init(void);
1990+bool ccs_used_by_cred(const struct ccs_domain_info *domain);
1991+int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep);
1992+void ccs_finish_execve(int retval, struct ccs_execve *ee);
1993+void ccs_load_policy(const char *filename);
1994+#ifndef CONFIG_AKARI_TRACE_EXECVE_COUNT
1995+#define ccs_audit_alloc_execve(ee) do { } while (0)
1996+#define ccs_audit_free_execve(ee, is_current) do { } while (0)
1997+#else
1998+void ccs_audit_alloc_execve(const struct ccs_execve * const ee);
1999+void ccs_audit_free_execve(const struct ccs_execve * const ee,
2000+ const bool is_current);
2001+#endif
2002+
2003+#define CCS_TASK_SECURITY_HASH_BITS 12
2004+#define CCS_MAX_TASK_SECURITY_HASH (1u << CCS_TASK_SECURITY_HASH_BITS)
2005+extern struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
2006+
2007+struct ccs_security *ccs_find_task_security(const struct task_struct *task);
2008+
2009+/**
2010+ * ccs_current_security - Get "struct ccs_security" for current thread.
2011+ *
2012+ * Returns pointer to "struct ccs_security" for current thread.
2013+ */
2014+static inline struct ccs_security *ccs_current_security(void)
2015+{
2016+ return ccs_find_task_security(current);
2017+}
2018+
2019+/**
2020+ * ccs_task_domain - Get "struct ccs_domain_info" for specified thread.
2021+ *
2022+ * @task: Pointer to "struct task_struct".
2023+ *
2024+ * Returns pointer to "struct ccs_security" for specified thread.
2025+ */
2026+static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
2027+{
2028+ struct ccs_domain_info *domain;
2029+ rcu_read_lock();
2030+ domain = ccs_find_task_security(task)->ccs_domain_info;
2031+ rcu_read_unlock();
2032+ return domain;
2033+}
2034+
2035+/**
2036+ * ccs_current_domain - Get "struct ccs_domain_info" for current thread.
2037+ *
2038+ * Returns pointer to "struct ccs_domain_info" for current thread.
2039+ */
2040+static inline struct ccs_domain_info *ccs_current_domain(void)
2041+{
2042+ return ccs_find_task_security(current)->ccs_domain_info;
2043+}
2044+
2045+/**
2046+ * ccs_task_flags - Get flags for specified thread.
2047+ *
2048+ * @task: Pointer to "struct task_struct".
2049+ *
2050+ * Returns flags for specified thread.
2051+ */
2052+static inline u32 ccs_task_flags(struct task_struct *task)
2053+{
2054+ u32 ccs_flags;
2055+ rcu_read_lock();
2056+ ccs_flags = ccs_find_task_security(task)->ccs_flags;
2057+ rcu_read_unlock();
2058+ return ccs_flags;
2059+}
2060+
2061+/**
2062+ * ccs_current_flags - Get flags for current thread.
2063+ *
2064+ * Returns flags for current thread.
2065+ */
2066+static inline u32 ccs_current_flags(void)
2067+{
2068+ return ccs_find_task_security(current)->ccs_flags;
2069+}
2070+
2071+#else
2072+
2073+/*
2074+ * "struct ccs_domain_info *" and "u32 ccs_flags" for each "struct task_struct"
2075+ * are maintained inside that "struct task_struct". Therefore, ccs_security ==
2076+ * task_struct . This allows fast access but breaks KABI checks for
2077+ * distributor's prebuilt kernels due to changes in "struct task_struct".
2078+ */
2079+#define ccs_security task_struct
2080+
2081+/**
2082+ * ccs_find_task_security - Find "struct ccs_security" for given task.
2083+ *
2084+ * @task: Pointer to "struct task_struct".
2085+ *
2086+ * Returns pointer to "struct ccs_security".
2087+ */
2088+static inline struct ccs_security *ccs_find_task_security(struct task_struct *
2089+ task)
2090+{
2091+ return task;
2092+}
2093+
2094+/**
2095+ * ccs_current_security - Get "struct ccs_security" for current thread.
2096+ *
2097+ * Returns pointer to "struct ccs_security" for current thread.
2098+ */
2099+static inline struct ccs_security *ccs_current_security(void)
2100+{
2101+ return ccs_find_task_security(current);
2102+}
2103+
2104+/**
2105+ * ccs_task_domain - Get "struct ccs_domain_info" for specified thread.
2106+ *
2107+ * @task: Pointer to "struct task_struct".
2108+ *
2109+ * Returns pointer to "struct ccs_security" for specified thread.
2110+ */
2111+static inline struct ccs_domain_info *ccs_task_domain(struct task_struct *task)
2112+{
2113+ struct ccs_domain_info *domain = task->ccs_domain_info;
2114+ return domain ? domain : &ccs_kernel_domain;
2115+}
2116+
2117+/**
2118+ * ccs_current_domain - Get "struct ccs_domain_info" for current thread.
2119+ *
2120+ * Returns pointer to "struct ccs_domain_info" for current thread.
2121+ *
2122+ * If current thread does not belong to a domain (which is true for initial
2123+ * init_task in order to hide ccs_kernel_domain from this module),
2124+ * current thread enters into ccs_kernel_domain.
2125+ */
2126+static inline struct ccs_domain_info *ccs_current_domain(void)
2127+{
2128+ struct task_struct *task = current;
2129+ if (!task->ccs_domain_info)
2130+ task->ccs_domain_info = &ccs_kernel_domain;
2131+ return task->ccs_domain_info;
2132+}
2133+
2134+/**
2135+ * ccs_task_flags - Get flags for specified thread.
2136+ *
2137+ * @task: Pointer to "struct task_struct".
2138+ *
2139+ * Returns flags for specified thread.
2140+ */
2141+static inline u32 ccs_task_flags(struct task_struct *task)
2142+{
2143+ return ccs_find_task_security(task)->ccs_flags;
2144+}
2145+
2146+/**
2147+ * ccs_current_flags - Get flags for current thread.
2148+ *
2149+ * Returns flags for current thread.
2150+ */
2151+static inline u32 ccs_current_flags(void)
2152+{
2153+ return ccs_find_task_security(current)->ccs_flags;
2154+}
2155+
2156+#endif
2157+
2158+/**
2159+ * ccs_current_namespace - Get "struct ccs_policy_namespace" for current thread.
2160+ *
2161+ * Returns pointer to "struct ccs_policy_namespace" for current thread.
2162+ */
2163+static inline struct ccs_policy_namespace *ccs_current_namespace(void)
2164+{
2165+ return ccs_current_domain()->ns;
2166+}
2167+
2168+#endif
--- tags/patches/1.0.47/load_policy.c (nonexistent)
+++ tags/patches/1.0.47/load_policy.c (revision 672)
@@ -0,0 +1,385 @@
1+/*
2+ * security/ccsecurity/load_policy.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#include <linux/version.h>
10+#include <linux/module.h>
11+#include <linux/init.h>
12+#include <linux/binfmts.h>
13+#include <linux/sched.h>
14+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
15+#include <linux/kmod.h>
16+/*
17+ * Regarding 2.4 kernels, we need to define __KERNEL_SYSCALLS__ in order to use
18+ * waitpid() because call_usermodehelper() does not support UMH_WAIT_PROC.
19+ */
20+#define __KERNEL_SYSCALLS__
21+#include <linux/unistd.h>
22+#else
23+#include <linux/fs.h>
24+#include <linux/namei.h>
25+#endif
26+#ifndef LOOKUP_POSITIVE
27+#define LOOKUP_POSITIVE 0
28+#endif
29+
30+/*
31+ * TOMOYO specific part start.
32+ */
33+
34+#include "internal.h"
35+
36+#if 0
37+/**
38+ * ccs_setup - Set enable/disable upon boot.
39+ *
40+ * @str: "off" to disable, "on" to enable.
41+ *
42+ * Returns 0.
43+ */
44+static int __init ccs_setup(char *str)
45+{
46+ if (!strcmp(str, "off"))
47+ ccsecurity_ops.disabled = 1;
48+ else if (!strcmp(str, "on"))
49+ ccsecurity_ops.disabled = 0;
50+ return 0;
51+}
52+
53+__setup("ccsecurity=", ccs_setup);
54+#endif
55+
56+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
57+
58+/* Path to the policy loader. (default = CONFIG_CCSECURITY_POLICY_LOADER) */
59+static const char *ccs_loader;
60+
61+#if 0
62+/**
63+ * ccs_loader_setup - Set policy loader.
64+ *
65+ * @str: Program to use as a policy loader (e.g. /sbin/ccs-init ).
66+ *
67+ * Returns 0.
68+ */
69+static int __init ccs_loader_setup(char *str)
70+{
71+ ccs_loader = str;
72+ return 0;
73+}
74+
75+__setup("CCS_loader=", ccs_loader_setup);
76+#endif
77+
78+/**
79+ * ccs_policy_loader_exists - Check whether /sbin/ccs-init exists.
80+ *
81+ * Returns true if /sbin/ccs-init exists, false otherwise.
82+ */
83+static _Bool ccs_policy_loader_exists(void)
84+{
85+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
86+ struct path path;
87+ if (!ccs_loader)
88+ ccs_loader = CONFIG_CCSECURITY_POLICY_LOADER;
89+ if (kern_path(ccs_loader, LOOKUP_FOLLOW | LOOKUP_POSITIVE,
90+ &path) == 0) {
91+ path_put(&path);
92+ return 1;
93+ }
94+#else
95+ struct nameidata nd;
96+ if (!ccs_loader)
97+ ccs_loader = CONFIG_CCSECURITY_POLICY_LOADER;
98+ if (path_lookup(ccs_loader, LOOKUP_FOLLOW | LOOKUP_POSITIVE,
99+ &nd) == 0) {
100+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
101+ path_put(&nd.path);
102+#else
103+ path_release(&nd);
104+#endif
105+ return 1;
106+ }
107+#endif
108+ printk(KERN_INFO "Not activating Mandatory Access Control "
109+ "as %s does not exist.\n", ccs_loader);
110+ return 0;
111+}
112+
113+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
114+
115+/**
116+ * ccs_run_loader - Start /sbin/ccs-init.
117+ *
118+ * @unused: Not used.
119+ *
120+ * Returns PID of /sbin/ccs-init on success, negative value otherwise.
121+ */
122+static int ccs_run_loader(void *unused)
123+{
124+ char *argv[2];
125+ char *envp[3];
126+ printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
127+ ccs_loader);
128+ argv[0] = (char *) ccs_loader;
129+ argv[1] = NULL;
130+ envp[0] = "HOME=/";
131+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
132+ envp[2] = NULL;
133+ return exec_usermodehelper(argv[0], argv, envp);
134+}
135+
136+#endif
137+
138+/* Path to the trigger. (default = CONFIG_CCSECURITY_ACTIVATION_TRIGGER) */
139+static const char *ccs_trigger;
140+
141+#if 0
142+/**
143+ * ccs_trigger_setup - Set trigger for activation.
144+ *
145+ * @str: Program to use as an activation trigger (e.g. /sbin/init ).
146+ *
147+ * Returns 0.
148+ */
149+static int __init ccs_trigger_setup(char *str)
150+{
151+ ccs_trigger = str;
152+ return 0;
153+}
154+
155+__setup("CCS_trigger=", ccs_trigger_setup);
156+#endif
157+
158+/**
159+ * ccs_load_policy - Run external policy loader to load policy.
160+ *
161+ * @filename: The program about to start.
162+ *
163+ * Returns nothing.
164+ *
165+ * This function checks whether @filename is /sbin/init, and if so
166+ * invoke /sbin/ccs-init and wait for the termination of /sbin/ccs-init
167+ * and then continues invocation of /sbin/init.
168+ * /sbin/ccs-init reads policy files in /etc/ccs/ directory and
169+ * writes to /proc/ccs/ interfaces.
170+ */
171+void ccs_load_policy(const char *filename)
172+{
173+ static _Bool done;
174+ if (ccsecurity_ops.disabled || done)
175+ return;
176+ if (!ccs_trigger)
177+ ccs_trigger = CONFIG_CCSECURITY_ACTIVATION_TRIGGER;
178+ if (strcmp(filename, ccs_trigger))
179+ return;
180+ if (!ccs_policy_loader_exists())
181+ return;
182+ done = 1;
183+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
184+ {
185+ char *argv[2];
186+ char *envp[3];
187+ printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
188+ ccs_loader);
189+ argv[0] = (char *) ccs_loader;
190+ argv[1] = NULL;
191+ envp[0] = "HOME=/";
192+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
193+ envp[2] = NULL;
194+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) || defined(UMH_WAIT_PROC)
195+ call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
196+#else
197+ call_usermodehelper(argv[0], argv, envp, 1);
198+#endif
199+ }
200+#elif defined(TASK_DEAD)
201+ {
202+ /* Copied from kernel/kmod.c */
203+ struct task_struct *task = current;
204+ pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
205+ sigset_t tmpsig;
206+ spin_lock_irq(&task->sighand->siglock);
207+ tmpsig = task->blocked;
208+ siginitsetinv(&task->blocked,
209+ sigmask(SIGKILL) | sigmask(SIGSTOP));
210+ recalc_sigpending();
211+ spin_unlock_irq(&task->sighand->siglock);
212+ if (pid >= 0)
213+ waitpid(pid, NULL, __WCLONE);
214+ spin_lock_irq(&task->sighand->siglock);
215+ task->blocked = tmpsig;
216+ recalc_sigpending();
217+ spin_unlock_irq(&task->sighand->siglock);
218+ }
219+#else
220+ {
221+ /* Copied from kernel/kmod.c */
222+ struct task_struct *task = current;
223+ pid_t pid = kernel_thread(ccs_run_loader, NULL, 0);
224+ sigset_t tmpsig;
225+ spin_lock_irq(&task->sigmask_lock);
226+ tmpsig = task->blocked;
227+ siginitsetinv(&task->blocked,
228+ sigmask(SIGKILL) | sigmask(SIGSTOP));
229+ recalc_sigpending(task);
230+ spin_unlock_irq(&task->sigmask_lock);
231+ if (pid >= 0)
232+ waitpid(pid, NULL, __WCLONE);
233+ spin_lock_irq(&task->sigmask_lock);
234+ task->blocked = tmpsig;
235+ recalc_sigpending(task);
236+ spin_unlock_irq(&task->sigmask_lock);
237+ }
238+#endif
239+ if (ccsecurity_ops.check_profile)
240+ ccsecurity_ops.check_profile();
241+ else
242+ panic("Failed to load policy.");
243+}
244+
245+#endif
246+
247+#if 0
248+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
249+
250+/**
251+ * ccs_start_execve - Load policy before calling search_binary_handler().
252+ *
253+ * @bprm: Pointer to "struct linux_binprm".
254+ * @eep: Pointer to "struct ccs_execve *".
255+ *
256+ * Returns 0 on success, negative value otherwise.
257+ */
258+static int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep)
259+{
260+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
261+ ccs_load_policy(bprm->filename);
262+#endif
263+ /*
264+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
265+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
266+ * load loadable kernel module. The loadable kernel module modifies
267+ * "struct ccsecurity_ops". Thus, we need to transfer control to
268+ * ccs_start_execve() in security/ccsecurity/permission.c
269+ * if "struct ccsecurity_ops" was modified.
270+ */
271+ if (ccsecurity_ops.start_execve != ccs_start_execve)
272+ return ccsecurity_ops.start_execve(bprm, eep);
273+ return 0;
274+}
275+
276+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
277+
278+/**
279+ * __ccs_search_binary_handler - Load policy before calling search_binary_handler().
280+ *
281+ * @bprm: Pointer to "struct linux_binprm".
282+ *
283+ * Returns 0 on success, negative value otherwise.
284+ */
285+static int __ccs_search_binary_handler(struct linux_binprm *bprm)
286+{
287+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
288+ ccs_load_policy(bprm->filename);
289+#endif
290+ /*
291+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
292+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
293+ * load loadable kernel module. The loadable kernel module modifies
294+ * "struct ccsecurity_ops". Thus, we need to transfer control to
295+ * __ccs_search_binary_handler() in security/ccsecurity/permission.c
296+ * if "struct ccsecurity_ops" was modified.
297+ */
298+ if (ccsecurity_ops.search_binary_handler
299+ != __ccs_search_binary_handler)
300+ return ccsecurity_ops.search_binary_handler(bprm);
301+ return search_binary_handler(bprm);
302+}
303+
304+#else
305+
306+/**
307+ * __ccs_search_binary_handler - Load policy before calling search_binary_handler().
308+ *
309+ * @bprm: Pointer to "struct linux_binprm".
310+ * @regs: Pointer to "struct pt_regs".
311+ *
312+ * Returns 0 on success, negative value otherwise.
313+ */
314+static int __ccs_search_binary_handler(struct linux_binprm *bprm,
315+ struct pt_regs *regs)
316+{
317+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
318+ ccs_load_policy(bprm->filename);
319+#endif
320+ /*
321+ * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is
322+ * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to
323+ * load loadable kernel module. The loadable kernel module modifies
324+ * "struct ccsecurity_ops". Thus, we need to transfer control to
325+ * __ccs_search_binary_handler() in security/ccsecurity/permission.c
326+ * if "struct ccsecurity_ops" was modified.
327+ */
328+ if (ccsecurity_ops.search_binary_handler
329+ != __ccs_search_binary_handler)
330+ return ccsecurity_ops.search_binary_handler(bprm, regs);
331+ return search_binary_handler(bprm, regs);
332+}
333+
334+#endif
335+
336+/*
337+ * Some exports for loadable kernel module part.
338+ *
339+ * Although scripts/checkpatch.pl complains about use of "extern" in C file,
340+ * we don't put these into security/ccsecurity/internal.h because we want to
341+ * split built-in part and loadable kernel module part.
342+ */
343+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
344+extern spinlock_t vfsmount_lock;
345+#endif
346+
347+/* For exporting variables and functions. */
348+const struct ccsecurity_exports ccsecurity_exports = {
349+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
350+ .load_policy = ccs_load_policy,
351+#endif
352+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
353+ .d_absolute_path = d_absolute_path,
354+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
355+ .__d_path = __d_path,
356+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
357+ .vfsmount_lock = &vfsmount_lock,
358+#endif
359+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
360+ .find_task_by_vpid = find_task_by_vpid,
361+ .find_task_by_pid_ns = find_task_by_pid_ns,
362+#endif
363+};
364+#ifdef CONFIG_CCSECURITY_LKM
365+/* Only ccsecurity module need to access this struct. */
366+EXPORT_SYMBOL_GPL(ccsecurity_exports);
367+#endif
368+
369+/* Members are updated by loadable kernel module. */
370+struct ccsecurity_operations ccsecurity_ops = {
371+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
372+ .start_execve = ccs_start_execve,
373+#else
374+ .search_binary_handler = __ccs_search_binary_handler,
375+#endif
376+#ifdef CONFIG_CCSECURITY_DISABLE_BY_DEFAULT
377+ .disabled = 1,
378+#endif
379+};
380+/*
381+ * Non-GPL modules might need to access this struct via inlined functions
382+ * embedded into include/linux/security.h and include/net/ip.h
383+ */
384+EXPORT_SYMBOL(ccsecurity_ops);
385+#endif
--- tags/patches/1.0.47/lsm-2.6.0-vfs.c (nonexistent)
+++ tags/patches/1.0.47/lsm-2.6.0-vfs.c (revision 672)
@@ -0,0 +1,1588 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+
14+static int __ccs_alloc_task_security(const struct task_struct *task);
15+static void __ccs_free_task_security(const struct task_struct *task);
16+
17+/* Dummy security context for avoiding NULL pointer dereference. */
18+static struct ccs_security ccs_oom_security = {
19+ .ccs_domain_info = &ccs_kernel_domain
20+};
21+
22+/* Dummy security context for avoiding NULL pointer dereference. */
23+static struct ccs_security ccs_default_security = {
24+ .ccs_domain_info = &ccs_kernel_domain
25+};
26+
27+/* List of "struct ccs_security". */
28+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
29+/* Lock for protecting ccs_task_security_list[]. */
30+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
31+
32+/* Dummy marker for calling security_bprm_free(). */
33+static const unsigned long ccs_bprm_security;
34+
35+/* For exporting variables and functions. */
36+struct ccsecurity_exports ccsecurity_exports;
37+/* Members are updated by loadable kernel module. */
38+struct ccsecurity_operations ccsecurity_ops;
39+
40+/* Function pointers originally registered by register_security(). */
41+static struct security_operations original_security_ops /* = *security_ops; */;
42+
43+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
44+
45+/**
46+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
47+ *
48+ * @count: Count to increment or decrement.
49+ *
50+ * Returns updated counter.
51+ */
52+static unsigned int ccs_update_ee_counter(int count)
53+{
54+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) || defined(atomic_add_return)
55+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
56+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
57+ return atomic_add_return(count, &ccs_ee_counter);
58+#else
59+ static DEFINE_SPINLOCK(ccs_ee_lock);
60+ static unsigned int ccs_ee_counter;
61+ unsigned long flags;
62+ spin_lock_irqsave(&ccs_ee_lock, flags);
63+ ccs_ee_counter += count;
64+ count = ccs_ee_counter;
65+ spin_unlock_irqrestore(&ccs_ee_lock, flags);
66+ return count;
67+#endif
68+}
69+
70+/**
71+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
72+ *
73+ * @ee: Pointer to "struct ccs_execve".
74+ *
75+ * Returns nothing.
76+ */
77+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
78+{
79+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
80+ current->pid, ccs_update_ee_counter(1) - 1);
81+}
82+
83+/**
84+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
85+ *
86+ * @ee: Pointer to "struct ccs_execve".
87+ * @task: True if released by current task, false otherwise.
88+ *
89+ * Returns nothing.
90+ */
91+void ccs_audit_free_execve(const struct ccs_execve * const ee,
92+ const bool is_current)
93+{
94+ const unsigned int tmp = ccs_update_ee_counter(-1);
95+ if (is_current)
96+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
97+ ee, current->pid, tmp);
98+ else
99+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
100+ ee, tmp);
101+}
102+
103+#endif
104+
105+#if !defined(CONFIG_AKARI_DEBUG)
106+#define ccs_debug_trace(pos) do { } while (0)
107+#else
108+#define ccs_debug_trace(pos) \
109+ do { \
110+ static bool done; \
111+ if (!done) { \
112+ printk(KERN_INFO \
113+ "AKARI: Debug trace: " pos " of 4\n"); \
114+ done = true; \
115+ } \
116+ } while (0)
117+#endif
118+
119+/**
120+ * ccs_clear_execve - Release memory used by do_execve().
121+ *
122+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
123+ * @security: Pointer to "struct ccs_security".
124+ *
125+ * Returns nothing.
126+ */
127+static void ccs_clear_execve(int ret, struct ccs_security *security)
128+{
129+ struct ccs_execve *ee;
130+ if (security == &ccs_default_security || security == &ccs_oom_security)
131+ return;
132+ ee = security->ee;
133+ security->ee = NULL;
134+ if (!ee)
135+ return;
136+ ccs_finish_execve(ret, ee);
137+}
138+
139+/**
140+ * ccs_task_alloc_security - Allocate memory for new tasks.
141+ *
142+ * @p: Pointer to "struct task_struct".
143+ *
144+ * Returns 0 on success, negative value otherwise.
145+ */
146+static int ccs_task_alloc_security(struct task_struct *p)
147+{
148+ int rc = __ccs_alloc_task_security(p);
149+ if (rc)
150+ return rc;
151+ while (!original_security_ops.task_alloc_security)
152+ smp_rmb();
153+ rc = original_security_ops.task_alloc_security(p);
154+ if (rc)
155+ __ccs_free_task_security(p);
156+ return rc;
157+}
158+
159+/**
160+ * ccs_task_free_security - Release memory for "struct task_struct".
161+ *
162+ * @p: Pointer to "struct task_struct".
163+ *
164+ * Returns nothing.
165+ */
166+static void ccs_task_free_security(struct task_struct *p)
167+{
168+ while (!original_security_ops.task_free_security)
169+ smp_rmb();
170+ original_security_ops.task_free_security(p);
171+ __ccs_free_task_security(p);
172+}
173+
174+/**
175+ * ccs_bprm_alloc_security - Allocate memory for "struct linux_binprm".
176+ *
177+ * @bprm: Pointer to "struct linux_binprm".
178+ *
179+ * Returns 0 on success, negative value otherwise.
180+ */
181+static int ccs_bprm_alloc_security(struct linux_binprm *bprm)
182+{
183+ int rc;
184+ while (!original_security_ops.bprm_alloc_security)
185+ smp_rmb();
186+ rc = original_security_ops.bprm_alloc_security(bprm);
187+ if (bprm->security || rc)
188+ return rc;
189+ /*
190+ * Update bprm->security to &ccs_bprm_security so that
191+ * security_bprm_free() is called even if do_execve() failed at
192+ * search_binary_handler() without allocating memory at
193+ * security_bprm_alloc(). This trick assumes that active LSM module
194+ * does not access bprm->security if that module did not allocate
195+ * memory at security_bprm_alloc().
196+ */
197+ bprm->security = (void *) &ccs_bprm_security;
198+ return 0;
199+}
200+
201+/**
202+ * ccs_bprm_free_security - Release memory for "struct linux_binprm".
203+ *
204+ * @bprm: Pointer to "struct linux_binprm".
205+ *
206+ * Returns nothing.
207+ */
208+static void ccs_bprm_free_security(struct linux_binprm *bprm)
209+{
210+ /*
211+ * If do_execve() succeeded, bprm->security will be updated to NULL at
212+ * security_bprm_compute_creds()/security_bprm_apply_creds() if
213+ * bprm->security was set to &ccs_bprm_security at
214+ * security_bprm_alloc().
215+ *
216+ * If do_execve() failed, bprm->security remains at &ccs_bprm_security
217+ * if bprm->security was set to &ccs_bprm_security at
218+ * security_bprm_alloc().
219+ *
220+ * And do_execve() does not call security_bprm_free() if do_execve()
221+ * failed and bprm->security == NULL. Therefore, do not call
222+ * original_security_ops.bprm_free_security() if bprm->security remains
223+ * at &ccs_bprm_security .
224+ */
225+ if (bprm->security != &ccs_bprm_security) {
226+ while (!original_security_ops.bprm_free_security)
227+ smp_rmb();
228+ original_security_ops.bprm_free_security(bprm);
229+ }
230+ /*
231+ * If do_execve() succeeded,
232+ * ccs_clear_execve(0, ccs_current_security());
233+ * is called before calling below one.
234+ * Thus, below call becomes no-op if do_execve() succeeded.
235+ */
236+ ccs_clear_execve(-1, ccs_current_security());
237+}
238+
239+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
240+
241+/**
242+ * ccs_bprm_compute_creds - A hook which is called when do_execve() succeeded.
243+ *
244+ * @bprm: Pointer to "struct linux_binprm".
245+ *
246+ * Returns nothing.
247+ */
248+static void ccs_bprm_compute_creds(struct linux_binprm *bprm)
249+{
250+ if (bprm->security == &ccs_bprm_security)
251+ bprm->security = NULL;
252+ while (!original_security_ops.bprm_compute_creds)
253+ smp_rmb();
254+ original_security_ops.bprm_compute_creds(bprm);
255+ ccs_clear_execve(0, ccs_current_security());
256+}
257+
258+#else
259+
260+/**
261+ * ccs_bprm_apply_creds - A hook which is called when do_execve() succeeded.
262+ *
263+ * @bprm: Pointer to "struct linux_binprm".
264+ * @unsafe: Unsafe flag.
265+ *
266+ * Returns nothing.
267+ */
268+static void ccs_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
269+{
270+ if (bprm->security == &ccs_bprm_security)
271+ bprm->security = NULL;
272+ while (!original_security_ops.bprm_apply_creds)
273+ smp_rmb();
274+ original_security_ops.bprm_apply_creds(bprm, unsafe);
275+ ccs_clear_execve(0, ccs_current_security());
276+}
277+
278+#endif
279+
280+/**
281+ * ccs_bprm_check_security - Check permission for execve().
282+ *
283+ * @bprm: Pointer to "struct linux_binprm".
284+ *
285+ * Returns 0 on success, negative value otherwise.
286+ */
287+static int ccs_bprm_check_security(struct linux_binprm *bprm)
288+{
289+ struct ccs_security *security = ccs_current_security();
290+ if (security == &ccs_default_security || security == &ccs_oom_security)
291+ return -ENOMEM;
292+ if (!security->ee) {
293+ int rc;
294+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
295+ if (!ccs_policy_loaded)
296+ ccs_load_policy(bprm->filename);
297+#endif
298+ rc = ccs_start_execve(bprm, &security->ee);
299+ if (rc)
300+ return rc;
301+ }
302+ while (!original_security_ops.bprm_check_security)
303+ smp_rmb();
304+ return original_security_ops.bprm_check_security(bprm);
305+}
306+
307+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
308+
309+/**
310+ * ccs_open - Check permission for open().
311+ *
312+ * @f: Pointer to "struct file".
313+ *
314+ * Returns 0 on success, negative value otherwise.
315+ */
316+static int ccs_open(struct file *f)
317+{
318+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
319+ f->f_flags + 1);
320+}
321+
322+#endif
323+
324+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
325+
326+/**
327+ * ccs_dentry_open - Check permission for open().
328+ *
329+ * @f: Pointer to "struct file".
330+ *
331+ * Returns 0 on success, negative value otherwise.
332+ */
333+static int ccs_dentry_open(struct file *f)
334+{
335+ int rc = ccs_open(f);
336+ if (rc)
337+ return rc;
338+ while (!original_security_ops.dentry_open)
339+ smp_rmb();
340+ return original_security_ops.dentry_open(f);
341+}
342+
343+#else
344+
345+/**
346+ * ccs_open - Check permission for open().
347+ *
348+ * @inode: Pointer to "struct inode".
349+ * @mask: Open mode.
350+ * @nd: Pointer to "struct nameidata".
351+ *
352+ * Returns 0 on success, negative value otherwise.
353+ */
354+static int ccs_open(struct inode *inode, int mask, struct nameidata *nd)
355+{
356+ int flags;
357+ if (!nd || !nd->dentry)
358+ return 0;
359+ /* open_exec() passes MAY_EXEC . */
360+ if (mask == MAY_EXEC && inode && S_ISREG(inode->i_mode) &&
361+ (ccs_current_flags() & CCS_TASK_IS_IN_EXECVE))
362+ mask = MAY_READ;
363+ /*
364+ * This flags value is passed to ACC_MODE().
365+ * ccs_open_permission() for older versions uses old ACC_MODE().
366+ */
367+ switch (mask & (MAY_READ | MAY_WRITE)) {
368+ case MAY_READ:
369+ flags = 01;
370+ break;
371+ case MAY_WRITE:
372+ flags = 02;
373+ break;
374+ case MAY_READ | MAY_WRITE:
375+ flags = 03;
376+ break;
377+ default:
378+ return 0;
379+ }
380+ return ccs_open_permission(nd->dentry, nd->mnt, flags);
381+}
382+
383+/**
384+ * ccs_inode_permission - Check permission for open().
385+ *
386+ * @inode: Pointer to "struct inode".
387+ * @mask: Open mode.
388+ * @nd: Pointer to "struct nameidata".
389+ *
390+ * Returns 0 on success, negative value otherwise.
391+ *
392+ * Note that this hook is called from permission(), and may not be called for
393+ * open(). Maybe it is better to use security_file_permission().
394+ */
395+static int ccs_inode_permission(struct inode *inode, int mask,
396+ struct nameidata *nd)
397+{
398+ int rc = ccs_open(inode, mask, nd);
399+ if (rc)
400+ return rc;
401+ while (!original_security_ops.inode_permission)
402+ smp_rmb();
403+ return original_security_ops.inode_permission(inode, mask, nd);
404+}
405+
406+#endif
407+
408+/**
409+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
410+ *
411+ * @dentry: Pointer to "struct dentry".
412+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
413+ * @attr: Pointer to "struct iattr".
414+ *
415+ * Returns 0 on success, negative value otherwise.
416+ */
417+static int ccs_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
418+ struct iattr *attr)
419+{
420+ int rc = 0;
421+ if (attr->ia_valid & ATTR_UID)
422+ rc = ccs_chown_permission(dentry, mnt, attr->ia_uid, -1);
423+ if (!rc && (attr->ia_valid & ATTR_GID))
424+ rc = ccs_chown_permission(dentry, mnt, -1, attr->ia_gid);
425+ if (!rc && (attr->ia_valid & ATTR_MODE))
426+ rc = ccs_chmod_permission(dentry, mnt, attr->ia_mode);
427+ if (!rc && (attr->ia_valid & ATTR_SIZE))
428+ rc = ccs_truncate_permission(dentry, mnt);
429+ if (rc)
430+ return rc;
431+ while (!original_security_ops.inode_setattr)
432+ smp_rmb();
433+ return original_security_ops.inode_setattr(dentry, mnt, attr);
434+}
435+
436+/**
437+ * ccs_inode_getattr - Check permission for stat().
438+ *
439+ * @mnt: Pointer to "struct vfsmount".
440+ * @dentry: Pointer to "struct dentry".
441+ *
442+ * Returns 0 on success, negative value otherwise.
443+ */
444+static int ccs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
445+{
446+ int rc = ccs_getattr_permission(mnt, dentry);
447+ if (rc)
448+ return rc;
449+ while (!original_security_ops.inode_getattr)
450+ smp_rmb();
451+ return original_security_ops.inode_getattr(mnt, dentry);
452+}
453+
454+/**
455+ * ccs_inode_mknod - Check permission for mknod().
456+ *
457+ * @dir: Pointer to "struct inode".
458+ * @dentry: Pointer to "struct dentry".
459+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
460+ * @mode: Create mode.
461+ * @dev: Device major/minor number.
462+ *
463+ * Returns 0 on success, negative value otherwise.
464+ */
465+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
466+ struct vfsmount *mnt, int mode, dev_t dev)
467+{
468+ int rc = ccs_mknod_permission(dentry, mnt, mode, dev);
469+ if (rc)
470+ return rc;
471+ while (!original_security_ops.inode_mknod)
472+ smp_rmb();
473+ return original_security_ops.inode_mknod(dir, dentry, mnt, mode, dev);
474+}
475+
476+/**
477+ * ccs_inode_mkdir - Check permission for mkdir().
478+ *
479+ * @dir: Pointer to "struct inode".
480+ * @dentry: Pointer to "struct dentry".
481+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
482+ * @mode: Create mode.
483+ *
484+ * Returns 0 on success, negative value otherwise.
485+ */
486+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
487+ struct vfsmount *mnt, int mode)
488+{
489+ int rc = ccs_mkdir_permission(dentry, mnt, mode);
490+ if (rc)
491+ return rc;
492+ while (!original_security_ops.inode_mkdir)
493+ smp_rmb();
494+ return original_security_ops.inode_mkdir(dir, dentry, mnt, mode);
495+}
496+
497+/**
498+ * ccs_inode_rmdir - Check permission for rmdir().
499+ *
500+ * @dir: Pointer to "struct inode".
501+ * @dentry: Pointer to "struct dentry".
502+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
503+ *
504+ * Returns 0 on success, negative value otherwise.
505+ */
506+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry,
507+ struct vfsmount *mnt)
508+{
509+ int rc = ccs_rmdir_permission(dentry, mnt);
510+ if (rc)
511+ return rc;
512+ while (!original_security_ops.inode_rmdir)
513+ smp_rmb();
514+ return original_security_ops.inode_rmdir(dir, dentry, mnt);
515+}
516+
517+/**
518+ * ccs_inode_unlink - Check permission for unlink().
519+ *
520+ * @dir: Pointer to "struct inode".
521+ * @dentry: Pointer to "struct dentry".
522+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
523+ *
524+ * Returns 0 on success, negative value otherwise.
525+ */
526+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry,
527+ struct vfsmount *mnt)
528+{
529+ int rc = ccs_unlink_permission(dentry, mnt);
530+ if (rc)
531+ return rc;
532+ while (!original_security_ops.inode_unlink)
533+ smp_rmb();
534+ return original_security_ops.inode_unlink(dir, dentry, mnt);
535+}
536+
537+/**
538+ * ccs_inode_symlink - Check permission for symlink().
539+ *
540+ * @dir: Pointer to "struct inode".
541+ * @dentry: Pointer to "struct dentry".
542+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
543+ * @old_name: Content of symbolic link.
544+ *
545+ * Returns 0 on success, negative value otherwise.
546+ */
547+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
548+ struct vfsmount *mnt, const char *old_name)
549+{
550+ int rc = ccs_symlink_permission(dentry, mnt, old_name);
551+ if (rc)
552+ return rc;
553+ while (!original_security_ops.inode_symlink)
554+ smp_rmb();
555+ return original_security_ops.inode_symlink(dir, dentry, mnt, old_name);
556+}
557+
558+/**
559+ * ccs_inode_rename - Check permission for rename().
560+ *
561+ * @old_dir: Pointer to "struct inode".
562+ * @old_dentry: Pointer to "struct dentry".
563+ * @old_mnt: Pointer to "struct vfsmount". Maybe NULL.
564+ * @new_dir: Pointer to "struct inode".
565+ * @new_dentry: Pointer to "struct dentry".
566+ * @new_mnt: Pointer to "struct vfsmount". Maybe NULL.
567+ *
568+ * Returns 0 on success, negative value otherwise.
569+ */
570+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
571+ struct vfsmount *old_mnt, struct inode *new_dir,
572+ struct dentry *new_dentry,
573+ struct vfsmount *new_mnt)
574+{
575+ int rc = ccs_rename_permission(old_dentry, new_dentry, new_mnt);
576+ if (rc)
577+ return rc;
578+ while (!original_security_ops.inode_rename)
579+ smp_rmb();
580+ return original_security_ops.inode_rename(old_dir, old_dentry, old_mnt,
581+ new_dir, new_dentry,
582+ new_mnt);
583+}
584+
585+/**
586+ * ccs_inode_link - Check permission for link().
587+ *
588+ * @old_dentry: Pointer to "struct dentry".
589+ * @old_mnt: Pointer to "struct vfsmount". Maybe NULL.
590+ * @dir: Pointer to "struct inode".
591+ * @new_dentry: Pointer to "struct dentry".
592+ * @new_mnt: Pointer to "struct vfsmount". Maybe NULL.
593+ *
594+ * Returns 0 on success, negative value otherwise.
595+ */
596+static int ccs_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
597+ struct inode *dir, struct dentry *new_dentry,
598+ struct vfsmount *new_mnt)
599+{
600+ int rc = ccs_link_permission(old_dentry, new_dentry, new_mnt);
601+ if (rc)
602+ return rc;
603+ while (!original_security_ops.inode_link)
604+ smp_rmb();
605+ return original_security_ops.inode_link(old_dentry, old_mnt, dir,
606+ new_dentry, new_mnt);
607+}
608+
609+/**
610+ * ccs_inode_create - Check permission for creat().
611+ *
612+ * @dir: Pointer to "struct inode".
613+ * @dentry: Pointer to "struct dentry".
614+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
615+ * @mode: Create mode.
616+ *
617+ * Returns 0 on success, negative value otherwise.
618+ */
619+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
620+ struct vfsmount *mnt, int mode)
621+{
622+ int rc = ccs_mknod_permission(dentry, mnt, mode, 0);
623+ if (rc)
624+ return rc;
625+ while (!original_security_ops.inode_create)
626+ smp_rmb();
627+ return original_security_ops.inode_create(dir, dentry, mnt, mode);
628+}
629+
630+#ifdef CONFIG_SECURITY_NETWORK
631+
632+#include <net/sock.h>
633+
634+/* Structure for remembering an accept()ed socket's status. */
635+struct ccs_socket_tag {
636+ struct list_head list;
637+ struct inode *inode;
638+ int status;
639+ struct rcu_head rcu;
640+};
641+
642+/*
643+ * List for managing accept()ed sockets.
644+ * Since we don't need to keep an accept()ed socket into this list after
645+ * once the permission was granted, the number of entries in this list is
646+ * likely small. Therefore, we don't use hash tables.
647+ */
648+static LIST_HEAD(ccs_accepted_socket_list);
649+/* Lock for protecting ccs_accepted_socket_list . */
650+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
651+
652+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
653+
654+/**
655+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
656+ *
657+ * @rcu: Pointer to "struct rcu_head".
658+ *
659+ * Returns nothing.
660+ */
661+static void ccs_socket_rcu_free(struct rcu_head *rcu)
662+{
663+ struct ccs_socket_tag *ptr = container_of(rcu, typeof(*ptr), rcu);
664+ kfree(ptr);
665+}
666+
667+#else
668+
669+/**
670+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
671+ *
672+ * @arg: Pointer to "void".
673+ *
674+ * Returns nothing.
675+ */
676+static void ccs_socket_rcu_free(void *arg)
677+{
678+ struct ccs_socket_tag *ptr = arg;
679+ kfree(ptr);
680+}
681+
682+#endif
683+
684+/**
685+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
686+ *
687+ * @inode: Pointer to "struct inode".
688+ * @status: New status.
689+ *
690+ * Returns nothing.
691+ *
692+ * If @status == 0, memory for that socket will be released after RCU grace
693+ * period.
694+ */
695+static void ccs_update_socket_tag(struct inode *inode, int status)
696+{
697+ struct ccs_socket_tag *ptr;
698+ /*
699+ * Protect whole section because multiple threads may call this
700+ * function with same "sock" via ccs_validate_socket().
701+ */
702+ spin_lock(&ccs_accepted_socket_list_lock);
703+ rcu_read_lock();
704+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
705+ if (ptr->inode != inode)
706+ continue;
707+ ptr->status = status;
708+ if (status)
709+ break;
710+ list_del_rcu(&ptr->list);
711+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
712+ call_rcu(&ptr->rcu, ccs_socket_rcu_free);
713+#else
714+ call_rcu(&ptr->rcu, ccs_socket_rcu_free, ptr);
715+#endif
716+ break;
717+ }
718+ rcu_read_unlock();
719+ spin_unlock(&ccs_accepted_socket_list_lock);
720+}
721+
722+/**
723+ * ccs_validate_socket - Check post accept() permission if needed.
724+ *
725+ * @sock: Pointer to "struct socket".
726+ *
727+ * Returns 0 on success, negative value otherwise.
728+ */
729+static int ccs_validate_socket(struct socket *sock)
730+{
731+ struct inode *inode = SOCK_INODE(sock);
732+ struct ccs_socket_tag *ptr;
733+ int ret = 0;
734+ rcu_read_lock();
735+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
736+ if (ptr->inode != inode)
737+ continue;
738+ ret = ptr->status;
739+ break;
740+ }
741+ rcu_read_unlock();
742+ if (ret <= 0)
743+ /*
744+ * This socket is not an accept()ed socket or this socket is
745+ * an accept()ed socket and post accept() permission is done.
746+ */
747+ return ret;
748+ /*
749+ * Check post accept() permission now.
750+ *
751+ * Strictly speaking, we need to pass both listen()ing socket and
752+ * accept()ed socket to __ccs_socket_post_accept_permission().
753+ * But since socket's family and type are same for both sockets,
754+ * passing the accept()ed socket in place for the listen()ing socket
755+ * will work.
756+ */
757+ ret = ccs_socket_post_accept_permission(sock, sock);
758+ /*
759+ * If permission was granted, we forget that this is an accept()ed
760+ * socket. Otherwise, we remember that this socket needs to return
761+ * error for subsequent socketcalls.
762+ */
763+ ccs_update_socket_tag(inode, ret);
764+ return ret;
765+}
766+
767+/**
768+ * ccs_socket_accept - Check permission for accept().
769+ *
770+ * @sock: Pointer to "struct socket".
771+ * @newsock: Pointer to "struct socket".
772+ *
773+ * Returns 0 on success, negative value otherwise.
774+ *
775+ * This hook is used for setting up environment for doing post accept()
776+ * permission check. If dereferencing sock->ops->something() were ordered by
777+ * rcu_dereference(), we could replace sock->ops with "a copy of original
778+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
779+ * in order to do post accept() permission check before returning to userspace.
780+ * If we make the copy in security_socket_post_create(), it would be possible
781+ * to safely replace sock->ops here, but we don't do so because we don't want
782+ * to allocate memory for sockets which do not call sock->ops->accept().
783+ * Therefore, we do post accept() permission check upon next socket syscalls
784+ * rather than between sock->ops->accept() and returning to userspace.
785+ * This means that if a socket was close()d before calling some socket
786+ * syscalls, post accept() permission check will not be done.
787+ */
788+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
789+{
790+ struct ccs_socket_tag *ptr;
791+ int rc = ccs_validate_socket(sock);
792+ if (rc < 0)
793+ return rc;
794+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
795+ if (!ptr)
796+ return -ENOMEM;
797+ while (!original_security_ops.socket_accept)
798+ smp_rmb();
799+ rc = original_security_ops.socket_accept(sock, newsock);
800+ if (rc) {
801+ kfree(ptr);
802+ return rc;
803+ }
804+ /*
805+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
806+ * "newsock" as "an accept()ed socket but post accept() permission
807+ * check is not done yet" by allocating memory using inode of the
808+ * "newsock" as a search key.
809+ */
810+ ptr->inode = SOCK_INODE(newsock);
811+ ptr->status = 1; /* Check post accept() permission later. */
812+ spin_lock(&ccs_accepted_socket_list_lock);
813+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
814+ spin_unlock(&ccs_accepted_socket_list_lock);
815+ return 0;
816+}
817+
818+/**
819+ * ccs_socket_listen - Check permission for listen().
820+ *
821+ * @sock: Pointer to "struct socket".
822+ * @backlog: Backlog parameter.
823+ *
824+ * Returns 0 on success, negative value otherwise.
825+ */
826+static int ccs_socket_listen(struct socket *sock, int backlog)
827+{
828+ int rc = ccs_validate_socket(sock);
829+ if (rc < 0)
830+ return rc;
831+ rc = ccs_socket_listen_permission(sock);
832+ if (rc)
833+ return rc;
834+ while (!original_security_ops.socket_listen)
835+ smp_rmb();
836+ return original_security_ops.socket_listen(sock, backlog);
837+}
838+
839+/**
840+ * ccs_socket_connect - Check permission for connect().
841+ *
842+ * @sock: Pointer to "struct socket".
843+ * @addr: Pointer to "struct sockaddr".
844+ * @addr_len: Size of @addr.
845+ *
846+ * Returns 0 on success, negative value otherwise.
847+ */
848+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
849+ int addr_len)
850+{
851+ int rc = ccs_validate_socket(sock);
852+ if (rc < 0)
853+ return rc;
854+ rc = ccs_socket_connect_permission(sock, addr, addr_len);
855+ if (rc)
856+ return rc;
857+ while (!original_security_ops.socket_connect)
858+ smp_rmb();
859+ return original_security_ops.socket_connect(sock, addr, addr_len);
860+}
861+
862+/**
863+ * ccs_socket_bind - Check permission for bind().
864+ *
865+ * @sock: Pointer to "struct socket".
866+ * @addr: Pointer to "struct sockaddr".
867+ * @addr_len: Size of @addr.
868+ *
869+ * Returns 0 on success, negative value otherwise.
870+ */
871+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
872+ int addr_len)
873+{
874+ int rc = ccs_validate_socket(sock);
875+ if (rc < 0)
876+ return rc;
877+ rc = ccs_socket_bind_permission(sock, addr, addr_len);
878+ if (rc)
879+ return rc;
880+ while (!original_security_ops.socket_bind)
881+ smp_rmb();
882+ return original_security_ops.socket_bind(sock, addr, addr_len);
883+}
884+
885+/**
886+ * ccs_socket_sendmsg - Check permission for sendmsg().
887+ *
888+ * @sock: Pointer to "struct socket".
889+ * @msg: Pointer to "struct msghdr".
890+ * @size: Size of message.
891+ *
892+ * Returns 0 on success, negative value otherwise.
893+ */
894+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
895+ int size)
896+{
897+ int rc = ccs_validate_socket(sock);
898+ if (rc < 0)
899+ return rc;
900+ rc = ccs_socket_sendmsg_permission(sock, msg, size);
901+ if (rc)
902+ return rc;
903+ while (!original_security_ops.socket_sendmsg)
904+ smp_rmb();
905+ return original_security_ops.socket_sendmsg(sock, msg, size);
906+}
907+
908+/**
909+ * ccs_socket_recvmsg - Check permission for recvmsg().
910+ *
911+ * @sock: Pointer to "struct socket".
912+ * @msg: Pointer to "struct msghdr".
913+ * @size: Size of message.
914+ * @flags: Flags.
915+ *
916+ * Returns 0 on success, negative value otherwise.
917+ */
918+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
919+ int size, int flags)
920+{
921+ int rc = ccs_validate_socket(sock);
922+ if (rc < 0)
923+ return rc;
924+ while (!original_security_ops.socket_recvmsg)
925+ smp_rmb();
926+ return original_security_ops.socket_recvmsg(sock, msg, size, flags);
927+}
928+
929+/**
930+ * ccs_socket_getsockname - Check permission for getsockname().
931+ *
932+ * @sock: Pointer to "struct socket".
933+ *
934+ * Returns 0 on success, negative value otherwise.
935+ */
936+static int ccs_socket_getsockname(struct socket *sock)
937+{
938+ int rc = ccs_validate_socket(sock);
939+ if (rc < 0)
940+ return rc;
941+ while (!original_security_ops.socket_getsockname)
942+ smp_rmb();
943+ return original_security_ops.socket_getsockname(sock);
944+}
945+
946+/**
947+ * ccs_socket_getpeername - Check permission for getpeername().
948+ *
949+ * @sock: Pointer to "struct socket".
950+ *
951+ * Returns 0 on success, negative value otherwise.
952+ */
953+static int ccs_socket_getpeername(struct socket *sock)
954+{
955+ int rc = ccs_validate_socket(sock);
956+ if (rc < 0)
957+ return rc;
958+ while (!original_security_ops.socket_getpeername)
959+ smp_rmb();
960+ return original_security_ops.socket_getpeername(sock);
961+}
962+
963+/**
964+ * ccs_socket_getsockopt - Check permission for getsockopt().
965+ *
966+ * @sock: Pointer to "struct socket".
967+ * @level: Level.
968+ * @optname: Option's name,
969+ *
970+ * Returns 0 on success, negative value otherwise.
971+ */
972+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
973+{
974+ int rc = ccs_validate_socket(sock);
975+ if (rc < 0)
976+ return rc;
977+ while (!original_security_ops.socket_getsockopt)
978+ smp_rmb();
979+ return original_security_ops.socket_getsockopt(sock, level, optname);
980+}
981+
982+/**
983+ * ccs_socket_setsockopt - Check permission for setsockopt().
984+ *
985+ * @sock: Pointer to "struct socket".
986+ * @level: Level.
987+ * @optname: Option's name,
988+ *
989+ * Returns 0 on success, negative value otherwise.
990+ */
991+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
992+{
993+ int rc = ccs_validate_socket(sock);
994+ if (rc < 0)
995+ return rc;
996+ while (!original_security_ops.socket_setsockopt)
997+ smp_rmb();
998+ return original_security_ops.socket_setsockopt(sock, level, optname);
999+}
1000+
1001+/**
1002+ * ccs_socket_shutdown - Check permission for shutdown().
1003+ *
1004+ * @sock: Pointer to "struct socket".
1005+ * @how: Shutdown mode.
1006+ *
1007+ * Returns 0 on success, negative value otherwise.
1008+ */
1009+static int ccs_socket_shutdown(struct socket *sock, int how)
1010+{
1011+ int rc = ccs_validate_socket(sock);
1012+ if (rc < 0)
1013+ return rc;
1014+ while (!original_security_ops.socket_shutdown)
1015+ smp_rmb();
1016+ return original_security_ops.socket_shutdown(sock, how);
1017+}
1018+
1019+#define SOCKFS_MAGIC 0x534F434B
1020+
1021+/**
1022+ * ccs_inode_free_security - Release memory associated with an inode.
1023+ *
1024+ * @inode: Pointer to "struct inode".
1025+ *
1026+ * Returns nothing.
1027+ *
1028+ * We use this hook for releasing memory associated with an accept()ed socket.
1029+ */
1030+static void ccs_inode_free_security(struct inode *inode)
1031+{
1032+ while (!original_security_ops.inode_free_security)
1033+ smp_rmb();
1034+ original_security_ops.inode_free_security(inode);
1035+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1036+ ccs_update_socket_tag(inode, 0);
1037+}
1038+
1039+#endif
1040+
1041+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1042+
1043+/**
1044+ * ccs_sb_pivotroot - Check permission for pivot_root().
1045+ *
1046+ * @old_nd: Pointer to "struct nameidata".
1047+ * @new_nd: Pointer to "struct nameidata".
1048+ *
1049+ * Returns 0 on success, negative value otherwise.
1050+ */
1051+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1052+{
1053+ int rc = ccs_pivot_root_permission(old_nd, new_nd);
1054+ if (rc)
1055+ return rc;
1056+ while (!original_security_ops.sb_pivotroot)
1057+ smp_rmb();
1058+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1059+}
1060+
1061+/**
1062+ * ccs_sb_mount - Check permission for mount().
1063+ *
1064+ * @dev_name: Name of device file.
1065+ * @nd: Pointer to "struct nameidata".
1066+ * @type: Name of filesystem type. Maybe NULL.
1067+ * @flags: Mount options.
1068+ * @data_page: Optional data. Maybe NULL.
1069+ *
1070+ * Returns 0 on success, negative value otherwise.
1071+ */
1072+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1073+ unsigned long flags, void *data_page)
1074+{
1075+ int rc = ccs_mount_permission(dev_name, nd, type, flags, data_page);
1076+ if (rc)
1077+ return rc;
1078+ while (!original_security_ops.sb_mount)
1079+ smp_rmb();
1080+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1081+ data_page);
1082+}
1083+
1084+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
1085+
1086+/**
1087+ * ccs_sb_pivotroot - Check permission for pivot_root().
1088+ *
1089+ * @old_nd: Pointer to "struct nameidata".
1090+ * @new_nd: Pointer to "struct nameidata".
1091+ *
1092+ * Returns 0 on success, negative value otherwise.
1093+ */
1094+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1095+{
1096+ int rc = ccs_pivot_root_permission(&old_nd->path, &new_nd->path);
1097+ if (rc)
1098+ return rc;
1099+ while (!original_security_ops.sb_pivotroot)
1100+ smp_rmb();
1101+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1102+}
1103+
1104+/**
1105+ * ccs_sb_mount - Check permission for mount().
1106+ *
1107+ * @dev_name: Name of device file.
1108+ * @nd: Pointer to "struct nameidata".
1109+ * @type: Name of filesystem type. Maybe NULL.
1110+ * @flags: Mount options.
1111+ * @data_page: Optional data. Maybe NULL.
1112+ *
1113+ * Returns 0 on success, negative value otherwise.
1114+ */
1115+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1116+ unsigned long flags, void *data_page)
1117+{
1118+ int rc = ccs_mount_permission(dev_name, &nd->path, type, flags,
1119+ data_page);
1120+ if (rc)
1121+ return rc;
1122+ while (!original_security_ops.sb_mount)
1123+ smp_rmb();
1124+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1125+ data_page);
1126+}
1127+
1128+#else
1129+
1130+/**
1131+ * ccs_sb_pivotroot - Check permission for pivot_root().
1132+ *
1133+ * @old_path: Pointer to "struct path".
1134+ * @new_path: Pointer to "struct path".
1135+ *
1136+ * Returns 0 on success, negative value otherwise.
1137+ */
1138+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1139+{
1140+ int rc = ccs_pivot_root_permission(old_path, new_path);
1141+ if (rc)
1142+ return rc;
1143+ while (!original_security_ops.sb_pivotroot)
1144+ smp_rmb();
1145+ return original_security_ops.sb_pivotroot(old_path, new_path);
1146+}
1147+
1148+/**
1149+ * ccs_sb_mount - Check permission for mount().
1150+ *
1151+ * @dev_name: Name of device file.
1152+ * @path: Pointer to "struct path".
1153+ * @type: Name of filesystem type. Maybe NULL.
1154+ * @flags: Mount options.
1155+ * @data_page: Optional data. Maybe NULL.
1156+ *
1157+ * Returns 0 on success, negative value otherwise.
1158+ */
1159+static int ccs_sb_mount(char *dev_name, struct path *path, char *type,
1160+ unsigned long flags, void *data_page)
1161+{
1162+ int rc = ccs_mount_permission(dev_name, path, type, flags, data_page);
1163+ if (rc)
1164+ return rc;
1165+ while (!original_security_ops.sb_mount)
1166+ smp_rmb();
1167+ return original_security_ops.sb_mount(dev_name, path, type, flags,
1168+ data_page);
1169+}
1170+
1171+#endif
1172+
1173+/**
1174+ * ccs_sb_umount - Check permission for umount().
1175+ *
1176+ * @mnt: Pointer to "struct vfsmount".
1177+ * @flags: Unmount flags.
1178+ *
1179+ * Returns 0 on success, negative value otherwise.
1180+ */
1181+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1182+{
1183+ int rc = ccs_umount_permission(mnt, flags);
1184+ if (rc)
1185+ return rc;
1186+ while (!original_security_ops.sb_umount)
1187+ smp_rmb();
1188+ return original_security_ops.sb_umount(mnt, flags);
1189+}
1190+
1191+/**
1192+ * ccs_file_fcntl - Check permission for fcntl().
1193+ *
1194+ * @file: Pointer to "struct file".
1195+ * @cmd: Command number.
1196+ * @arg: Value for @cmd.
1197+ *
1198+ * Returns 0 on success, negative value otherwise.
1199+ */
1200+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1201+ unsigned long arg)
1202+{
1203+ int rc = ccs_fcntl_permission(file, cmd, arg);
1204+ if (rc)
1205+ return rc;
1206+ while (!original_security_ops.file_fcntl)
1207+ smp_rmb();
1208+ return original_security_ops.file_fcntl(file, cmd, arg);
1209+}
1210+
1211+/**
1212+ * ccs_file_ioctl - Check permission for ioctl().
1213+ *
1214+ * @filp: Pointer to "struct file".
1215+ * @cmd: Command number.
1216+ * @arg: Value for @cmd.
1217+ *
1218+ * Returns 0 on success, negative value otherwise.
1219+ */
1220+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1221+ unsigned long arg)
1222+{
1223+ int rc = ccs_ioctl_permission(filp, cmd, arg);
1224+ if (rc)
1225+ return rc;
1226+ while (!original_security_ops.file_ioctl)
1227+ smp_rmb();
1228+ return original_security_ops.file_ioctl(filp, cmd, arg);
1229+}
1230+
1231+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1232+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
1233+ const struct ccs_path_info *filename);
1234+
1235+/**
1236+ * ccs_prepend - Copy of prepend() in fs/dcache.c.
1237+ *
1238+ * @buffer: Pointer to "struct char *".
1239+ * @buflen: Pointer to int which holds size of @buffer.
1240+ * @str: String to copy.
1241+ *
1242+ * Returns 0 on success, negative value otherwise.
1243+ *
1244+ * @buffer and @buflen are updated upon success.
1245+ */
1246+static int ccs_prepend(char **buffer, int *buflen, const char *str)
1247+{
1248+ int namelen = strlen(str);
1249+ if (*buflen < namelen)
1250+ return -ENOMEM;
1251+ *buflen -= namelen;
1252+ *buffer -= namelen;
1253+ memcpy(*buffer, str, namelen);
1254+ return 0;
1255+}
1256+
1257+/**
1258+ * ccs_sysctl_permission - Check permission for sysctl().
1259+ *
1260+ * @table: Pointer to "struct ctl_table".
1261+ * @op: Operation. (MAY_READ and/or MAY_WRITE)
1262+ *
1263+ * Returns 0 on success, negative value otherwise.
1264+ */
1265+static int ccs_sysctl(struct ctl_table *table, int op)
1266+{
1267+ int error;
1268+ struct ccs_path_info buf;
1269+ struct ccs_request_info r;
1270+ int buflen;
1271+ char *buffer;
1272+ int idx;
1273+ while (!original_security_ops.sysctl)
1274+ smp_rmb();
1275+ error = original_security_ops.sysctl(table, op);
1276+ if (error)
1277+ return error;
1278+ op &= MAY_READ | MAY_WRITE;
1279+ if (!op)
1280+ return 0;
1281+ buffer = NULL;
1282+ buf.name = NULL;
1283+ idx = ccs_read_lock();
1284+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
1285+ == CCS_CONFIG_DISABLED)
1286+ goto out;
1287+ error = -ENOMEM;
1288+ buflen = 4096;
1289+ buffer = kmalloc(buflen, CCS_GFP_FLAGS);
1290+ if (buffer) {
1291+ char *end = buffer + buflen;
1292+ *--end = '\0';
1293+ buflen--;
1294+ while (table) {
1295+ char num[32];
1296+ const char *sp = table->procname;
1297+ if (!sp) {
1298+ memset(num, 0, sizeof(num));
1299+ snprintf(num, sizeof(num) - 1, "=%d=",
1300+ table->ctl_name);
1301+ sp = num;
1302+ }
1303+ if (ccs_prepend(&end, &buflen, sp) ||
1304+ ccs_prepend(&end, &buflen, "/"))
1305+ goto out;
1306+ table = table->parent;
1307+ }
1308+ if (ccs_prepend(&end, &buflen, "proc:/sys"))
1309+ goto out;
1310+ buf.name = ccs_encode(end);
1311+ }
1312+ if (buf.name) {
1313+ ccs_fill_path_info(&buf);
1314+ if (op & MAY_READ)
1315+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
1316+ else
1317+ error = 0;
1318+ if (!error && (op & MAY_WRITE))
1319+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
1320+ }
1321+out:
1322+ ccs_read_unlock(idx);
1323+ kfree(buf.name);
1324+ kfree(buffer);
1325+ return error;
1326+}
1327+
1328+#endif
1329+
1330+/*
1331+ * Why not to copy all operations by "original_security_ops = *ops" ?
1332+ * Because copying byte array is not atomic. Reader checks
1333+ * original_security_ops.op != NULL before doing original_security_ops.op().
1334+ * Thus, modifying original_security_ops.op has to be atomic.
1335+ */
1336+#define swap_security_ops(op) \
1337+ original_security_ops.op = ops->op; smp_wmb(); ops->op = ccs_##op;
1338+
1339+/**
1340+ * ccs_update_security_ops - Overwrite original "struct security_operations".
1341+ *
1342+ * @ops: Pointer to "struct security_operations".
1343+ *
1344+ * Returns nothing.
1345+ */
1346+static void __init ccs_update_security_ops(struct security_operations *ops)
1347+{
1348+ /* Security context allocator. */
1349+ swap_security_ops(task_alloc_security);
1350+ swap_security_ops(task_free_security);
1351+ swap_security_ops(bprm_alloc_security);
1352+ swap_security_ops(bprm_free_security);
1353+ /* Security context updater for successful execve(). */
1354+ swap_security_ops(bprm_check_security);
1355+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
1356+ swap_security_ops(bprm_compute_creds);
1357+#else
1358+ swap_security_ops(bprm_apply_creds);
1359+#endif
1360+ /* Various permission checker. */
1361+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1362+ swap_security_ops(dentry_open);
1363+#else
1364+ swap_security_ops(inode_permission);
1365+#endif
1366+ swap_security_ops(file_fcntl);
1367+ swap_security_ops(file_ioctl);
1368+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1369+ swap_security_ops(sysctl);
1370+#endif
1371+ swap_security_ops(sb_pivotroot);
1372+ swap_security_ops(sb_mount);
1373+ swap_security_ops(sb_umount);
1374+ swap_security_ops(inode_mknod);
1375+ swap_security_ops(inode_mkdir);
1376+ swap_security_ops(inode_rmdir);
1377+ swap_security_ops(inode_unlink);
1378+ swap_security_ops(inode_symlink);
1379+ swap_security_ops(inode_rename);
1380+ swap_security_ops(inode_link);
1381+ swap_security_ops(inode_create);
1382+ swap_security_ops(inode_setattr);
1383+ swap_security_ops(inode_getattr);
1384+#ifdef CONFIG_SECURITY_NETWORK
1385+ swap_security_ops(socket_bind);
1386+ swap_security_ops(socket_connect);
1387+ swap_security_ops(socket_listen);
1388+ swap_security_ops(socket_sendmsg);
1389+ swap_security_ops(socket_recvmsg);
1390+ swap_security_ops(socket_getsockname);
1391+ swap_security_ops(socket_getpeername);
1392+ swap_security_ops(socket_getsockopt);
1393+ swap_security_ops(socket_setsockopt);
1394+ swap_security_ops(socket_shutdown);
1395+ swap_security_ops(socket_accept);
1396+ swap_security_ops(inode_free_security);
1397+#endif
1398+}
1399+
1400+#undef swap_security_ops
1401+
1402+/**
1403+ * ccs_init - Initialize this module.
1404+ *
1405+ * Returns 0 on success, negative value otherwise.
1406+ */
1407+static int __init ccs_init(void)
1408+{
1409+ struct security_operations *ops = probe_security_ops();
1410+ if (!ops)
1411+ goto out;
1412+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1413+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1414+ if (!ccsecurity_exports.find_task_by_vpid)
1415+ goto out;
1416+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1417+ if (!ccsecurity_exports.find_task_by_pid_ns)
1418+ goto out;
1419+#endif
1420+ ccsecurity_exports.vfsmount_lock = probe_vfsmount_lock();
1421+ if (!ccsecurity_exports.vfsmount_lock)
1422+ goto out;
1423+ ccs_main_init();
1424+ ccs_update_security_ops(ops);
1425+ printk(KERN_INFO "AKARI: 1.0.47 2021/04/01\n");
1426+ printk(KERN_INFO
1427+ "Access Keeping And Regulating Instrument registered.\n");
1428+ return 0;
1429+out:
1430+ return -EINVAL;
1431+}
1432+
1433+module_init(ccs_init);
1434+MODULE_LICENSE("GPL");
1435+
1436+/**
1437+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1438+ *
1439+ * @domain: Pointer to "struct ccs_domain_info".
1440+ *
1441+ * Returns true if @domain is in use, false otherwise.
1442+ *
1443+ * Caller holds rcu_read_lock().
1444+ */
1445+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1446+{
1447+ return false;
1448+}
1449+
1450+/**
1451+ * ccs_add_task_security - Add "struct ccs_security" to list.
1452+ *
1453+ * @ptr: Pointer to "struct ccs_security".
1454+ * @list: Pointer to "struct list_head".
1455+ *
1456+ * Returns nothing.
1457+ */
1458+static void ccs_add_task_security(struct ccs_security *ptr,
1459+ struct list_head *list)
1460+{
1461+ unsigned long flags;
1462+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1463+ list_add_rcu(&ptr->list, list);
1464+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1465+}
1466+
1467+/**
1468+ * __ccs_alloc_task_security - Allocate memory for new tasks.
1469+ *
1470+ * @task: Pointer to "struct task_struct".
1471+ *
1472+ * Returns 0 on success, negative value otherwise.
1473+ */
1474+static int __ccs_alloc_task_security(const struct task_struct *task)
1475+{
1476+ struct ccs_security *old_security = ccs_current_security();
1477+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
1478+ GFP_KERNEL);
1479+ struct list_head *list = &ccs_task_security_list
1480+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1481+ if (!new_security)
1482+ return -ENOMEM;
1483+ new_security->task = task;
1484+ new_security->ccs_domain_info = old_security->ccs_domain_info;
1485+ new_security->ccs_flags = old_security->ccs_flags;
1486+ ccs_add_task_security(new_security, list);
1487+ return 0;
1488+}
1489+
1490+/**
1491+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1492+ *
1493+ * @task: Pointer to "struct task_struct".
1494+ *
1495+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1496+ * out of memory, &ccs_default_security otherwise.
1497+ *
1498+ * If @task is current thread and "struct ccs_security" for current thread was
1499+ * not found, I try to allocate it. But if allocation failed, current thread
1500+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1501+ * won't work.
1502+ */
1503+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1504+{
1505+ struct ccs_security *ptr;
1506+ struct list_head *list = &ccs_task_security_list
1507+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1508+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1509+ while (!list->next)
1510+ smp_rmb();
1511+ rcu_read_lock();
1512+ list_for_each_entry_rcu(ptr, list, list) {
1513+ if (ptr->task != task)
1514+ continue;
1515+ rcu_read_unlock();
1516+ return ptr;
1517+ }
1518+ rcu_read_unlock();
1519+ if (task != current)
1520+ return &ccs_default_security;
1521+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1522+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1523+ if (!ptr) {
1524+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1525+ task->pid);
1526+ send_sig(SIGKILL, current, 0);
1527+ return &ccs_oom_security;
1528+ }
1529+ *ptr = ccs_default_security;
1530+ ptr->task = task;
1531+ ccs_add_task_security(ptr, list);
1532+ return ptr;
1533+}
1534+
1535+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1536+
1537+/**
1538+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1539+ *
1540+ * @rcu: Pointer to "struct rcu_head".
1541+ *
1542+ * Returns nothing.
1543+ */
1544+static void ccs_rcu_free(struct rcu_head *rcu)
1545+{
1546+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
1547+ kfree(ptr);
1548+}
1549+
1550+#else
1551+
1552+/**
1553+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1554+ *
1555+ * @arg: Pointer to "void".
1556+ *
1557+ * Returns nothing.
1558+ */
1559+static void ccs_rcu_free(void *arg)
1560+{
1561+ struct ccs_security *ptr = arg;
1562+ kfree(ptr);
1563+}
1564+
1565+#endif
1566+
1567+/**
1568+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
1569+ *
1570+ * @task: Pointer to "struct task_struct".
1571+ *
1572+ * Returns nothing.
1573+ */
1574+static void __ccs_free_task_security(const struct task_struct *task)
1575+{
1576+ unsigned long flags;
1577+ struct ccs_security *ptr = ccs_find_task_security(task);
1578+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
1579+ return;
1580+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1581+ list_del_rcu(&ptr->list);
1582+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1583+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1584+ call_rcu(&ptr->rcu, ccs_rcu_free);
1585+#else
1586+ call_rcu(&ptr->rcu, ccs_rcu_free, ptr);
1587+#endif
1588+}
--- tags/patches/1.0.47/lsm-2.6.0.c (nonexistent)
+++ tags/patches/1.0.47/lsm-2.6.0.c (revision 672)
@@ -0,0 +1,1568 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+
14+static int __ccs_alloc_task_security(const struct task_struct *task);
15+static void __ccs_free_task_security(const struct task_struct *task);
16+
17+/* Dummy security context for avoiding NULL pointer dereference. */
18+static struct ccs_security ccs_oom_security = {
19+ .ccs_domain_info = &ccs_kernel_domain
20+};
21+
22+/* Dummy security context for avoiding NULL pointer dereference. */
23+static struct ccs_security ccs_default_security = {
24+ .ccs_domain_info = &ccs_kernel_domain
25+};
26+
27+/* List of "struct ccs_security". */
28+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
29+/* Lock for protecting ccs_task_security_list[]. */
30+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
31+
32+/* Dummy marker for calling security_bprm_free(). */
33+static const unsigned long ccs_bprm_security;
34+
35+/* For exporting variables and functions. */
36+struct ccsecurity_exports ccsecurity_exports;
37+/* Members are updated by loadable kernel module. */
38+struct ccsecurity_operations ccsecurity_ops;
39+
40+/* Function pointers originally registered by register_security(). */
41+static struct security_operations original_security_ops /* = *security_ops; */;
42+
43+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
44+
45+/**
46+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
47+ *
48+ * @count: Count to increment or decrement.
49+ *
50+ * Returns updated counter.
51+ */
52+static unsigned int ccs_update_ee_counter(int count)
53+{
54+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) || defined(atomic_add_return)
55+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
56+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
57+ return atomic_add_return(count, &ccs_ee_counter);
58+#else
59+ static DEFINE_SPINLOCK(ccs_ee_lock);
60+ static unsigned int ccs_ee_counter;
61+ unsigned long flags;
62+ spin_lock_irqsave(&ccs_ee_lock, flags);
63+ ccs_ee_counter += count;
64+ count = ccs_ee_counter;
65+ spin_unlock_irqrestore(&ccs_ee_lock, flags);
66+ return count;
67+#endif
68+}
69+
70+/**
71+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
72+ *
73+ * @ee: Pointer to "struct ccs_execve".
74+ *
75+ * Returns nothing.
76+ */
77+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
78+{
79+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
80+ current->pid, ccs_update_ee_counter(1) - 1);
81+}
82+
83+/**
84+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
85+ *
86+ * @ee: Pointer to "struct ccs_execve".
87+ * @task: True if released by current task, false otherwise.
88+ *
89+ * Returns nothing.
90+ */
91+void ccs_audit_free_execve(const struct ccs_execve * const ee,
92+ const bool is_current)
93+{
94+ const unsigned int tmp = ccs_update_ee_counter(-1);
95+ if (is_current)
96+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
97+ ee, current->pid, tmp);
98+ else
99+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
100+ ee, tmp);
101+}
102+
103+#endif
104+
105+#if !defined(CONFIG_AKARI_DEBUG)
106+#define ccs_debug_trace(pos) do { } while (0)
107+#else
108+#define ccs_debug_trace(pos) \
109+ do { \
110+ static bool done; \
111+ if (!done) { \
112+ printk(KERN_INFO \
113+ "AKARI: Debug trace: " pos " of 4\n"); \
114+ done = true; \
115+ } \
116+ } while (0)
117+#endif
118+
119+/**
120+ * ccs_clear_execve - Release memory used by do_execve().
121+ *
122+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
123+ * @security: Pointer to "struct ccs_security".
124+ *
125+ * Returns nothing.
126+ */
127+static void ccs_clear_execve(int ret, struct ccs_security *security)
128+{
129+ struct ccs_execve *ee;
130+ if (security == &ccs_default_security || security == &ccs_oom_security)
131+ return;
132+ ee = security->ee;
133+ security->ee = NULL;
134+ if (!ee)
135+ return;
136+ ccs_finish_execve(ret, ee);
137+}
138+
139+/**
140+ * ccs_task_alloc_security - Allocate memory for new tasks.
141+ *
142+ * @p: Pointer to "struct task_struct".
143+ *
144+ * Returns 0 on success, negative value otherwise.
145+ */
146+static int ccs_task_alloc_security(struct task_struct *p)
147+{
148+ int rc = __ccs_alloc_task_security(p);
149+ if (rc)
150+ return rc;
151+ while (!original_security_ops.task_alloc_security)
152+ smp_rmb();
153+ rc = original_security_ops.task_alloc_security(p);
154+ if (rc)
155+ __ccs_free_task_security(p);
156+ return rc;
157+}
158+
159+/**
160+ * ccs_task_free_security - Release memory for "struct task_struct".
161+ *
162+ * @p: Pointer to "struct task_struct".
163+ *
164+ * Returns nothing.
165+ */
166+static void ccs_task_free_security(struct task_struct *p)
167+{
168+ while (!original_security_ops.task_free_security)
169+ smp_rmb();
170+ original_security_ops.task_free_security(p);
171+ __ccs_free_task_security(p);
172+}
173+
174+/**
175+ * ccs_bprm_alloc_security - Allocate memory for "struct linux_binprm".
176+ *
177+ * @bprm: Pointer to "struct linux_binprm".
178+ *
179+ * Returns 0 on success, negative value otherwise.
180+ */
181+static int ccs_bprm_alloc_security(struct linux_binprm *bprm)
182+{
183+ int rc;
184+ while (!original_security_ops.bprm_alloc_security)
185+ smp_rmb();
186+ rc = original_security_ops.bprm_alloc_security(bprm);
187+ if (bprm->security || rc)
188+ return rc;
189+ /*
190+ * Update bprm->security to &ccs_bprm_security so that
191+ * security_bprm_free() is called even if do_execve() failed at
192+ * search_binary_handler() without allocating memory at
193+ * security_bprm_alloc(). This trick assumes that active LSM module
194+ * does not access bprm->security if that module did not allocate
195+ * memory at security_bprm_alloc().
196+ */
197+ bprm->security = (void *) &ccs_bprm_security;
198+ return 0;
199+}
200+
201+/**
202+ * ccs_bprm_free_security - Release memory for "struct linux_binprm".
203+ *
204+ * @bprm: Pointer to "struct linux_binprm".
205+ *
206+ * Returns nothing.
207+ */
208+static void ccs_bprm_free_security(struct linux_binprm *bprm)
209+{
210+ /*
211+ * If do_execve() succeeded, bprm->security will be updated to NULL at
212+ * security_bprm_compute_creds()/security_bprm_apply_creds() if
213+ * bprm->security was set to &ccs_bprm_security at
214+ * security_bprm_alloc().
215+ *
216+ * If do_execve() failed, bprm->security remains at &ccs_bprm_security
217+ * if bprm->security was set to &ccs_bprm_security at
218+ * security_bprm_alloc().
219+ *
220+ * And do_execve() does not call security_bprm_free() if do_execve()
221+ * failed and bprm->security == NULL. Therefore, do not call
222+ * original_security_ops.bprm_free_security() if bprm->security remains
223+ * at &ccs_bprm_security .
224+ */
225+ if (bprm->security != &ccs_bprm_security) {
226+ while (!original_security_ops.bprm_free_security)
227+ smp_rmb();
228+ original_security_ops.bprm_free_security(bprm);
229+ }
230+ /*
231+ * If do_execve() succeeded,
232+ * ccs_clear_execve(0, ccs_current_security());
233+ * is called before calling below one.
234+ * Thus, below call becomes no-op if do_execve() succeeded.
235+ */
236+ ccs_clear_execve(-1, ccs_current_security());
237+}
238+
239+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
240+
241+/**
242+ * ccs_bprm_compute_creds - A hook which is called when do_execve() succeeded.
243+ *
244+ * @bprm: Pointer to "struct linux_binprm".
245+ *
246+ * Returns nothing.
247+ */
248+static void ccs_bprm_compute_creds(struct linux_binprm *bprm)
249+{
250+ if (bprm->security == &ccs_bprm_security)
251+ bprm->security = NULL;
252+ while (!original_security_ops.bprm_compute_creds)
253+ smp_rmb();
254+ original_security_ops.bprm_compute_creds(bprm);
255+ ccs_clear_execve(0, ccs_current_security());
256+}
257+
258+#else
259+
260+/**
261+ * ccs_bprm_apply_creds - A hook which is called when do_execve() succeeded.
262+ *
263+ * @bprm: Pointer to "struct linux_binprm".
264+ * @unsafe: Unsafe flag.
265+ *
266+ * Returns nothing.
267+ */
268+static void ccs_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
269+{
270+ if (bprm->security == &ccs_bprm_security)
271+ bprm->security = NULL;
272+ while (!original_security_ops.bprm_apply_creds)
273+ smp_rmb();
274+ original_security_ops.bprm_apply_creds(bprm, unsafe);
275+ ccs_clear_execve(0, ccs_current_security());
276+}
277+
278+#endif
279+
280+/**
281+ * ccs_bprm_check_security - Check permission for execve().
282+ *
283+ * @bprm: Pointer to "struct linux_binprm".
284+ *
285+ * Returns 0 on success, negative value otherwise.
286+ */
287+static int ccs_bprm_check_security(struct linux_binprm *bprm)
288+{
289+ struct ccs_security *security = ccs_current_security();
290+ if (security == &ccs_default_security || security == &ccs_oom_security)
291+ return -ENOMEM;
292+ if (!security->ee) {
293+ int rc;
294+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
295+ if (!ccs_policy_loaded)
296+ ccs_load_policy(bprm->filename);
297+#endif
298+ rc = ccs_start_execve(bprm, &security->ee);
299+ if (rc)
300+ return rc;
301+ }
302+ while (!original_security_ops.bprm_check_security)
303+ smp_rmb();
304+ return original_security_ops.bprm_check_security(bprm);
305+}
306+
307+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
308+
309+/**
310+ * ccs_open - Check permission for open().
311+ *
312+ * @f: Pointer to "struct file".
313+ *
314+ * Returns 0 on success, negative value otherwise.
315+ */
316+static int ccs_open(struct file *f)
317+{
318+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
319+ f->f_flags + 1);
320+}
321+
322+#endif
323+
324+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
325+
326+/**
327+ * ccs_dentry_open - Check permission for open().
328+ *
329+ * @f: Pointer to "struct file".
330+ *
331+ * Returns 0 on success, negative value otherwise.
332+ */
333+static int ccs_dentry_open(struct file *f)
334+{
335+ int rc = ccs_open(f);
336+ if (rc)
337+ return rc;
338+ while (!original_security_ops.dentry_open)
339+ smp_rmb();
340+ return original_security_ops.dentry_open(f);
341+}
342+
343+#else
344+
345+/**
346+ * ccs_open - Check permission for open().
347+ *
348+ * @inode: Pointer to "struct inode".
349+ * @mask: Open mode.
350+ * @nd: Pointer to "struct nameidata".
351+ *
352+ * Returns 0 on success, negative value otherwise.
353+ */
354+static int ccs_open(struct inode *inode, int mask, struct nameidata *nd)
355+{
356+ int flags;
357+ if (!nd || !nd->dentry)
358+ return 0;
359+ /* open_exec() passes MAY_EXEC . */
360+ if (mask == MAY_EXEC && inode && S_ISREG(inode->i_mode) &&
361+ (ccs_current_flags() & CCS_TASK_IS_IN_EXECVE))
362+ mask = MAY_READ;
363+ /*
364+ * This flags value is passed to ACC_MODE().
365+ * ccs_open_permission() for older versions uses old ACC_MODE().
366+ */
367+ switch (mask & (MAY_READ | MAY_WRITE)) {
368+ case MAY_READ:
369+ flags = 01;
370+ break;
371+ case MAY_WRITE:
372+ flags = 02;
373+ break;
374+ case MAY_READ | MAY_WRITE:
375+ flags = 03;
376+ break;
377+ default:
378+ return 0;
379+ }
380+ return ccs_open_permission(nd->dentry, nd->mnt, flags);
381+}
382+
383+/**
384+ * ccs_inode_permission - Check permission for open().
385+ *
386+ * @inode: Pointer to "struct inode".
387+ * @mask: Open mode.
388+ * @nd: Pointer to "struct nameidata".
389+ *
390+ * Returns 0 on success, negative value otherwise.
391+ *
392+ * Note that this hook is called from permission(), and may not be called for
393+ * open(). Maybe it is better to use security_file_permission().
394+ */
395+static int ccs_inode_permission(struct inode *inode, int mask,
396+ struct nameidata *nd)
397+{
398+ int rc = ccs_open(inode, mask, nd);
399+ if (rc)
400+ return rc;
401+ while (!original_security_ops.inode_permission)
402+ smp_rmb();
403+ return original_security_ops.inode_permission(inode, mask, nd);
404+}
405+
406+#endif
407+
408+/**
409+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
410+ *
411+ * @dentry: Pointer to "struct dentry".
412+ * @attr: Pointer to "struct iattr".
413+ *
414+ * Returns 0 on success, negative value otherwise.
415+ */
416+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
417+{
418+ int rc = 0;
419+ if (attr->ia_valid & ATTR_UID)
420+ rc = ccs_chown_permission(dentry, NULL, attr->ia_uid, -1);
421+ if (!rc && (attr->ia_valid & ATTR_GID))
422+ rc = ccs_chown_permission(dentry, NULL, -1, attr->ia_gid);
423+ if (!rc && (attr->ia_valid & ATTR_MODE))
424+ rc = ccs_chmod_permission(dentry, NULL, attr->ia_mode);
425+ if (!rc && (attr->ia_valid & ATTR_SIZE))
426+ rc = ccs_truncate_permission(dentry, NULL);
427+ if (rc)
428+ return rc;
429+ while (!original_security_ops.inode_setattr)
430+ smp_rmb();
431+ return original_security_ops.inode_setattr(dentry, attr);
432+}
433+
434+/**
435+ * ccs_inode_getattr - Check permission for stat().
436+ *
437+ * @mnt: Pointer to "struct vfsmount".
438+ * @dentry: Pointer to "struct dentry".
439+ *
440+ * Returns 0 on success, negative value otherwise.
441+ */
442+static int ccs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
443+{
444+ int rc = ccs_getattr_permission(mnt, dentry);
445+ if (rc)
446+ return rc;
447+ while (!original_security_ops.inode_getattr)
448+ smp_rmb();
449+ return original_security_ops.inode_getattr(mnt, dentry);
450+}
451+
452+/**
453+ * ccs_inode_mknod - Check permission for mknod().
454+ *
455+ * @dir: Pointer to "struct inode".
456+ * @dentry: Pointer to "struct dentry".
457+ * @mode: Create mode.
458+ * @dev: Device major/minor number.
459+ *
460+ * Returns 0 on success, negative value otherwise.
461+ */
462+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry, int mode,
463+ dev_t dev)
464+{
465+ int rc = ccs_mknod_permission(dentry, NULL, mode, dev);
466+ if (rc)
467+ return rc;
468+ while (!original_security_ops.inode_mknod)
469+ smp_rmb();
470+ return original_security_ops.inode_mknod(dir, dentry, mode, dev);
471+}
472+
473+/**
474+ * ccs_inode_mkdir - Check permission for mkdir().
475+ *
476+ * @dir: Pointer to "struct inode".
477+ * @dentry: Pointer to "struct dentry".
478+ * @mode: Create mode.
479+ *
480+ * Returns 0 on success, negative value otherwise.
481+ */
482+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
483+{
484+ int rc = ccs_mkdir_permission(dentry, NULL, mode);
485+ if (rc)
486+ return rc;
487+ while (!original_security_ops.inode_mkdir)
488+ smp_rmb();
489+ return original_security_ops.inode_mkdir(dir, dentry, mode);
490+}
491+
492+/**
493+ * ccs_inode_rmdir - Check permission for rmdir().
494+ *
495+ * @dir: Pointer to "struct inode".
496+ * @dentry: Pointer to "struct dentry".
497+ *
498+ * Returns 0 on success, negative value otherwise.
499+ */
500+static int ccs_inode_rmdir(struct inode *dir, struct dentry *dentry)
501+{
502+ int rc = ccs_rmdir_permission(dentry, NULL);
503+ if (rc)
504+ return rc;
505+ while (!original_security_ops.inode_rmdir)
506+ smp_rmb();
507+ return original_security_ops.inode_rmdir(dir, dentry);
508+}
509+
510+/**
511+ * ccs_inode_unlink - Check permission for unlink().
512+ *
513+ * @dir: Pointer to "struct inode".
514+ * @dentry: Pointer to "struct dentry".
515+ *
516+ * Returns 0 on success, negative value otherwise.
517+ */
518+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
519+{
520+ int rc = ccs_unlink_permission(dentry, NULL);
521+ if (rc)
522+ return rc;
523+ while (!original_security_ops.inode_unlink)
524+ smp_rmb();
525+ return original_security_ops.inode_unlink(dir, dentry);
526+}
527+
528+/**
529+ * ccs_inode_symlink - Check permission for symlink().
530+ *
531+ * @dir: Pointer to "struct inode".
532+ * @dentry: Pointer to "struct dentry".
533+ * @old_name: Content of symbolic link.
534+ *
535+ * Returns 0 on success, negative value otherwise.
536+ */
537+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
538+ const char *old_name)
539+{
540+ int rc = ccs_symlink_permission(dentry, NULL, old_name);
541+ if (rc)
542+ return rc;
543+ while (!original_security_ops.inode_symlink)
544+ smp_rmb();
545+ return original_security_ops.inode_symlink(dir, dentry, old_name);
546+}
547+
548+/**
549+ * ccs_inode_rename - Check permission for rename().
550+ *
551+ * @old_dir: Pointer to "struct inode".
552+ * @old_dentry: Pointer to "struct dentry".
553+ * @new_dir: Pointer to "struct inode".
554+ * @new_dentry: Pointer to "struct dentry".
555+ *
556+ * Returns 0 on success, negative value otherwise.
557+ */
558+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
559+ struct inode *new_dir, struct dentry *new_dentry)
560+{
561+ int rc = ccs_rename_permission(old_dentry, new_dentry, NULL);
562+ if (rc)
563+ return rc;
564+ while (!original_security_ops.inode_rename)
565+ smp_rmb();
566+ return original_security_ops.inode_rename(old_dir, old_dentry, new_dir,
567+ new_dentry);
568+}
569+
570+/**
571+ * ccs_inode_link - Check permission for link().
572+ *
573+ * @old_dentry: Pointer to "struct dentry".
574+ * @dir: Pointer to "struct inode".
575+ * @new_dentry: Pointer to "struct dentry".
576+ *
577+ * Returns 0 on success, negative value otherwise.
578+ */
579+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
580+ struct dentry *new_dentry)
581+{
582+ int rc = ccs_link_permission(old_dentry, new_dentry, NULL);
583+ if (rc)
584+ return rc;
585+ while (!original_security_ops.inode_link)
586+ smp_rmb();
587+ return original_security_ops.inode_link(old_dentry, dir, new_dentry);
588+}
589+
590+/**
591+ * ccs_inode_create - Check permission for creat().
592+ *
593+ * @dir: Pointer to "struct inode".
594+ * @dentry: Pointer to "struct dentry".
595+ * @mode: Create mode.
596+ *
597+ * Returns 0 on success, negative value otherwise.
598+ */
599+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
600+ int mode)
601+{
602+ int rc = ccs_mknod_permission(dentry, NULL, mode, 0);
603+ if (rc)
604+ return rc;
605+ while (!original_security_ops.inode_create)
606+ smp_rmb();
607+ return original_security_ops.inode_create(dir, dentry, mode);
608+}
609+
610+#ifdef CONFIG_SECURITY_NETWORK
611+
612+#include <net/sock.h>
613+
614+/* Structure for remembering an accept()ed socket's status. */
615+struct ccs_socket_tag {
616+ struct list_head list;
617+ struct inode *inode;
618+ int status;
619+ struct rcu_head rcu;
620+};
621+
622+/*
623+ * List for managing accept()ed sockets.
624+ * Since we don't need to keep an accept()ed socket into this list after
625+ * once the permission was granted, the number of entries in this list is
626+ * likely small. Therefore, we don't use hash tables.
627+ */
628+static LIST_HEAD(ccs_accepted_socket_list);
629+/* Lock for protecting ccs_accepted_socket_list . */
630+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
631+
632+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
633+
634+/**
635+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
636+ *
637+ * @rcu: Pointer to "struct rcu_head".
638+ *
639+ * Returns nothing.
640+ */
641+static void ccs_socket_rcu_free(struct rcu_head *rcu)
642+{
643+ struct ccs_socket_tag *ptr = container_of(rcu, typeof(*ptr), rcu);
644+ kfree(ptr);
645+}
646+
647+#else
648+
649+/**
650+ * ccs_socket_rcu_free - RCU callback for releasing "struct ccs_socket_tag".
651+ *
652+ * @arg: Pointer to "void".
653+ *
654+ * Returns nothing.
655+ */
656+static void ccs_socket_rcu_free(void *arg)
657+{
658+ struct ccs_socket_tag *ptr = arg;
659+ kfree(ptr);
660+}
661+
662+#endif
663+
664+/**
665+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
666+ *
667+ * @inode: Pointer to "struct inode".
668+ * @status: New status.
669+ *
670+ * Returns nothing.
671+ *
672+ * If @status == 0, memory for that socket will be released after RCU grace
673+ * period.
674+ */
675+static void ccs_update_socket_tag(struct inode *inode, int status)
676+{
677+ struct ccs_socket_tag *ptr;
678+ /*
679+ * Protect whole section because multiple threads may call this
680+ * function with same "sock" via ccs_validate_socket().
681+ */
682+ spin_lock(&ccs_accepted_socket_list_lock);
683+ rcu_read_lock();
684+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
685+ if (ptr->inode != inode)
686+ continue;
687+ ptr->status = status;
688+ if (status)
689+ break;
690+ list_del_rcu(&ptr->list);
691+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
692+ call_rcu(&ptr->rcu, ccs_socket_rcu_free);
693+#else
694+ call_rcu(&ptr->rcu, ccs_socket_rcu_free, ptr);
695+#endif
696+ break;
697+ }
698+ rcu_read_unlock();
699+ spin_unlock(&ccs_accepted_socket_list_lock);
700+}
701+
702+/**
703+ * ccs_validate_socket - Check post accept() permission if needed.
704+ *
705+ * @sock: Pointer to "struct socket".
706+ *
707+ * Returns 0 on success, negative value otherwise.
708+ */
709+static int ccs_validate_socket(struct socket *sock)
710+{
711+ struct inode *inode = SOCK_INODE(sock);
712+ struct ccs_socket_tag *ptr;
713+ int ret = 0;
714+ rcu_read_lock();
715+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
716+ if (ptr->inode != inode)
717+ continue;
718+ ret = ptr->status;
719+ break;
720+ }
721+ rcu_read_unlock();
722+ if (ret <= 0)
723+ /*
724+ * This socket is not an accept()ed socket or this socket is
725+ * an accept()ed socket and post accept() permission is done.
726+ */
727+ return ret;
728+ /*
729+ * Check post accept() permission now.
730+ *
731+ * Strictly speaking, we need to pass both listen()ing socket and
732+ * accept()ed socket to __ccs_socket_post_accept_permission().
733+ * But since socket's family and type are same for both sockets,
734+ * passing the accept()ed socket in place for the listen()ing socket
735+ * will work.
736+ */
737+ ret = ccs_socket_post_accept_permission(sock, sock);
738+ /*
739+ * If permission was granted, we forget that this is an accept()ed
740+ * socket. Otherwise, we remember that this socket needs to return
741+ * error for subsequent socketcalls.
742+ */
743+ ccs_update_socket_tag(inode, ret);
744+ return ret;
745+}
746+
747+/**
748+ * ccs_socket_accept - Check permission for accept().
749+ *
750+ * @sock: Pointer to "struct socket".
751+ * @newsock: Pointer to "struct socket".
752+ *
753+ * Returns 0 on success, negative value otherwise.
754+ *
755+ * This hook is used for setting up environment for doing post accept()
756+ * permission check. If dereferencing sock->ops->something() were ordered by
757+ * rcu_dereference(), we could replace sock->ops with "a copy of original
758+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
759+ * in order to do post accept() permission check before returning to userspace.
760+ * If we make the copy in security_socket_post_create(), it would be possible
761+ * to safely replace sock->ops here, but we don't do so because we don't want
762+ * to allocate memory for sockets which do not call sock->ops->accept().
763+ * Therefore, we do post accept() permission check upon next socket syscalls
764+ * rather than between sock->ops->accept() and returning to userspace.
765+ * This means that if a socket was close()d before calling some socket
766+ * syscalls, post accept() permission check will not be done.
767+ */
768+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
769+{
770+ struct ccs_socket_tag *ptr;
771+ int rc = ccs_validate_socket(sock);
772+ if (rc < 0)
773+ return rc;
774+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
775+ if (!ptr)
776+ return -ENOMEM;
777+ while (!original_security_ops.socket_accept)
778+ smp_rmb();
779+ rc = original_security_ops.socket_accept(sock, newsock);
780+ if (rc) {
781+ kfree(ptr);
782+ return rc;
783+ }
784+ /*
785+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
786+ * "newsock" as "an accept()ed socket but post accept() permission
787+ * check is not done yet" by allocating memory using inode of the
788+ * "newsock" as a search key.
789+ */
790+ ptr->inode = SOCK_INODE(newsock);
791+ ptr->status = 1; /* Check post accept() permission later. */
792+ spin_lock(&ccs_accepted_socket_list_lock);
793+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
794+ spin_unlock(&ccs_accepted_socket_list_lock);
795+ return 0;
796+}
797+
798+/**
799+ * ccs_socket_listen - Check permission for listen().
800+ *
801+ * @sock: Pointer to "struct socket".
802+ * @backlog: Backlog parameter.
803+ *
804+ * Returns 0 on success, negative value otherwise.
805+ */
806+static int ccs_socket_listen(struct socket *sock, int backlog)
807+{
808+ int rc = ccs_validate_socket(sock);
809+ if (rc < 0)
810+ return rc;
811+ rc = ccs_socket_listen_permission(sock);
812+ if (rc)
813+ return rc;
814+ while (!original_security_ops.socket_listen)
815+ smp_rmb();
816+ return original_security_ops.socket_listen(sock, backlog);
817+}
818+
819+/**
820+ * ccs_socket_connect - Check permission for connect().
821+ *
822+ * @sock: Pointer to "struct socket".
823+ * @addr: Pointer to "struct sockaddr".
824+ * @addr_len: Size of @addr.
825+ *
826+ * Returns 0 on success, negative value otherwise.
827+ */
828+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
829+ int addr_len)
830+{
831+ int rc = ccs_validate_socket(sock);
832+ if (rc < 0)
833+ return rc;
834+ rc = ccs_socket_connect_permission(sock, addr, addr_len);
835+ if (rc)
836+ return rc;
837+ while (!original_security_ops.socket_connect)
838+ smp_rmb();
839+ return original_security_ops.socket_connect(sock, addr, addr_len);
840+}
841+
842+/**
843+ * ccs_socket_bind - Check permission for bind().
844+ *
845+ * @sock: Pointer to "struct socket".
846+ * @addr: Pointer to "struct sockaddr".
847+ * @addr_len: Size of @addr.
848+ *
849+ * Returns 0 on success, negative value otherwise.
850+ */
851+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
852+ int addr_len)
853+{
854+ int rc = ccs_validate_socket(sock);
855+ if (rc < 0)
856+ return rc;
857+ rc = ccs_socket_bind_permission(sock, addr, addr_len);
858+ if (rc)
859+ return rc;
860+ while (!original_security_ops.socket_bind)
861+ smp_rmb();
862+ return original_security_ops.socket_bind(sock, addr, addr_len);
863+}
864+
865+/**
866+ * ccs_socket_sendmsg - Check permission for sendmsg().
867+ *
868+ * @sock: Pointer to "struct socket".
869+ * @msg: Pointer to "struct msghdr".
870+ * @size: Size of message.
871+ *
872+ * Returns 0 on success, negative value otherwise.
873+ */
874+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
875+ int size)
876+{
877+ int rc = ccs_validate_socket(sock);
878+ if (rc < 0)
879+ return rc;
880+ rc = ccs_socket_sendmsg_permission(sock, msg, size);
881+ if (rc)
882+ return rc;
883+ while (!original_security_ops.socket_sendmsg)
884+ smp_rmb();
885+ return original_security_ops.socket_sendmsg(sock, msg, size);
886+}
887+
888+/**
889+ * ccs_socket_recvmsg - Check permission for recvmsg().
890+ *
891+ * @sock: Pointer to "struct socket".
892+ * @msg: Pointer to "struct msghdr".
893+ * @size: Size of message.
894+ * @flags: Flags.
895+ *
896+ * Returns 0 on success, negative value otherwise.
897+ */
898+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
899+ int size, int flags)
900+{
901+ int rc = ccs_validate_socket(sock);
902+ if (rc < 0)
903+ return rc;
904+ while (!original_security_ops.socket_recvmsg)
905+ smp_rmb();
906+ return original_security_ops.socket_recvmsg(sock, msg, size, flags);
907+}
908+
909+/**
910+ * ccs_socket_getsockname - Check permission for getsockname().
911+ *
912+ * @sock: Pointer to "struct socket".
913+ *
914+ * Returns 0 on success, negative value otherwise.
915+ */
916+static int ccs_socket_getsockname(struct socket *sock)
917+{
918+ int rc = ccs_validate_socket(sock);
919+ if (rc < 0)
920+ return rc;
921+ while (!original_security_ops.socket_getsockname)
922+ smp_rmb();
923+ return original_security_ops.socket_getsockname(sock);
924+}
925+
926+/**
927+ * ccs_socket_getpeername - Check permission for getpeername().
928+ *
929+ * @sock: Pointer to "struct socket".
930+ *
931+ * Returns 0 on success, negative value otherwise.
932+ */
933+static int ccs_socket_getpeername(struct socket *sock)
934+{
935+ int rc = ccs_validate_socket(sock);
936+ if (rc < 0)
937+ return rc;
938+ while (!original_security_ops.socket_getpeername)
939+ smp_rmb();
940+ return original_security_ops.socket_getpeername(sock);
941+}
942+
943+/**
944+ * ccs_socket_getsockopt - Check permission for getsockopt().
945+ *
946+ * @sock: Pointer to "struct socket".
947+ * @level: Level.
948+ * @optname: Option's name,
949+ *
950+ * Returns 0 on success, negative value otherwise.
951+ */
952+static int ccs_socket_getsockopt(struct socket *sock, int level, int optname)
953+{
954+ int rc = ccs_validate_socket(sock);
955+ if (rc < 0)
956+ return rc;
957+ while (!original_security_ops.socket_getsockopt)
958+ smp_rmb();
959+ return original_security_ops.socket_getsockopt(sock, level, optname);
960+}
961+
962+/**
963+ * ccs_socket_setsockopt - Check permission for setsockopt().
964+ *
965+ * @sock: Pointer to "struct socket".
966+ * @level: Level.
967+ * @optname: Option's name,
968+ *
969+ * Returns 0 on success, negative value otherwise.
970+ */
971+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
972+{
973+ int rc = ccs_validate_socket(sock);
974+ if (rc < 0)
975+ return rc;
976+ while (!original_security_ops.socket_setsockopt)
977+ smp_rmb();
978+ return original_security_ops.socket_setsockopt(sock, level, optname);
979+}
980+
981+/**
982+ * ccs_socket_shutdown - Check permission for shutdown().
983+ *
984+ * @sock: Pointer to "struct socket".
985+ * @how: Shutdown mode.
986+ *
987+ * Returns 0 on success, negative value otherwise.
988+ */
989+static int ccs_socket_shutdown(struct socket *sock, int how)
990+{
991+ int rc = ccs_validate_socket(sock);
992+ if (rc < 0)
993+ return rc;
994+ while (!original_security_ops.socket_shutdown)
995+ smp_rmb();
996+ return original_security_ops.socket_shutdown(sock, how);
997+}
998+
999+#define SOCKFS_MAGIC 0x534F434B
1000+
1001+/**
1002+ * ccs_inode_free_security - Release memory associated with an inode.
1003+ *
1004+ * @inode: Pointer to "struct inode".
1005+ *
1006+ * Returns nothing.
1007+ *
1008+ * We use this hook for releasing memory associated with an accept()ed socket.
1009+ */
1010+static void ccs_inode_free_security(struct inode *inode)
1011+{
1012+ while (!original_security_ops.inode_free_security)
1013+ smp_rmb();
1014+ original_security_ops.inode_free_security(inode);
1015+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1016+ ccs_update_socket_tag(inode, 0);
1017+}
1018+
1019+#endif
1020+
1021+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1022+
1023+/**
1024+ * ccs_sb_pivotroot - Check permission for pivot_root().
1025+ *
1026+ * @old_nd: Pointer to "struct nameidata".
1027+ * @new_nd: Pointer to "struct nameidata".
1028+ *
1029+ * Returns 0 on success, negative value otherwise.
1030+ */
1031+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1032+{
1033+ int rc = ccs_pivot_root_permission(old_nd, new_nd);
1034+ if (rc)
1035+ return rc;
1036+ while (!original_security_ops.sb_pivotroot)
1037+ smp_rmb();
1038+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1039+}
1040+
1041+/**
1042+ * ccs_sb_mount - Check permission for mount().
1043+ *
1044+ * @dev_name: Name of device file.
1045+ * @nd: Pointer to "struct nameidata".
1046+ * @type: Name of filesystem type. Maybe NULL.
1047+ * @flags: Mount options.
1048+ * @data_page: Optional data. Maybe NULL.
1049+ *
1050+ * Returns 0 on success, negative value otherwise.
1051+ */
1052+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1053+ unsigned long flags, void *data_page)
1054+{
1055+ int rc = ccs_mount_permission(dev_name, nd, type, flags, data_page);
1056+ if (rc)
1057+ return rc;
1058+ while (!original_security_ops.sb_mount)
1059+ smp_rmb();
1060+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1061+ data_page);
1062+}
1063+
1064+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
1065+
1066+/**
1067+ * ccs_sb_pivotroot - Check permission for pivot_root().
1068+ *
1069+ * @old_nd: Pointer to "struct nameidata".
1070+ * @new_nd: Pointer to "struct nameidata".
1071+ *
1072+ * Returns 0 on success, negative value otherwise.
1073+ */
1074+static int ccs_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd)
1075+{
1076+ int rc = ccs_pivot_root_permission(&old_nd->path, &new_nd->path);
1077+ if (rc)
1078+ return rc;
1079+ while (!original_security_ops.sb_pivotroot)
1080+ smp_rmb();
1081+ return original_security_ops.sb_pivotroot(old_nd, new_nd);
1082+}
1083+
1084+/**
1085+ * ccs_sb_mount - Check permission for mount().
1086+ *
1087+ * @dev_name: Name of device file.
1088+ * @nd: Pointer to "struct nameidata".
1089+ * @type: Name of filesystem type. Maybe NULL.
1090+ * @flags: Mount options.
1091+ * @data_page: Optional data. Maybe NULL.
1092+ *
1093+ * Returns 0 on success, negative value otherwise.
1094+ */
1095+static int ccs_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1096+ unsigned long flags, void *data_page)
1097+{
1098+ int rc = ccs_mount_permission(dev_name, &nd->path, type, flags,
1099+ data_page);
1100+ if (rc)
1101+ return rc;
1102+ while (!original_security_ops.sb_mount)
1103+ smp_rmb();
1104+ return original_security_ops.sb_mount(dev_name, nd, type, flags,
1105+ data_page);
1106+}
1107+
1108+#else
1109+
1110+/**
1111+ * ccs_sb_pivotroot - Check permission for pivot_root().
1112+ *
1113+ * @old_path: Pointer to "struct path".
1114+ * @new_path: Pointer to "struct path".
1115+ *
1116+ * Returns 0 on success, negative value otherwise.
1117+ */
1118+static int ccs_sb_pivotroot(struct path *old_path, struct path *new_path)
1119+{
1120+ int rc = ccs_pivot_root_permission(old_path, new_path);
1121+ if (rc)
1122+ return rc;
1123+ while (!original_security_ops.sb_pivotroot)
1124+ smp_rmb();
1125+ return original_security_ops.sb_pivotroot(old_path, new_path);
1126+}
1127+
1128+/**
1129+ * ccs_sb_mount - Check permission for mount().
1130+ *
1131+ * @dev_name: Name of device file.
1132+ * @path: Pointer to "struct path".
1133+ * @type: Name of filesystem type. Maybe NULL.
1134+ * @flags: Mount options.
1135+ * @data_page: Optional data. Maybe NULL.
1136+ *
1137+ * Returns 0 on success, negative value otherwise.
1138+ */
1139+static int ccs_sb_mount(char *dev_name, struct path *path, char *type,
1140+ unsigned long flags, void *data_page)
1141+{
1142+ int rc = ccs_mount_permission(dev_name, path, type, flags, data_page);
1143+ if (rc)
1144+ return rc;
1145+ while (!original_security_ops.sb_mount)
1146+ smp_rmb();
1147+ return original_security_ops.sb_mount(dev_name, path, type, flags,
1148+ data_page);
1149+}
1150+
1151+#endif
1152+
1153+/**
1154+ * ccs_sb_umount - Check permission for umount().
1155+ *
1156+ * @mnt: Pointer to "struct vfsmount".
1157+ * @flags: Unmount flags.
1158+ *
1159+ * Returns 0 on success, negative value otherwise.
1160+ */
1161+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
1162+{
1163+ int rc = ccs_umount_permission(mnt, flags);
1164+ if (rc)
1165+ return rc;
1166+ while (!original_security_ops.sb_umount)
1167+ smp_rmb();
1168+ return original_security_ops.sb_umount(mnt, flags);
1169+}
1170+
1171+/**
1172+ * ccs_file_fcntl - Check permission for fcntl().
1173+ *
1174+ * @file: Pointer to "struct file".
1175+ * @cmd: Command number.
1176+ * @arg: Value for @cmd.
1177+ *
1178+ * Returns 0 on success, negative value otherwise.
1179+ */
1180+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
1181+ unsigned long arg)
1182+{
1183+ int rc = ccs_fcntl_permission(file, cmd, arg);
1184+ if (rc)
1185+ return rc;
1186+ while (!original_security_ops.file_fcntl)
1187+ smp_rmb();
1188+ return original_security_ops.file_fcntl(file, cmd, arg);
1189+}
1190+
1191+/**
1192+ * ccs_file_ioctl - Check permission for ioctl().
1193+ *
1194+ * @filp: Pointer to "struct file".
1195+ * @cmd: Command number.
1196+ * @arg: Value for @cmd.
1197+ *
1198+ * Returns 0 on success, negative value otherwise.
1199+ */
1200+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
1201+ unsigned long arg)
1202+{
1203+ int rc = ccs_ioctl_permission(filp, cmd, arg);
1204+ if (rc)
1205+ return rc;
1206+ while (!original_security_ops.file_ioctl)
1207+ smp_rmb();
1208+ return original_security_ops.file_ioctl(filp, cmd, arg);
1209+}
1210+
1211+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1212+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
1213+ const struct ccs_path_info *filename);
1214+
1215+/**
1216+ * ccs_prepend - Copy of prepend() in fs/dcache.c.
1217+ *
1218+ * @buffer: Pointer to "struct char *".
1219+ * @buflen: Pointer to int which holds size of @buffer.
1220+ * @str: String to copy.
1221+ *
1222+ * Returns 0 on success, negative value otherwise.
1223+ *
1224+ * @buffer and @buflen are updated upon success.
1225+ */
1226+static int ccs_prepend(char **buffer, int *buflen, const char *str)
1227+{
1228+ int namelen = strlen(str);
1229+ if (*buflen < namelen)
1230+ return -ENOMEM;
1231+ *buflen -= namelen;
1232+ *buffer -= namelen;
1233+ memcpy(*buffer, str, namelen);
1234+ return 0;
1235+}
1236+
1237+/**
1238+ * ccs_sysctl_permission - Check permission for sysctl().
1239+ *
1240+ * @table: Pointer to "struct ctl_table".
1241+ * @op: Operation. (MAY_READ and/or MAY_WRITE)
1242+ *
1243+ * Returns 0 on success, negative value otherwise.
1244+ */
1245+static int ccs_sysctl(struct ctl_table *table, int op)
1246+{
1247+ int error;
1248+ struct ccs_path_info buf;
1249+ struct ccs_request_info r;
1250+ int buflen;
1251+ char *buffer;
1252+ int idx;
1253+ while (!original_security_ops.sysctl)
1254+ smp_rmb();
1255+ error = original_security_ops.sysctl(table, op);
1256+ if (error)
1257+ return error;
1258+ op &= MAY_READ | MAY_WRITE;
1259+ if (!op)
1260+ return 0;
1261+ buffer = NULL;
1262+ buf.name = NULL;
1263+ idx = ccs_read_lock();
1264+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
1265+ == CCS_CONFIG_DISABLED)
1266+ goto out;
1267+ error = -ENOMEM;
1268+ buflen = 4096;
1269+ buffer = kmalloc(buflen, CCS_GFP_FLAGS);
1270+ if (buffer) {
1271+ char *end = buffer + buflen;
1272+ *--end = '\0';
1273+ buflen--;
1274+ while (table) {
1275+ char num[32];
1276+ const char *sp = table->procname;
1277+ if (!sp) {
1278+ memset(num, 0, sizeof(num));
1279+ snprintf(num, sizeof(num) - 1, "=%d=",
1280+ table->ctl_name);
1281+ sp = num;
1282+ }
1283+ if (ccs_prepend(&end, &buflen, sp) ||
1284+ ccs_prepend(&end, &buflen, "/"))
1285+ goto out;
1286+ table = table->parent;
1287+ }
1288+ if (ccs_prepend(&end, &buflen, "proc:/sys"))
1289+ goto out;
1290+ buf.name = ccs_encode(end);
1291+ }
1292+ if (buf.name) {
1293+ ccs_fill_path_info(&buf);
1294+ if (op & MAY_READ)
1295+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
1296+ else
1297+ error = 0;
1298+ if (!error && (op & MAY_WRITE))
1299+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
1300+ }
1301+out:
1302+ ccs_read_unlock(idx);
1303+ kfree(buf.name);
1304+ kfree(buffer);
1305+ return error;
1306+}
1307+
1308+#endif
1309+
1310+/*
1311+ * Why not to copy all operations by "original_security_ops = *ops" ?
1312+ * Because copying byte array is not atomic. Reader checks
1313+ * original_security_ops.op != NULL before doing original_security_ops.op().
1314+ * Thus, modifying original_security_ops.op has to be atomic.
1315+ */
1316+#define swap_security_ops(op) \
1317+ original_security_ops.op = ops->op; smp_wmb(); ops->op = ccs_##op;
1318+
1319+/**
1320+ * ccs_update_security_ops - Overwrite original "struct security_operations".
1321+ *
1322+ * @ops: Pointer to "struct security_operations".
1323+ *
1324+ * Returns nothing.
1325+ */
1326+static void __init ccs_update_security_ops(struct security_operations *ops)
1327+{
1328+ /* Security context allocator. */
1329+ swap_security_ops(task_alloc_security);
1330+ swap_security_ops(task_free_security);
1331+ swap_security_ops(bprm_alloc_security);
1332+ swap_security_ops(bprm_free_security);
1333+ /* Security context updater for successful execve(). */
1334+ swap_security_ops(bprm_check_security);
1335+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
1336+ swap_security_ops(bprm_compute_creds);
1337+#else
1338+ swap_security_ops(bprm_apply_creds);
1339+#endif
1340+ /* Various permission checker. */
1341+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1342+ swap_security_ops(dentry_open);
1343+#else
1344+ swap_security_ops(inode_permission);
1345+#endif
1346+ swap_security_ops(file_fcntl);
1347+ swap_security_ops(file_ioctl);
1348+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21) && defined(CONFIG_SYSCTL_SYSCALL)
1349+ swap_security_ops(sysctl);
1350+#endif
1351+ swap_security_ops(sb_pivotroot);
1352+ swap_security_ops(sb_mount);
1353+ swap_security_ops(sb_umount);
1354+ swap_security_ops(inode_mknod);
1355+ swap_security_ops(inode_mkdir);
1356+ swap_security_ops(inode_rmdir);
1357+ swap_security_ops(inode_unlink);
1358+ swap_security_ops(inode_symlink);
1359+ swap_security_ops(inode_rename);
1360+ swap_security_ops(inode_link);
1361+ swap_security_ops(inode_create);
1362+ swap_security_ops(inode_setattr);
1363+ swap_security_ops(inode_getattr);
1364+#ifdef CONFIG_SECURITY_NETWORK
1365+ swap_security_ops(socket_bind);
1366+ swap_security_ops(socket_connect);
1367+ swap_security_ops(socket_listen);
1368+ swap_security_ops(socket_sendmsg);
1369+ swap_security_ops(socket_recvmsg);
1370+ swap_security_ops(socket_getsockname);
1371+ swap_security_ops(socket_getpeername);
1372+ swap_security_ops(socket_getsockopt);
1373+ swap_security_ops(socket_setsockopt);
1374+ swap_security_ops(socket_shutdown);
1375+ swap_security_ops(socket_accept);
1376+ swap_security_ops(inode_free_security);
1377+#endif
1378+}
1379+
1380+#undef swap_security_ops
1381+
1382+/**
1383+ * ccs_init - Initialize this module.
1384+ *
1385+ * Returns 0 on success, negative value otherwise.
1386+ */
1387+static int __init ccs_init(void)
1388+{
1389+ struct security_operations *ops = probe_security_ops();
1390+ if (!ops)
1391+ goto out;
1392+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1393+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1394+ if (!ccsecurity_exports.find_task_by_vpid)
1395+ goto out;
1396+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1397+ if (!ccsecurity_exports.find_task_by_pid_ns)
1398+ goto out;
1399+#endif
1400+ ccsecurity_exports.vfsmount_lock = probe_vfsmount_lock();
1401+ if (!ccsecurity_exports.vfsmount_lock)
1402+ goto out;
1403+ ccs_main_init();
1404+ ccs_update_security_ops(ops);
1405+ printk(KERN_INFO "AKARI: 1.0.47 2021/04/01\n");
1406+ printk(KERN_INFO
1407+ "Access Keeping And Regulating Instrument registered.\n");
1408+ return 0;
1409+out:
1410+ return -EINVAL;
1411+}
1412+
1413+module_init(ccs_init);
1414+MODULE_LICENSE("GPL");
1415+
1416+/**
1417+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1418+ *
1419+ * @domain: Pointer to "struct ccs_domain_info".
1420+ *
1421+ * Returns true if @domain is in use, false otherwise.
1422+ *
1423+ * Caller holds rcu_read_lock().
1424+ */
1425+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1426+{
1427+ return false;
1428+}
1429+
1430+/**
1431+ * ccs_add_task_security - Add "struct ccs_security" to list.
1432+ *
1433+ * @ptr: Pointer to "struct ccs_security".
1434+ * @list: Pointer to "struct list_head".
1435+ *
1436+ * Returns nothing.
1437+ */
1438+static void ccs_add_task_security(struct ccs_security *ptr,
1439+ struct list_head *list)
1440+{
1441+ unsigned long flags;
1442+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1443+ list_add_rcu(&ptr->list, list);
1444+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1445+}
1446+
1447+/**
1448+ * __ccs_alloc_task_security - Allocate memory for new tasks.
1449+ *
1450+ * @task: Pointer to "struct task_struct".
1451+ *
1452+ * Returns 0 on success, negative value otherwise.
1453+ */
1454+static int __ccs_alloc_task_security(const struct task_struct *task)
1455+{
1456+ struct ccs_security *old_security = ccs_current_security();
1457+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
1458+ GFP_KERNEL);
1459+ struct list_head *list = &ccs_task_security_list
1460+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1461+ if (!new_security)
1462+ return -ENOMEM;
1463+ new_security->task = task;
1464+ new_security->ccs_domain_info = old_security->ccs_domain_info;
1465+ new_security->ccs_flags = old_security->ccs_flags;
1466+ ccs_add_task_security(new_security, list);
1467+ return 0;
1468+}
1469+
1470+/**
1471+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1472+ *
1473+ * @task: Pointer to "struct task_struct".
1474+ *
1475+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1476+ * out of memory, &ccs_default_security otherwise.
1477+ *
1478+ * If @task is current thread and "struct ccs_security" for current thread was
1479+ * not found, I try to allocate it. But if allocation failed, current thread
1480+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1481+ * won't work.
1482+ */
1483+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1484+{
1485+ struct ccs_security *ptr;
1486+ struct list_head *list = &ccs_task_security_list
1487+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1488+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1489+ while (!list->next)
1490+ smp_rmb();
1491+ rcu_read_lock();
1492+ list_for_each_entry_rcu(ptr, list, list) {
1493+ if (ptr->task != task)
1494+ continue;
1495+ rcu_read_unlock();
1496+ return ptr;
1497+ }
1498+ rcu_read_unlock();
1499+ if (task != current)
1500+ return &ccs_default_security;
1501+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1502+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1503+ if (!ptr) {
1504+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1505+ task->pid);
1506+ send_sig(SIGKILL, current, 0);
1507+ return &ccs_oom_security;
1508+ }
1509+ *ptr = ccs_default_security;
1510+ ptr->task = task;
1511+ ccs_add_task_security(ptr, list);
1512+ return ptr;
1513+}
1514+
1515+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1516+
1517+/**
1518+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1519+ *
1520+ * @rcu: Pointer to "struct rcu_head".
1521+ *
1522+ * Returns nothing.
1523+ */
1524+static void ccs_rcu_free(struct rcu_head *rcu)
1525+{
1526+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
1527+ kfree(ptr);
1528+}
1529+
1530+#else
1531+
1532+/**
1533+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
1534+ *
1535+ * @arg: Pointer to "void".
1536+ *
1537+ * Returns nothing.
1538+ */
1539+static void ccs_rcu_free(void *arg)
1540+{
1541+ struct ccs_security *ptr = arg;
1542+ kfree(ptr);
1543+}
1544+
1545+#endif
1546+
1547+/**
1548+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
1549+ *
1550+ * @task: Pointer to "struct task_struct".
1551+ *
1552+ * Returns nothing.
1553+ */
1554+static void __ccs_free_task_security(const struct task_struct *task)
1555+{
1556+ unsigned long flags;
1557+ struct ccs_security *ptr = ccs_find_task_security(task);
1558+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
1559+ return;
1560+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1561+ list_del_rcu(&ptr->list);
1562+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1563+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)
1564+ call_rcu(&ptr->rcu, ccs_rcu_free);
1565+#else
1566+ call_rcu(&ptr->rcu, ccs_rcu_free, ptr);
1567+#endif
1568+}
--- tags/patches/1.0.47/lsm-2.6.29.c (nonexistent)
+++ tags/patches/1.0.47/lsm-2.6.29.c (revision 672)
@@ -0,0 +1,2246 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
12+#define USE_UMODE_T
13+#else
14+#include "check_umode_t.h"
15+#endif
16+
17+/* Prototype definition. */
18+static void ccs_task_security_gc(void);
19+static int ccs_copy_cred_security(const struct cred *new,
20+ const struct cred *old, gfp_t gfp);
21+static struct ccs_security *ccs_find_cred_security(const struct cred *cred);
22+static DEFINE_SPINLOCK(ccs_task_security_list_lock);
23+static atomic_t ccs_in_execve_tasks = ATOMIC_INIT(0);
24+/*
25+ * List of "struct ccs_security" for "struct pid".
26+ *
27+ * All instances on this list is guaranteed that "struct ccs_security"->pid !=
28+ * NULL. Also, instances on this list that are in execve() are guaranteed that
29+ * "struct ccs_security"->cred remembers "struct linux_binprm"->cred with a
30+ * refcount on "struct linux_binprm"->cred.
31+ */
32+struct list_head ccs_task_security_list[CCS_MAX_TASK_SECURITY_HASH];
33+/*
34+ * List of "struct ccs_security" for "struct cred".
35+ *
36+ * Since the number of "struct cred" is nearly equals to the number of
37+ * "struct pid", we allocate hash tables like ccs_task_security_list.
38+ *
39+ * All instances on this list are guaranteed that "struct ccs_security"->pid ==
40+ * NULL and "struct ccs_security"->cred != NULL.
41+ */
42+static struct list_head ccs_cred_security_list[CCS_MAX_TASK_SECURITY_HASH];
43+
44+/* Dummy security context for avoiding NULL pointer dereference. */
45+static struct ccs_security ccs_oom_security = {
46+ .ccs_domain_info = &ccs_kernel_domain
47+};
48+
49+/* Dummy security context for avoiding NULL pointer dereference. */
50+static struct ccs_security ccs_default_security = {
51+ .ccs_domain_info = &ccs_kernel_domain
52+};
53+
54+/* For exporting variables and functions. */
55+struct ccsecurity_exports ccsecurity_exports;
56+/* Members are updated by loadable kernel module. */
57+struct ccsecurity_operations ccsecurity_ops;
58+
59+/* Function pointers originally registered by register_security(). */
60+static struct security_operations original_security_ops /* = *security_ops; */;
61+
62+#ifdef CONFIG_AKARI_TRACE_EXECVE_COUNT
63+
64+/**
65+ * ccs_update_ee_counter - Update "struct ccs_execve" counter.
66+ *
67+ * @count: Count to increment or decrement.
68+ *
69+ * Returns updated counter.
70+ */
71+static unsigned int ccs_update_ee_counter(int count)
72+{
73+ /* Debug counter for detecting "struct ccs_execve" memory leak. */
74+ static atomic_t ccs_ee_counter = ATOMIC_INIT(0);
75+ return atomic_add_return(count, &ccs_ee_counter);
76+}
77+
78+/**
79+ * ccs_audit_alloc_execve - Audit allocation of "struct ccs_execve".
80+ *
81+ * @ee: Pointer to "struct ccs_execve".
82+ *
83+ * Returns nothing.
84+ */
85+void ccs_audit_alloc_execve(const struct ccs_execve * const ee)
86+{
87+ printk(KERN_INFO "AKARI: Allocated %p by pid=%u (count=%u)\n", ee,
88+ current->pid, ccs_update_ee_counter(1) - 1);
89+}
90+
91+/**
92+ * ccs_audit_free_execve - Audit release of "struct ccs_execve".
93+ *
94+ * @ee: Pointer to "struct ccs_execve".
95+ * @task: True if released by current task, false otherwise.
96+ *
97+ * Returns nothing.
98+ */
99+void ccs_audit_free_execve(const struct ccs_execve * const ee,
100+ const bool is_current)
101+{
102+ const unsigned int tmp = ccs_update_ee_counter(-1);
103+ if (is_current)
104+ printk(KERN_INFO "AKARI: Releasing %p by pid=%u (count=%u)\n",
105+ ee, current->pid, tmp);
106+ else
107+ printk(KERN_INFO "AKARI: Releasing %p by kernel (count=%u)\n",
108+ ee, tmp);
109+}
110+
111+#endif
112+
113+#if !defined(CONFIG_AKARI_DEBUG)
114+#define ccs_debug_trace(pos) do { } while (0)
115+#else
116+#define ccs_debug_trace(pos) \
117+ do { \
118+ static bool done; \
119+ if (!done) { \
120+ printk(KERN_INFO \
121+ "AKARI: Debug trace: " pos " of 4\n"); \
122+ done = true; \
123+ } \
124+ } while (0)
125+#endif
126+
127+/**
128+ * ccs_clear_execve - Release memory used by do_execve().
129+ *
130+ * @ret: 0 if do_execve() succeeded, negative value otherwise.
131+ * @security: Pointer to "struct ccs_security".
132+ *
133+ * Returns nothing.
134+ */
135+static void ccs_clear_execve(int ret, struct ccs_security *security)
136+{
137+ struct ccs_execve *ee;
138+ if (security == &ccs_default_security || security == &ccs_oom_security)
139+ return;
140+ ee = security->ee;
141+ security->ee = NULL;
142+ if (!ee)
143+ return;
144+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
145+ /*
146+ * Drop refcount on "struct cred" in "struct linux_binprm" and forget
147+ * it.
148+ */
149+ put_cred(security->cred);
150+ security->cred = NULL;
151+#endif
152+ atomic_dec(&ccs_in_execve_tasks);
153+ ccs_finish_execve(ret, ee);
154+}
155+
156+/**
157+ * ccs_rcu_free - RCU callback for releasing "struct ccs_security".
158+ *
159+ * @rcu: Pointer to "struct rcu_head".
160+ *
161+ * Returns nothing.
162+ */
163+static void ccs_rcu_free(struct rcu_head *rcu)
164+{
165+ struct ccs_security *ptr = container_of(rcu, typeof(*ptr), rcu);
166+ struct ccs_execve *ee = ptr->ee;
167+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
168+ /*
169+ * If this security context was associated with "struct pid" and
170+ * ptr->ccs_flags has CCS_TASK_IS_IN_EXECVE set, it indicates that a
171+ * "struct task_struct" associated with this security context exited
172+ * immediately after do_execve() has failed.
173+ */
174+ if (ptr->pid && (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE)) {
175+ ccs_debug_trace("1");
176+ atomic_dec(&ccs_in_execve_tasks);
177+ }
178+#else
179+ /*
180+ * If this security context was associated with "struct pid" and
181+ * remembers "struct cred" in "struct linux_binprm", it indicates that
182+ * a "struct task_struct" associated with this security context exited
183+ * immediately after do_execve() has failed.
184+ */
185+ if (ptr->pid && ptr->cred) {
186+ ccs_debug_trace("1");
187+ put_cred(ptr->cred);
188+ atomic_dec(&ccs_in_execve_tasks);
189+ }
190+#endif
191+ /*
192+ * If this security context was associated with "struct pid",
193+ * drop refcount obtained by get_pid() in ccs_find_task_security().
194+ */
195+ if (ptr->pid) {
196+ ccs_debug_trace("2");
197+ put_pid(ptr->pid);
198+ }
199+ if (ee) {
200+ ccs_debug_trace("3");
201+ ccs_audit_free_execve(ee, false);
202+ kfree(ee->handler_path);
203+ kfree(ee);
204+ }
205+ kfree(ptr);
206+}
207+
208+/**
209+ * ccs_del_security - Release "struct ccs_security".
210+ *
211+ * @ptr: Pointer to "struct ccs_security".
212+ *
213+ * Returns nothing.
214+ */
215+static void ccs_del_security(struct ccs_security *ptr)
216+{
217+ unsigned long flags;
218+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
219+ return;
220+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
221+ list_del_rcu(&ptr->list);
222+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
223+ call_rcu(&ptr->rcu, ccs_rcu_free);
224+}
225+
226+/**
227+ * ccs_add_cred_security - Add "struct ccs_security" to list.
228+ *
229+ * @ptr: Pointer to "struct ccs_security".
230+ *
231+ * Returns nothing.
232+ */
233+static void ccs_add_cred_security(struct ccs_security *ptr)
234+{
235+ unsigned long flags;
236+ struct list_head *list = &ccs_cred_security_list
237+ [hash_ptr((void *) ptr->cred, CCS_TASK_SECURITY_HASH_BITS)];
238+#ifdef CONFIG_AKARI_DEBUG
239+ if (ptr->pid)
240+ printk(KERN_INFO "AKARI: \"struct ccs_security\"->pid != NULL"
241+ "\n");
242+#endif
243+ ptr->pid = NULL;
244+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
245+ list_add_rcu(&ptr->list, list);
246+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
247+}
248+
249+/**
250+ * ccs_task_create - Make snapshot of security context for new task.
251+ *
252+ * @clone_flags: Flags passed to clone().
253+ *
254+ * Returns 0 on success, negative value otherwise.
255+ */
256+static int ccs_task_create(unsigned long clone_flags)
257+{
258+ int rc;
259+ struct ccs_security *old_security;
260+ struct ccs_security *new_security;
261+ struct cred *cred = prepare_creds();
262+ if (!cred)
263+ return -ENOMEM;
264+ while (!original_security_ops.task_create)
265+ smp_rmb();
266+ rc = original_security_ops.task_create(clone_flags);
267+ if (rc) {
268+ abort_creds(cred);
269+ return rc;
270+ }
271+ old_security = ccs_find_task_security(current);
272+ new_security = ccs_find_cred_security(cred);
273+ new_security->ccs_domain_info = old_security->ccs_domain_info;
274+ new_security->ccs_flags = old_security->ccs_flags;
275+ return commit_creds(cred);
276+}
277+
278+/**
279+ * ccs_cred_prepare - Allocate memory for new credentials.
280+ *
281+ * @new: Pointer to "struct cred".
282+ * @old: Pointer to "struct cred".
283+ * @gfp: Memory allocation flags.
284+ *
285+ * Returns 0 on success, negative value otherwise.
286+ */
287+static int ccs_cred_prepare(struct cred *new, const struct cred *old,
288+ gfp_t gfp)
289+{
290+ int rc;
291+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
292+ /*
293+ * For checking whether reverting domain transition is needed or not.
294+ *
295+ * See ccs_find_task_security() for reason.
296+ */
297+ if (gfp == GFP_KERNEL)
298+ ccs_find_task_security(current);
299+#endif
300+ rc = ccs_copy_cred_security(new, old, gfp);
301+ if (rc)
302+ return rc;
303+ if (gfp == GFP_KERNEL)
304+ ccs_task_security_gc();
305+ while (!original_security_ops.cred_prepare)
306+ smp_rmb();
307+ rc = original_security_ops.cred_prepare(new, old, gfp);
308+ if (rc)
309+ ccs_del_security(ccs_find_cred_security(new));
310+ return rc;
311+}
312+
313+/**
314+ * ccs_cred_free - Release memory used by credentials.
315+ *
316+ * @cred: Pointer to "struct cred".
317+ *
318+ * Returns nothing.
319+ */
320+static void ccs_cred_free(struct cred *cred)
321+{
322+ while (!original_security_ops.cred_free)
323+ smp_rmb();
324+ original_security_ops.cred_free(cred);
325+ ccs_del_security(ccs_find_cred_security(cred));
326+}
327+
328+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
329+
330+/**
331+ * ccs_alloc_cred_security - Allocate memory for new credentials.
332+ *
333+ * @cred: Pointer to "struct cred".
334+ * @gfp: Memory allocation flags.
335+ *
336+ * Returns 0 on success, negative value otherwise.
337+ */
338+static int ccs_alloc_cred_security(const struct cred *cred, gfp_t gfp)
339+{
340+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
341+ gfp);
342+ if (!new_security)
343+ return -ENOMEM;
344+ new_security->cred = cred;
345+ ccs_add_cred_security(new_security);
346+ return 0;
347+}
348+
349+/**
350+ * ccs_cred_alloc_blank - Allocate memory for new credentials.
351+ *
352+ * @new: Pointer to "struct cred".
353+ * @gfp: Memory allocation flags.
354+ *
355+ * Returns 0 on success, negative value otherwise.
356+ */
357+static int ccs_cred_alloc_blank(struct cred *new, gfp_t gfp)
358+{
359+ int rc = ccs_alloc_cred_security(new, gfp);
360+ if (rc)
361+ return rc;
362+ while (!original_security_ops.cred_alloc_blank)
363+ smp_rmb();
364+ rc = original_security_ops.cred_alloc_blank(new, gfp);
365+ if (rc)
366+ ccs_del_security(ccs_find_cred_security(new));
367+ return rc;
368+}
369+
370+/**
371+ * ccs_cred_transfer - Transfer "struct ccs_security" between credentials.
372+ *
373+ * @new: Pointer to "struct cred".
374+ * @old: Pointer to "struct cred".
375+ *
376+ * Returns nothing.
377+ */
378+static void ccs_cred_transfer(struct cred *new, const struct cred *old)
379+{
380+ struct ccs_security *new_security;
381+ struct ccs_security *old_security;
382+ while (!original_security_ops.cred_transfer)
383+ smp_rmb();
384+ original_security_ops.cred_transfer(new, old);
385+ new_security = ccs_find_cred_security(new);
386+ old_security = ccs_find_cred_security(old);
387+ if (new_security == &ccs_default_security ||
388+ new_security == &ccs_oom_security ||
389+ old_security == &ccs_default_security ||
390+ old_security == &ccs_oom_security)
391+ return;
392+ new_security->ccs_flags = old_security->ccs_flags;
393+ new_security->ccs_domain_info = old_security->ccs_domain_info;
394+}
395+
396+#endif
397+
398+/**
399+ * ccs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
400+ *
401+ * @bprm: Pointer to "struct linux_binprm".
402+ *
403+ * Returns nothing.
404+ */
405+static void ccs_bprm_committing_creds(struct linux_binprm *bprm)
406+{
407+ struct ccs_security *old_security;
408+ struct ccs_security *new_security;
409+ while (!original_security_ops.bprm_committing_creds)
410+ smp_rmb();
411+ original_security_ops.bprm_committing_creds(bprm);
412+ old_security = ccs_current_security();
413+ if (old_security == &ccs_default_security ||
414+ old_security == &ccs_oom_security)
415+ return;
416+ ccs_clear_execve(0, old_security);
417+ /* Update current task's cred's domain for future fork(). */
418+ new_security = ccs_find_cred_security(bprm->cred);
419+ new_security->ccs_flags = old_security->ccs_flags;
420+ new_security->ccs_domain_info = old_security->ccs_domain_info;
421+}
422+
423+/**
424+ * ccs_bprm_check_security - Check permission for execve().
425+ *
426+ * @bprm: Pointer to "struct linux_binprm".
427+ *
428+ * Returns 0 on success, negative value otherwise.
429+ */
430+static int ccs_bprm_check_security(struct linux_binprm *bprm)
431+{
432+ struct ccs_security *security = ccs_current_security();
433+ if (security == &ccs_default_security || security == &ccs_oom_security)
434+ return -ENOMEM;
435+ if (!security->ee) {
436+ int rc;
437+#ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER
438+ if (!ccs_policy_loaded)
439+ ccs_load_policy(bprm->filename);
440+#endif
441+ rc = ccs_start_execve(bprm, &security->ee);
442+ if (security->ee) {
443+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
444+ /*
445+ * Get refcount on "struct cred" in
446+ * "struct linux_binprm" and remember it.
447+ */
448+ get_cred(bprm->cred);
449+ security->cred = bprm->cred;
450+#endif
451+ atomic_inc(&ccs_in_execve_tasks);
452+ }
453+ if (rc)
454+ return rc;
455+ }
456+ while (!original_security_ops.bprm_check_security)
457+ smp_rmb();
458+ return original_security_ops.bprm_check_security(bprm);
459+}
460+
461+/**
462+ * ccs_open - Check permission for open().
463+ *
464+ * @f: Pointer to "struct file".
465+ *
466+ * Returns 0 on success, negative value otherwise.
467+ */
468+static int ccs_open(struct file *f)
469+{
470+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
471+ return ccs_open_permission(f);
472+#elif defined(RHEL_MAJOR) && RHEL_MAJOR == 6
473+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
474+ f->f_flags);
475+#else
476+ return ccs_open_permission(f->f_path.dentry, f->f_path.mnt,
477+ f->f_flags + 1);
478+#endif
479+}
480+
481+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
482+
483+/**
484+ * ccs_file_open - Check permission for open().
485+ *
486+ * @f: Pointer to "struct file".
487+ * @cred: Pointer to "struct cred".
488+ *
489+ * Returns 0 on success, negative value otherwise.
490+ */
491+static int ccs_file_open(struct file *f, const struct cred *cred)
492+{
493+ int rc = ccs_open(f);
494+ if (rc)
495+ return rc;
496+ while (!original_security_ops.file_open)
497+ smp_rmb();
498+ return original_security_ops.file_open(f, cred);
499+}
500+
501+#else
502+
503+/**
504+ * ccs_dentry_open - Check permission for open().
505+ *
506+ * @f: Pointer to "struct file".
507+ * @cred: Pointer to "struct cred".
508+ *
509+ * Returns 0 on success, negative value otherwise.
510+ */
511+static int ccs_dentry_open(struct file *f, const struct cred *cred)
512+{
513+ int rc = ccs_open(f);
514+ if (rc)
515+ return rc;
516+ while (!original_security_ops.dentry_open)
517+ smp_rmb();
518+ return original_security_ops.dentry_open(f, cred);
519+}
520+
521+#endif
522+
523+#if defined(CONFIG_SECURITY_PATH)
524+
525+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
526+
527+/**
528+ * ccs_path_chown - Check permission for chown()/chgrp().
529+ *
530+ * @path: Pointer to "struct path".
531+ * @user: User ID.
532+ * @group: Group ID.
533+ *
534+ * Returns 0 on success, negative value otherwise.
535+ */
536+static int ccs_path_chown(struct path *path, kuid_t user, kgid_t group)
537+{
538+ int rc = ccs_chown_permission(path->dentry, path->mnt, user, group);
539+ if (rc)
540+ return rc;
541+ while (!original_security_ops.path_chown)
542+ smp_rmb();
543+ return original_security_ops.path_chown(path, user, group);
544+}
545+
546+/**
547+ * ccs_path_chmod - Check permission for chmod().
548+ *
549+ * @path: Pointer to "struct path".
550+ * @mode: Mode.
551+ *
552+ * Returns 0 on success, negative value otherwise.
553+ */
554+static int ccs_path_chmod(struct path *path, umode_t mode)
555+{
556+ int rc = ccs_chmod_permission(path->dentry, path->mnt, mode);
557+ if (rc)
558+ return rc;
559+ while (!original_security_ops.path_chmod)
560+ smp_rmb();
561+ return original_security_ops.path_chmod(path, mode);
562+}
563+
564+/**
565+ * ccs_path_chroot - Check permission for chroot().
566+ *
567+ * @path: Pointer to "struct path".
568+ *
569+ * Returns 0 on success, negative value otherwise.
570+ */
571+static int ccs_path_chroot(struct path *path)
572+{
573+ int rc = ccs_chroot_permission(path);
574+ if (rc)
575+ return rc;
576+ while (!original_security_ops.path_chroot)
577+ smp_rmb();
578+ return original_security_ops.path_chroot(path);
579+}
580+
581+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
582+
583+/**
584+ * ccs_path_chown - Check permission for chown()/chgrp().
585+ *
586+ * @path: Pointer to "struct path".
587+ * @user: User ID.
588+ * @group: Group ID.
589+ *
590+ * Returns 0 on success, negative value otherwise.
591+ */
592+static int ccs_path_chown(struct path *path, uid_t user, gid_t group)
593+{
594+ int rc = ccs_chown_permission(path->dentry, path->mnt, user, group);
595+ if (rc)
596+ return rc;
597+ while (!original_security_ops.path_chown)
598+ smp_rmb();
599+ return original_security_ops.path_chown(path, user, group);
600+}
601+
602+#if defined(USE_UMODE_T)
603+
604+/**
605+ * ccs_path_chmod - Check permission for chmod().
606+ *
607+ * @path: Pointer to "struct path".
608+ * @mode: Mode.
609+ *
610+ * Returns 0 on success, negative value otherwise.
611+ */
612+static int ccs_path_chmod(struct path *path, umode_t mode)
613+{
614+ int rc = ccs_chmod_permission(path->dentry, path->mnt, mode);
615+ if (rc)
616+ return rc;
617+ while (!original_security_ops.path_chmod)
618+ smp_rmb();
619+ return original_security_ops.path_chmod(path, mode);
620+}
621+
622+#else
623+
624+/**
625+ * ccs_path_chmod - Check permission for chmod().
626+ *
627+ * @dentry: Pointer to "struct dentry".
628+ * @vfsmnt: Pointer to "struct vfsmount".
629+ * @mode: Mode.
630+ *
631+ * Returns 0 on success, negative value otherwise.
632+ */
633+static int ccs_path_chmod(struct dentry *dentry, struct vfsmount *vfsmnt,
634+ mode_t mode)
635+{
636+ int rc = ccs_chmod_permission(dentry, vfsmnt, mode);
637+ if (rc)
638+ return rc;
639+ while (!original_security_ops.path_chmod)
640+ smp_rmb();
641+ return original_security_ops.path_chmod(dentry, vfsmnt, mode);
642+}
643+
644+#endif
645+
646+/**
647+ * ccs_path_chroot - Check permission for chroot().
648+ *
649+ * @path: Pointer to "struct path".
650+ *
651+ * Returns 0 on success, negative value otherwise.
652+ */
653+static int ccs_path_chroot(struct path *path)
654+{
655+ int rc = ccs_chroot_permission(path);
656+ if (rc)
657+ return rc;
658+ while (!original_security_ops.path_chroot)
659+ smp_rmb();
660+ return original_security_ops.path_chroot(path);
661+}
662+
663+#endif
664+
665+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
666+
667+/**
668+ * ccs_path_truncate - Check permission for truncate().
669+ *
670+ * @path: Pointer to "struct path".
671+ *
672+ * Returns 0 on success, negative value otherwise.
673+ */
674+static int ccs_path_truncate(struct path *path)
675+{
676+ int rc = ccs_truncate_permission(path->dentry, path->mnt);
677+ if (rc)
678+ return rc;
679+ while (!original_security_ops.path_truncate)
680+ smp_rmb();
681+ return original_security_ops.path_truncate(path);
682+}
683+
684+#else
685+
686+/**
687+ * ccs_path_truncate - Check permission for truncate().
688+ *
689+ * @path: Pointer to "struct path".
690+ * @length: New length.
691+ * @time_attrs: New time attributes.
692+ *
693+ * Returns 0 on success, negative value otherwise.
694+ */
695+static int ccs_path_truncate(struct path *path, loff_t length,
696+ unsigned int time_attrs)
697+{
698+ int rc = ccs_truncate_permission(path->dentry, path->mnt);
699+ if (rc)
700+ return rc;
701+ while (!original_security_ops.path_truncate)
702+ smp_rmb();
703+ return original_security_ops.path_truncate(path, length, time_attrs);
704+}
705+
706+#endif
707+
708+#endif
709+
710+/**
711+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
712+ *
713+ * @dentry: Pointer to "struct dentry".
714+ * @attr: Pointer to "struct iattr".
715+ *
716+ * Returns 0 on success, negative value otherwise.
717+ */
718+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
719+{
720+ int rc = 0;
721+#if !defined(CONFIG_SECURITY_PATH) || LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
722+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
723+ if (attr->ia_valid & ATTR_UID)
724+ rc = ccs_chown_permission(dentry, NULL, attr->ia_uid,
725+ INVALID_GID);
726+ if (!rc && (attr->ia_valid & ATTR_GID))
727+ rc = ccs_chown_permission(dentry, NULL, INVALID_UID,
728+ attr->ia_gid);
729+#else
730+ if (attr->ia_valid & ATTR_UID)
731+ rc = ccs_chown_permission(dentry, NULL, attr->ia_uid, -1);
732+ if (!rc && (attr->ia_valid & ATTR_GID))
733+ rc = ccs_chown_permission(dentry, NULL, -1, attr->ia_gid);
734+#endif
735+ if (!rc && (attr->ia_valid & ATTR_MODE))
736+ rc = ccs_chmod_permission(dentry, NULL, attr->ia_mode);
737+#endif
738+#if !defined(CONFIG_SECURITY_PATH)
739+ if (!rc && (attr->ia_valid & ATTR_SIZE))
740+ rc = ccs_truncate_permission(dentry, NULL);
741+#endif
742+ if (rc)
743+ return rc;
744+ while (!original_security_ops.inode_setattr)
745+ smp_rmb();
746+ return original_security_ops.inode_setattr(dentry, attr);
747+}
748+
749+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
750+
751+/**
752+ * ccs_inode_getattr - Check permission for stat().
753+ *
754+ * @path: Pointer to "struct path".
755+ *
756+ * Returns 0 on success, negative value otherwise.
757+ */
758+static int ccs_inode_getattr(const struct path *path)
759+{
760+ int rc = ccs_getattr_permission(path->mnt, path->dentry);
761+ if (rc)
762+ return rc;
763+ while (!original_security_ops.inode_getattr)
764+ smp_rmb();
765+ return original_security_ops.inode_getattr(path);
766+}
767+
768+#else
769+
770+/**
771+ * ccs_inode_getattr - Check permission for stat().
772+ *
773+ * @mnt: Pointer to "struct vfsmount".
774+ * @dentry: Pointer to "struct dentry".
775+ *
776+ * Returns 0 on success, negative value otherwise.
777+ */
778+static int ccs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
779+{
780+ int rc = ccs_getattr_permission(mnt, dentry);
781+ if (rc)
782+ return rc;
783+ while (!original_security_ops.inode_getattr)
784+ smp_rmb();
785+ return original_security_ops.inode_getattr(mnt, dentry);
786+}
787+
788+#endif
789+
790+#if defined(CONFIG_SECURITY_PATH)
791+
792+#if defined(USE_UMODE_T)
793+
794+/**
795+ * ccs_path_mknod - Check permission for mknod().
796+ *
797+ * @dir: Pointer to "struct path".
798+ * @dentry: Pointer to "struct dentry".
799+ * @mode: Create mode.
800+ * @dev: Device major/minor number.
801+ *
802+ * Returns 0 on success, negative value otherwise.
803+ */
804+static int ccs_path_mknod(struct path *dir, struct dentry *dentry,
805+ umode_t mode, unsigned int dev)
806+{
807+ int rc = ccs_mknod_permission(dentry, dir->mnt, mode, dev);
808+ if (rc)
809+ return rc;
810+ while (!original_security_ops.path_mknod)
811+ smp_rmb();
812+ return original_security_ops.path_mknod(dir, dentry, mode, dev);
813+}
814+
815+/**
816+ * ccs_path_mkdir - Check permission for mkdir().
817+ *
818+ * @dir: Pointer to "struct path".
819+ * @dentry: Pointer to "struct dentry".
820+ * @mode: Create mode.
821+ *
822+ * Returns 0 on success, negative value otherwise.
823+ */
824+static int ccs_path_mkdir(struct path *dir, struct dentry *dentry,
825+ umode_t mode)
826+{
827+ int rc = ccs_mkdir_permission(dentry, dir->mnt, mode);
828+ if (rc)
829+ return rc;
830+ while (!original_security_ops.path_mkdir)
831+ smp_rmb();
832+ return original_security_ops.path_mkdir(dir, dentry, mode);
833+}
834+
835+#else
836+
837+/**
838+ * ccs_path_mknod - Check permission for mknod().
839+ *
840+ * @dir: Pointer to "struct path".
841+ * @dentry: Pointer to "struct dentry".
842+ * @mode: Create mode.
843+ * @dev: Device major/minor number.
844+ *
845+ * Returns 0 on success, negative value otherwise.
846+ */
847+static int ccs_path_mknod(struct path *dir, struct dentry *dentry, int mode,
848+ unsigned int dev)
849+{
850+ int rc = ccs_mknod_permission(dentry, dir->mnt, mode, dev);
851+ if (rc)
852+ return rc;
853+ while (!original_security_ops.path_mknod)
854+ smp_rmb();
855+ return original_security_ops.path_mknod(dir, dentry, mode, dev);
856+}
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.47 2021/04/01\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.47/lsm-4.12.c (nonexistent)
+++ tags/patches/1.0.47/lsm-4.12.c (revision 672)
@@ -0,0 +1,1392 @@
1+/*
2+ * lsm.c
3+ *
4+ * Copyright (C) 2010-2015 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5+ *
6+ * Version: 1.0.47 2021/04/01
7+ */
8+
9+#include "internal.h"
10+#include "probe.h"
11+
12+/* Prototype definition. */
13+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+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
229+ if (!strcmp(bprm->filename, "none")) {
230+ /*
231+ * Since we can't calculate pathname when called from
232+ * call_usermodehelper_setup_file() from fork_usermode_blob(),
233+ * skip permission check and suppress domain transition.
234+ */
235+ const char *s = kstrdup_const(bprm->filename, GFP_NOWAIT | __GFP_NOWARN);
236+
237+ if (s == bprm->filename)
238+ return 0;
239+ kfree_const(s);
240+ }
241+#endif
242+ return ccs_start_execve(bprm, &security->ee);
243+}
244+
245+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) || (defined(RHEL_MAJOR) && RHEL_MAJOR == 8)
246+/**
247+ * ccs_file_open - Check permission for open().
248+ *
249+ * @f: Pointer to "struct file".
250+ *
251+ * Returns 0 on success, negative value otherwise.
252+ */
253+static int ccs_file_open(struct file *f)
254+{
255+ return ccs_open_permission(f);
256+}
257+#else
258+/**
259+ * ccs_file_open - Check permission for open().
260+ *
261+ * @f: Pointer to "struct file".
262+ * @cred: Pointer to "struct cred".
263+ *
264+ * Returns 0 on success, negative value otherwise.
265+ */
266+static int ccs_file_open(struct file *f, const struct cred *cred)
267+{
268+ return ccs_open_permission(f);
269+}
270+#endif
271+
272+#ifdef CONFIG_SECURITY_PATH
273+
274+/**
275+ * ccs_path_chown - Check permission for chown()/chgrp().
276+ *
277+ * @path: Pointer to "struct path".
278+ * @user: User ID.
279+ * @group: Group ID.
280+ *
281+ * Returns 0 on success, negative value otherwise.
282+ */
283+static int ccs_path_chown(const struct path *path, kuid_t user, kgid_t group)
284+{
285+ return ccs_chown_permission(path->dentry, path->mnt, user, group);
286+}
287+
288+/**
289+ * ccs_path_chmod - Check permission for chmod().
290+ *
291+ * @path: Pointer to "struct path".
292+ * @mode: Mode.
293+ *
294+ * Returns 0 on success, negative value otherwise.
295+ */
296+static int ccs_path_chmod(const struct path *path, umode_t mode)
297+{
298+ return ccs_chmod_permission(path->dentry, path->mnt, mode);
299+}
300+
301+/**
302+ * ccs_path_chroot - Check permission for chroot().
303+ *
304+ * @path: Pointer to "struct path".
305+ *
306+ * Returns 0 on success, negative value otherwise.
307+ */
308+static int ccs_path_chroot(const struct path *path)
309+{
310+ return ccs_chroot_permission(path);
311+}
312+
313+/**
314+ * ccs_path_truncate - Check permission for truncate().
315+ *
316+ * @path: Pointer to "struct path".
317+ *
318+ * Returns 0 on success, negative value otherwise.
319+ */
320+static int ccs_path_truncate(const struct path *path)
321+{
322+ return ccs_truncate_permission(path->dentry, path->mnt);
323+}
324+
325+#else
326+
327+/**
328+ * ccs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
329+ *
330+ * @dentry: Pointer to "struct dentry".
331+ * @attr: Pointer to "struct iattr".
332+ *
333+ * Returns 0 on success, negative value otherwise.
334+ */
335+static int ccs_inode_setattr(struct dentry *dentry, struct iattr *attr)
336+{
337+ const int rc1 = (attr->ia_valid & ATTR_UID) ?
338+ ccs_chown_permission(dentry, NULL, attr->ia_uid, INVALID_GID) :
339+ 0;
340+ const int rc2 = (attr->ia_valid & ATTR_GID) ?
341+ ccs_chown_permission(dentry, NULL, INVALID_UID, attr->ia_gid) :
342+ 0;
343+ const int rc3 = (attr->ia_valid & ATTR_MODE) ?
344+ ccs_chmod_permission(dentry, NULL, attr->ia_mode) : 0;
345+ const int rc4 = (attr->ia_valid & ATTR_SIZE) ?
346+ ccs_truncate_permission(dentry, NULL) : 0;
347+ if (rc4)
348+ return rc4;
349+ if (rc3)
350+ return rc3;
351+ if (rc2)
352+ return rc2;
353+ return rc1;
354+}
355+
356+#endif
357+
358+/**
359+ * ccs_inode_getattr - Check permission for stat().
360+ *
361+ * @path: Pointer to "struct path".
362+ *
363+ * Returns 0 on success, negative value otherwise.
364+ */
365+static int ccs_inode_getattr(const struct path *path)
366+{
367+ return ccs_getattr_permission(path->mnt, path->dentry);
368+}
369+
370+#ifdef CONFIG_SECURITY_PATH
371+
372+/**
373+ * ccs_path_mknod - Check permission for mknod().
374+ *
375+ * @dir: Pointer to "struct path".
376+ * @dentry: Pointer to "struct dentry".
377+ * @mode: Create mode.
378+ * @dev: Device major/minor number.
379+ *
380+ * Returns 0 on success, negative value otherwise.
381+ */
382+static int ccs_path_mknod(const struct path *dir, struct dentry *dentry,
383+ umode_t mode, unsigned int dev)
384+{
385+ return ccs_mknod_permission(dentry, dir->mnt, mode, dev);
386+}
387+
388+/**
389+ * ccs_path_mkdir - Check permission for mkdir().
390+ *
391+ * @dir: Pointer to "struct path".
392+ * @dentry: Pointer to "struct dentry".
393+ * @mode: Create mode.
394+ *
395+ * Returns 0 on success, negative value otherwise.
396+ */
397+static int ccs_path_mkdir(const struct path *dir, struct dentry *dentry,
398+ umode_t mode)
399+{
400+ return ccs_mkdir_permission(dentry, dir->mnt, mode);
401+}
402+
403+/**
404+ * ccs_path_rmdir - Check permission for rmdir().
405+ *
406+ * @dir: Pointer to "struct path".
407+ * @dentry: Pointer to "struct dentry".
408+ *
409+ * Returns 0 on success, negative value otherwise.
410+ */
411+static int ccs_path_rmdir(const struct path *dir, struct dentry *dentry)
412+{
413+ return ccs_rmdir_permission(dentry, dir->mnt);
414+}
415+
416+/**
417+ * ccs_path_unlink - Check permission for unlink().
418+ *
419+ * @dir: Pointer to "struct path".
420+ * @dentry: Pointer to "struct dentry".
421+ *
422+ * Returns 0 on success, negative value otherwise.
423+ */
424+static int ccs_path_unlink(const struct path *dir, struct dentry *dentry)
425+{
426+ return ccs_unlink_permission(dentry, dir->mnt);
427+}
428+
429+/**
430+ * ccs_path_symlink - Check permission for symlink().
431+ *
432+ * @dir: Pointer to "struct path".
433+ * @dentry: Pointer to "struct dentry".
434+ * @old_name: Content of symbolic link.
435+ *
436+ * Returns 0 on success, negative value otherwise.
437+ */
438+static int ccs_path_symlink(const struct path *dir, struct dentry *dentry,
439+ const char *old_name)
440+{
441+ return ccs_symlink_permission(dentry, dir->mnt, old_name);
442+}
443+
444+/**
445+ * ccs_path_rename - Check permission for rename().
446+ *
447+ * @old_dir: Pointer to "struct path".
448+ * @old_dentry: Pointer to "struct dentry".
449+ * @new_dir: Pointer to "struct path".
450+ * @new_dentry: Pointer to "struct dentry".
451+ *
452+ * Returns 0 on success, negative value otherwise.
453+ */
454+static int ccs_path_rename(const struct path *old_dir,
455+ struct dentry *old_dentry,
456+ const struct path *new_dir,
457+ struct dentry *new_dentry)
458+{
459+ return ccs_rename_permission(old_dentry, new_dentry, old_dir->mnt);
460+}
461+
462+/**
463+ * ccs_path_link - Check permission for link().
464+ *
465+ * @old_dentry: Pointer to "struct dentry".
466+ * @new_dir: Pointer to "struct path".
467+ * @new_dentry: Pointer to "struct dentry".
468+ *
469+ * Returns 0 on success, negative value otherwise.
470+ */
471+static int ccs_path_link(struct dentry *old_dentry, const struct path *new_dir,
472+ struct dentry *new_dentry)
473+{
474+ return ccs_link_permission(old_dentry, new_dentry, new_dir->mnt);
475+}
476+
477+#else
478+
479+/**
480+ * ccs_inode_mknod - Check permission for mknod().
481+ *
482+ * @dir: Pointer to "struct inode".
483+ * @dentry: Pointer to "struct dentry".
484+ * @mode: Create mode.
485+ * @dev: Device major/minor number.
486+ *
487+ * Returns 0 on success, negative value otherwise.
488+ */
489+static int ccs_inode_mknod(struct inode *dir, struct dentry *dentry,
490+ umode_t mode, dev_t dev)
491+{
492+ return ccs_mknod_permission(dentry, NULL, mode, dev);
493+}
494+
495+/**
496+ * ccs_inode_mkdir - Check permission for mkdir().
497+ *
498+ * @dir: Pointer to "struct inode".
499+ * @dentry: Pointer to "struct dentry".
500+ * @mode: Create mode.
501+ *
502+ * Returns 0 on success, negative value otherwise.
503+ */
504+static int ccs_inode_mkdir(struct inode *dir, struct dentry *dentry,
505+ umode_t mode)
506+{
507+ return ccs_mkdir_permission(dentry, NULL, mode);
508+}
509+
510+/**
511+ * ccs_inode_rmdir - Check permission for rmdir().
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_rmdir(struct inode *dir, struct dentry *dentry)
519+{
520+ return ccs_rmdir_permission(dentry, NULL);
521+}
522+
523+/**
524+ * ccs_inode_unlink - Check permission for unlink().
525+ *
526+ * @dir: Pointer to "struct inode".
527+ * @dentry: Pointer to "struct dentry".
528+ *
529+ * Returns 0 on success, negative value otherwise.
530+ */
531+static int ccs_inode_unlink(struct inode *dir, struct dentry *dentry)
532+{
533+ return ccs_unlink_permission(dentry, NULL);
534+}
535+
536+/**
537+ * ccs_inode_symlink - Check permission for symlink().
538+ *
539+ * @dir: Pointer to "struct inode".
540+ * @dentry: Pointer to "struct dentry".
541+ * @old_name: Content of symbolic link.
542+ *
543+ * Returns 0 on success, negative value otherwise.
544+ */
545+static int ccs_inode_symlink(struct inode *dir, struct dentry *dentry,
546+ const char *old_name)
547+{
548+ return ccs_symlink_permission(dentry, NULL, old_name);
549+}
550+
551+/**
552+ * ccs_inode_rename - Check permission for rename().
553+ *
554+ * @old_dir: Pointer to "struct inode".
555+ * @old_dentry: Pointer to "struct dentry".
556+ * @new_dir: Pointer to "struct inode".
557+ * @new_dentry: Pointer to "struct dentry".
558+ *
559+ * Returns 0 on success, negative value otherwise.
560+ */
561+static int ccs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
562+ struct inode *new_dir, struct dentry *new_dentry)
563+{
564+ return ccs_rename_permission(old_dentry, new_dentry, NULL);
565+}
566+
567+/**
568+ * ccs_inode_link - Check permission for link().
569+ *
570+ * @old_dentry: Pointer to "struct dentry".
571+ * @dir: Pointer to "struct inode".
572+ * @new_dentry: Pointer to "struct dentry".
573+ *
574+ * Returns 0 on success, negative value otherwise.
575+ */
576+static int ccs_inode_link(struct dentry *old_dentry, struct inode *dir,
577+ struct dentry *new_dentry)
578+{
579+ return ccs_link_permission(old_dentry, new_dentry, NULL);
580+}
581+
582+/**
583+ * ccs_inode_create - Check permission for creat().
584+ *
585+ * @dir: Pointer to "struct inode".
586+ * @dentry: Pointer to "struct dentry".
587+ * @mode: Create mode.
588+ *
589+ * Returns 0 on success, negative value otherwise.
590+ */
591+static int ccs_inode_create(struct inode *dir, struct dentry *dentry,
592+ umode_t mode)
593+{
594+ return ccs_mknod_permission(dentry, NULL, mode, 0);
595+}
596+
597+#endif
598+
599+#ifdef CONFIG_SECURITY_NETWORK
600+
601+#include <net/sock.h>
602+
603+/* Structure for remembering an accept()ed socket's status. */
604+struct ccs_socket_tag {
605+ struct list_head list;
606+ struct inode *inode;
607+ int status;
608+ struct rcu_head rcu;
609+};
610+
611+/*
612+ * List for managing accept()ed sockets.
613+ * Since we don't need to keep an accept()ed socket into this list after
614+ * once the permission was granted, the number of entries in this list is
615+ * likely small. Therefore, we don't use hash tables.
616+ */
617+static LIST_HEAD(ccs_accepted_socket_list);
618+/* Lock for protecting ccs_accepted_socket_list . */
619+static DEFINE_SPINLOCK(ccs_accepted_socket_list_lock);
620+
621+/**
622+ * ccs_update_socket_tag - Update tag associated with accept()ed sockets.
623+ *
624+ * @inode: Pointer to "struct inode".
625+ * @status: New status.
626+ *
627+ * Returns nothing.
628+ *
629+ * If @status == 0, memory for that socket will be released after RCU grace
630+ * period.
631+ */
632+static void ccs_update_socket_tag(struct inode *inode, int status)
633+{
634+ struct ccs_socket_tag *ptr;
635+ /*
636+ * Protect whole section because multiple threads may call this
637+ * function with same "sock" via ccs_validate_socket().
638+ */
639+ spin_lock(&ccs_accepted_socket_list_lock);
640+ rcu_read_lock();
641+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
642+ if (ptr->inode != inode)
643+ continue;
644+ ptr->status = status;
645+ if (status)
646+ break;
647+ list_del_rcu(&ptr->list);
648+ kfree_rcu(ptr, rcu);
649+ break;
650+ }
651+ rcu_read_unlock();
652+ spin_unlock(&ccs_accepted_socket_list_lock);
653+}
654+
655+/**
656+ * ccs_validate_socket - Check post accept() permission if needed.
657+ *
658+ * @sock: Pointer to "struct socket".
659+ *
660+ * Returns 0 on success, negative value otherwise.
661+ */
662+static int ccs_validate_socket(struct socket *sock)
663+{
664+ struct inode *inode = SOCK_INODE(sock);
665+ struct ccs_socket_tag *ptr;
666+ int ret = 0;
667+ rcu_read_lock();
668+ list_for_each_entry_rcu(ptr, &ccs_accepted_socket_list, list) {
669+ if (ptr->inode != inode)
670+ continue;
671+ ret = ptr->status;
672+ break;
673+ }
674+ rcu_read_unlock();
675+ if (ret <= 0)
676+ /*
677+ * This socket is not an accept()ed socket or this socket is
678+ * an accept()ed socket and post accept() permission is done.
679+ */
680+ return ret;
681+ /*
682+ * Check post accept() permission now.
683+ *
684+ * Strictly speaking, we need to pass both listen()ing socket and
685+ * accept()ed socket to __ccs_socket_post_accept_permission().
686+ * But since socket's family and type are same for both sockets,
687+ * passing the accept()ed socket in place for the listen()ing socket
688+ * will work.
689+ */
690+ ret = ccs_socket_post_accept_permission(sock, sock);
691+ /*
692+ * If permission was granted, we forget that this is an accept()ed
693+ * socket. Otherwise, we remember that this socket needs to return
694+ * error for subsequent socketcalls.
695+ */
696+ ccs_update_socket_tag(inode, ret);
697+ return ret;
698+}
699+
700+/**
701+ * ccs_socket_accept - Check permission for accept().
702+ *
703+ * @sock: Pointer to "struct socket".
704+ * @newsock: Pointer to "struct socket".
705+ *
706+ * Returns 0 on success, negative value otherwise.
707+ *
708+ * This hook is used for setting up environment for doing post accept()
709+ * permission check. If dereferencing sock->ops->something() were ordered by
710+ * rcu_dereference(), we could replace sock->ops with "a copy of original
711+ * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
712+ * in order to do post accept() permission check before returning to userspace.
713+ * If we make the copy in security_socket_post_create(), it would be possible
714+ * to safely replace sock->ops here, but we don't do so because we don't want
715+ * to allocate memory for sockets which do not call sock->ops->accept().
716+ * Therefore, we do post accept() permission check upon next socket syscalls
717+ * rather than between sock->ops->accept() and returning to userspace.
718+ * This means that if a socket was close()d before calling some socket
719+ * syscalls, post accept() permission check will not be done.
720+ */
721+static int ccs_socket_accept(struct socket *sock, struct socket *newsock)
722+{
723+ struct ccs_socket_tag *ptr;
724+ const int rc = ccs_validate_socket(sock);
725+ if (rc < 0)
726+ return rc;
727+ ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
728+ if (!ptr)
729+ return -ENOMEM;
730+ /*
731+ * Subsequent LSM hooks will receive "newsock". Therefore, I mark
732+ * "newsock" as "an accept()ed socket but post accept() permission
733+ * check is not done yet" by allocating memory using inode of the
734+ * "newsock" as a search key.
735+ */
736+ ptr->inode = SOCK_INODE(newsock);
737+ ptr->status = 1; /* Check post accept() permission later. */
738+ spin_lock(&ccs_accepted_socket_list_lock);
739+ list_add_tail_rcu(&ptr->list, &ccs_accepted_socket_list);
740+ spin_unlock(&ccs_accepted_socket_list_lock);
741+ return 0;
742+}
743+
744+/**
745+ * ccs_socket_listen - Check permission for listen().
746+ *
747+ * @sock: Pointer to "struct socket".
748+ * @backlog: Backlog parameter.
749+ *
750+ * Returns 0 on success, negative value otherwise.
751+ */
752+static int ccs_socket_listen(struct socket *sock, int backlog)
753+{
754+ const int rc = ccs_validate_socket(sock);
755+ if (rc < 0)
756+ return rc;
757+ return ccs_socket_listen_permission(sock);
758+}
759+
760+/**
761+ * ccs_socket_connect - Check permission for connect().
762+ *
763+ * @sock: Pointer to "struct socket".
764+ * @addr: Pointer to "struct sockaddr".
765+ * @addr_len: Size of @addr.
766+ *
767+ * Returns 0 on success, negative value otherwise.
768+ */
769+static int ccs_socket_connect(struct socket *sock, struct sockaddr *addr,
770+ int addr_len)
771+{
772+ const int rc = ccs_validate_socket(sock);
773+ if (rc < 0)
774+ return rc;
775+ return ccs_socket_connect_permission(sock, addr, addr_len);
776+}
777+
778+/**
779+ * ccs_socket_bind - Check permission for bind().
780+ *
781+ * @sock: Pointer to "struct socket".
782+ * @addr: Pointer to "struct sockaddr".
783+ * @addr_len: Size of @addr.
784+ *
785+ * Returns 0 on success, negative value otherwise.
786+ */
787+static int ccs_socket_bind(struct socket *sock, struct sockaddr *addr,
788+ int addr_len)
789+{
790+ const int rc = ccs_validate_socket(sock);
791+ if (rc < 0)
792+ return rc;
793+ return ccs_socket_bind_permission(sock, addr, addr_len);
794+}
795+
796+/**
797+ * ccs_socket_sendmsg - Check permission for sendmsg().
798+ *
799+ * @sock: Pointer to "struct socket".
800+ * @msg: Pointer to "struct msghdr".
801+ * @size: Size of message.
802+ *
803+ * Returns 0 on success, negative value otherwise.
804+ */
805+static int ccs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
806+ int size)
807+{
808+ const int rc = ccs_validate_socket(sock);
809+ if (rc < 0)
810+ return rc;
811+ return ccs_socket_sendmsg_permission(sock, msg, size);
812+}
813+
814+/**
815+ * ccs_socket_recvmsg - Check permission for recvmsg().
816+ *
817+ * @sock: Pointer to "struct socket".
818+ * @msg: Pointer to "struct msghdr".
819+ * @size: Size of message.
820+ * @flags: Flags.
821+ *
822+ * Returns 0 on success, negative value otherwise.
823+ */
824+static int ccs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
825+ int size, int flags)
826+{
827+ return ccs_validate_socket(sock);
828+}
829+
830+/**
831+ * ccs_socket_getsockname - Check permission for getsockname().
832+ *
833+ * @sock: Pointer to "struct socket".
834+ *
835+ * Returns 0 on success, negative value otherwise.
836+ */
837+static int ccs_socket_getsockname(struct socket *sock)
838+{
839+ return ccs_validate_socket(sock);
840+}
841+
842+/**
843+ * ccs_socket_getpeername - Check permission for getpeername().
844+ *
845+ * @sock: Pointer to "struct socket".
846+ *
847+ * Returns 0 on success, negative value otherwise.
848+ */
849+static int ccs_socket_getpeername(struct socket *sock)
850+{
851+ return ccs_validate_socket(sock);
852+}
853+
854+/**
855+ * ccs_socket_getsockopt - Check permission for getsockopt().
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_getsockopt(struct socket *sock, int level, int optname)
864+{
865+ return ccs_validate_socket(sock);
866+}
867+
868+/**
869+ * ccs_socket_setsockopt - Check permission for setsockopt().
870+ *
871+ * @sock: Pointer to "struct socket".
872+ * @level: Level.
873+ * @optname: Option's name,
874+ *
875+ * Returns 0 on success, negative value otherwise.
876+ */
877+static int ccs_socket_setsockopt(struct socket *sock, int level, int optname)
878+{
879+ return ccs_validate_socket(sock);
880+}
881+
882+/**
883+ * ccs_socket_shutdown - Check permission for shutdown().
884+ *
885+ * @sock: Pointer to "struct socket".
886+ * @how: Shutdown mode.
887+ *
888+ * Returns 0 on success, negative value otherwise.
889+ */
890+static int ccs_socket_shutdown(struct socket *sock, int how)
891+{
892+ return ccs_validate_socket(sock);
893+}
894+
895+#define SOCKFS_MAGIC 0x534F434B
896+
897+/**
898+ * ccs_inode_free_security - Release memory associated with an inode.
899+ *
900+ * @inode: Pointer to "struct inode".
901+ *
902+ * Returns nothing.
903+ *
904+ * We use this hook for releasing memory associated with an accept()ed socket.
905+ */
906+static void ccs_inode_free_security(struct inode *inode)
907+{
908+ if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
909+ ccs_update_socket_tag(inode, 0);
910+}
911+
912+#endif
913+
914+/**
915+ * ccs_sb_pivotroot - Check permission for pivot_root().
916+ *
917+ * @old_path: Pointer to "struct path".
918+ * @new_path: Pointer to "struct path".
919+ *
920+ * Returns 0 on success, negative value otherwise.
921+ */
922+static int ccs_sb_pivotroot(const struct path *old_path,
923+ const struct path *new_path)
924+{
925+ return ccs_pivot_root_permission(old_path, new_path);
926+}
927+
928+/**
929+ * ccs_sb_mount - Check permission for mount().
930+ *
931+ * @dev_name: Name of device file.
932+ * @path: Pointer to "struct path".
933+ * @type: Name of filesystem type. Maybe NULL.
934+ * @flags: Mount options.
935+ * @data_page: Optional data. Maybe NULL.
936+ *
937+ * Returns 0 on success, negative value otherwise.
938+ */
939+static int ccs_sb_mount(const char *dev_name, const struct path *path,
940+ const char *type, unsigned long flags, void *data_page)
941+{
942+ return ccs_mount_permission(dev_name, path, type, flags, data_page);
943+}
944+
945+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
946+/**
947+ * ccs_move_mount - Check permission for move_mount() operation.
948+ *
949+ * @from_path: Pointer to "struct path".
950+ * @to_path: Pointer to "struct path".
951+ *
952+ * Returns 0 on success, negative value otherwise.
953+ */
954+static int ccs_move_mount(const struct path *from_path, const struct path *to_path)
955+{
956+ return ccs_move_mount_permission(from_path, to_path);
957+}
958+#endif
959+
960+/**
961+ * ccs_sb_umount - Check permission for umount().
962+ *
963+ * @mnt: Pointer to "struct vfsmount".
964+ * @flags: Unmount flags.
965+ *
966+ * Returns 0 on success, negative value otherwise.
967+ */
968+static int ccs_sb_umount(struct vfsmount *mnt, int flags)
969+{
970+ return ccs_umount_permission(mnt, flags);
971+}
972+
973+/**
974+ * ccs_file_fcntl - Check permission for fcntl().
975+ *
976+ * @file: Pointer to "struct file".
977+ * @cmd: Command number.
978+ * @arg: Value for @cmd.
979+ *
980+ * Returns 0 on success, negative value otherwise.
981+ */
982+static int ccs_file_fcntl(struct file *file, unsigned int cmd,
983+ unsigned long arg)
984+{
985+ return ccs_fcntl_permission(file, cmd, arg);
986+}
987+
988+/**
989+ * ccs_file_ioctl - Check permission for ioctl().
990+ *
991+ * @filp: Pointer to "struct file".
992+ * @cmd: Command number.
993+ * @arg: Value for @cmd.
994+ *
995+ * Returns 0 on success, negative value otherwise.
996+ */
997+static int ccs_file_ioctl(struct file *filp, unsigned int cmd,
998+ unsigned long arg)
999+{
1000+ return ccs_ioctl_permission(filp, cmd, arg);
1001+}
1002+
1003+#define MY_HOOK_INIT(HEAD, HOOK) \
1004+ { .head = &probe_dummy_security_hook_heads.HEAD, \
1005+ .hook = { .HEAD = HOOK } }
1006+
1007+static struct security_hook_list akari_hooks[] = {
1008+ /* Security context allocator. */
1009+ MY_HOOK_INIT(task_free, ccs_task_free_security),
1010+ MY_HOOK_INIT(cred_prepare, ccs_cred_prepare),
1011+ MY_HOOK_INIT(task_alloc, ccs_task_alloc_security),
1012+ /* Security context updater for successful execve(). */
1013+ MY_HOOK_INIT(bprm_check_security, ccs_bprm_check_security),
1014+ MY_HOOK_INIT(bprm_committing_creds, ccs_bprm_committing_creds),
1015+ /* Various permission checker. */
1016+ MY_HOOK_INIT(file_open, ccs_file_open),
1017+ MY_HOOK_INIT(file_fcntl, ccs_file_fcntl),
1018+ MY_HOOK_INIT(file_ioctl, ccs_file_ioctl),
1019+ MY_HOOK_INIT(sb_pivotroot, ccs_sb_pivotroot),
1020+ MY_HOOK_INIT(sb_mount, ccs_sb_mount),
1021+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1022+ MY_HOOK_INIT(move_mount, ccs_move_mount),
1023+#endif
1024+ MY_HOOK_INIT(sb_umount, ccs_sb_umount),
1025+#ifdef CONFIG_SECURITY_PATH
1026+ MY_HOOK_INIT(path_mknod, ccs_path_mknod),
1027+ MY_HOOK_INIT(path_mkdir, ccs_path_mkdir),
1028+ MY_HOOK_INIT(path_rmdir, ccs_path_rmdir),
1029+ MY_HOOK_INIT(path_unlink, ccs_path_unlink),
1030+ MY_HOOK_INIT(path_symlink, ccs_path_symlink),
1031+ MY_HOOK_INIT(path_rename, ccs_path_rename),
1032+ MY_HOOK_INIT(path_link, ccs_path_link),
1033+ MY_HOOK_INIT(path_truncate, ccs_path_truncate),
1034+ MY_HOOK_INIT(path_chmod, ccs_path_chmod),
1035+ MY_HOOK_INIT(path_chown, ccs_path_chown),
1036+ MY_HOOK_INIT(path_chroot, ccs_path_chroot),
1037+#else
1038+ MY_HOOK_INIT(inode_mknod, ccs_inode_mknod),
1039+ MY_HOOK_INIT(inode_mkdir, ccs_inode_mkdir),
1040+ MY_HOOK_INIT(inode_rmdir, ccs_inode_rmdir),
1041+ MY_HOOK_INIT(inode_unlink, ccs_inode_unlink),
1042+ MY_HOOK_INIT(inode_symlink, ccs_inode_symlink),
1043+ MY_HOOK_INIT(inode_rename, ccs_inode_rename),
1044+ MY_HOOK_INIT(inode_link, ccs_inode_link),
1045+ MY_HOOK_INIT(inode_create, ccs_inode_create),
1046+ MY_HOOK_INIT(inode_setattr, ccs_inode_setattr),
1047+#endif
1048+ MY_HOOK_INIT(inode_getattr, ccs_inode_getattr),
1049+#ifdef CONFIG_SECURITY_NETWORK
1050+ MY_HOOK_INIT(socket_bind, ccs_socket_bind),
1051+ MY_HOOK_INIT(socket_connect, ccs_socket_connect),
1052+ MY_HOOK_INIT(socket_listen, ccs_socket_listen),
1053+ MY_HOOK_INIT(socket_sendmsg, ccs_socket_sendmsg),
1054+ MY_HOOK_INIT(socket_recvmsg, ccs_socket_recvmsg),
1055+ MY_HOOK_INIT(socket_getsockname, ccs_socket_getsockname),
1056+ MY_HOOK_INIT(socket_getpeername, ccs_socket_getpeername),
1057+ MY_HOOK_INIT(socket_getsockopt, ccs_socket_getsockopt),
1058+ MY_HOOK_INIT(socket_setsockopt, ccs_socket_setsockopt),
1059+ MY_HOOK_INIT(socket_shutdown, ccs_socket_shutdown),
1060+ MY_HOOK_INIT(socket_accept, ccs_socket_accept),
1061+ MY_HOOK_INIT(inode_free_security, ccs_inode_free_security),
1062+#endif
1063+};
1064+
1065+static inline void add_hook(struct security_hook_list *hook)
1066+{
1067+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1068+ hlist_add_tail_rcu(&hook->list, hook->head);
1069+#else
1070+ list_add_tail_rcu(&hook->list, hook->head);
1071+#endif
1072+}
1073+
1074+static void __init swap_hook(struct security_hook_list *hook,
1075+ union security_list_options *original)
1076+{
1077+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1078+ struct hlist_head *list = hook->head;
1079+
1080+ if (hlist_empty(list)) {
1081+ add_hook(hook);
1082+ } else {
1083+ struct security_hook_list *shp =
1084+ hlist_entry(list->first, typeof(*shp), list);
1085+
1086+ while (shp->list.next)
1087+ shp = hlist_entry(shp->list.next, typeof(*shp), list);
1088+ *original = shp->hook;
1089+ smp_wmb();
1090+ shp->hook = hook->hook;
1091+ }
1092+#else
1093+ struct list_head *list = hook->head;
1094+
1095+ if (list_empty(list)) {
1096+ add_hook(hook);
1097+ } else {
1098+ struct security_hook_list *shp =
1099+ list_last_entry(list, struct security_hook_list, list);
1100+ *original = shp->hook;
1101+ smp_wmb();
1102+ shp->hook = hook->hook;
1103+ }
1104+#endif
1105+}
1106+
1107+#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS)
1108+#include <linux/uaccess.h> /* probe_kernel_write() */
1109+#define NEED_TO_CHECK_HOOKS_ARE_WRITABLE
1110+
1111+#if defined(CONFIG_X86)
1112+#define MAX_RO_PAGES 1024
1113+static struct page *ro_pages[MAX_RO_PAGES] __initdata;
1114+static unsigned int ro_pages_len __initdata;
1115+
1116+static bool __init lsm_test_page_ro(void *addr)
1117+{
1118+ unsigned int i;
1119+ int unused;
1120+ struct page *page;
1121+
1122+ page = (struct page *) lookup_address((unsigned long) addr, &unused);
1123+ if (!page)
1124+ return false;
1125+ if (test_bit(_PAGE_BIT_RW, &(page->flags)))
1126+ return true;
1127+ for (i = 0; i < ro_pages_len; i++)
1128+ if (page == ro_pages[i])
1129+ return true;
1130+ if (ro_pages_len == MAX_RO_PAGES)
1131+ return false;
1132+ ro_pages[ro_pages_len++] = page;
1133+ return true;
1134+}
1135+
1136+static bool __init check_ro_pages(struct security_hook_heads *hooks)
1137+{
1138+ int i;
1139+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1140+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
1141+ struct hlist_head *list = &hooks->capable;
1142+
1143+ if (!probe_kernel_write(list, list, sizeof(void *)))
1144+ return true;
1145+#endif
1146+ for (i = 0; i < ARRAY_SIZE(akari_hooks); i++) {
1147+ struct hlist_head *head = akari_hooks[i].head;
1148+ struct security_hook_list *shp;
1149+
1150+ if (!lsm_test_page_ro(&head->first))
1151+ return false;
1152+ hlist_for_each_entry(shp, head, list)
1153+ if (!lsm_test_page_ro(&shp->list.next) ||
1154+ !lsm_test_page_ro(&shp->list.pprev))
1155+ return false;
1156+ }
1157+#else
1158+ struct list_head *list = &hooks->capable;
1159+
1160+ if (!probe_kernel_write(list, list, sizeof(void *)))
1161+ return true;
1162+ for (i = 0; i < ARRAY_SIZE(akari_hooks); i++) {
1163+ struct list_head *head = akari_hooks[i].head;
1164+ struct security_hook_list *shp;
1165+
1166+ if (!lsm_test_page_ro(&head->next) ||
1167+ !lsm_test_page_ro(&head->prev))
1168+ return false;
1169+ list_for_each_entry(shp, head, list)
1170+ if (!lsm_test_page_ro(&shp->list.next) ||
1171+ !lsm_test_page_ro(&shp->list.prev))
1172+ return false;
1173+ }
1174+#endif
1175+ return true;
1176+}
1177+#else
1178+static bool __init check_ro_pages(struct security_hook_heads *hooks)
1179+{
1180+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1181+ struct hlist_head *list = &hooks->capable;
1182+#else
1183+ struct list_head *list = &hooks->capable;
1184+#endif
1185+
1186+ return !probe_kernel_write(list, list, sizeof(void *));
1187+}
1188+#endif
1189+#endif
1190+
1191+/**
1192+ * ccs_init - Initialize this module.
1193+ *
1194+ * Returns 0 on success, negative value otherwise.
1195+ */
1196+static int __init ccs_init(void)
1197+{
1198+ int idx;
1199+ struct security_hook_heads *hooks = probe_security_hook_heads();
1200+ if (!hooks)
1201+ goto out;
1202+ for (idx = 0; idx < ARRAY_SIZE(akari_hooks); idx++)
1203+ akari_hooks[idx].head = ((void *) hooks)
1204+ + ((unsigned long) akari_hooks[idx].head)
1205+ - ((unsigned long) &probe_dummy_security_hook_heads);
1206+#if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE)
1207+ if (!check_ro_pages(hooks)) {
1208+ printk(KERN_INFO "Can't update security_hook_heads due to write protected. Retry with rodata=0 kernel command line option added.\n");
1209+ return -EINVAL;
1210+ }
1211+#endif
1212+ ccsecurity_exports.find_task_by_vpid = probe_find_task_by_vpid();
1213+ if (!ccsecurity_exports.find_task_by_vpid)
1214+ goto out;
1215+ ccsecurity_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1216+ if (!ccsecurity_exports.find_task_by_pid_ns)
1217+ goto out;
1218+ ccsecurity_exports.d_absolute_path = probe_d_absolute_path();
1219+ if (!ccsecurity_exports.d_absolute_path)
1220+ goto out;
1221+ for (idx = 0; idx < CCS_MAX_TASK_SECURITY_HASH; idx++)
1222+ INIT_LIST_HEAD(&ccs_task_security_list[idx]);
1223+ ccs_main_init();
1224+#if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86)
1225+ for (idx = 0; idx < ro_pages_len; idx++)
1226+ set_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags));
1227+#endif
1228+ swap_hook(&akari_hooks[0], &original_task_free);
1229+ swap_hook(&akari_hooks[1], &original_cred_prepare);
1230+ swap_hook(&akari_hooks[2], &original_task_alloc);
1231+ for (idx = 3; idx < ARRAY_SIZE(akari_hooks); idx++)
1232+ add_hook(&akari_hooks[idx]);
1233+#if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86)
1234+ for (idx = 0; idx < ro_pages_len; idx++)
1235+ clear_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags));
1236+#endif
1237+ printk(KERN_INFO "AKARI: 1.0.47 2021/04/01\n");
1238+ printk(KERN_INFO
1239+ "Access Keeping And Regulating Instrument registered.\n");
1240+ return 0;
1241+out:
1242+ return -EINVAL;
1243+}
1244+
1245+module_init(ccs_init);
1246+MODULE_LICENSE("GPL");
1247+
1248+/**
1249+ * ccs_used_by_cred - Check whether the given domain is in use or not.
1250+ *
1251+ * @domain: Pointer to "struct ccs_domain_info".
1252+ *
1253+ * Returns true if @domain is in use, false otherwise.
1254+ *
1255+ * Caller holds rcu_read_lock().
1256+ */
1257+bool ccs_used_by_cred(const struct ccs_domain_info *domain)
1258+{
1259+ return false;
1260+}
1261+
1262+/**
1263+ * ccs_add_task_security - Add "struct ccs_security" to list.
1264+ *
1265+ * @ptr: Pointer to "struct ccs_security".
1266+ * @list: Pointer to "struct list_head".
1267+ *
1268+ * Returns nothing.
1269+ */
1270+static void ccs_add_task_security(struct ccs_security *ptr,
1271+ struct list_head *list)
1272+{
1273+ unsigned long flags;
1274+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1275+ list_add_rcu(&ptr->list, list);
1276+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1277+}
1278+
1279+/**
1280+ * __ccs_alloc_task_security - Allocate memory for new tasks.
1281+ *
1282+ * @task: Pointer to "struct task_struct".
1283+ *
1284+ * Returns 0 on success, negative value otherwise.
1285+ */
1286+static int __ccs_alloc_task_security(const struct task_struct *task)
1287+{
1288+ struct ccs_security *old_security = ccs_current_security();
1289+ struct ccs_security *new_security = kzalloc(sizeof(*new_security),
1290+ GFP_KERNEL);
1291+ struct list_head *list = &ccs_task_security_list
1292+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1293+ if (!new_security)
1294+ return -ENOMEM;
1295+ new_security->task = task;
1296+ new_security->ccs_domain_info = old_security->ccs_domain_info;
1297+ new_security->ccs_flags = old_security->ccs_flags;
1298+ ccs_add_task_security(new_security, list);
1299+ return 0;
1300+}
1301+
1302+/**
1303+ * ccs_find_task_security - Find "struct ccs_security" for given task.
1304+ *
1305+ * @task: Pointer to "struct task_struct".
1306+ *
1307+ * Returns pointer to "struct ccs_security" on success, &ccs_oom_security on
1308+ * out of memory, &ccs_default_security otherwise.
1309+ *
1310+ * If @task is current thread and "struct ccs_security" for current thread was
1311+ * not found, I try to allocate it. But if allocation failed, current thread
1312+ * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1313+ * won't work.
1314+ */
1315+struct ccs_security *ccs_find_task_security(const struct task_struct *task)
1316+{
1317+ struct ccs_security *ptr;
1318+ struct list_head *list = &ccs_task_security_list
1319+ [hash_ptr((void *) task, CCS_TASK_SECURITY_HASH_BITS)];
1320+ /* Make sure INIT_LIST_HEAD() in ccs_mm_init() takes effect. */
1321+ while (!list->next)
1322+ smp_rmb();
1323+ rcu_read_lock();
1324+ list_for_each_entry_rcu(ptr, list, list) {
1325+ if (ptr->task != task)
1326+ continue;
1327+ rcu_read_unlock();
1328+ /*
1329+ * Current thread needs to transit from old domain to new
1330+ * domain before do_execve() succeeds in order to check
1331+ * permission for interpreters and environment variables using
1332+ * new domain's ACL rules. The domain transition has to be
1333+ * visible from other CPU in order to allow interactive
1334+ * enforcing mode. Also, the domain transition has to be
1335+ * reverted if do_execve() failed. However, an LSM hook for
1336+ * reverting domain transition is missing.
1337+ *
1338+ * security_prepare_creds() is called from prepare_creds() from
1339+ * prepare_bprm_creds() from do_execve() before setting
1340+ * current->in_execve flag, and current->in_execve flag is
1341+ * cleared by the time next do_execve() request starts.
1342+ * This means that we can emulate the missing LSM hook for
1343+ * reverting domain transition, by calling this function from
1344+ * security_prepare_creds().
1345+ *
1346+ * If current->in_execve is not set but ptr->ccs_flags has
1347+ * CCS_TASK_IS_IN_EXECVE set, it indicates that do_execve()
1348+ * has failed and reverting domain transition is needed.
1349+ */
1350+ if (task == current &&
1351+ (ptr->ccs_flags & CCS_TASK_IS_IN_EXECVE) &&
1352+ !current->in_execve) {
1353+ ccs_debug_trace("1");
1354+ ccs_clear_execve(-1, ptr);
1355+ }
1356+ return ptr;
1357+ }
1358+ rcu_read_unlock();
1359+ if (task != current)
1360+ return &ccs_default_security;
1361+ /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1362+ ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1363+ if (!ptr) {
1364+ printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1365+ task->pid);
1366+ send_sig(SIGKILL, current, 0);
1367+ return &ccs_oom_security;
1368+ }
1369+ *ptr = ccs_default_security;
1370+ ptr->task = task;
1371+ ccs_add_task_security(ptr, list);
1372+ return ptr;
1373+}
1374+
1375+/**
1376+ * __ccs_free_task_security - Release memory associated with "struct task_struct".
1377+ *
1378+ * @task: Pointer to "struct task_struct".
1379+ *
1380+ * Returns nothing.
1381+ */
1382+static void __ccs_free_task_security(const struct task_struct *task)
1383+{
1384+ unsigned long flags;
1385+ struct ccs_security *ptr = ccs_find_task_security(task);
1386+ if (ptr == &ccs_default_security || ptr == &ccs_oom_security)
1387+ return;
1388+ spin_lock_irqsave(&ccs_task_security_list_lock, flags);
1389+ list_del_rcu(&ptr->list);
1390+ spin_unlock_irqrestore(&ccs_task_security_list_lock, flags);
1391+ kfree_rcu(ptr, rcu);
1392+}
--- tags/patches/1.0.47/lsm-4.2.c (nonexistent)
+++ tags/patches/1.0.47/lsm-4.2.c (revision 672)
@@ -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.47 2021/04/01
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.47 2021/04/01\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.47/lsm-4.7.c (nonexistent)
+++ tags/patches/1.0.47/lsm-4.7.c (revision 672)
@@ -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.47 2021/04/01
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.47 2021/04/01\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.47/lsm.c (nonexistent)
+++ tags/patches/1.0.47/lsm.c (revision 672)
@@ -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.47 2021/04/01
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.47/memory.c (nonexistent)
+++ tags/patches/1.0.47/memory.c (revision 672)
@@ -0,0 +1,364 @@
1+/*
2+ * security/ccsecurity/memory.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#include "internal.h"
10+
11+/* 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.47/permission.c (nonexistent)
+++ tags/patches/1.0.47/permission.c (revision 672)
@@ -0,0 +1,5117 @@
1+/*
2+ * security/ccsecurity/permission.c
3+ *
4+ * Copyright (C) 2005-2012 NTT DATA CORPORATION
5+ *
6+ * Version: 1.8.9 2021/04/01
7+ */
8+
9+#include "internal.h"
10+
11+/***** SECTION1: Constants definition *****/
12+
13+#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+ struct pt_regs *regs);
302+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
303+static int __ccs_search_binary_handler(struct linux_binprm *bprm);
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(5, 8, 0)
435+
436+/**
437+ * prepare_binprm - Read the first BINPRM_BUF_SIZE bytes.
438+ *
439+ * @bprm: Pointer to "struct linux_binprm".
440+ *
441+ * Same with prepare_binprm() in fs/exec.c
442+ */
443+static inline int prepare_binprm(struct linux_binprm *bprm)
444+{
445+ loff_t pos = 0;
446+
447+ memset(bprm->buf, 0, BINPRM_BUF_SIZE);
448+ return kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, &pos);
449+}
450+
451+/**
452+ * ccs_copy_argv - Wrapper for copy_string_kernel().
453+ *
454+ * @arg: String to copy.
455+ * @bprm: Pointer to "struct linux_binprm".
456+ *
457+ * Returns return value of copy_string_kernel().
458+ */
459+static inline int ccs_copy_argv(const char *arg, struct linux_binprm *bprm)
460+{
461+ const int ret = copy_string_kernel(arg, bprm);
462+ if (ret >= 0)
463+ bprm->argc++;
464+ return ret;
465+}
466+
467+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
468+
469+/**
470+ * ccs_copy_argv - Wrapper for copy_strings_kernel().
471+ *
472+ * @arg: String to copy.
473+ * @bprm: Pointer to "struct linux_binprm".
474+ *
475+ * Returns return value of copy_strings_kernel().
476+ */
477+static inline int ccs_copy_argv(const char *arg, struct linux_binprm *bprm)
478+{
479+ const int ret = copy_strings_kernel(1, &arg, bprm);
480+ if (ret >= 0)
481+ bprm->argc++;
482+ return ret;
483+}
484+
485+#else
486+
487+/**
488+ * ccs_copy_argv - Wrapper for copy_strings_kernel().
489+ *
490+ * @arg: String to copy.
491+ * @bprm: Pointer to "struct linux_binprm".
492+ *
493+ * Returns return value of copy_strings_kernel().
494+ */
495+static inline int ccs_copy_argv(char *arg, struct linux_binprm *bprm)
496+{
497+ const int ret = copy_strings_kernel(1, &arg, bprm);
498+ if (ret >= 0)
499+ bprm->argc++;
500+ return ret;
501+}
502+
503+#endif
504+
505+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)
506+
507+/**
508+ * get_fs_root - Get reference on root directory.
509+ *
510+ * @fs: Pointer to "struct fs_struct".
511+ * @root: Pointer to "struct path".
512+ *
513+ * Returns nothing.
514+ *
515+ * This is for compatibility with older kernels.
516+ */
517+static inline void get_fs_root(struct fs_struct *fs, struct path *root)
518+{
519+ read_lock(&fs->lock);
520+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
521+ *root = fs->root;
522+ path_get(root);
523+#else
524+ root->dentry = dget(fs->root);
525+ root->mnt = mntget(fs->rootmnt);
526+#endif
527+ read_unlock(&fs->lock);
528+}
529+
530+#endif
531+
532+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
533+
534+/**
535+ * module_put - Put a reference on module.
536+ *
537+ * @module: Pointer to "struct module". Maybe NULL.
538+ *
539+ * Returns nothing.
540+ *
541+ * This is for compatibility with older kernels.
542+ */
543+static inline void module_put(struct module *module)
544+{
545+ if (module)
546+ __MOD_DEC_USE_COUNT(module);
547+}
548+
549+#endif
550+
551+/**
552+ * ccs_put_filesystem - Wrapper for put_filesystem().
553+ *
554+ * @fstype: Pointer to "struct file_system_type".
555+ *
556+ * Returns nothing.
557+ *
558+ * Since put_filesystem() is not exported, I embed put_filesystem() here.
559+ */
560+static inline void ccs_put_filesystem(struct file_system_type *fstype)
561+{
562+ module_put(fstype->owner);
563+}
564+
565+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
566+
567+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
568+#if !defined(RHEL_MAJOR) || RHEL_MAJOR != 5
569+#if !defined(AX_MAJOR) || AX_MAJOR != 3
570+
571+/**
572+ * ip_hdr - Get "struct iphdr".
573+ *
574+ * @skb: Pointer to "struct sk_buff".
575+ *
576+ * Returns pointer to "struct iphdr".
577+ *
578+ * This is for compatibility with older kernels.
579+ */
580+static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
581+{
582+ return skb->nh.iph;
583+}
584+
585+/**
586+ * udp_hdr - Get "struct udphdr".
587+ *
588+ * @skb: Pointer to "struct sk_buff".
589+ *
590+ * Returns pointer to "struct udphdr".
591+ *
592+ * This is for compatibility with older kernels.
593+ */
594+static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
595+{
596+ return skb->h.uh;
597+}
598+
599+/**
600+ * ipv6_hdr - Get "struct ipv6hdr".
601+ *
602+ * @skb: Pointer to "struct sk_buff".
603+ *
604+ * Returns pointer to "struct ipv6hdr".
605+ *
606+ * This is for compatibility with older kernels.
607+ */
608+static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
609+{
610+ return skb->nh.ipv6h;
611+}
612+
613+#endif
614+#endif
615+#endif
616+
617+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
618+
619+/**
620+ * skb_kill_datagram - Kill a datagram forcibly.
621+ *
622+ * @sk: Pointer to "struct sock".
623+ * @skb: Pointer to "struct sk_buff".
624+ * @flags: Flags passed to skb_recv_datagram().
625+ *
626+ * Returns nothing.
627+ */
628+static inline void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
629+ int flags)
630+{
631+ /* Clear queue. */
632+ if (flags & MSG_PEEK) {
633+ int clear = 0;
634+ spin_lock_irq(&sk->receive_queue.lock);
635+ if (skb == skb_peek(&sk->receive_queue)) {
636+ __skb_unlink(skb, &sk->receive_queue);
637+ clear = 1;
638+ }
639+ spin_unlock_irq(&sk->receive_queue.lock);
640+ if (clear)
641+ kfree_skb(skb);
642+ }
643+ skb_free_datagram(sk, skb);
644+}
645+
646+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
647+
648+/**
649+ * skb_kill_datagram - Kill a datagram forcibly.
650+ *
651+ * @sk: Pointer to "struct sock".
652+ * @skb: Pointer to "struct sk_buff".
653+ * @flags: Flags passed to skb_recv_datagram().
654+ *
655+ * Returns nothing.
656+ */
657+static inline void skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
658+ int flags)
659+{
660+ /* Clear queue. */
661+ if (flags & MSG_PEEK) {
662+ int clear = 0;
663+ spin_lock_bh(&sk->sk_receive_queue.lock);
664+ if (skb == skb_peek(&sk->sk_receive_queue)) {
665+ __skb_unlink(skb, &sk->sk_receive_queue);
666+ clear = 1;
667+ }
668+ spin_unlock_bh(&sk->sk_receive_queue.lock);
669+ if (clear)
670+ kfree_skb(skb);
671+ }
672+ skb_free_datagram(sk, skb);
673+}
674+
675+#endif
676+
677+#endif
678+
679+/***** SECTION5: Variables definition section *****/
680+
681+/* The initial domain. */
682+struct ccs_domain_info ccs_kernel_domain;
683+
684+/* The list for "struct ccs_domain_info". */
685+LIST_HEAD(ccs_domain_list);
686+
687+/***** SECTION6: Dependent functions section *****/
688+
689+/**
690+ * ccs_path_matches_group - Check whether the given pathname matches members of the given pathname group.
691+ *
692+ * @pathname: The name of pathname.
693+ * @group: Pointer to "struct ccs_path_group".
694+ *
695+ * Returns matched member's pathname if @pathname matches pathnames in @group,
696+ * NULL otherwise.
697+ *
698+ * Caller holds ccs_read_lock().
699+ */
700+static const struct ccs_path_info *ccs_path_matches_group
701+(const struct ccs_path_info *pathname, const struct ccs_group *group)
702+{
703+ struct ccs_path_group *member;
704+ list_for_each_entry_srcu(member, &group->member_list, head.list,
705+ &ccs_ss) {
706+ if (member->head.is_deleted)
707+ continue;
708+ if (!ccs_path_matches_pattern(pathname, member->member_name))
709+ continue;
710+ return member->member_name;
711+ }
712+ return NULL;
713+}
714+
715+/**
716+ * ccs_number_matches_group - Check whether the given number matches members of the given number group.
717+ *
718+ * @min: Min number.
719+ * @max: Max number.
720+ * @group: Pointer to "struct ccs_number_group".
721+ *
722+ * Returns true if @min and @max partially overlaps @group, false otherwise.
723+ *
724+ * Caller holds ccs_read_lock().
725+ */
726+static bool ccs_number_matches_group(const unsigned long min,
727+ const unsigned long max,
728+ const struct ccs_group *group)
729+{
730+ struct ccs_number_group *member;
731+ bool matched = false;
732+ list_for_each_entry_srcu(member, &group->member_list, head.list,
733+ &ccs_ss) {
734+ if (member->head.is_deleted)
735+ continue;
736+ if (min > member->number.values[1] ||
737+ max < member->number.values[0])
738+ continue;
739+ matched = true;
740+ break;
741+ }
742+ return matched;
743+}
744+
745+/**
746+ * ccs_check_entry - Do permission check.
747+ *
748+ * @r: Pointer to "struct ccs_request_info".
749+ * @ptr: Pointer to "struct ccs_acl_info".
750+ *
751+ * Returns true on match, false otherwise.
752+ *
753+ * Caller holds ccs_read_lock().
754+ */
755+static bool ccs_check_entry(struct ccs_request_info *r,
756+ struct ccs_acl_info *ptr)
757+{
758+ if (ptr->is_deleted || ptr->type != r->param_type)
759+ return false;
760+ switch (r->param_type) {
761+ case CCS_TYPE_PATH_ACL:
762+ return ccs_check_path_acl(r, ptr);
763+ case CCS_TYPE_PATH2_ACL:
764+ return ccs_check_path2_acl(r, ptr);
765+ case CCS_TYPE_PATH_NUMBER_ACL:
766+ return ccs_check_path_number_acl(r, ptr);
767+ case CCS_TYPE_MKDEV_ACL:
768+ return ccs_check_mkdev_acl(r, ptr);
769+ case CCS_TYPE_MOUNT_ACL:
770+ return ccs_check_mount_acl(r, ptr);
771+#ifdef CONFIG_CCSECURITY_MISC
772+ case CCS_TYPE_ENV_ACL:
773+ return ccs_check_env_acl(r, ptr);
774+#endif
775+#ifdef CONFIG_CCSECURITY_CAPABILITY
776+ case CCS_TYPE_CAPABILITY_ACL:
777+ return ccs_check_capability_acl(r, ptr);
778+#endif
779+#ifdef CONFIG_CCSECURITY_NETWORK
780+ case CCS_TYPE_INET_ACL:
781+ return ccs_check_inet_acl(r, ptr);
782+ case CCS_TYPE_UNIX_ACL:
783+ return ccs_check_unix_acl(r, ptr);
784+#endif
785+#ifdef CONFIG_CCSECURITY_IPC
786+ case CCS_TYPE_SIGNAL_ACL:
787+ return ccs_check_signal_acl(r, ptr);
788+#endif
789+#ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
790+ case CCS_TYPE_MANUAL_TASK_ACL:
791+ return ccs_check_task_acl(r, ptr);
792+#endif
793+ }
794+ return true;
795+}
796+
797+/**
798+ * ccs_check_acl - Do permission check.
799+ *
800+ * @r: Pointer to "struct ccs_request_info".
801+ *
802+ * Returns 0 on success, negative value otherwise.
803+ *
804+ * Caller holds ccs_read_lock().
805+ */
806+int ccs_check_acl(struct ccs_request_info *r)
807+{
808+ const struct ccs_domain_info *domain = ccs_current_domain();
809+ int error;
810+ r->matched_acl = NULL;
811+ do {
812+ struct ccs_acl_info *ptr;
813+ const struct list_head *list = &domain->acl_info_list;
814+ u16 i = 0;
815+retry:
816+ list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
817+ if (!ccs_check_entry(r, ptr))
818+ continue;
819+ if (!ccs_condition(r, ptr->cond))
820+ continue;
821+ r->matched_acl = ptr;
822+ r->granted = true;
823+ ccs_audit_log(r);
824+ return 0;
825+ }
826+ for (; i < CCS_MAX_ACL_GROUPS; i++) {
827+ if (!test_bit(i, domain->group))
828+ continue;
829+ list = &domain->ns->acl_group[i++];
830+ goto retry;
831+ }
832+ r->granted = false;
833+ error = ccs_audit_log(r);
834+ } while (error == CCS_RETRY_REQUEST &&
835+ r->type != CCS_MAC_FILE_EXECUTE);
836+ return error;
837+}
838+
839+/**
840+ * ccs_last_word - Get last component of a domainname.
841+ *
842+ * @name: Domainname to check.
843+ *
844+ * Returns the last word of @name.
845+ */
846+static const char *ccs_last_word(const char *name)
847+{
848+ const char *cp = strrchr(name, ' ');
849+ if (cp)
850+ return cp + 1;
851+ return name;
852+}
853+
854+/**
855+ * ccs_scan_transition - Try to find specific domain transition type.
856+ *
857+ * @list: Pointer to "struct list_head".
858+ * @domainname: The name of current domain.
859+ * @program: The name of requested program.
860+ * @last_name: The last component of @domainname.
861+ * @type: One of values in "enum ccs_transition_type".
862+ *
863+ * Returns true if found one, false otherwise.
864+ *
865+ * Caller holds ccs_read_lock().
866+ */
867+static bool ccs_scan_transition(const struct list_head *list,
868+ const struct ccs_path_info *domainname,
869+ const struct ccs_path_info *program,
870+ const char *last_name,
871+ const enum ccs_transition_type type)
872+{
873+ const struct ccs_transition_control *ptr;
874+ list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
875+ if (ptr->head.is_deleted || ptr->type != type)
876+ continue;
877+ if (ptr->domainname) {
878+ if (!ptr->is_last_name) {
879+ if (ptr->domainname != domainname)
880+ continue;
881+ } else {
882+ /*
883+ * Use direct strcmp() since this is
884+ * unlikely used.
885+ */
886+ if (strcmp(ptr->domainname->name, last_name))
887+ continue;
888+ }
889+ }
890+ if (ptr->program && ccs_pathcmp(ptr->program, program))
891+ continue;
892+ return true;
893+ }
894+ return false;
895+}
896+
897+/**
898+ * ccs_transition_type - Get domain transition type.
899+ *
900+ * @ns: Pointer to "struct ccs_policy_namespace".
901+ * @domainname: The name of current domain.
902+ * @program: The name of requested program.
903+ *
904+ * Returns CCS_TRANSITION_CONTROL_TRANSIT if executing @program causes domain
905+ * transition across namespaces, CCS_TRANSITION_CONTROL_INITIALIZE if executing
906+ * @program reinitializes domain transition within that namespace,
907+ * CCS_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
908+ * others otherwise.
909+ *
910+ * Caller holds ccs_read_lock().
911+ */
912+static enum ccs_transition_type ccs_transition_type
913+(const struct ccs_policy_namespace *ns, const struct ccs_path_info *domainname,
914+ const struct ccs_path_info *program)
915+{
916+ const char *last_name = ccs_last_word(domainname->name);
917+ enum ccs_transition_type type = CCS_TRANSITION_CONTROL_NO_RESET;
918+ while (type < CCS_MAX_TRANSITION_TYPE) {
919+ const struct list_head * const list =
920+ &ns->policy_list[CCS_ID_TRANSITION_CONTROL];
921+ if (!ccs_scan_transition(list, domainname, program, last_name,
922+ type)) {
923+ type++;
924+ continue;
925+ }
926+ if (type != CCS_TRANSITION_CONTROL_NO_RESET &&
927+ type != CCS_TRANSITION_CONTROL_NO_INITIALIZE)
928+ break;
929+ /*
930+ * Do not check for reset_domain if no_reset_domain matched.
931+ * Do not check for initialize_domain if no_initialize_domain
932+ * matched.
933+ */
934+ type++;
935+ type++;
936+ }
937+ return type;
938+}
939+
940+/**
941+ * ccs_find_next_domain - Find a domain.
942+ *
943+ * @ee: Pointer to "struct ccs_execve".
944+ *
945+ * Returns 0 on success, negative value otherwise.
946+ *
947+ * Caller holds ccs_read_lock().
948+ */
949+static int ccs_find_next_domain(struct ccs_execve *ee)
950+{
951+ struct ccs_request_info *r = &ee->r;
952+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
953+ const struct ccs_path_info *handler = ee->handler;
954+#endif
955+ struct ccs_domain_info *domain = NULL;
956+ struct ccs_domain_info * const old_domain = ccs_current_domain();
957+ struct linux_binprm *bprm = ee->bprm;
958+ struct ccs_security *task = ccs_current_security();
959+ const struct ccs_path_info *candidate;
960+ struct ccs_path_info exename;
961+ int retval;
962+ bool reject_on_transition_failure = false;
963+
964+ /* Get symlink's pathname of program. */
965+ retval = ccs_symlink_path(bprm->filename, &exename);
966+ if (retval < 0)
967+ return retval;
968+
969+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
970+ if (handler) {
971+ /* No permission check for execute handler. */
972+ candidate = &exename;
973+ if (ccs_pathcmp(candidate, handler)) {
974+ /* Failed to verify execute handler. */
975+ static u8 counter = 20;
976+ if (counter) {
977+ counter--;
978+ printk(KERN_WARNING "Failed to verify: %s\n",
979+ handler->name);
980+ }
981+ goto out;
982+ }
983+ } else
984+#endif
985+ {
986+ struct ccs_aggregator *ptr;
987+ struct list_head *list;
988+retry:
989+ /* Check 'aggregator' directive. */
990+ candidate = &exename;
991+ list = &old_domain->ns->policy_list[CCS_ID_AGGREGATOR];
992+ list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
993+ if (ptr->head.is_deleted ||
994+ !ccs_path_matches_pattern(candidate,
995+ ptr->original_name))
996+ continue;
997+ candidate = ptr->aggregated_name;
998+ break;
999+ }
1000+
1001+ /* Check execute permission. */
1002+ retval = ccs_execute_permission(r, candidate);
1003+ if (retval == CCS_RETRY_REQUEST)
1004+ goto retry;
1005+ if (retval < 0)
1006+ goto out;
1007+ /*
1008+ * To be able to specify domainnames with wildcards, use the
1009+ * pathname specified in the policy (which may contain
1010+ * wildcard) rather than the pathname passed to execve()
1011+ * (which never contains wildcard).
1012+ */
1013+ if (r->param.path.matched_path)
1014+ candidate = r->param.path.matched_path;
1015+ }
1016+ /*
1017+ * Check for domain transition preference if "file execute" matched.
1018+ * If preference is given, make do_execve() fail if domain transition
1019+ * has failed, for domain transition preference should be used with
1020+ * destination domain defined.
1021+ */
1022+ if (r->ee->transition) {
1023+ const char *domainname = r->ee->transition->name;
1024+ reject_on_transition_failure = true;
1025+ if (!strcmp(domainname, "keep"))
1026+ goto force_keep_domain;
1027+ if (!strcmp(domainname, "child"))
1028+ goto force_child_domain;
1029+ if (!strcmp(domainname, "reset"))
1030+ goto force_reset_domain;
1031+ if (!strcmp(domainname, "initialize"))
1032+ goto force_initialize_domain;
1033+ if (!strcmp(domainname, "parent")) {
1034+ char *cp;
1035+ strncpy(ee->tmp, old_domain->domainname->name,
1036+ CCS_EXEC_TMPSIZE - 1);
1037+ cp = strrchr(ee->tmp, ' ');
1038+ if (cp)
1039+ *cp = '\0';
1040+ } else if (*domainname == '<')
1041+ strncpy(ee->tmp, domainname, CCS_EXEC_TMPSIZE - 1);
1042+ else
1043+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
1044+ old_domain->domainname->name, domainname);
1045+ goto force_jump_domain;
1046+ }
1047+ /*
1048+ * No domain transition preference specified.
1049+ * Calculate domain to transit to.
1050+ */
1051+ switch (ccs_transition_type(old_domain->ns, old_domain->domainname,
1052+ candidate)) {
1053+ case CCS_TRANSITION_CONTROL_RESET:
1054+force_reset_domain:
1055+ /* Transit to the root of specified namespace. */
1056+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "<%s>",
1057+ candidate->name);
1058+ /*
1059+ * Make do_execve() fail if domain transition across namespaces
1060+ * has failed.
1061+ */
1062+ reject_on_transition_failure = true;
1063+ break;
1064+ case CCS_TRANSITION_CONTROL_INITIALIZE:
1065+force_initialize_domain:
1066+ /* Transit to the child of current namespace's root. */
1067+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
1068+ old_domain->ns->name, candidate->name);
1069+ break;
1070+ case CCS_TRANSITION_CONTROL_KEEP:
1071+force_keep_domain:
1072+ /* Keep current domain. */
1073+ domain = old_domain;
1074+ break;
1075+ default:
1076+ if (old_domain == &ccs_kernel_domain && !ccs_policy_loaded) {
1077+ /*
1078+ * Needn't to transit from kernel domain before
1079+ * starting /sbin/init. But transit from kernel domain
1080+ * if executing initializers because they might start
1081+ * before /sbin/init.
1082+ */
1083+ domain = old_domain;
1084+ break;
1085+ }
1086+force_child_domain:
1087+ /* Normal domain transition. */
1088+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
1089+ old_domain->domainname->name, candidate->name);
1090+ break;
1091+ }
1092+force_jump_domain:
1093+ /*
1094+ * Tell GC that I started execve().
1095+ * Also, tell open_exec() to check read permission.
1096+ */
1097+ task->ccs_flags |= CCS_TASK_IS_IN_EXECVE;
1098+ /*
1099+ * Make task->ccs_flags visible to GC before changing
1100+ * task->ccs_domain_info.
1101+ */
1102+ smp_wmb();
1103+ /*
1104+ * Proceed to the next domain in order to allow reaching via PID.
1105+ * It will be reverted if execve() failed. Reverting is not good.
1106+ * But it is better than being unable to reach via PID in interactive
1107+ * enforcing mode.
1108+ */
1109+ if (!domain)
1110+ domain = ccs_assign_domain(ee->tmp, true);
1111+ if (domain)
1112+ retval = 0;
1113+ else if (reject_on_transition_failure) {
1114+ printk(KERN_WARNING
1115+ "ERROR: Domain '%s' not ready.\n", ee->tmp);
1116+ retval = -ENOMEM;
1117+ } else if (r->mode == CCS_CONFIG_ENFORCING)
1118+ retval = -ENOMEM;
1119+ else {
1120+ retval = 0;
1121+ if (!old_domain->flags[CCS_DIF_TRANSITION_FAILED]) {
1122+ old_domain->flags[CCS_DIF_TRANSITION_FAILED] = true;
1123+ r->granted = false;
1124+ ccs_write_log(r, "%s",
1125+ ccs_dif[CCS_DIF_TRANSITION_FAILED]);
1126+ printk(KERN_WARNING
1127+ "ERROR: Domain '%s' not defined.\n", ee->tmp);
1128+ }
1129+ }
1130+out:
1131+ kfree(exename.name);
1132+ return retval;
1133+}
1134+
1135+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1136+
1137+/**
1138+ * ccs_unescape - Unescape escaped string.
1139+ *
1140+ * @dest: String to unescape.
1141+ *
1142+ * Returns nothing.
1143+ */
1144+static void ccs_unescape(unsigned char *dest)
1145+{
1146+ unsigned char *src = dest;
1147+ unsigned char c;
1148+ unsigned char d;
1149+ unsigned char e;
1150+ while (1) {
1151+ c = *src++;
1152+ if (!c)
1153+ break;
1154+ if (c != '\\') {
1155+ *dest++ = c;
1156+ continue;
1157+ }
1158+ c = *src++;
1159+ if (c == '\\') {
1160+ *dest++ = c;
1161+ continue;
1162+ }
1163+ if (c < '0' || c > '3')
1164+ break;
1165+ d = *src++;
1166+ if (d < '0' || d > '7')
1167+ break;
1168+ e = *src++;
1169+ if (e < '0' || e > '7')
1170+ break;
1171+ *dest++ = ((c - '0') << 6) + ((d - '0') << 3) + (e - '0');
1172+ }
1173+ *dest = '\0';
1174+}
1175+
1176+/**
1177+ * ccs_try_alt_exec - Try to start execute handler.
1178+ *
1179+ * @ee: Pointer to "struct ccs_execve".
1180+ *
1181+ * Returns 0 on success, negative value otherwise.
1182+ */
1183+static int ccs_try_alt_exec(struct ccs_execve *ee)
1184+{
1185+ /*
1186+ * Contents of modified bprm.
1187+ * The envp[] in original bprm is moved to argv[] so that
1188+ * the alternatively executed program won't be affected by
1189+ * some dangerous environment variables like LD_PRELOAD.
1190+ *
1191+ * modified bprm->argc
1192+ * = original bprm->argc + original bprm->envc + 7
1193+ * modified bprm->envc
1194+ * = 0
1195+ *
1196+ * modified bprm->argv[0]
1197+ * = the program's name specified by *_execute_handler
1198+ * modified bprm->argv[1]
1199+ * = ccs_current_domain()->domainname->name
1200+ * modified bprm->argv[2]
1201+ * = the current process's name
1202+ * modified bprm->argv[3]
1203+ * = the current process's information (e.g. uid/gid).
1204+ * modified bprm->argv[4]
1205+ * = original bprm->filename
1206+ * modified bprm->argv[5]
1207+ * = original bprm->argc in string expression
1208+ * modified bprm->argv[6]
1209+ * = original bprm->envc in string expression
1210+ * modified bprm->argv[7]
1211+ * = original bprm->argv[0]
1212+ * ...
1213+ * modified bprm->argv[bprm->argc + 6]
1214+ * = original bprm->argv[bprm->argc - 1]
1215+ * modified bprm->argv[bprm->argc + 7]
1216+ * = original bprm->envp[0]
1217+ * ...
1218+ * modified bprm->argv[bprm->envc + bprm->argc + 6]
1219+ * = original bprm->envp[bprm->envc - 1]
1220+ */
1221+ struct linux_binprm *bprm = ee->bprm;
1222+ struct file *filp;
1223+ int retval;
1224+ const int original_argc = bprm->argc;
1225+ const int original_envc = bprm->envc;
1226+
1227+ /* Close the requested program's dentry. */
1228+ ee->obj.path1.dentry = NULL;
1229+ ee->obj.path1.mnt = NULL;
1230+ ee->obj.stat_valid[CCS_PATH1] = false;
1231+ ee->obj.stat_valid[CCS_PATH1_PARENT] = false;
1232+ ee->obj.validate_done = false;
1233+ allow_write_access(bprm->file);
1234+ fput(bprm->file);
1235+ bprm->file = NULL;
1236+
1237+ /* Invalidate page dump cache. */
1238+ ee->dump.page = NULL;
1239+
1240+ /* Move envp[] to argv[] */
1241+ bprm->argc += bprm->envc;
1242+ bprm->envc = 0;
1243+
1244+ /* Set argv[6] */
1245+ {
1246+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%d", original_envc);
1247+ retval = ccs_copy_argv(ee->tmp, bprm);
1248+ if (retval < 0)
1249+ goto out;
1250+ }
1251+
1252+ /* Set argv[5] */
1253+ {
1254+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%d", original_argc);
1255+ retval = ccs_copy_argv(ee->tmp, bprm);
1256+ if (retval < 0)
1257+ goto out;
1258+ }
1259+
1260+ /* Set argv[4] */
1261+ {
1262+ retval = ccs_copy_argv(bprm->filename, bprm);
1263+ if (retval < 0)
1264+ goto out;
1265+ }
1266+
1267+ /* Set argv[3] */
1268+ {
1269+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
1270+ /*
1271+ * Pass uid/gid seen from current user namespace, for these
1272+ * values are used by programs in current user namespace in
1273+ * order to decide whether to execve() or not (rather than by
1274+ * auditing daemon in init's user namespace).
1275+ */
1276+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1,
1277+ "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
1278+ "sgid=%d fsuid=%d fsgid=%d", ccs_sys_getpid(),
1279+ __kuid_val(current_uid()), __kgid_val(current_gid()),
1280+ __kuid_val(current_euid()),
1281+ __kgid_val(current_egid()),
1282+ __kuid_val(current_suid()),
1283+ __kgid_val(current_sgid()),
1284+ __kuid_val(current_fsuid()),
1285+ __kgid_val(current_fsgid()));
1286+#else
1287+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1,
1288+ "pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d "
1289+ "sgid=%d fsuid=%d fsgid=%d", ccs_sys_getpid(),
1290+ current_uid(), current_gid(), current_euid(),
1291+ current_egid(), current_suid(), current_sgid(),
1292+ current_fsuid(), current_fsgid());
1293+#endif
1294+ retval = ccs_copy_argv(ee->tmp, bprm);
1295+ if (retval < 0)
1296+ goto out;
1297+ }
1298+
1299+ /* Set argv[2] */
1300+ {
1301+ char *exe = (char *) ccs_get_exe();
1302+ if (exe) {
1303+ retval = ccs_copy_argv(exe, bprm);
1304+ kfree(exe);
1305+ } else {
1306+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1307+ retval = ccs_copy_argv("<unknown>", bprm);
1308+#else
1309+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "<unknown>");
1310+ retval = ccs_copy_argv(ee->tmp, bprm);
1311+#endif
1312+ }
1313+ if (retval < 0)
1314+ goto out;
1315+ }
1316+
1317+ /* Set argv[1] */
1318+ {
1319+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1320+ retval = ccs_copy_argv(ccs_current_domain()->domainname->name,
1321+ bprm);
1322+#else
1323+ snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s",
1324+ ccs_current_domain()->domainname->name);
1325+ retval = ccs_copy_argv(ee->tmp, bprm);
1326+#endif
1327+ if (retval < 0)
1328+ goto out;
1329+ }
1330+
1331+ /* Set argv[0] */
1332+ {
1333+ struct path root;
1334+ char *cp;
1335+ int root_len;
1336+ int handler_len;
1337+ get_fs_root(current->fs, &root);
1338+ cp = ccs_realpath(&root);
1339+ path_put(&root);
1340+ if (!cp) {
1341+ retval = -ENOMEM;
1342+ goto out;
1343+ }
1344+ root_len = strlen(cp);
1345+ retval = strncmp(ee->handler->name, cp, root_len);
1346+ root_len--;
1347+ kfree(cp);
1348+ if (retval) {
1349+ retval = -ENOENT;
1350+ goto out;
1351+ }
1352+ handler_len = ee->handler->total_len + 1;
1353+ cp = kmalloc(handler_len, CCS_GFP_FLAGS);
1354+ if (!cp) {
1355+ retval = -ENOMEM;
1356+ goto out;
1357+ }
1358+ /* ee->handler_path is released by ccs_finish_execve(). */
1359+ ee->handler_path = cp;
1360+ /* Adjust root directory for open_exec(). */
1361+ memmove(cp, ee->handler->name + root_len,
1362+ handler_len - root_len);
1363+ ccs_unescape(cp);
1364+ retval = -ENOENT;
1365+ if (*cp != '/')
1366+ goto out;
1367+ retval = ccs_copy_argv(cp, bprm);
1368+ if (retval < 0)
1369+ goto out;
1370+ }
1371+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
1372+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
1373+ bprm->argv_len = bprm->exec - bprm->p;
1374+#endif
1375+#endif
1376+
1377+ /*
1378+ * OK, now restart the process with execute handler program's dentry.
1379+ */
1380+ filp = open_exec(ee->handler_path);
1381+ if (IS_ERR(filp)) {
1382+ retval = PTR_ERR(filp);
1383+ goto out;
1384+ }
1385+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
1386+ ee->obj.path1 = filp->f_path;
1387+#else
1388+ ee->obj.path1.dentry = filp->f_dentry;
1389+ ee->obj.path1.mnt = filp->f_vfsmnt;
1390+#endif
1391+ bprm->file = filp;
1392+ bprm->filename = ee->handler_path;
1393+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1394+ bprm->interp = bprm->filename;
1395+#endif
1396+ retval = prepare_binprm(bprm);
1397+ if (retval < 0)
1398+ goto out;
1399+ ee->r.dont_sleep_on_enforce_error = true;
1400+ retval = ccs_find_next_domain(ee);
1401+ ee->r.dont_sleep_on_enforce_error = false;
1402+out:
1403+ return retval;
1404+}
1405+
1406+/**
1407+ * ccs_find_execute_handler - Find an execute handler.
1408+ *
1409+ * @ee: Pointer to "struct ccs_execve".
1410+ * @type: Type of execute handler.
1411+ *
1412+ * Returns true if found, false otherwise.
1413+ *
1414+ * Caller holds ccs_read_lock().
1415+ */
1416+static bool ccs_find_execute_handler(struct ccs_execve *ee, const u8 type)
1417+{
1418+ struct ccs_request_info *r = &ee->r;
1419+ /*
1420+ * To avoid infinite execute handler loop, don't use execute handler
1421+ * if the current process is marked as execute handler.
1422+ */
1423+ if (ccs_current_flags() & CCS_TASK_IS_EXECUTE_HANDLER)
1424+ return false;
1425+ r->param_type = type;
1426+ ccs_check_acl(r);
1427+ if (!r->granted)
1428+ return false;
1429+ ee->handler = container_of(r->matched_acl, struct ccs_handler_acl,
1430+ head)->handler;
1431+ ee->transition = r->matched_acl && r->matched_acl->cond &&
1432+ r->matched_acl->cond->exec_transit ?
1433+ r->matched_acl->cond->transit : NULL;
1434+ return true;
1435+}
1436+
1437+#endif
1438+
1439+#ifdef CONFIG_MMU
1440+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
1441+#define CCS_BPRM_MMU
1442+#elif defined(RHEL_MAJOR) && RHEL_MAJOR == 5 && defined(RHEL_MINOR) && RHEL_MINOR >= 3
1443+#define CCS_BPRM_MMU
1444+#elif defined(AX_MAJOR) && AX_MAJOR == 3 && defined(AX_MINOR) && AX_MINOR >= 2
1445+#define CCS_BPRM_MMU
1446+#endif
1447+#endif
1448+
1449+/**
1450+ * ccs_dump_page - Dump a page to buffer.
1451+ *
1452+ * @bprm: Pointer to "struct linux_binprm".
1453+ * @pos: Location to dump.
1454+ * @dump: Pointer to "struct ccs_page_dump".
1455+ *
1456+ * Returns true on success, false otherwise.
1457+ */
1458+bool ccs_dump_page(struct linux_binprm *bprm, unsigned long pos,
1459+ struct ccs_page_dump *dump)
1460+{
1461+ struct page *page;
1462+ /* dump->data is released by ccs_start_execve(). */
1463+ if (!dump->data) {
1464+ dump->data = kzalloc(PAGE_SIZE, CCS_GFP_FLAGS);
1465+ if (!dump->data)
1466+ return false;
1467+ }
1468+ /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
1469+#ifdef CCS_BPRM_MMU
1470+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
1471+ if (get_user_pages_remote(bprm->mm, pos, 1, FOLL_FORCE, &page,
1472+ NULL, NULL) <= 0)
1473+ return false;
1474+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
1475+ if (get_user_pages_remote(current, bprm->mm, pos, 1, FOLL_FORCE, &page,
1476+ NULL, NULL) <= 0)
1477+ return false;
1478+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
1479+ if (get_user_pages_remote(current, bprm->mm, pos, 1, FOLL_FORCE, &page,
1480+ NULL) <= 0)
1481+ return false;
1482+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 168) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
1483+ if (get_user_pages(current, bprm->mm, pos, 1, FOLL_FORCE, &page,
1484+ NULL) <= 0)
1485+ return false;
1486+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
1487+ if (get_user_pages_remote(current, bprm->mm, pos, 1, 0, 1, &page,
1488+ NULL) <= 0)
1489+ return false;
1490+#else
1491+ if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
1492+ return false;
1493+#endif
1494+#else
1495+ page = bprm->page[pos / PAGE_SIZE];
1496+#endif
1497+ if (page != dump->page) {
1498+ const unsigned int offset = pos % PAGE_SIZE;
1499+ /*
1500+ * Maybe kmap()/kunmap() should be used here.
1501+ * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
1502+ * So do I.
1503+ */
1504+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1505+ char *kaddr = kmap_atomic(page);
1506+#else
1507+ char *kaddr = kmap_atomic(page, KM_USER0);
1508+#endif
1509+ dump->page = page;
1510+ memcpy(dump->data + offset, kaddr + offset,
1511+ PAGE_SIZE - offset);
1512+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1513+ kunmap_atomic(kaddr);
1514+#else
1515+ kunmap_atomic(kaddr, KM_USER0);
1516+#endif
1517+ }
1518+ /* Same with put_arg_page(page) in fs/exec.c */
1519+#ifdef CCS_BPRM_MMU
1520+ put_page(page);
1521+#endif
1522+ return true;
1523+}
1524+
1525+/**
1526+ * ccs_start_execve - Prepare for execve() operation.
1527+ *
1528+ * @bprm: Pointer to "struct linux_binprm".
1529+ * @eep: Pointer to "struct ccs_execve *".
1530+ *
1531+ * Returns 0 on success, negative value otherwise.
1532+ */
1533+int ccs_start_execve(struct linux_binprm *bprm, struct ccs_execve **eep)
1534+{
1535+ int retval;
1536+ struct ccs_security *task;
1537+ struct ccs_execve *ee;
1538+ int idx;
1539+ *eep = NULL;
1540+ ee = kzalloc(sizeof(*ee), CCS_GFP_FLAGS);
1541+ if (!ee)
1542+ return -ENOMEM;
1543+ ee->tmp = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
1544+ if (!ee->tmp) {
1545+ kfree(ee);
1546+ return -ENOMEM;
1547+ }
1548+ ccs_audit_alloc_execve(ee);
1549+ task = ccs_current_security();
1550+ idx = ccs_read_lock();
1551+ /* ee->dump->data is allocated by ccs_dump_page(). */
1552+ ee->previous_domain = task->ccs_domain_info;
1553+ /* Clear manager flag. */
1554+ task->ccs_flags &= ~CCS_TASK_IS_MANAGER;
1555+ *eep = ee;
1556+ ccs_init_request_info(&ee->r, CCS_MAC_FILE_EXECUTE);
1557+ ee->r.ee = ee;
1558+ ee->bprm = bprm;
1559+ ee->r.obj = &ee->obj;
1560+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
1561+ ee->obj.path1 = bprm->file->f_path;
1562+#else
1563+ ee->obj.path1.dentry = bprm->file->f_dentry;
1564+ ee->obj.path1.mnt = bprm->file->f_vfsmnt;
1565+#endif
1566+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1567+ /*
1568+ * No need to call ccs_environ() for execute handler because envp[] is
1569+ * moved to argv[].
1570+ */
1571+ if (ccs_find_execute_handler(ee, CCS_TYPE_AUTO_EXECUTE_HANDLER)) {
1572+ retval = ccs_try_alt_exec(ee);
1573+ goto done;
1574+ }
1575+#endif
1576+ retval = ccs_find_next_domain(ee);
1577+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1578+ if (retval == -EPERM &&
1579+ ccs_find_execute_handler(ee, CCS_TYPE_DENIED_EXECUTE_HANDLER)) {
1580+ retval = ccs_try_alt_exec(ee);
1581+ goto done;
1582+ }
1583+#endif
1584+#ifdef CONFIG_CCSECURITY_MISC
1585+ if (!retval)
1586+ retval = ccs_environ(ee);
1587+#endif
1588+#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
1589+done:
1590+#endif
1591+ ccs_read_unlock(idx);
1592+ kfree(ee->tmp);
1593+ ee->tmp = NULL;
1594+ kfree(ee->dump.data);
1595+ ee->dump.data = NULL;
1596+ return retval;
1597+}
1598+
1599+/**
1600+ * ccs_finish_execve - Clean up execve() operation.
1601+ *
1602+ * @retval: Return code of an execve() operation.
1603+ * @ee: Pointer to "struct ccs_execve".
1604+ *
1605+ * Returns nothing.
1606+ */
1607+void ccs_finish_execve(int retval, struct ccs_execve *ee)
1608+{
1609+ struct ccs_security *task = ccs_current_security();
1610+ if (!ee)
1611+ return;
1612+ if (retval < 0) {
1613+ task->ccs_domain_info = ee->previous_domain;
1614+ /*
1615+ * Make task->ccs_domain_info visible to GC before changing
1616+ * task->ccs_flags.
1617+ */
1618+ smp_wmb();
1619+ } else {
1620+ /* Mark the current process as execute handler. */
1621+ if (ee->handler)
1622+ task->ccs_flags |= CCS_TASK_IS_EXECUTE_HANDLER;
1623+ /* Mark the current process as normal process. */
1624+ else
1625+ task->ccs_flags &= ~CCS_TASK_IS_EXECUTE_HANDLER;
1626+ }
1627+ /* Tell GC that I finished execve(). */
1628+ task->ccs_flags &= ~CCS_TASK_IS_IN_EXECVE;
1629+ ccs_audit_free_execve(ee, true);
1630+ kfree(ee->handler_path);
1631+ kfree(ee);
1632+}
1633+
1634+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1635+
1636+/**
1637+ * __ccs_search_binary_handler - Main routine for do_execve().
1638+ *
1639+ * @bprm: Pointer to "struct linux_binprm".
1640+ * @regs: Pointer to "struct pt_regs".
1641+ *
1642+ * Returns 0 on success, negative value otherwise.
1643+ *
1644+ * Performs permission checks for do_execve() and domain transition.
1645+ * Domain transition by "struct ccs_domain_transition_control" and
1646+ * "auto_domain_transition=" parameter of "struct ccs_condition" are reverted
1647+ * if do_execve() failed.
1648+ * Garbage collector does not remove "struct ccs_domain_info" from
1649+ * ccs_domain_list nor kfree("struct ccs_domain_info") if the current thread is
1650+ * marked as CCS_TASK_IS_IN_EXECVE.
1651+ */
1652+static int __ccs_search_binary_handler(struct linux_binprm *bprm,
1653+ struct pt_regs *regs)
1654+{
1655+ struct ccs_execve *ee;
1656+ int retval = ccs_start_execve(bprm, &ee);
1657+ if (!retval)
1658+ retval = search_binary_handler(bprm, regs);
1659+ ccs_finish_execve(retval, ee);
1660+ return retval;
1661+}
1662+
1663+#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
1664+
1665+/**
1666+ * __ccs_search_binary_handler - Main routine for do_execve().
1667+ *
1668+ * @bprm: Pointer to "struct linux_binprm".
1669+ *
1670+ * Returns 0 on success, negative value otherwise.
1671+ *
1672+ * Performs permission checks for do_execve() and domain transition.
1673+ * Domain transition by "struct ccs_domain_transition_control" and
1674+ * "auto_domain_transition=" parameter of "struct ccs_condition" are reverted
1675+ * if do_execve() failed.
1676+ * Garbage collector does not remove "struct ccs_domain_info" from
1677+ * ccs_domain_list nor kfree("struct ccs_domain_info") if the current thread is
1678+ * marked as CCS_TASK_IS_IN_EXECVE.
1679+ */
1680+static int __ccs_search_binary_handler(struct linux_binprm *bprm)
1681+{
1682+ struct ccs_execve *ee;
1683+ int retval = ccs_start_execve(bprm, &ee);
1684+ if (!retval)
1685+ retval = search_binary_handler(bprm);
1686+ ccs_finish_execve(retval, ee);
1687+ return retval;
1688+}
1689+
1690+#endif
1691+
1692+/**
1693+ * ccs_permission_init - Register permission check hooks.
1694+ *
1695+ * Returns nothing.
1696+ */
1697+void __init ccs_permission_init(void)
1698+{
1699+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
1700+ ccsecurity_ops.save_open_mode = __ccs_save_open_mode;
1701+ ccsecurity_ops.clear_open_mode = __ccs_clear_open_mode;
1702+ ccsecurity_ops.open_permission = __ccs_open_permission;
1703+#else
1704+ ccsecurity_ops.open_permission = ccs_new_open_permission;
1705+#endif
1706+ ccsecurity_ops.fcntl_permission = __ccs_fcntl_permission;
1707+ ccsecurity_ops.ioctl_permission = __ccs_ioctl_permission;
1708+ ccsecurity_ops.chmod_permission = __ccs_chmod_permission;
1709+ ccsecurity_ops.chown_permission = __ccs_chown_permission;
1710+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
1711+ ccsecurity_ops.getattr_permission = __ccs_getattr_permission;
1712+#endif
1713+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1714+ ccsecurity_ops.pivot_root_permission = __ccs_pivot_root_permission;
1715+ ccsecurity_ops.chroot_permission = __ccs_chroot_permission;
1716+#else
1717+ ccsecurity_ops.pivot_root_permission = ccs_old_pivot_root_permission;
1718+ ccsecurity_ops.chroot_permission = ccs_old_chroot_permission;
1719+#endif
1720+ ccsecurity_ops.umount_permission = __ccs_umount_permission;
1721+ ccsecurity_ops.mknod_permission = __ccs_mknod_permission;
1722+ ccsecurity_ops.mkdir_permission = __ccs_mkdir_permission;
1723+ ccsecurity_ops.rmdir_permission = __ccs_rmdir_permission;
1724+ ccsecurity_ops.unlink_permission = __ccs_unlink_permission;
1725+ ccsecurity_ops.symlink_permission = __ccs_symlink_permission;
1726+ ccsecurity_ops.truncate_permission = __ccs_truncate_permission;
1727+ ccsecurity_ops.rename_permission = __ccs_rename_permission;
1728+ ccsecurity_ops.link_permission = __ccs_link_permission;
1729+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
1730+ ccsecurity_ops.open_exec_permission = __ccs_open_exec_permission;
1731+ ccsecurity_ops.uselib_permission = __ccs_uselib_permission;
1732+#endif
1733+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
1734+ ccsecurity_ops.parse_table = __ccs_parse_table;
1735+#endif
1736+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1737+ ccsecurity_ops.mount_permission = __ccs_mount_permission;
1738+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1739+ ccsecurity_ops.move_mount_permission = __ccs_move_mount_permission;
1740+#endif
1741+#else
1742+ ccsecurity_ops.mount_permission = ccs_old_mount_permission;
1743+#endif
1744+#ifdef CONFIG_CCSECURITY_CAPABILITY
1745+ ccsecurity_ops.socket_create_permission =
1746+ __ccs_socket_create_permission;
1747+#endif
1748+#ifdef CONFIG_CCSECURITY_NETWORK
1749+ ccsecurity_ops.socket_listen_permission =
1750+ __ccs_socket_listen_permission;
1751+ ccsecurity_ops.socket_connect_permission =
1752+ __ccs_socket_connect_permission;
1753+ ccsecurity_ops.socket_bind_permission = __ccs_socket_bind_permission;
1754+ ccsecurity_ops.socket_post_accept_permission =
1755+ __ccs_socket_post_accept_permission;
1756+ ccsecurity_ops.socket_sendmsg_permission =
1757+ __ccs_socket_sendmsg_permission;
1758+#endif
1759+#ifdef CONFIG_CCSECURITY_NETWORK_RECVMSG
1760+ ccsecurity_ops.socket_post_recvmsg_permission =
1761+ __ccs_socket_post_recvmsg_permission;
1762+#endif
1763+#ifdef CONFIG_CCSECURITY_IPC
1764+ ccsecurity_ops.kill_permission = ccs_signal_acl;
1765+ ccsecurity_ops.tgkill_permission = ccs_signal_acl0;
1766+ ccsecurity_ops.tkill_permission = ccs_signal_acl;
1767+ ccsecurity_ops.sigqueue_permission = ccs_signal_acl;
1768+ ccsecurity_ops.tgsigqueue_permission = ccs_signal_acl0;
1769+#endif
1770+#ifdef CONFIG_CCSECURITY_CAPABILITY
1771+ ccsecurity_ops.capable = __ccs_capable;
1772+ ccsecurity_ops.ptrace_permission = __ccs_ptrace_permission;
1773+#endif
1774+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
1775+ ccsecurity_ops.finish_execve = ccs_finish_execve;
1776+ ccsecurity_ops.start_execve = ccs_start_execve;
1777+#else
1778+ ccsecurity_ops.search_binary_handler = __ccs_search_binary_handler;
1779+#endif
1780+}
1781+
1782+/**
1783+ * ccs_kern_path - Wrapper for kern_path().
1784+ *
1785+ * @pathname: Pathname to resolve. Maybe NULL.
1786+ * @flags: Lookup flags.
1787+ * @path: Pointer to "struct path".
1788+ *
1789+ * Returns 0 on success, negative value otherwise.
1790+ */
1791+static int ccs_kern_path(const char *pathname, int flags, struct path *path)
1792+{
1793+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
1794+ if (!pathname || kern_path(pathname, flags, path))
1795+ return -ENOENT;
1796+#else
1797+ struct nameidata nd;
1798+ if (!pathname || path_lookup(pathname, flags, &nd))
1799+ return -ENOENT;
1800+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
1801+ *path = nd.path;
1802+#else
1803+ path->dentry = nd.dentry;
1804+ path->mnt = nd.mnt;
1805+#endif
1806+#endif
1807+ return 0;
1808+}
1809+
1810+/**
1811+ * ccs_get_path - Get dentry/vfsmmount of a pathname.
1812+ *
1813+ * @pathname: The pathname to solve. Maybe NULL.
1814+ * @path: Pointer to "struct path".
1815+ *
1816+ * Returns 0 on success, negative value otherwise.
1817+ */
1818+static int ccs_get_path(const char *pathname, struct path *path)
1819+{
1820+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1821+ return ccs_kern_path(pathname, LOOKUP_FOLLOW, path);
1822+#else
1823+ return ccs_kern_path(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, path);
1824+#endif
1825+}
1826+
1827+/**
1828+ * ccs_symlink_path - Get symlink's pathname.
1829+ *
1830+ * @pathname: The pathname to solve. Maybe NULL.
1831+ * @name: Pointer to "struct ccs_path_info".
1832+ *
1833+ * Returns 0 on success, negative value otherwise.
1834+ *
1835+ * This function uses kzalloc(), so caller must kfree() if this function
1836+ * didn't return NULL.
1837+ */
1838+static int ccs_symlink_path(const char *pathname, struct ccs_path_info *name)
1839+{
1840+ char *buf;
1841+ struct path path;
1842+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
1843+ if (ccs_kern_path(pathname, 0, &path))
1844+ return -ENOENT;
1845+#else
1846+ if (ccs_kern_path(pathname, LOOKUP_POSITIVE, &path))
1847+ return -ENOENT;
1848+#endif
1849+ buf = ccs_realpath(&path);
1850+ path_put(&path);
1851+ if (buf) {
1852+ name->name = buf;
1853+ ccs_fill_path_info(name);
1854+ return 0;
1855+ }
1856+ return -ENOMEM;
1857+}
1858+
1859+/**
1860+ * ccs_check_mount_acl - Check permission for path path path number operation.
1861+ *
1862+ * @r: Pointer to "struct ccs_request_info".
1863+ * @ptr: Pointer to "struct ccs_acl_info".
1864+ *
1865+ * Returns true if granted, false otherwise.
1866+ */
1867+static bool ccs_check_mount_acl(struct ccs_request_info *r,
1868+ const struct ccs_acl_info *ptr)
1869+{
1870+ const struct ccs_mount_acl *acl =
1871+ container_of(ptr, typeof(*acl), head);
1872+ return ccs_compare_number_union(r->param.mount.flags, &acl->flags) &&
1873+ ccs_compare_name_union(r->param.mount.type, &acl->fs_type) &&
1874+ ccs_compare_name_union(r->param.mount.dir, &acl->dir_name) &&
1875+ (!r->param.mount.need_dev ||
1876+ ccs_compare_name_union(r->param.mount.dev, &acl->dev_name));
1877+}
1878+
1879+/**
1880+ * ccs_mount_acl - Check permission for mount() operation.
1881+ *
1882+ * @r: Pointer to "struct ccs_request_info".
1883+ * @dev_name: Name of device file. Maybe NULL.
1884+ * @dir: Pointer to "struct path".
1885+ * @type: Name of filesystem type.
1886+ * @flags: Mount options.
1887+ *
1888+ * Returns 0 on success, negative value otherwise.
1889+ *
1890+ * Caller holds ccs_read_lock().
1891+ */
1892+static int ccs_mount_acl(struct ccs_request_info *r, const char *dev_name,
1893+ const struct path *dir, const char *type,
1894+ unsigned long flags)
1895+{
1896+ struct ccs_obj_info obj = { };
1897+ struct file_system_type *fstype = NULL;
1898+ const char *requested_type = NULL;
1899+ const char *requested_dir_name = NULL;
1900+ const char *requested_dev_name = NULL;
1901+ struct ccs_path_info rtype;
1902+ struct ccs_path_info rdev;
1903+ struct ccs_path_info rdir;
1904+ int need_dev = 0;
1905+ int error = -ENOMEM;
1906+ r->obj = &obj;
1907+
1908+ /* Get fstype. */
1909+ requested_type = ccs_encode(type);
1910+ if (!requested_type)
1911+ goto out;
1912+ rtype.name = requested_type;
1913+ ccs_fill_path_info(&rtype);
1914+
1915+ /* Get mount point. */
1916+ obj.path2 = *dir;
1917+ requested_dir_name = ccs_realpath(dir);
1918+ if (!requested_dir_name) {
1919+ error = -ENOMEM;
1920+ goto out;
1921+ }
1922+ rdir.name = requested_dir_name;
1923+ ccs_fill_path_info(&rdir);
1924+
1925+ /* Compare fs name. */
1926+ if (type == ccs_mounts[CCS_MOUNT_REMOUNT]) {
1927+ /* dev_name is ignored. */
1928+ } else if (type == ccs_mounts[CCS_MOUNT_MAKE_UNBINDABLE] ||
1929+ type == ccs_mounts[CCS_MOUNT_MAKE_PRIVATE] ||
1930+ type == ccs_mounts[CCS_MOUNT_MAKE_SLAVE] ||
1931+ type == ccs_mounts[CCS_MOUNT_MAKE_SHARED]) {
1932+ /* dev_name is ignored. */
1933+ } else if (type == ccs_mounts[CCS_MOUNT_BIND] ||
1934+ type == ccs_mounts[CCS_MOUNT_MOVE]) {
1935+ need_dev = -1; /* dev_name is a directory */
1936+ } else {
1937+ fstype = get_fs_type(type);
1938+ if (!fstype) {
1939+ error = -ENODEV;
1940+ goto out;
1941+ }
1942+ if (fstype->fs_flags & FS_REQUIRES_DEV)
1943+ /* dev_name is a block device file. */
1944+ need_dev = 1;
1945+ }
1946+ if (need_dev) {
1947+ /* Get mount point or device file. */
1948+ if (ccs_get_path(dev_name, &obj.path1)) {
1949+ error = -ENOENT;
1950+ goto out;
1951+ }
1952+ requested_dev_name = ccs_realpath(&obj.path1);
1953+ if (!requested_dev_name) {
1954+ error = -ENOENT;
1955+ goto out;
1956+ }
1957+ } else {
1958+ /* Map dev_name to "<NULL>" if no dev_name given. */
1959+ if (!dev_name)
1960+ dev_name = "<NULL>";
1961+ requested_dev_name = ccs_encode(dev_name);
1962+ if (!requested_dev_name) {
1963+ error = -ENOMEM;
1964+ goto out;
1965+ }
1966+ }
1967+ rdev.name = requested_dev_name;
1968+ ccs_fill_path_info(&rdev);
1969+ r->param_type = CCS_TYPE_MOUNT_ACL;
1970+ r->param.mount.need_dev = need_dev;
1971+ r->param.mount.dev = &rdev;
1972+ r->param.mount.dir = &rdir;
1973+ r->param.mount.type = &rtype;
1974+ r->param.mount.flags = flags;
1975+ error = ccs_check_acl(r);
1976+out:
1977+ kfree(requested_dev_name);
1978+ kfree(requested_dir_name);
1979+ if (fstype)
1980+ ccs_put_filesystem(fstype);
1981+ kfree(requested_type);
1982+ /* Drop refcount obtained by ccs_get_path(). */
1983+ if (obj.path1.dentry)
1984+ path_put(&obj.path1);
1985+ return error;
1986+}
1987+
1988+/**
1989+ * __ccs_mount_permission - Check permission for mount() operation.
1990+ *
1991+ * @dev_name: Name of device file. Maybe NULL.
1992+ * @path: Pointer to "struct path".
1993+ * @type: Name of filesystem type. Maybe NULL.
1994+ * @flags: Mount options.
1995+ * @data_page: Optional data. Maybe NULL.
1996+ *
1997+ * Returns 0 on success, negative value otherwise.
1998+ */
1999+static int __ccs_mount_permission(const char *dev_name,
2000+ const struct path *path, const char *type,
2001+ unsigned long flags, void *data_page)
2002+{
2003+ struct ccs_request_info r;
2004+ int error = 0;
2005+ int idx;
2006+ if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
2007+ flags &= ~MS_MGC_MSK;
2008+ if (flags & MS_REMOUNT) {
2009+ type = ccs_mounts[CCS_MOUNT_REMOUNT];
2010+ flags &= ~MS_REMOUNT;
2011+ } else if (flags & MS_BIND) {
2012+ type = ccs_mounts[CCS_MOUNT_BIND];
2013+ flags &= ~MS_BIND;
2014+ } else if (flags & MS_SHARED) {
2015+ if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
2016+ return -EINVAL;
2017+ type = ccs_mounts[CCS_MOUNT_MAKE_SHARED];
2018+ flags &= ~MS_SHARED;
2019+ } else if (flags & MS_PRIVATE) {
2020+ if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE))
2021+ return -EINVAL;
2022+ type = ccs_mounts[CCS_MOUNT_MAKE_PRIVATE];
2023+ flags &= ~MS_PRIVATE;
2024+ } else if (flags & MS_SLAVE) {
2025+ if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE))
2026+ return -EINVAL;
2027+ type = ccs_mounts[CCS_MOUNT_MAKE_SLAVE];
2028+ flags &= ~MS_SLAVE;
2029+ } else if (flags & MS_UNBINDABLE) {
2030+ if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE))
2031+ return -EINVAL;
2032+ type = ccs_mounts[CCS_MOUNT_MAKE_UNBINDABLE];
2033+ flags &= ~MS_UNBINDABLE;
2034+ } else if (flags & MS_MOVE) {
2035+ type = ccs_mounts[CCS_MOUNT_MOVE];
2036+ flags &= ~MS_MOVE;
2037+ }
2038+ if (!type)
2039+ type = "<NULL>";
2040+ idx = ccs_read_lock();
2041+ if (ccs_init_request_info(&r, CCS_MAC_FILE_MOUNT)
2042+ != CCS_CONFIG_DISABLED)
2043+ error = ccs_mount_acl(&r, dev_name, path, type, flags);
2044+ ccs_read_unlock(idx);
2045+ return error;
2046+}
2047+
2048+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
2049+
2050+/**
2051+ * ccs_old_mount_permission - Check permission for mount() operation.
2052+ *
2053+ * @dev_name: Name of device file.
2054+ * @nd: Pointer to "struct nameidata".
2055+ * @type: Name of filesystem type. Maybe NULL.
2056+ * @flags: Mount options.
2057+ * @data_page: Optional data. Maybe NULL.
2058+ *
2059+ * Returns 0 on success, negative value otherwise.
2060+ */
2061+static int ccs_old_mount_permission(const char *dev_name, struct nameidata *nd,
2062+ const char *type, unsigned long flags,
2063+ void *data_page)
2064+{
2065+ struct path path = { nd->mnt, nd->dentry };
2066+ return __ccs_mount_permission(dev_name, &path, type, flags, data_page);
2067+}
2068+
2069+#endif
2070+
2071+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
2072+/**
2073+ * __ccs_move_mount_permission - Check permission for move_mount() operation.
2074+ *
2075+ * @from_path: Pointer to "struct path".
2076+ * @to_path: Pointer to "struct path".
2077+ *
2078+ * Returns 0 on success, negative value otherwise.
2079+ */
2080+static int __ccs_move_mount_permission(const struct path *from_path,
2081+ const struct path *to_path)
2082+{
2083+ return -ENOSYS; /* For now. */
2084+}
2085+#endif
2086+
2087+/**
2088+ * ccs_compare_number_union - Check whether a value matches "struct ccs_number_union" or not.
2089+ *
2090+ * @value: Number to check.
2091+ * @ptr: Pointer to "struct ccs_number_union".
2092+ *
2093+ * Returns true if @value matches @ptr, false otherwise.
2094+ */
2095+static bool ccs_compare_number_union(const unsigned long value,
2096+ const struct ccs_number_union *ptr)
2097+{
2098+ if (ptr->group)
2099+ return ccs_number_matches_group(value, value, ptr->group);
2100+ return value >= ptr->values[0] && value <= ptr->values[1];
2101+}
2102+
2103+/**
2104+ * ccs_compare_name_union - Check whether a name matches "struct ccs_name_union" or not.
2105+ *
2106+ * @name: Pointer to "struct ccs_path_info".
2107+ * @ptr: Pointer to "struct ccs_name_union".
2108+ *
2109+ * Returns "struct ccs_path_info" if @name matches @ptr, NULL otherwise.
2110+ */
2111+static const struct ccs_path_info *ccs_compare_name_union
2112+(const struct ccs_path_info *name, const struct ccs_name_union *ptr)
2113+{
2114+ if (ptr->group)
2115+ return ccs_path_matches_group(name, ptr->group);
2116+ if (ccs_path_matches_pattern(name, ptr->filename))
2117+ return ptr->filename;
2118+ return NULL;
2119+}
2120+
2121+/**
2122+ * ccs_add_slash - Add trailing '/' if needed.
2123+ *
2124+ * @buf: Pointer to "struct ccs_path_info".
2125+ *
2126+ * Returns nothing.
2127+ *
2128+ * @buf must be generated by ccs_encode() because this function does not
2129+ * allocate memory for adding '/'.
2130+ */
2131+static void ccs_add_slash(struct ccs_path_info *buf)
2132+{
2133+ if (buf->is_dir)
2134+ return;
2135+ /* This is OK because ccs_encode() reserves space for appending "/". */
2136+ strcat((char *) buf->name, "/");
2137+ ccs_fill_path_info(buf);
2138+}
2139+
2140+/**
2141+ * ccs_get_realpath - Get realpath.
2142+ *
2143+ * @buf: Pointer to "struct ccs_path_info".
2144+ * @path: Pointer to "struct path". @path->mnt may be NULL.
2145+ *
2146+ * Returns true on success, false otherwise.
2147+ */
2148+static bool ccs_get_realpath(struct ccs_path_info *buf, struct path *path)
2149+{
2150+ buf->name = ccs_realpath(path);
2151+ if (buf->name) {
2152+ ccs_fill_path_info(buf);
2153+ return true;
2154+ }
2155+ return false;
2156+}
2157+
2158+/**
2159+ * ccs_check_path_acl - Check permission for path operation.
2160+ *
2161+ * @r: Pointer to "struct ccs_request_info".
2162+ * @ptr: Pointer to "struct ccs_acl_info".
2163+ *
2164+ * Returns true if granted, false otherwise.
2165+ *
2166+ * To be able to use wildcard for domain transition, this function sets
2167+ * matching entry on success. Since the caller holds ccs_read_lock(),
2168+ * it is safe to set matching entry.
2169+ */
2170+static bool ccs_check_path_acl(struct ccs_request_info *r,
2171+ const struct ccs_acl_info *ptr)
2172+{
2173+ const struct ccs_path_acl *acl = container_of(ptr, typeof(*acl), head);
2174+ if (ptr->perm & (1 << r->param.path.operation)) {
2175+ r->param.path.matched_path =
2176+ ccs_compare_name_union(r->param.path.filename,
2177+ &acl->name);
2178+ return r->param.path.matched_path != NULL;
2179+ }
2180+ return false;
2181+}
2182+
2183+/**
2184+ * ccs_check_path_number_acl - Check permission for path number operation.
2185+ *
2186+ * @r: Pointer to "struct ccs_request_info".
2187+ * @ptr: Pointer to "struct ccs_acl_info".
2188+ *
2189+ * Returns true if granted, false otherwise.
2190+ */
2191+static bool ccs_check_path_number_acl(struct ccs_request_info *r,
2192+ const struct ccs_acl_info *ptr)
2193+{
2194+ const struct ccs_path_number_acl *acl =
2195+ container_of(ptr, typeof(*acl), head);
2196+ return (ptr->perm & (1 << r->param.path_number.operation)) &&
2197+ ccs_compare_number_union(r->param.path_number.number,
2198+ &acl->number) &&
2199+ ccs_compare_name_union(r->param.path_number.filename,
2200+ &acl->name);
2201+}
2202+
2203+/**
2204+ * ccs_check_path2_acl - Check permission for path path operation.
2205+ *
2206+ * @r: Pointer to "struct ccs_request_info".
2207+ * @ptr: Pointer to "struct ccs_acl_info".
2208+ *
2209+ * Returns true if granted, false otherwise.
2210+ */
2211+static bool ccs_check_path2_acl(struct ccs_request_info *r,
2212+ const struct ccs_acl_info *ptr)
2213+{
2214+ const struct ccs_path2_acl *acl =
2215+ container_of(ptr, typeof(*acl), head);
2216+ return (ptr->perm & (1 << r->param.path2.operation)) &&
2217+ ccs_compare_name_union(r->param.path2.filename1, &acl->name1)
2218+ && ccs_compare_name_union(r->param.path2.filename2,
2219+ &acl->name2);
2220+}
2221+
2222+/**
2223+ * ccs_check_mkdev_acl - Check permission for path number number number operation.
2224+ *
2225+ * @r: Pointer to "struct ccs_request_info".
2226+ * @ptr: Pointer to "struct ccs_acl_info".
2227+ *
2228+ * Returns true if granted, false otherwise.
2229+ */
2230+static bool ccs_check_mkdev_acl(struct ccs_request_info *r,
2231+ const struct ccs_acl_info *ptr)
2232+{
2233+ const struct ccs_mkdev_acl *acl =
2234+ container_of(ptr, typeof(*acl), head);
2235+ return (ptr->perm & (1 << r->param.mkdev.operation)) &&
2236+ ccs_compare_number_union(r->param.mkdev.mode, &acl->mode) &&
2237+ ccs_compare_number_union(r->param.mkdev.major, &acl->major) &&
2238+ ccs_compare_number_union(r->param.mkdev.minor, &acl->minor) &&
2239+ ccs_compare_name_union(r->param.mkdev.filename, &acl->name);
2240+}
2241+
2242+/**
2243+ * ccs_path_permission - Check permission for path operation.
2244+ *
2245+ * @r: Pointer to "struct ccs_request_info".
2246+ * @operation: Type of operation.
2247+ * @filename: Filename to check.
2248+ *
2249+ * Returns 0 on success, negative value otherwise.
2250+ *
2251+ * Caller holds ccs_read_lock().
2252+ */
2253+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || !defined(CONFIG_SYSCTL_SYSCALL)
2254+static
2255+#endif
2256+int ccs_path_permission(struct ccs_request_info *r, u8 operation,
2257+ const struct ccs_path_info *filename)
2258+{
2259+ r->type = ccs_p2mac[operation];
2260+ r->mode = ccs_get_mode(r->profile, r->type);
2261+ if (r->mode == CCS_CONFIG_DISABLED)
2262+ return 0;
2263+ r->param_type = CCS_TYPE_PATH_ACL;
2264+ r->param.path.filename = filename;
2265+ r->param.path.operation = operation;
2266+ return ccs_check_acl(r);
2267+}
2268+
2269+/**
2270+ * ccs_execute_permission - Check permission for execute operation.
2271+ *
2272+ * @r: Pointer to "struct ccs_request_info".
2273+ * @filename: Filename to check.
2274+ *
2275+ * Returns 0 on success, CCS_RETRY_REQUEST on retry, negative value otherwise.
2276+ *
2277+ * Caller holds ccs_read_lock().
2278+ */
2279+static int ccs_execute_permission(struct ccs_request_info *r,
2280+ const struct ccs_path_info *filename)
2281+{
2282+ int error;
2283+ /*
2284+ * Unlike other permission checks, this check is done regardless of
2285+ * profile mode settings in order to check for domain transition
2286+ * preference.
2287+ */
2288+ r->type = CCS_MAC_FILE_EXECUTE;
2289+ r->mode = ccs_get_mode(r->profile, r->type);
2290+ r->param_type = CCS_TYPE_PATH_ACL;
2291+ r->param.path.filename = filename;
2292+ r->param.path.operation = CCS_TYPE_EXECUTE;
2293+ error = ccs_check_acl(r);
2294+ r->ee->transition = r->matched_acl && r->matched_acl->cond &&
2295+ r->matched_acl->cond->exec_transit ?
2296+ r->matched_acl->cond->transit : NULL;
2297+ return error;
2298+}
2299+
2300+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
2301+
2302+/**
2303+ * __ccs_save_open_mode - Remember original flags passed to sys_open().
2304+ *
2305+ * @mode: Flags passed to sys_open().
2306+ *
2307+ * Returns nothing.
2308+ *
2309+ * TOMOYO does not check "file write" if open(path, O_TRUNC | O_RDONLY) was
2310+ * requested because write() is not permitted. Instead, TOMOYO checks
2311+ * "file truncate" if O_TRUNC is passed.
2312+ *
2313+ * TOMOYO does not check "file read" and "file write" if open(path, 3) was
2314+ * requested because read()/write() are not permitted. Instead, TOMOYO checks
2315+ * "file ioctl" when ioctl() is requested.
2316+ */
2317+static void __ccs_save_open_mode(int mode)
2318+{
2319+ if ((mode & 3) == 3)
2320+ ccs_current_security()->ccs_flags |= CCS_OPEN_FOR_IOCTL_ONLY;
2321+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 14)
2322+ /* O_TRUNC passes MAY_WRITE to ccs_open_permission(). */
2323+ else if (!(mode & 3) && (mode & O_TRUNC))
2324+ ccs_current_security()->ccs_flags |=
2325+ CCS_OPEN_FOR_READ_TRUNCATE;
2326+#endif
2327+}
2328+
2329+/**
2330+ * __ccs_clear_open_mode - Forget original flags passed to sys_open().
2331+ *
2332+ * Returns nothing.
2333+ */
2334+static void __ccs_clear_open_mode(void)
2335+{
2336+ ccs_current_security()->ccs_flags &= ~(CCS_OPEN_FOR_IOCTL_ONLY |
2337+ CCS_OPEN_FOR_READ_TRUNCATE);
2338+}
2339+
2340+#endif
2341+
2342+/**
2343+ * __ccs_open_permission - Check permission for "read" and "write".
2344+ *
2345+ * @dentry: Pointer to "struct dentry".
2346+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2347+ * @flag: Flags for open().
2348+ *
2349+ * Returns 0 on success, negative value otherwise.
2350+ */
2351+static int __ccs_open_permission(struct dentry *dentry, struct vfsmount *mnt,
2352+ const int flag)
2353+{
2354+ struct ccs_request_info r;
2355+ struct ccs_obj_info obj = {
2356+ .path1.dentry = dentry,
2357+ .path1.mnt = mnt,
2358+ };
2359+ const u32 ccs_flags = ccs_current_flags();
2360+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
2361+ const u8 acc_mode = (flag & 3) == 3 ? 0 : ACC_MODE(flag);
2362+#else
2363+ const u8 acc_mode = (ccs_flags & CCS_OPEN_FOR_IOCTL_ONLY) ? 0 :
2364+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 14)
2365+ (ccs_flags & CCS_OPEN_FOR_READ_TRUNCATE) ? 4 :
2366+#endif
2367+ ACC_MODE(flag);
2368+#endif
2369+ int error = 0;
2370+ struct ccs_path_info buf;
2371+ int idx;
2372+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
2373+ if (current->in_execve && !(ccs_flags & CCS_TASK_IS_IN_EXECVE))
2374+ return 0;
2375+#endif
2376+#ifndef CONFIG_CCSECURITY_FILE_READDIR
2377+ if (d_is_dir(dentry))
2378+ return 0;
2379+#endif
2380+ buf.name = NULL;
2381+ r.mode = CCS_CONFIG_DISABLED;
2382+ idx = ccs_read_lock();
2383+ if (acc_mode && ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
2384+ != CCS_CONFIG_DISABLED) {
2385+ if (!ccs_get_realpath(&buf, &obj.path1)) {
2386+ error = -ENOMEM;
2387+ goto out;
2388+ }
2389+ r.obj = &obj;
2390+ if (acc_mode & MAY_READ)
2391+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
2392+ if (!error && (acc_mode & MAY_WRITE))
2393+ error = ccs_path_permission(&r, (flag & O_APPEND) ?
2394+ CCS_TYPE_APPEND :
2395+ CCS_TYPE_WRITE, &buf);
2396+ }
2397+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
2398+ if (!error && (flag & O_TRUNC) &&
2399+ ccs_init_request_info(&r, CCS_MAC_FILE_TRUNCATE)
2400+ != CCS_CONFIG_DISABLED) {
2401+ if (!buf.name && !ccs_get_realpath(&buf, &obj.path1)) {
2402+ error = -ENOMEM;
2403+ goto out;
2404+ }
2405+ r.obj = &obj;
2406+ error = ccs_path_permission(&r, CCS_TYPE_TRUNCATE, &buf);
2407+ }
2408+#endif
2409+out:
2410+ kfree(buf.name);
2411+ ccs_read_unlock(idx);
2412+ if (r.mode != CCS_CONFIG_ENFORCING)
2413+ error = 0;
2414+ return error;
2415+}
2416+
2417+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
2418+
2419+/**
2420+ * ccs_new_open_permission - Check permission for "read" and "write".
2421+ *
2422+ * @filp: Pointer to "struct file".
2423+ *
2424+ * Returns 0 on success, negative value otherwise.
2425+ */
2426+static int ccs_new_open_permission(struct file *filp)
2427+{
2428+ return __ccs_open_permission(filp->f_path.dentry, filp->f_path.mnt,
2429+ filp->f_flags);
2430+}
2431+
2432+#endif
2433+
2434+/**
2435+ * ccs_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "getattr", "chroot" and "unmount".
2436+ *
2437+ * @operation: Type of operation.
2438+ * @dentry: Pointer to "struct dentry".
2439+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2440+ * @target: Symlink's target if @operation is CCS_TYPE_SYMLINK,
2441+ * NULL otherwise.
2442+ *
2443+ * Returns 0 on success, negative value otherwise.
2444+ */
2445+static int ccs_path_perm(const u8 operation, struct dentry *dentry,
2446+ struct vfsmount *mnt, const char *target)
2447+{
2448+ struct ccs_request_info r;
2449+ struct ccs_obj_info obj = {
2450+ .path1.dentry = dentry,
2451+ .path1.mnt = mnt,
2452+ };
2453+ int error = 0;
2454+ struct ccs_path_info buf;
2455+ bool is_enforce = false;
2456+ struct ccs_path_info symlink_target;
2457+ int idx;
2458+ buf.name = NULL;
2459+ symlink_target.name = NULL;
2460+ idx = ccs_read_lock();
2461+ if (ccs_init_request_info(&r, ccs_p2mac[operation])
2462+ == CCS_CONFIG_DISABLED)
2463+ goto out;
2464+ is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
2465+ error = -ENOMEM;
2466+ if (!ccs_get_realpath(&buf, &obj.path1))
2467+ goto out;
2468+ r.obj = &obj;
2469+ switch (operation) {
2470+ case CCS_TYPE_RMDIR:
2471+ case CCS_TYPE_CHROOT:
2472+ ccs_add_slash(&buf);
2473+ break;
2474+ case CCS_TYPE_SYMLINK:
2475+ symlink_target.name = ccs_encode(target);
2476+ if (!symlink_target.name)
2477+ goto out;
2478+ ccs_fill_path_info(&symlink_target);
2479+ obj.symlink_target = &symlink_target;
2480+ break;
2481+ }
2482+ error = ccs_path_permission(&r, operation, &buf);
2483+ if (operation == CCS_TYPE_SYMLINK)
2484+ kfree(symlink_target.name);
2485+out:
2486+ kfree(buf.name);
2487+ ccs_read_unlock(idx);
2488+ if (!is_enforce)
2489+ error = 0;
2490+ return error;
2491+}
2492+
2493+/**
2494+ * ccs_mkdev_perm - Check permission for "mkblock" and "mkchar".
2495+ *
2496+ * @operation: Type of operation. (CCS_TYPE_MKCHAR or CCS_TYPE_MKBLOCK)
2497+ * @dentry: Pointer to "struct dentry".
2498+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2499+ * @mode: Create mode.
2500+ * @dev: Device number.
2501+ *
2502+ * Returns 0 on success, negative value otherwise.
2503+ */
2504+static int ccs_mkdev_perm(const u8 operation, struct dentry *dentry,
2505+ struct vfsmount *mnt, const unsigned int mode,
2506+ unsigned int dev)
2507+{
2508+ struct ccs_request_info r;
2509+ struct ccs_obj_info obj = {
2510+ .path1.dentry = dentry,
2511+ .path1.mnt = mnt,
2512+ };
2513+ int error = 0;
2514+ struct ccs_path_info buf;
2515+ bool is_enforce = false;
2516+ int idx;
2517+ idx = ccs_read_lock();
2518+ if (ccs_init_request_info(&r, ccs_pnnn2mac[operation])
2519+ == CCS_CONFIG_DISABLED)
2520+ goto out;
2521+ is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
2522+ error = -EPERM;
2523+ if (!capable(CAP_MKNOD))
2524+ goto out;
2525+ error = -ENOMEM;
2526+ if (!ccs_get_realpath(&buf, &obj.path1))
2527+ goto out;
2528+ r.obj = &obj;
2529+#ifdef CONFIG_SECURITY_PATH
2530+ dev = new_decode_dev(dev);
2531+#endif
2532+ r.param_type = CCS_TYPE_MKDEV_ACL;
2533+ r.param.mkdev.filename = &buf;
2534+ r.param.mkdev.operation = operation;
2535+ r.param.mkdev.mode = mode;
2536+ r.param.mkdev.major = MAJOR(dev);
2537+ r.param.mkdev.minor = MINOR(dev);
2538+ error = ccs_check_acl(&r);
2539+ kfree(buf.name);
2540+out:
2541+ ccs_read_unlock(idx);
2542+ if (!is_enforce)
2543+ error = 0;
2544+ return error;
2545+}
2546+
2547+/**
2548+ * ccs_path2_perm - Check permission for "rename", "link" and "pivot_root".
2549+ *
2550+ * @operation: Type of operation.
2551+ * @dentry1: Pointer to "struct dentry".
2552+ * @mnt1: Pointer to "struct vfsmount". Maybe NULL.
2553+ * @dentry2: Pointer to "struct dentry".
2554+ * @mnt2: Pointer to "struct vfsmount". Maybe NULL.
2555+ *
2556+ * Returns 0 on success, negative value otherwise.
2557+ */
2558+static int ccs_path2_perm(const u8 operation, struct dentry *dentry1,
2559+ struct vfsmount *mnt1, struct dentry *dentry2,
2560+ struct vfsmount *mnt2)
2561+{
2562+ struct ccs_request_info r;
2563+ int error = 0;
2564+ struct ccs_path_info buf1;
2565+ struct ccs_path_info buf2;
2566+ bool is_enforce = false;
2567+ struct ccs_obj_info obj = {
2568+ .path1.dentry = dentry1,
2569+ .path1.mnt = mnt1,
2570+ .path2.dentry = dentry2,
2571+ .path2.mnt = mnt2,
2572+ };
2573+ int idx;
2574+ buf1.name = NULL;
2575+ buf2.name = NULL;
2576+ idx = ccs_read_lock();
2577+ if (ccs_init_request_info(&r, ccs_pp2mac[operation])
2578+ == CCS_CONFIG_DISABLED)
2579+ goto out;
2580+ is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
2581+ error = -ENOMEM;
2582+ if (!ccs_get_realpath(&buf1, &obj.path1) ||
2583+ !ccs_get_realpath(&buf2, &obj.path2))
2584+ goto out;
2585+ switch (operation) {
2586+ case CCS_TYPE_RENAME:
2587+ case CCS_TYPE_LINK:
2588+ if (!d_is_dir(dentry1))
2589+ break;
2590+ /* fall through */
2591+ case CCS_TYPE_PIVOT_ROOT:
2592+ ccs_add_slash(&buf1);
2593+ ccs_add_slash(&buf2);
2594+ break;
2595+ }
2596+ r.obj = &obj;
2597+ r.param_type = CCS_TYPE_PATH2_ACL;
2598+ r.param.path2.operation = operation;
2599+ r.param.path2.filename1 = &buf1;
2600+ r.param.path2.filename2 = &buf2;
2601+ error = ccs_check_acl(&r);
2602+out:
2603+ kfree(buf1.name);
2604+ kfree(buf2.name);
2605+ ccs_read_unlock(idx);
2606+ if (!is_enforce)
2607+ error = 0;
2608+ return error;
2609+}
2610+
2611+/**
2612+ * ccs_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
2613+ *
2614+ * @type: Type of operation.
2615+ * @dentry: Pointer to "struct dentry".
2616+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2617+ * @number: Number.
2618+ *
2619+ * Returns 0 on success, negative value otherwise.
2620+ */
2621+static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
2622+ struct vfsmount *vfsmnt, unsigned long number)
2623+{
2624+ struct ccs_request_info r;
2625+ struct ccs_obj_info obj = {
2626+ .path1.dentry = dentry,
2627+ .path1.mnt = vfsmnt,
2628+ };
2629+ int error = 0;
2630+ struct ccs_path_info buf;
2631+ int idx;
2632+ if (!dentry)
2633+ return 0;
2634+ idx = ccs_read_lock();
2635+ if (ccs_init_request_info(&r, ccs_pn2mac[type]) == CCS_CONFIG_DISABLED)
2636+ goto out;
2637+ error = -ENOMEM;
2638+ if (!ccs_get_realpath(&buf, &obj.path1))
2639+ goto out;
2640+ r.obj = &obj;
2641+ if (type == CCS_TYPE_MKDIR)
2642+ ccs_add_slash(&buf);
2643+ r.param_type = CCS_TYPE_PATH_NUMBER_ACL;
2644+ r.param.path_number.operation = type;
2645+ r.param.path_number.filename = &buf;
2646+ r.param.path_number.number = number;
2647+ error = ccs_check_acl(&r);
2648+ kfree(buf.name);
2649+out:
2650+ ccs_read_unlock(idx);
2651+ if (r.mode != CCS_CONFIG_ENFORCING)
2652+ error = 0;
2653+ return error;
2654+}
2655+
2656+/**
2657+ * __ccs_ioctl_permission - Check permission for "ioctl".
2658+ *
2659+ * @filp: Pointer to "struct file".
2660+ * @cmd: Ioctl command number.
2661+ * @arg: Param for @cmd.
2662+ *
2663+ * Returns 0 on success, negative value otherwise.
2664+ */
2665+static int __ccs_ioctl_permission(struct file *filp, unsigned int cmd,
2666+ unsigned long arg)
2667+{
2668+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
2669+ return ccs_path_number_perm(CCS_TYPE_IOCTL, filp->f_path.dentry,
2670+ filp->f_path.mnt, cmd);
2671+#else
2672+ return ccs_path_number_perm(CCS_TYPE_IOCTL, filp->f_dentry,
2673+ filp->f_vfsmnt, cmd);
2674+#endif
2675+}
2676+
2677+/**
2678+ * __ccs_chmod_permission - Check permission for "chmod".
2679+ *
2680+ * @dentry: Pointer to "struct dentry".
2681+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2682+ * @mode: Mode.
2683+ *
2684+ * Returns 0 on success, negative value otherwise.
2685+ */
2686+static int __ccs_chmod_permission(struct dentry *dentry,
2687+ struct vfsmount *vfsmnt, mode_t mode)
2688+{
2689+ return ccs_path_number_perm(CCS_TYPE_CHMOD, dentry, vfsmnt,
2690+ mode & S_IALLUGO);
2691+}
2692+
2693+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
2694+
2695+/**
2696+ * __ccs_chown_permission - Check permission for "chown/chgrp".
2697+ *
2698+ * @dentry: Pointer to "struct dentry".
2699+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2700+ * @user: User ID.
2701+ * @group: Group ID.
2702+ *
2703+ * Returns 0 on success, negative value otherwise.
2704+ */
2705+static int __ccs_chown_permission(struct dentry *dentry,
2706+ struct vfsmount *vfsmnt, kuid_t user,
2707+ kgid_t group)
2708+{
2709+ int error = 0;
2710+ if (uid_valid(user))
2711+ error = ccs_path_number_perm(CCS_TYPE_CHOWN, dentry, vfsmnt,
2712+ from_kuid(&init_user_ns, user));
2713+ if (!error && gid_valid(group))
2714+ error = ccs_path_number_perm(CCS_TYPE_CHGRP, dentry, vfsmnt,
2715+ from_kgid(&init_user_ns, group));
2716+ return error;
2717+}
2718+
2719+#else
2720+
2721+/**
2722+ * __ccs_chown_permission - Check permission for "chown/chgrp".
2723+ *
2724+ * @dentry: Pointer to "struct dentry".
2725+ * @vfsmnt: Pointer to "struct vfsmount". Maybe NULL.
2726+ * @user: User ID.
2727+ * @group: Group ID.
2728+ *
2729+ * Returns 0 on success, negative value otherwise.
2730+ */
2731+static int __ccs_chown_permission(struct dentry *dentry,
2732+ struct vfsmount *vfsmnt, uid_t user,
2733+ gid_t group)
2734+{
2735+ int error = 0;
2736+ if (user == (uid_t) -1 && group == (gid_t) -1)
2737+ return 0;
2738+ if (user != (uid_t) -1)
2739+ error = ccs_path_number_perm(CCS_TYPE_CHOWN, dentry, vfsmnt,
2740+ user);
2741+ if (!error && group != (gid_t) -1)
2742+ error = ccs_path_number_perm(CCS_TYPE_CHGRP, dentry, vfsmnt,
2743+ group);
2744+ return error;
2745+}
2746+
2747+#endif
2748+
2749+/**
2750+ * __ccs_fcntl_permission - Check permission for changing O_APPEND flag.
2751+ *
2752+ * @file: Pointer to "struct file".
2753+ * @cmd: Command number.
2754+ * @arg: Value for @cmd.
2755+ *
2756+ * Returns 0 on success, negative value otherwise.
2757+ */
2758+static int __ccs_fcntl_permission(struct file *file, unsigned int cmd,
2759+ unsigned long arg)
2760+{
2761+ if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
2762+ return 0;
2763+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
2764+ return __ccs_open_permission(file->f_path.dentry, file->f_path.mnt,
2765+ O_WRONLY | (arg & O_APPEND));
2766+#elif defined(RHEL_MAJOR) && RHEL_MAJOR == 6
2767+ return __ccs_open_permission(file->f_dentry, file->f_vfsmnt,
2768+ O_WRONLY | (arg & O_APPEND));
2769+#else
2770+ return __ccs_open_permission(file->f_dentry, file->f_vfsmnt,
2771+ (O_WRONLY + 1) | (arg & O_APPEND));
2772+#endif
2773+}
2774+
2775+/**
2776+ * __ccs_pivot_root_permission - Check permission for pivot_root().
2777+ *
2778+ * @old_path: Pointer to "struct path".
2779+ * @new_path: Pointer to "struct path".
2780+ *
2781+ * Returns 0 on success, negative value otherwise.
2782+ */
2783+static int __ccs_pivot_root_permission(const struct path *old_path,
2784+ const struct path *new_path)
2785+{
2786+ return ccs_path2_perm(CCS_TYPE_PIVOT_ROOT, new_path->dentry,
2787+ new_path->mnt, old_path->dentry, old_path->mnt);
2788+}
2789+
2790+/**
2791+ * __ccs_chroot_permission - Check permission for chroot().
2792+ *
2793+ * @path: Pointer to "struct path".
2794+ *
2795+ * Returns 0 on success, negative value otherwise.
2796+ */
2797+static int __ccs_chroot_permission(const struct path *path)
2798+{
2799+ return ccs_path_perm(CCS_TYPE_CHROOT, path->dentry, path->mnt, NULL);
2800+}
2801+
2802+/**
2803+ * __ccs_umount_permission - Check permission for unmount.
2804+ *
2805+ * @mnt: Pointer to "struct vfsmount".
2806+ * @flags: Unused.
2807+ *
2808+ * Returns 0 on success, negative value otherwise.
2809+ */
2810+static int __ccs_umount_permission(struct vfsmount *mnt, int flags)
2811+{
2812+ return ccs_path_perm(CCS_TYPE_UMOUNT, mnt->mnt_root, mnt, NULL);
2813+}
2814+
2815+/**
2816+ * __ccs_mknod_permission - Check permission for vfs_mknod().
2817+ *
2818+ * @dentry: Pointer to "struct dentry".
2819+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2820+ * @mode: Device type and permission.
2821+ * @dev: Device number for block or character device.
2822+ *
2823+ * Returns 0 on success, negative value otherwise.
2824+ */
2825+static int __ccs_mknod_permission(struct dentry *dentry, struct vfsmount *mnt,
2826+ const unsigned int mode, unsigned int dev)
2827+{
2828+ int error = 0;
2829+ const unsigned int perm = mode & S_IALLUGO;
2830+ switch (mode & S_IFMT) {
2831+ case S_IFCHR:
2832+ error = ccs_mkdev_perm(CCS_TYPE_MKCHAR, dentry, mnt, perm,
2833+ dev);
2834+ break;
2835+ case S_IFBLK:
2836+ error = ccs_mkdev_perm(CCS_TYPE_MKBLOCK, dentry, mnt, perm,
2837+ dev);
2838+ break;
2839+ case S_IFIFO:
2840+ error = ccs_path_number_perm(CCS_TYPE_MKFIFO, dentry, mnt,
2841+ perm);
2842+ break;
2843+ case S_IFSOCK:
2844+ error = ccs_path_number_perm(CCS_TYPE_MKSOCK, dentry, mnt,
2845+ perm);
2846+ break;
2847+ case 0:
2848+ case S_IFREG:
2849+ error = ccs_path_number_perm(CCS_TYPE_CREATE, dentry, mnt,
2850+ perm);
2851+ break;
2852+ }
2853+ return error;
2854+}
2855+
2856+/**
2857+ * __ccs_mkdir_permission - Check permission for vfs_mkdir().
2858+ *
2859+ * @dentry: Pointer to "struct dentry".
2860+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2861+ * @mode: Create mode.
2862+ *
2863+ * Returns 0 on success, negative value otherwise.
2864+ */
2865+static int __ccs_mkdir_permission(struct dentry *dentry, struct vfsmount *mnt,
2866+ unsigned int mode)
2867+{
2868+ return ccs_path_number_perm(CCS_TYPE_MKDIR, dentry, mnt, mode);
2869+}
2870+
2871+/**
2872+ * __ccs_rmdir_permission - Check permission for vfs_rmdir().
2873+ *
2874+ * @dentry: Pointer to "struct dentry".
2875+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2876+ *
2877+ * Returns 0 on success, negative value otherwise.
2878+ */
2879+static int __ccs_rmdir_permission(struct dentry *dentry, struct vfsmount *mnt)
2880+{
2881+ return ccs_path_perm(CCS_TYPE_RMDIR, dentry, mnt, NULL);
2882+}
2883+
2884+/**
2885+ * __ccs_unlink_permission - Check permission for vfs_unlink().
2886+ *
2887+ * @dentry: Pointer to "struct dentry".
2888+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2889+ *
2890+ * Returns 0 on success, negative value otherwise.
2891+ */
2892+static int __ccs_unlink_permission(struct dentry *dentry, struct vfsmount *mnt)
2893+{
2894+ return ccs_path_perm(CCS_TYPE_UNLINK, dentry, mnt, NULL);
2895+}
2896+
2897+#ifdef CONFIG_CCSECURITY_FILE_GETATTR
2898+
2899+/**
2900+ * __ccs_getattr_permission - Check permission for vfs_getattr().
2901+ *
2902+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2903+ * @dentry: Pointer to "struct dentry".
2904+ *
2905+ * Returns 0 on success, negative value otherwise.
2906+ */
2907+static int __ccs_getattr_permission(struct vfsmount *mnt,
2908+ struct dentry *dentry)
2909+{
2910+ return ccs_path_perm(CCS_TYPE_GETATTR, dentry, mnt, NULL);
2911+}
2912+
2913+#endif
2914+
2915+/**
2916+ * __ccs_symlink_permission - Check permission for vfs_symlink().
2917+ *
2918+ * @dentry: Pointer to "struct dentry".
2919+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2920+ * @from: Content of symlink.
2921+ *
2922+ * Returns 0 on success, negative value otherwise.
2923+ */
2924+static int __ccs_symlink_permission(struct dentry *dentry,
2925+ struct vfsmount *mnt, const char *from)
2926+{
2927+ return ccs_path_perm(CCS_TYPE_SYMLINK, dentry, mnt, from);
2928+}
2929+
2930+/**
2931+ * __ccs_truncate_permission - Check permission for notify_change().
2932+ *
2933+ * @dentry: Pointer to "struct dentry".
2934+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2935+ *
2936+ * Returns 0 on success, negative value otherwise.
2937+ */
2938+static int __ccs_truncate_permission(struct dentry *dentry,
2939+ struct vfsmount *mnt)
2940+{
2941+ return ccs_path_perm(CCS_TYPE_TRUNCATE, dentry, mnt, NULL);
2942+}
2943+
2944+/**
2945+ * __ccs_rename_permission - Check permission for vfs_rename().
2946+ *
2947+ * @old_dentry: Pointer to "struct dentry".
2948+ * @new_dentry: Pointer to "struct dentry".
2949+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2950+ *
2951+ * Returns 0 on success, negative value otherwise.
2952+ */
2953+static int __ccs_rename_permission(struct dentry *old_dentry,
2954+ struct dentry *new_dentry,
2955+ struct vfsmount *mnt)
2956+{
2957+ return ccs_path2_perm(CCS_TYPE_RENAME, old_dentry, mnt, new_dentry,
2958+ mnt);
2959+}
2960+
2961+/**
2962+ * __ccs_link_permission - Check permission for vfs_link().
2963+ *
2964+ * @old_dentry: Pointer to "struct dentry".
2965+ * @new_dentry: Pointer to "struct dentry".
2966+ * @mnt: Pointer to "struct vfsmount". Maybe NULL.
2967+ *
2968+ * Returns 0 on success, negative value otherwise.
2969+ */
2970+static int __ccs_link_permission(struct dentry *old_dentry,
2971+ struct dentry *new_dentry,
2972+ struct vfsmount *mnt)
2973+{
2974+ return ccs_path2_perm(CCS_TYPE_LINK, old_dentry, mnt, new_dentry, mnt);
2975+}
2976+
2977+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
2978+
2979+/**
2980+ * __ccs_open_exec_permission - Check permission for open_exec().
2981+ *
2982+ * @dentry: Pointer to "struct dentry".
2983+ * @mnt: Pointer to "struct vfsmount".
2984+ *
2985+ * Returns 0 on success, negative value otherwise.
2986+ */
2987+static int __ccs_open_exec_permission(struct dentry *dentry,
2988+ struct vfsmount *mnt)
2989+{
2990+ return (ccs_current_flags() & CCS_TASK_IS_IN_EXECVE) ?
2991+ __ccs_open_permission(dentry, mnt, O_RDONLY + 1) : 0;
2992+}
2993+
2994+/**
2995+ * __ccs_uselib_permission - Check permission for sys_uselib().
2996+ *
2997+ * @dentry: Pointer to "struct dentry".
2998+ * @mnt: Pointer to "struct vfsmount".
2999+ *
3000+ * Returns 0 on success, negative value otherwise.
3001+ */
3002+static int __ccs_uselib_permission(struct dentry *dentry, struct vfsmount *mnt)
3003+{
3004+ return __ccs_open_permission(dentry, mnt, O_RDONLY + 1);
3005+}
3006+
3007+#endif
3008+
3009+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) || (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && defined(CONFIG_SYSCTL_SYSCALL))
3010+
3011+/**
3012+ * __ccs_parse_table - Check permission for parse_table().
3013+ *
3014+ * @name: Pointer to "int __user".
3015+ * @nlen: Number of elements in @name.
3016+ * @oldval: Pointer to "void __user".
3017+ * @newval: Pointer to "void __user".
3018+ * @table: Pointer to "struct ctl_table".
3019+ *
3020+ * Returns 0 on success, negative value otherwise.
3021+ *
3022+ * Note that this function is racy because this function checks values in
3023+ * userspace memory which could be changed after permission check.
3024+ */
3025+static int __ccs_parse_table(int __user *name, int nlen, void __user *oldval,
3026+ void __user *newval, struct ctl_table *table)
3027+{
3028+ int n;
3029+ int error = -ENOMEM;
3030+ int op = 0;
3031+ struct ccs_path_info buf;
3032+ char *buffer = NULL;
3033+ struct ccs_request_info r;
3034+ int idx;
3035+ if (oldval)
3036+ op |= 004;
3037+ if (newval)
3038+ op |= 002;
3039+ if (!op) /* Neither read nor write */
3040+ return 0;
3041+ idx = ccs_read_lock();
3042+ if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
3043+ == CCS_CONFIG_DISABLED) {
3044+ error = 0;
3045+ goto out;
3046+ }
3047+ buffer = kmalloc(PAGE_SIZE, CCS_GFP_FLAGS);
3048+ if (!buffer)
3049+ goto out;
3050+ snprintf(buffer, PAGE_SIZE - 1, "proc:/sys");
3051+repeat:
3052+ if (!nlen) {
3053+ error = -ENOTDIR;
3054+ goto out;
3055+ }
3056+ if (get_user(n, name)) {
3057+ error = -EFAULT;
3058+ goto out;
3059+ }
3060+ for ( ; table->ctl_name
3061+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)
3062+ || table->procname
3063+#endif
3064+ ; table++) {
3065+ int pos;
3066+ const char *cp;
3067+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21)
3068+ if (n != table->ctl_name && table->ctl_name != CTL_ANY)
3069+ continue;
3070+#else
3071+ if (!n || n != table->ctl_name)
3072+ continue;
3073+#endif
3074+ pos = strlen(buffer);
3075+ cp = table->procname;
3076+ error = -ENOMEM;
3077+ if (cp) {
3078+ int len = strlen(cp);
3079+ if (len + 2 > PAGE_SIZE - 1)
3080+ goto out;
3081+ buffer[pos++] = '/';
3082+ memmove(buffer + pos, cp, len + 1);
3083+ } else {
3084+ /* Assume nobody assigns "=\$=" for procname. */
3085+ snprintf(buffer + pos, PAGE_SIZE - pos - 1,
3086+ "/=%d=", table->ctl_name);
3087+ if (!memchr(buffer, '\0', PAGE_SIZE - 2))
3088+ goto out;
3089+ }
3090+ if (!table->child)
3091+ goto no_child;
3092+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 21)
3093+ if (!table->strategy)
3094+ goto no_strategy;
3095+ /* printk("sysctl='%s'\n", buffer); */
3096+ buf.name = ccs_encode(buffer);
3097+ if (!buf.name)
3098+ goto out;
3099+ ccs_fill_path_info(&buf);
3100+ if (op & MAY_READ)
3101+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
3102+ else
3103+ error = 0;
3104+ if (!error && (op & MAY_WRITE))
3105+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
3106+ kfree(buf.name);
3107+ if (error)
3108+ goto out;
3109+no_strategy:
3110+#endif
3111+ name++;
3112+ nlen--;
3113+ table = table->child;
3114+ goto repeat;
3115+no_child:
3116+ /* printk("sysctl='%s'\n", buffer); */
3117+ buf.name = ccs_encode(buffer);
3118+ if (!buf.name)
3119+ goto out;
3120+ ccs_fill_path_info(&buf);
3121+ if (op & MAY_READ)
3122+ error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
3123+ else
3124+ error = 0;
3125+ if (!error && (op & MAY_WRITE))
3126+ error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
3127+ kfree(buf.name);
3128+ goto out;
3129+ }
3130+ error = -ENOTDIR;
3131+out:
3132+ ccs_read_unlock(idx);
3133+ kfree(buffer);
3134+ return error;
3135+}
3136+
3137+#endif
3138+
3139+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
3140+
3141+/**
3142+ * ccs_old_pivot_root_permission - Check permission for pivot_root().
3143+ *
3144+ * @old_nd: Pointer to "struct nameidata".
3145+ * @new_nd: Pointer to "struct nameidata".
3146+ *
3147+ * Returns 0 on success, negative value otherwise.
3148+ */
3149+static int ccs_old_pivot_root_permission(struct nameidata *old_nd,
3150+ struct nameidata *new_nd)
3151+{
3152+ struct path old_path = { old_nd->mnt, old_nd->dentry };
3153+ struct path new_path = { new_nd->mnt, new_nd->dentry };
3154+ return __ccs_pivot_root_permission(&old_path, &new_path);
3155+}
3156+
3157+/**
3158+ * ccs_old_chroot_permission - Check permission for chroot().
3159+ *
3160+ * @nd: Pointer to "struct nameidata".
3161+ *
3162+ * Returns 0 on success, negative value otherwise.
3163+ */
3164+static int ccs_old_chroot_permission(struct nameidata *nd)
3165+{
3166+ struct path path = { nd->mnt, nd->dentry };
3167+ return __ccs_chroot_permission(&path);
3168+}
3169+
3170+#endif
3171+
3172+#ifdef CONFIG_CCSECURITY_NETWORK
3173+
3174+/**
3175+ * ccs_address_matches_group - Check whether the given address matches members of the given address group.
3176+ *
3177+ * @is_ipv6: True if @address is an IPv6 address.
3178+ * @address: An IPv4 or IPv6 address.
3179+ * @group: Pointer to "struct ccs_address_group".
3180+ *
3181+ * Returns true if @address matches addresses in @group group, false otherwise.
3182+ *
3183+ * Caller holds ccs_read_lock().
3184+ */
3185+static bool ccs_address_matches_group(const bool is_ipv6, const u32 *address,
3186+ const struct ccs_group *grou

Part of diff was cut off due to size limit. Use your local client to view the full diff.

Show on old repository browser