From 13c3a21c549a87cf7410bd2ff88eeb6cb1ddda8c Mon Sep 17 00:00:00 2001 From: invalid_git config Date: Sun, 25 Oct 2015 12:34:02 -0700 Subject: [PATCH] This is TOMOYO Linux patch for kernel 4.1.8. Source code for this patch is https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.1.8.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 | 6 +++ include/linux/security.h | 62 ++++++++++++++++---------- include/net/ip.h | 4 ++ kernel/fork.c | 5 +++ kernel/kexec.c | 3 ++ 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 | 4 ++ net/ipv6/raw.c | 4 ++ net/ipv6/udp.c | 4 ++ net/socket.c | 4 ++ net/unix/af_unix.c | 4 ++ security/Kconfig | 2 + security/Makefile | 3 ++ security/security.c | 110 +++++++++++++++++++++++++++++++++++++++++----- 25 files changed, 248 insertions(+), 37 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 1977c2a..5c69bcc 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1461,7 +1461,7 @@ static int exec_binprm(struct linux_binprm *bprm) 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); diff --git a/fs/open.c b/fs/open.c index a94e2e7..6c79f72c 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1108,6 +1108,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; diff --git a/fs/proc/version.c b/fs/proc/version.c index d2154eb..a84ba8d 100644 --- a/fs/proc/version.c +++ b/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.1.8 2015/09/26\n"); + return 0; +} +fs_initcall(ccs_show_version); diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 696d223..c112803 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -182,6 +182,14 @@ extern struct task_group root_task_group; # define INIT_KASAN(tsk) #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) @@ -258,6 +266,7 @@ extern struct task_group root_task_group; INIT_VTIME(tsk) \ INIT_NUMA_BALANCING(tsk) \ INIT_KASAN(tsk) \ + INIT_CCSECURITY \ } diff --git a/include/linux/sched.h b/include/linux/sched.h index 26a2e61..c32a704 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -6,6 +6,8 @@ #include +struct ccs_domain_info; + struct sched_param { int sched_priority; }; @@ -1724,6 +1726,10 @@ struct task_struct { #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif +#if defined(CONFIG_CCSECURITY) && !defined(CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY) + struct ccs_domain_info *ccs_domain_info; + u32 ccs_flags; +#endif }; /* Future-safe accessor for struct task_struct's cpus_allowed. */ diff --git a/include/linux/security.h b/include/linux/security.h index 18264ea..621562b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -53,6 +53,7 @@ struct msg_queue; struct xattr; struct xfrm_sec_ctx; struct mm_struct; +#include /* Maximum number of letters for an LSM name string */ #define SECURITY_NAME_MAX 10 @@ -2042,7 +2043,10 @@ static inline int security_syslog(int type) static inline int security_settime(const struct timespec *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_vm_enough_memory_mm(struct mm_struct *mm, long pages) @@ -2111,18 +2115,18 @@ static inline int security_sb_mount(const char *dev_name, struct path *path, 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(struct path *old_path, 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, @@ -2260,7 +2264,7 @@ static inline int security_inode_setattr(struct dentry *dentry, 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, @@ -2336,7 +2340,7 @@ static inline void security_file_free(struct file *file) 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, @@ -2365,7 +2369,7 @@ static inline int security_file_lock(struct file *file, unsigned int cmd) 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) @@ -2388,7 +2392,7 @@ static inline int security_file_receive(struct file *file) 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) @@ -2750,7 +2754,7 @@ static inline int security_unix_may_send(struct socket *sock, 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, @@ -2765,19 +2769,19 @@ static inline int security_socket_bind(struct socket *sock, 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, @@ -2789,7 +2793,7 @@ static inline int security_socket_accept(struct socket *sock, 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, @@ -3031,42 +3035,42 @@ int security_path_chroot(struct path *path); #else /* CONFIG_SECURITY_PATH */ static inline int security_path_unlink(struct path *dir, struct dentry *dentry) { - return 0; + return ccs_path_unlink(dir, dentry); } static inline int security_path_mkdir(struct path *dir, struct dentry *dentry, umode_t mode) { - return 0; + return ccs_path_mkdir(dir, dentry, mode); } static inline int security_path_rmdir(struct path *dir, struct dentry *dentry) { - return 0; + return ccs_path_rmdir(dir, dentry); } static inline int security_path_mknod(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(struct path *path) { - return 0; + return ccs_path_truncate(path); } static inline int security_path_symlink(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, 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(struct path *old_dir, @@ -3075,22 +3079,32 @@ static inline int security_path_rename(struct path *old_dir, struct dentry *new_dentry, unsigned int flags) { - return 0; + /* + * Not using RENAME_EXCHANGE here in order to avoid KABI breakage + * by doing "#include " . + */ + 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(struct path *path, umode_t mode) { - return 0; + return ccs_path_chmod(path, mode); } static inline int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { - return 0; + return ccs_path_chown(path, uid, gid); } static inline int security_path_chroot(struct path *path) { - return 0; + return ccs_path_chroot(path); } #endif /* CONFIG_SECURITY_PATH */ diff --git a/include/net/ip.h b/include/net/ip.h index d14af7e..34eb1cb 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -216,6 +216,8 @@ void inet_get_local_port_range(struct net *net, int *low, int *high); #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); @@ -229,6 +231,8 @@ static inline bool sysctl_dev_name_is_allowed(const char *name) #else static inline int inet_is_local_reserved_port(struct net *net, int port) { + if (ccs_lport_reserved(port)) + return 1; return 0; } #endif diff --git a/kernel/fork.c b/kernel/fork.c index 7e215ba..9bce902 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -257,6 +257,7 @@ void __put_task_struct(struct task_struct *tsk) delayacct_tsk_free(tsk); put_signal_struct(tsk->signal); + ccs_free_task_security(tsk); if (!profile_handoff_task(tsk)) free_task(tsk); } @@ -1423,6 +1424,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, goto bad_fork_cleanup_perf; /* copy all the process information */ shm_init_task(p); + retval = ccs_alloc_task_security(p); + if (retval) + goto bad_fork_cleanup_audit; retval = copy_semundo(clone_flags, p); if (retval) goto bad_fork_cleanup_audit; @@ -1627,6 +1631,7 @@ bad_fork_cleanup_semundo: exit_sem(p); bad_fork_cleanup_audit: audit_free(p); + ccs_free_task_security(p); bad_fork_cleanup_perf: perf_event_free_task(p); bad_fork_cleanup_policy: diff --git a/kernel/kexec.c b/kernel/kexec.c index 7a36fdc..294444e 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -1245,6 +1246,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, /* 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 diff --git a/kernel/module.c b/kernel/module.c index cfc9e84..73fd5f5 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -61,6 +61,7 @@ #include #include #include "module-internal.h" +#include #define CREATE_TRACE_POINTS #include @@ -799,6 +800,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, 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; @@ -3155,6 +3158,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; } diff --git a/kernel/ptrace.c b/kernel/ptrace.c index c8e0e05..4106a2a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -1034,6 +1034,11 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, { 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(); @@ -1180,6 +1185,11 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid, { 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(); diff --git a/kernel/reboot.c b/kernel/reboot.c index d20c85d..61ffd97 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * 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, unsigned int, cmd, 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 diff --git a/kernel/sched/core.c b/kernel/sched/core.c index e691052..c63bbd8 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3145,6 +3145,8 @@ int can_nice(const struct task_struct *p, const int nice) 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. diff --git a/kernel/signal.c b/kernel/signal.c index 0206be7..9e01cca 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2901,6 +2901,8 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, 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; @@ -2969,6 +2971,8 @@ SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid_t, pid, int, sig) /* 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); } @@ -2985,6 +2989,8 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig) /* 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); } @@ -2999,6 +3005,8 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info) 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); @@ -3047,6 +3055,8 @@ static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) return -EPERM; info->si_signo = sig; + if (ccs_tgsigqueue_permission(tgid, pid, sig)) + return -EPERM; return do_send_specific(tgid, pid, sig, info); } diff --git a/kernel/sys.c b/kernel/sys.c index a4e372b..77c6970 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -183,6 +183,10 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) 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; @@ -1222,6 +1226,8 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len) 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)) { @@ -1272,6 +1278,8 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len) 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; diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 7a68100..3c8766f 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ntp_internal.h" @@ -626,10 +627,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! @@ -642,6 +648,8 @@ int ntp_validate_timex(struct timex *txc) if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME))) return -EPERM; + if ((txc->modes & ADJ_SETOFFSET) && !ccs_capable(CCS_SYS_SETTIME)) + return -EPERM; /* * Check for potential multiplication overflows that can diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 561cd4b..16e23e5 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -727,6 +727,10 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, 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) { diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 83aa604..0326e29 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1272,6 +1272,10 @@ try_again: &peeked, &off, &err); if (!skb) goto out; + if (ccs_socket_post_recvmsg_permission(sk, skb, flags)) { + err = -EAGAIN; /* Hope less harmful than -EPERM. */ + goto out; + } ulen = skb->len - sizeof(struct udphdr); copied = len; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 8072bd4..fbd33d4 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -477,6 +477,10 @@ static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, 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) { diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e51fc3e..5b09dbb 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -413,6 +413,10 @@ try_again: &peeked, &off, &err); if (!skb) goto out; + if (ccs_socket_post_recvmsg_permission(sk, skb, flags)) { + err = -EAGAIN; /* Hope less harmful than -EPERM. */ + goto out; + } ulen = skb->len - sizeof(struct udphdr); copied = len; diff --git a/net/socket.c b/net/socket.c index 884e329..767338ff 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1485,6 +1485,10 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, 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) { diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 0643059..ba5d3d0 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1800,6 +1800,10 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, wake_up_interruptible_sync_poll(&u->peer_wait, 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); diff --git a/security/Kconfig b/security/Kconfig index bf4ec46..4ce2bf2 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -168,5 +168,7 @@ config DEFAULT_SECURITY default "yama" if DEFAULT_SECURITY_YAMA default "" if DEFAULT_SECURITY_DAC +source security/ccsecurity/Kconfig + endmenu diff --git a/security/Makefile b/security/Makefile index 05f1c93..4a42724 100644 --- a/security/Makefile +++ b/security/Makefile @@ -27,3 +27,6 @@ obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o # Object integrity file lists subdir-$(CONFIG_INTEGRITY) += integrity obj-$(CONFIG_INTEGRITY) += integrity/ + +subdir-$(CONFIG_CCSECURITY) += ccsecurity +obj-$(CONFIG_CCSECURITY) += ccsecurity/ diff --git a/security/security.c b/security/security.c index c1c7cd1..a8ed3d0 100644 --- a/security/security.c +++ b/security/security.c @@ -226,7 +226,10 @@ int security_syslog(int type) int security_settime(const struct timespec *ts, const struct timezone *tz) { - return security_ops->settime(ts, tz); + int error = security_ops->settime(ts, tz); + if (!error) + error = ccs_settime(ts, tz); + return error; } int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) @@ -303,17 +306,26 @@ int security_sb_statfs(struct dentry *dentry) int security_sb_mount(const char *dev_name, struct path *path, const char *type, unsigned long flags, void *data) { - return security_ops->sb_mount(dev_name, path, type, flags, data); + int error = security_ops->sb_mount(dev_name, path, type, flags, data); + if (!error) + error = ccs_sb_mount(dev_name, path, type, flags, data); + return error; } int security_sb_umount(struct vfsmount *mnt, int flags) { - return security_ops->sb_umount(mnt, flags); + int error = security_ops->sb_umount(mnt, flags); + if (!error) + error = ccs_sb_umount(mnt, flags); + return error; } int security_sb_pivotroot(struct path *old_path, struct path *new_path) { - return security_ops->sb_pivotroot(old_path, new_path); + int error = security_ops->sb_pivotroot(old_path, new_path); + if (!error) + error = ccs_sb_pivotroot(old_path, new_path); + return error; } int security_sb_set_mnt_opts(struct super_block *sb, @@ -410,32 +422,48 @@ EXPORT_SYMBOL(security_old_inode_init_security); int security_path_mknod(struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) return 0; + error = ccs_path_mknod(dir, dentry, mode, dev); + if (error) + return error; return security_ops->path_mknod(dir, dentry, mode, dev); } EXPORT_SYMBOL(security_path_mknod); int security_path_mkdir(struct path *dir, struct dentry *dentry, umode_t mode) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) return 0; + error = ccs_path_mkdir(dir, dentry, mode); + if (error) + return error; return security_ops->path_mkdir(dir, dentry, mode); } EXPORT_SYMBOL(security_path_mkdir); int security_path_rmdir(struct path *dir, struct dentry *dentry) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) return 0; + error = ccs_path_rmdir(dir, dentry); + if (error) + return error; return security_ops->path_rmdir(dir, dentry); } EXPORT_SYMBOL(security_path_rmdir); int security_path_unlink(struct path *dir, struct dentry *dentry) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) return 0; + error = ccs_path_unlink(dir, dentry); + if (error) + return error; return security_ops->path_unlink(dir, dentry); } EXPORT_SYMBOL(security_path_unlink); @@ -443,8 +471,12 @@ EXPORT_SYMBOL(security_path_unlink); int security_path_symlink(struct path *dir, struct dentry *dentry, const char *old_name) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(dir->dentry)))) return 0; + error = ccs_path_symlink(dir, dentry, old_name); + if (error) + return error; return security_ops->path_symlink(dir, dentry, old_name); } EXPORT_SYMBOL(security_path_symlink); @@ -452,8 +484,12 @@ EXPORT_SYMBOL(security_path_symlink); int security_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)))) return 0; + error = ccs_path_link(old_dentry, new_dir, new_dentry); + if (error) + return error; return security_ops->path_link(old_dentry, new_dir, new_dentry); } EXPORT_SYMBOL(security_path_link); @@ -462,6 +498,7 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry, unsigned int flags) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(old_dentry)) || (d_is_positive(new_dentry) && IS_PRIVATE(d_backing_inode(new_dentry))))) return 0; @@ -471,8 +508,15 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, old_dir, old_dentry); if (err) return err; + err = ccs_path_rename(new_dir, new_dentry, old_dir, + old_dentry); + if (err) + return err; } + error = ccs_path_rename(old_dir, old_dentry, new_dir, new_dentry); + if (error) + return error; return security_ops->path_rename(old_dir, old_dentry, new_dir, new_dentry); } @@ -480,30 +524,45 @@ EXPORT_SYMBOL(security_path_rename); int security_path_truncate(struct path *path) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) return 0; + error = ccs_path_truncate(path); + if (error) + return error; return security_ops->path_truncate(path); } EXPORT_SYMBOL(security_path_truncate); int security_path_chmod(struct path *path, umode_t mode) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) return 0; + error = ccs_path_chmod(path, mode); + if (error) + return error; return security_ops->path_chmod(path, mode); } EXPORT_SYMBOL(security_path_chmod); int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) return 0; + error = ccs_path_chown(path, uid, gid); + if (error) + return error; return security_ops->path_chown(path, uid, gid); } EXPORT_SYMBOL(security_path_chown); int security_path_chroot(struct path *path) { + int error = ccs_path_chroot(path); + if (error) + return error; return security_ops->path_chroot(path); } #endif @@ -618,9 +677,13 @@ EXPORT_SYMBOL_GPL(security_inode_setattr); int security_inode_getattr(const struct path *path) { + int error; if (unlikely(IS_PRIVATE(d_backing_inode(path->dentry)))) return 0; - return security_ops->inode_getattr(path); + error = security_ops->inode_getattr(path); + if (!error) + error = ccs_inode_getattr(path); + return error; } int security_inode_setxattr(struct dentry *dentry, const char *name, @@ -738,7 +801,10 @@ void security_file_free(struct file *file) int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return security_ops->file_ioctl(file, cmd, arg); + int error = security_ops->file_ioctl(file, cmd, arg); + if (!error) + error = ccs_file_ioctl(file, cmd, arg); + return error; } static inline unsigned long mmap_prot(struct file *file, unsigned long prot) @@ -804,7 +870,10 @@ int security_file_lock(struct file *file, unsigned int cmd) int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) { - return security_ops->file_fcntl(file, cmd, arg); + int error = security_ops->file_fcntl(file, cmd, arg); + if (!error) + error = ccs_file_fcntl(file, cmd, arg); + return error; } void security_file_set_fowner(struct file *file) @@ -828,6 +897,8 @@ int security_file_open(struct file *file, const struct cred *cred) int ret; ret = security_ops->file_open(file, cred); + if (!ret) + ret = ccs_file_open(file, cred); if (ret) return ret; @@ -1178,7 +1249,10 @@ EXPORT_SYMBOL(security_unix_may_send); int security_socket_create(int family, int type, int protocol, int kern) { - return security_ops->socket_create(family, type, protocol, kern); + int error = security_ops->socket_create(family, type, protocol, kern); + if (!error) + error = ccs_socket_create(family, type, protocol, kern); + return error; } int security_socket_post_create(struct socket *sock, int family, @@ -1190,17 +1264,26 @@ int security_socket_post_create(struct socket *sock, int family, int security_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { - return security_ops->socket_bind(sock, address, addrlen); + int error = security_ops->socket_bind(sock, address, addrlen); + if (!error) + error = ccs_socket_bind(sock, address, addrlen); + return error; } int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) { - return security_ops->socket_connect(sock, address, addrlen); + int error = security_ops->socket_connect(sock, address, addrlen); + if (!error) + error = ccs_socket_connect(sock, address, addrlen); + return error; } int security_socket_listen(struct socket *sock, int backlog) { - return security_ops->socket_listen(sock, backlog); + int error = security_ops->socket_listen(sock, backlog); + if (!error) + error = ccs_socket_listen(sock, backlog); + return error; } int security_socket_accept(struct socket *sock, struct socket *newsock) @@ -1210,7 +1293,10 @@ int security_socket_accept(struct socket *sock, struct socket *newsock) int security_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) { - return security_ops->socket_sendmsg(sock, msg, size); + int error = security_ops->socket_sendmsg(sock, msg, size); + if (!error) + error = ccs_socket_sendmsg(sock, msg, size); + return error; } int security_socket_recvmsg(struct socket *sock, struct msghdr *msg, -- 1.9.1