This is TOMOYO Linux patch for kernel 4.12.14.

Source code for this patch is https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.12.14.tar.xz
---
 fs/exec.c                 |    2 -
 fs/open.c                 |    2 +
 fs/proc/version.c         |    7 ++++
 include/linux/init_task.h |    9 ++++++
 include/linux/sched.h     |    5 +++
 include/linux/security.h  |   68 ++++++++++++++++++++++++++++------------------
 include/net/ip.h          |    4 ++
 kernel/kexec.c            |    4 ++
 kernel/module.c           |    5 +++
 kernel/ptrace.c           |   10 ++++++
 kernel/reboot.c           |    3 ++
 kernel/sched/core.c       |    2 +
 kernel/signal.c           |   10 ++++++
 kernel/sys.c              |    8 +++++
 kernel/time/ntp.c         |    8 +++++
 net/ipv4/raw.c            |    4 ++
 net/ipv4/udp.c            |    2 +
 net/ipv6/raw.c            |    4 ++
 net/ipv6/udp.c            |    2 +
 net/socket.c              |    4 ++
 net/unix/af_unix.c        |    5 +++
 security/Kconfig          |    2 +
 security/Makefile         |    3 ++
 security/security.c       |    9 +++++-
 24 files changed, 153 insertions(+), 29 deletions(-)

--- linux-4.12.14.orig/fs/exec.c
+++ linux-4.12.14/fs/exec.c
@@ -1665,7 +1665,7 @@ static int exec_binprm(struct linux_binp
 	old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
 	rcu_read_unlock();
 
-	ret = search_binary_handler(bprm);
+	ret = ccs_search_binary_handler(bprm);
 	if (ret >= 0) {
 		audit_bprm(bprm);
 		trace_sched_process_exec(current, old_pid, bprm);
--- linux-4.12.14.orig/fs/open.c
+++ linux-4.12.14/fs/open.c
@@ -1167,6 +1167,8 @@ EXPORT_SYMBOL(sys_close);
  */
 SYSCALL_DEFINE0(vhangup)
 {
+	if (!ccs_capable(CCS_SYS_VHANGUP))
+		return -EPERM;
 	if (capable(CAP_SYS_TTY_CONFIG)) {
 		tty_vhangup_self();
 		return 0;
--- linux-4.12.14.orig/fs/proc/version.c
+++ linux-4.12.14/fs/proc/version.c
@@ -32,3 +32,10 @@ static int __init proc_version_init(void
 	return 0;
 }
 fs_initcall(proc_version_init);
+
+static int __init ccs_show_version(void)
+{
+	printk(KERN_INFO "Hook version: 4.12.14 2017/09/25\n");
+	return 0;
+}
+fs_initcall(ccs_show_version);
--- linux-4.12.14.orig/include/linux/init_task.h
+++ linux-4.12.14/include/linux/init_task.h
@@ -225,6 +225,14 @@ extern struct cred init_cred;
 #define INIT_TASK_SECURITY
 #endif
 
+#if defined(CONFIG_CCSECURITY) && !defined(CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY)
+#define INIT_CCSECURITY          \
+	.ccs_domain_info = NULL, \
+	.ccs_flags = 0,
+#else
+#define INIT_CCSECURITY
+#endif
+
 /*
  *  INIT_TASK is used to set up the first task table, touch at
  * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -305,6 +313,7 @@ extern struct cred init_cred;
 	INIT_KASAN(tsk)							\
 	INIT_LIVEPATCH(tsk)						\
 	INIT_TASK_SECURITY						\
+	INIT_CCSECURITY                                                 \
 }
 
 
--- linux-4.12.14.orig/include/linux/sched.h
+++ linux-4.12.14/include/linux/sched.h
@@ -32,6 +32,7 @@ struct audit_context;
 struct backing_dev_info;
 struct bio_list;
 struct blk_plug;
+struct ccs_domain_info;
 struct cfs_rq;
 struct fs_struct;
 struct futex_pi_state;
@@ -1060,6 +1061,10 @@ struct task_struct {
 	/* Used by LSM modules for access restriction: */
 	void				*security;
 #endif
+#if defined(CONFIG_CCSECURITY) && !defined(CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY)
+	struct ccs_domain_info		*ccs_domain_info;
+	u32				ccs_flags;
+#endif
 	/* CPU-specific state of this task: */
 	struct thread_struct		thread;
 
--- linux-4.12.14.orig/include/linux/security.h
+++ linux-4.12.14/include/linux/security.h
@@ -55,6 +55,7 @@ struct msg_queue;
 struct xattr;
 struct xfrm_sec_ctx;
 struct mm_struct;
+#include <linux/ccsecurity.h>
 
 /* If capable should audit the security request */
 #define SECURITY_CAP_NOAUDIT 0
@@ -481,7 +482,10 @@ static inline int security_syslog(int ty
 static inline int security_settime64(const struct timespec64 *ts,
 				     const struct timezone *tz)
 {
-	return cap_settime(ts, tz);
+	int error = cap_settime(ts, tz);
+	if (!error)
+		error = ccs_settime(ts, tz);
+	return error;
 }
 
 static inline int security_settime(const struct timespec *ts,
@@ -558,18 +562,18 @@ static inline int security_sb_mount(cons
 				    const char *type, unsigned long flags,
 				    void *data)
 {
-	return 0;
+	return ccs_sb_mount(dev_name, path, type, flags, data);
 }
 
 static inline int security_sb_umount(struct vfsmount *mnt, int flags)
 {
-	return 0;
+	return ccs_sb_umount(mnt, flags);
 }
 
 static inline int security_sb_pivotroot(const struct path *old_path,
 					const struct path *new_path)
 {
-	return 0;
+	return ccs_sb_pivotroot(old_path, new_path);
 }
 
 static inline int security_sb_set_mnt_opts(struct super_block *sb,
@@ -716,7 +720,7 @@ static inline int security_inode_setattr
 
 static inline int security_inode_getattr(const struct path *path)
 {
-	return 0;
+	return ccs_inode_getattr(path);
 }
 
 static inline int security_inode_setxattr(struct dentry *dentry,
@@ -802,7 +806,7 @@ static inline void security_file_free(st
 static inline int security_file_ioctl(struct file *file, unsigned int cmd,
 				      unsigned long arg)
 {
-	return 0;
+	return ccs_file_ioctl(file, cmd, arg);
 }
 
 static inline int security_mmap_file(struct file *file, unsigned long prot,
@@ -831,7 +835,7 @@ static inline int security_file_lock(str
 static inline int security_file_fcntl(struct file *file, unsigned int cmd,
 				      unsigned long arg)
 {
-	return 0;
+	return ccs_file_fcntl(file, cmd, arg);
 }
 
 static inline void security_file_set_fowner(struct file *file)
@@ -854,7 +858,7 @@ static inline int security_file_receive(
 static inline int security_file_open(struct file *file,
 				     const struct cred *cred)
 {
-	return 0;
+	return ccs_file_open(file, cred);
 }
 
 static inline int security_task_create(unsigned long clone_flags)
@@ -865,11 +869,13 @@ static inline int security_task_create(u
 static inline int security_task_alloc(struct task_struct *task,
 				      unsigned long clone_flags)
 {
-	return 0;
+	return ccs_alloc_task_security(task);
 }
 
 static inline void security_task_free(struct task_struct *task)
-{ }
+{
+	ccs_free_task_security(task);
+}
 
 static inline int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
@@ -1230,7 +1236,7 @@ static inline int security_unix_may_send
 static inline int security_socket_create(int family, int type,
 					 int protocol, int kern)
 {
-	return 0;
+	return ccs_socket_create(family, type, protocol, kern);
 }
 
 static inline int security_socket_post_create(struct socket *sock,
@@ -1245,19 +1251,19 @@ static inline int security_socket_bind(s
 				       struct sockaddr *address,
 				       int addrlen)
 {
-	return 0;
+	return ccs_socket_bind(sock, address, addrlen);
 }
 
 static inline int security_socket_connect(struct socket *sock,
 					  struct sockaddr *address,
 					  int addrlen)
 {
-	return 0;
+	return ccs_socket_connect(sock, address, addrlen);
 }
 
 static inline int security_socket_listen(struct socket *sock, int backlog)
 {
-	return 0;
+	return ccs_socket_listen(sock, backlog);
 }
 
 static inline int security_socket_accept(struct socket *sock,
@@ -1269,7 +1275,7 @@ static inline int security_socket_accept
 static inline int security_socket_sendmsg(struct socket *sock,
 					  struct msghdr *msg, int size)
 {
-	return 0;
+	return ccs_socket_sendmsg(sock, msg, size);
 }
 
 static inline int security_socket_recvmsg(struct socket *sock,
@@ -1511,42 +1517,42 @@ int security_path_chroot(const struct pa
 #else	/* CONFIG_SECURITY_PATH */
 static inline int security_path_unlink(const struct path *dir, struct dentry *dentry)
 {
-	return 0;
+	return ccs_path_unlink(dir, dentry);
 }
 
 static inline int security_path_mkdir(const struct path *dir, struct dentry *dentry,
 				      umode_t mode)
 {
-	return 0;
+	return ccs_path_mkdir(dir, dentry, mode);
 }
 
 static inline int security_path_rmdir(const struct path *dir, struct dentry *dentry)
 {
-	return 0;
+	return ccs_path_rmdir(dir, dentry);
 }
 
 static inline int security_path_mknod(const struct path *dir, struct dentry *dentry,
 				      umode_t mode, unsigned int dev)
 {
-	return 0;
+	return ccs_path_mknod(dir, dentry, mode, dev);
 }
 
 static inline int security_path_truncate(const struct path *path)
 {
-	return 0;
+	return ccs_path_truncate(path);
 }
 
 static inline int security_path_symlink(const struct path *dir, struct dentry *dentry,
 					const char *old_name)
 {
-	return 0;
+	return ccs_path_symlink(dir, dentry, old_name);
 }
 
 static inline int security_path_link(struct dentry *old_dentry,
 				     const struct path *new_dir,
 				     struct dentry *new_dentry)
 {
-	return 0;
+	return ccs_path_link(old_dentry, new_dir, new_dentry);
 }
 
 static inline int security_path_rename(const struct path *old_dir,
@@ -1555,22 +1561,32 @@ static inline int security_path_rename(c
 				       struct dentry *new_dentry,
 				       unsigned int flags)
 {
-	return 0;
+	/*
+	 * Not using RENAME_EXCHANGE here in order to avoid KABI breakage
+	 * by doing "#include <uapi/linux/fs.h>" .
+	 */
+	if (flags & (1 << 1)) {
+		int err = ccs_path_rename(new_dir, new_dentry, old_dir,
+					  old_dentry);
+		if (err)
+			return err;
+	}
+	return ccs_path_rename(old_dir, old_dentry, new_dir, new_dentry);
 }
 
 static inline int security_path_chmod(const struct path *path, umode_t mode)
 {
-	return 0;
+	return ccs_path_chmod(path, mode);
 }
 
 static inline int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
 {
-	return 0;
+	return ccs_path_chown(path, uid, gid);
 }
 
 static inline int security_path_chroot(const struct path *path)
 {
-	return 0;
+	return ccs_path_chroot(path);
 }
 #endif	/* CONFIG_SECURITY_PATH */
 
--- linux-4.12.14.orig/include/net/ip.h
+++ linux-4.12.14/include/net/ip.h
@@ -255,6 +255,8 @@ void inet_get_local_port_range(struct ne
 #ifdef CONFIG_SYSCTL
 static inline int inet_is_local_reserved_port(struct net *net, int port)
 {
+	if (ccs_lport_reserved(port))
+		return 1;
 	if (!net->ipv4.sysctl_local_reserved_ports)
 		return 0;
 	return test_bit(port, net->ipv4.sysctl_local_reserved_ports);
@@ -273,6 +275,8 @@ static inline int inet_prot_sock(struct
 #else
 static inline int inet_is_local_reserved_port(struct net *net, int port)
 {
+	if (ccs_lport_reserved(port))
+		return 1;
 	return 0;
 }
 
--- linux-4.12.14.orig/kernel/kexec.c
+++ linux-4.12.14/kernel/kexec.c
@@ -17,7 +17,7 @@
 #include <linux/syscalls.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-
+#include <linux/ccsecurity.h>
 #include "kexec_internal.h"
 
 static int copy_user_segment_list(struct kimage *image,
@@ -192,6 +192,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
 	/* We only trust the superuser with rebooting the system. */
 	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
 		return -EPERM;
+	if (!ccs_capable(CCS_SYS_KEXEC_LOAD))
+		return -EPERM;
 
 	/*
 	 * Verify we have a legal set of flags
--- linux-4.12.14.orig/kernel/module.c
+++ linux-4.12.14/kernel/module.c
@@ -68,6 +68,7 @@
 #include <linux/audit.h>
 #include <uapi/linux/module.h>
 #include "module-internal.h"
+#include <linux/ccsecurity.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
@@ -961,6 +962,8 @@ SYSCALL_DEFINE2(delete_module, const cha
 
 	if (!capable(CAP_SYS_MODULE) || modules_disabled)
 		return -EPERM;
+	if (!ccs_capable(CCS_USE_KERNEL_MODULE))
+		return -EPERM;
 
 	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
 		return -EFAULT;
@@ -3504,6 +3507,8 @@ static int may_init_module(void)
 {
 	if (!capable(CAP_SYS_MODULE) || modules_disabled)
 		return -EPERM;
+	if (!ccs_capable(CCS_USE_KERNEL_MODULE))
+		return -EPERM;
 
 	return 0;
 }
--- linux-4.12.14.orig/kernel/ptrace.c
+++ linux-4.12.14/kernel/ptrace.c
@@ -1125,6 +1125,11 @@ SYSCALL_DEFINE4(ptrace, long, request, l
 {
 	struct task_struct *child;
 	long ret;
+	{
+		const int rc = ccs_ptrace_permission(request, pid);
+		if (rc)
+			return rc;
+	}
 
 	if (request == PTRACE_TRACEME) {
 		ret = ptrace_traceme();
@@ -1274,6 +1279,11 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_lo
 {
 	struct task_struct *child;
 	long ret;
+	{
+		const int rc = ccs_ptrace_permission(request, pid);
+		if (rc)
+			return rc;
+	}
 
 	if (request == PTRACE_TRACEME) {
 		ret = ptrace_traceme();
--- linux-4.12.14.orig/kernel/reboot.c
+++ linux-4.12.14/kernel/reboot.c
@@ -16,6 +16,7 @@
 #include <linux/syscalls.h>
 #include <linux/syscore_ops.h>
 #include <linux/uaccess.h>
+#include <linux/ccsecurity.h>
 
 /*
  * this indicates whether you can reboot with ctrl-alt-del: the default is yes
@@ -295,6 +296,8 @@ SYSCALL_DEFINE4(reboot, int, magic1, int
 			magic2 != LINUX_REBOOT_MAGIC2B &&
 			magic2 != LINUX_REBOOT_MAGIC2C))
 		return -EINVAL;
+	if (!ccs_capable(CCS_SYS_REBOOT))
+		return -EPERM;
 
 	/*
 	 * If pid namespaces are enabled and the current task is in a child
--- linux-4.12.14.orig/kernel/sched/core.c
+++ linux-4.12.14/kernel/sched/core.c
@@ -3926,6 +3926,8 @@ int can_nice(const struct task_struct *p
 SYSCALL_DEFINE1(nice, int, increment)
 {
 	long nice, retval;
+	if (!ccs_capable(CCS_SYS_NICE))
+		return -EPERM;
 
 	/*
 	 * Setpriority might change our priority at the same moment.
--- linux-4.12.14.orig/kernel/signal.c
+++ linux-4.12.14/kernel/signal.c
@@ -2873,6 +2873,8 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const s
 SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
 {
 	struct siginfo info;
+	if (ccs_kill_permission(pid, sig))
+		return -EPERM;
 
 	info.si_signo = sig;
 	info.si_errno = 0;
@@ -2941,6 +2943,8 @@ SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid
 	/* This is only valid for single tasks */
 	if (pid <= 0 || tgid <= 0)
 		return -EINVAL;
+	if (ccs_tgkill_permission(tgid, pid, sig))
+		return -EPERM;
 
 	return do_tkill(tgid, pid, sig);
 }
@@ -2957,6 +2961,8 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int,
 	/* This is only valid for single tasks */
 	if (pid <= 0)
 		return -EINVAL;
+	if (ccs_tkill_permission(pid, sig))
+		return -EPERM;
 
 	return do_tkill(0, pid, sig);
 }
@@ -2971,6 +2977,8 @@ static int do_rt_sigqueueinfo(pid_t pid,
 		return -EPERM;
 
 	info->si_signo = sig;
+	if (ccs_sigqueue_permission(pid, sig))
+		return -EPERM;
 
 	/* POSIX.1b doesn't mention process groups.  */
 	return kill_proc_info(sig, info, pid);
@@ -3019,6 +3027,8 @@ static int do_rt_tgsigqueueinfo(pid_t tg
 		return -EPERM;
 
 	info->si_signo = sig;
+	if (ccs_tgsigqueue_permission(tgid, pid, sig))
+		return -EPERM;
 
 	return do_send_specific(tgid, pid, sig, info);
 }
--- linux-4.12.14.orig/kernel/sys.c
+++ linux-4.12.14/kernel/sys.c
@@ -190,6 +190,10 @@ SYSCALL_DEFINE3(setpriority, int, which,
 
 	if (which > PRIO_USER || which < PRIO_PROCESS)
 		goto out;
+	if (!ccs_capable(CCS_SYS_NICE)) {
+		error = -EPERM;
+		goto out;
+	}
 
 	/* normalize: avoid signed division (rounding problems) */
 	error = -ESRCH;
@@ -1229,6 +1233,8 @@ SYSCALL_DEFINE2(sethostname, char __user
 
 	if (len < 0 || len > __NEW_UTS_LEN)
 		return -EINVAL;
+	if (!ccs_capable(CCS_SYS_SETHOSTNAME))
+		return -EPERM;
 	down_write(&uts_sem);
 	errno = -EFAULT;
 	if (!copy_from_user(tmp, name, len)) {
@@ -1279,6 +1285,8 @@ SYSCALL_DEFINE2(setdomainname, char __us
 		return -EPERM;
 	if (len < 0 || len > __NEW_UTS_LEN)
 		return -EINVAL;
+	if (!ccs_capable(CCS_SYS_SETHOSTNAME))
+		return -EPERM;
 
 	down_write(&uts_sem);
 	errno = -EFAULT;
--- linux-4.12.14.orig/kernel/time/ntp.c
+++ linux-4.12.14/kernel/time/ntp.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/math64.h>
+#include <linux/ccsecurity.h>
 
 #include "ntp_internal.h"
 #include "timekeeping_internal.h"
@@ -666,10 +667,15 @@ int ntp_validate_timex(struct timex *txc
 		if (!(txc->modes & ADJ_OFFSET_READONLY) &&
 		    !capable(CAP_SYS_TIME))
 			return -EPERM;
+		if (!(txc->modes & ADJ_OFFSET_READONLY) &&
+		    !ccs_capable(CCS_SYS_SETTIME))
+			return -EPERM;
 	} else {
 		/* In order to modify anything, you gotta be super-user! */
 		 if (txc->modes && !capable(CAP_SYS_TIME))
 			return -EPERM;
+		if (txc->modes && !ccs_capable(CCS_SYS_SETTIME))
+			return -EPERM;
 		/*
 		 * if the quartz is off by more than 10% then
 		 * something is VERY wrong!
@@ -684,6 +690,8 @@ int ntp_validate_timex(struct timex *txc
 		/* In order to inject time, you gotta be super-user! */
 		if (!capable(CAP_SYS_TIME))
 			return -EPERM;
+		if (!ccs_capable(CCS_SYS_SETTIME))
+			return -EPERM;
 
 		if (txc->modes & ADJ_NANO) {
 			struct timespec ts;
--- linux-4.12.14.orig/net/ipv4/raw.c
+++ linux-4.12.14/net/ipv4/raw.c
@@ -755,6 +755,10 @@ static int raw_recvmsg(struct sock *sk,
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb)
 		goto out;
+	if (ccs_socket_post_recvmsg_permission(sk, skb, flags)) {
+		err = -EAGAIN; /* Hope less harmful than -EPERM. */
+		goto out;
+	}
 
 	copied = skb->len;
 	if (len < copied) {
--- linux-4.12.14.orig/net/ipv4/udp.c
+++ linux-4.12.14/net/ipv4/udp.c
@@ -1425,6 +1425,8 @@ try_again:
 	skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
 	if (!skb)
 		return err;
+	if (ccs_socket_post_recvmsg_permission(sk, skb, flags))
+		return -EAGAIN; /* Hope less harmful than -EPERM. */
 
 	ulen = skb->len;
 	copied = len;
--- linux-4.12.14.orig/net/ipv6/raw.c
+++ linux-4.12.14/net/ipv6/raw.c
@@ -480,6 +480,10 @@ static int rawv6_recvmsg(struct sock *sk
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb)
 		goto out;
+	if (ccs_socket_post_recvmsg_permission(sk, skb, flags)) {
+		err = -EAGAIN; /* Hope less harmful than -EPERM. */
+		goto out;
+	}
 
 	copied = skb->len;
 	if (copied > len) {
--- linux-4.12.14.orig/net/ipv6/udp.c
+++ linux-4.12.14/net/ipv6/udp.c
@@ -357,6 +357,8 @@ try_again:
 	skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
 	if (!skb)
 		return err;
+	if (ccs_socket_post_recvmsg_permission(sk, skb, flags))
+		return -EAGAIN; /* Hope less harmful than -EPERM. */
 
 	ulen = skb->len;
 	copied = len;
--- linux-4.12.14.orig/net/socket.c
+++ linux-4.12.14/net/socket.c
@@ -1521,6 +1521,10 @@ SYSCALL_DEFINE4(accept4, int, fd, struct
 	if (err < 0)
 		goto out_fd;
 
+	if (ccs_socket_post_accept_permission(sock, newsock)) {
+		err = -EAGAIN; /* Hope less harmful than -EPERM. */
+		goto out_fd;
+	}
 	if (upeer_sockaddr) {
 		if (newsock->ops->getname(newsock, (struct sockaddr *)&address,
 					  &len, 2) < 0) {
--- linux-4.12.14.orig/net/unix/af_unix.c
+++ linux-4.12.14/net/unix/af_unix.c
@@ -2152,6 +2152,10 @@ static int unix_dgram_recvmsg(struct soc
 						POLLOUT | POLLWRNORM |
 						POLLWRBAND);
 
+	if (ccs_socket_post_recvmsg_permission(sk, skb, flags)) {
+		err = -EAGAIN; /* Hope less harmful than -EPERM. */
+		goto out_unlock;
+	}
 	if (msg->msg_name)
 		unix_copy_addr(msg, skb->sk);
 
@@ -2202,6 +2206,7 @@ static int unix_dgram_recvmsg(struct soc
 
 out_free:
 	skb_free_datagram(sk, skb);
+out_unlock:
 	mutex_unlock(&u->iolock);
 out:
 	return err;
--- linux-4.12.14.orig/security/Kconfig
+++ linux-4.12.14/security/Kconfig
@@ -235,5 +235,7 @@ config DEFAULT_SECURITY
 	default "apparmor" if DEFAULT_SECURITY_APPARMOR
 	default "" if DEFAULT_SECURITY_DAC
 
+source security/ccsecurity/Kconfig
+
 endmenu
 
--- linux-4.12.14.orig/security/Makefile
+++ linux-4.12.14/security/Makefile
@@ -29,3 +29,6 @@ obj-$(CONFIG_CGROUP_DEVICE)		+= device_c
 # Object integrity file lists
 subdir-$(CONFIG_INTEGRITY)		+= integrity
 obj-$(CONFIG_INTEGRITY)			+= integrity/
+
+subdir-$(CONFIG_CCSECURITY)		+= ccsecurity
+obj-$(CONFIG_CCSECURITY)		+= ccsecurity/
--- linux-4.12.14.orig/security/security.c
+++ linux-4.12.14/security/security.c
@@ -943,12 +943,19 @@ int security_task_create(unsigned long c
 
 int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
 {
-	return call_int_hook(task_alloc, 0, task, clone_flags);
+	int ret = ccs_alloc_task_security(task);
+	if (ret)
+		return ret;
+	ret = call_int_hook(task_alloc, 0, task, clone_flags);
+	if (ret)
+		ccs_free_task_security(task);
+	return ret;
 }
 
 void security_task_free(struct task_struct *task)
 {
 	call_void_hook(task_free, task);
+	ccs_free_task_security(task);
 }
 
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
