drivers: acpi: silence pointer bool conversion warning
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / fs / exec.c
index 0428c34d4773225614909ece27cc791e2cc4c328..97d04340b65929731df8496ba47fdcf1547121ab 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
 
 #include <trace/events/sched.h>
 
+#ifdef CONFIG_SECURITY_DEFEX
+#include <linux/defex.h>
+#endif
+
+#ifdef CONFIG_RKP_KDP
+#define rkp_is_nonroot(x) ((x->cred->type)>>1 & 1)
+#ifdef CONFIG_LOD_SEC
+#define rkp_is_lod(x) ((x->cred->type)>>3 & 1)
+#endif
+#endif /*CONFIG_RKP_KDP*/
+
 int suid_dumpable = 0;
 
 static LIST_HEAD(formats);
@@ -893,6 +904,11 @@ static int exec_mmap(struct mm_struct *mm)
        activate_mm(active_mm, mm);
        tsk->mm->vmacache_seqnum = 0;
        vmacache_flush(tsk);
+#ifdef CONFIG_RKP_KDP
+       if(rkp_cred_enable){
+               rkp_call(RKP_CMDID(0x43),(unsigned long long)current_cred(), (unsigned long long)mm->pgd,0,0,0);
+       }
+#endif /*CONFIG_RKP_KDP*/
        task_unlock(tsk);
        if (old_mm) {
                up_read(&old_mm->mmap_sem);
@@ -1100,6 +1116,47 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
        task_unlock(tsk);
        perf_event_comm(tsk, exec);
 }
+#ifdef CONFIG_RKP_NS_PROT
+extern struct super_block *sys_sb;     /* pointer to superblock */
+extern struct super_block *rootfs_sb;  /* pointer to superblock */
+extern int is_boot_recovery;
+
+static int invalid_drive(struct linux_binprm * bprm) 
+{
+       struct super_block *sb =  NULL;
+       struct vfsmount *vfsmnt = NULL;
+       
+       vfsmnt = bprm->file->f_path.mnt;
+       if(!vfsmnt || 
+               !rkp_ro_page((unsigned long)vfsmnt)) {
+               printk("\nInvalid Drive #%s# #%p#\n",bprm->filename,vfsmnt);
+               return 1;
+       } 
+       sb = vfsmnt->mnt_sb;
+
+       if((!is_boot_recovery) &&
+               sb != rootfs_sb   
+               && sb != sys_sb) {
+               printk("\n Superblock Mismatch #%s# vfsmnt #%p#sb #%p:%p:%p#\n",
+                                       bprm->filename,vfsmnt,sb,rootfs_sb,sys_sb);
+               return 1;
+       }
+
+       return 0;
+}
+#define RKP_CRED_SYS_ID 1000
+
+static int is_rkp_priv_task(void)
+{
+       struct cred *cred = (struct cred *)current_cred();
+
+       if(cred->uid.val <= (uid_t)RKP_CRED_SYS_ID || cred->euid.val <= (uid_t)RKP_CRED_SYS_ID ||
+               cred->gid.val <= (gid_t)RKP_CRED_SYS_ID || cred->egid.val <= (gid_t)RKP_CRED_SYS_ID ){
+               return 1;
+       }
+       return 0;
+}
+#endif
 
 int flush_old_exec(struct linux_binprm * bprm)
 {
@@ -1124,6 +1181,13 @@ int flush_old_exec(struct linux_binprm * bprm)
         * Release all of the old mmap stuff
         */
        acct_arg_size(bprm, 0);
+#ifdef CONFIG_RKP_NS_PROT
+       if(rkp_cred_enable &&
+               is_rkp_priv_task() && 
+               invalid_drive(bprm)) {
+               panic("\n Illegal Execution file_name #%s#\n",bprm->filename);
+       }
+#endif /*CONFIG_RKP_NS_PROT*/
        retval = exec_mmap(bprm->mm);
        if (retval)
                goto out;
@@ -1499,6 +1563,161 @@ int search_binary_handler(struct linux_binprm *bprm)
 }
 EXPORT_SYMBOL(search_binary_handler);
 
+#if defined CONFIG_SEC_RESTRICT_FORK
+#if defined CONFIG_SEC_RESTRICT_ROOTING_LOG
+#define PRINT_LOG(...) printk(KERN_ERR __VA_ARGS__)
+#else
+#define PRINT_LOG(...)
+#endif // End of CONFIG_SEC_RESTRICT_ROOTING_LOG
+
+#define CHECK_ROOT_UID(x) (x->cred->uid.val == 0 || x->cred->gid.val == 0 || \
+                       x->cred->euid.val == 0 || x->cred->egid.val == 0 || \
+                       x->cred->suid.val == 0 || x->cred->sgid.val == 0)
+
+/*  sec_check_execpath
+    return value : give task's exec path is matched or not
+*/
+int sec_check_execpath(struct mm_struct *mm, char *denypath)
+{
+       struct file *exe_file;
+       char *path, *pathbuf = NULL;
+       unsigned int path_length = 0, denypath_length = 0;
+       int ret = 0;
+
+       if (mm == NULL)
+               return 0;
+
+       if (!(exe_file = get_mm_exe_file(mm))) {
+               PRINT_LOG("Cannot get exe from task->mm.\n");
+               goto out_nofile;
+       }
+
+       if (!(pathbuf = kmalloc(PATH_MAX, GFP_TEMPORARY))) {
+               PRINT_LOG("failed to kmalloc for pathbuf\n");
+               goto out;
+       }
+
+       path = d_path(&exe_file->f_path, pathbuf, PATH_MAX);
+       if (IS_ERR(path)) {
+               PRINT_LOG("Error get path..\n");
+               goto out;
+       }
+
+       path_length = strlen(path);
+       denypath_length = strlen(denypath);
+
+       if (!strncmp(path, denypath, (path_length < denypath_length) ?
+                               path_length : denypath_length)) {
+               ret = 1;
+       }
+out:
+       fput(exe_file);
+out_nofile:
+       if (pathbuf)
+               kfree(pathbuf);
+
+       return ret;
+}
+EXPORT_SYMBOL(sec_check_execpath);
+#ifdef CONFIG_RKP_KDP
+static int rkp_restrict_fork(struct filename *path)
+{
+       struct cred *shellcred;
+
+       if(!strcmp(path->name,"/system/bin/patchoat")){
+               return 0 ;
+       }
+/* If the Process is from Linux on Dex, 
+then no need to reduce privilege */
+#ifdef CONFIG_LOD_SEC
+    if(rkp_is_lod(current)){
+        return 0;
+    }
+#endif
+
+       if(rkp_is_nonroot(current)){
+               shellcred = prepare_creds();
+               if (!shellcred) {
+                       return 1;
+               }
+               shellcred->uid.val = 2000;
+               shellcred->gid.val = 2000;
+               shellcred->euid.val = 2000;
+               shellcred->egid.val = 2000;
+
+               commit_creds(shellcred);
+       }
+       return 0;
+}
+#endif /*CONFIG_RKP_KDP*/
+static int sec_restrict_fork(void)
+{
+       struct cred *shellcred;
+       int ret = 0;
+       struct task_struct *parent_tsk;
+       struct mm_struct *parent_mm = NULL;
+       const struct cred *parent_cred;
+
+       read_lock(&tasklist_lock);
+       parent_tsk = current->parent;
+       if (!parent_tsk) {
+               read_unlock(&tasklist_lock);
+               return 0;
+       }
+
+       get_task_struct(parent_tsk);
+       /* holding on to the task struct is enough so just release
+        * the tasklist lock here */
+       read_unlock(&tasklist_lock);
+
+       if (current->pid == 1 || parent_tsk->pid == 1)
+               goto out;
+
+       /* get current->parent's mm struct to access it's mm
+        * and to keep it alive */
+       parent_mm = get_task_mm(parent_tsk);
+
+       if (current->mm == NULL || parent_mm == NULL)
+               goto out;
+
+       if (sec_check_execpath(parent_mm, "/sbin/adbd")) {
+               shellcred = prepare_creds();
+               if (!shellcred) {
+                       ret = 1;
+                       goto out;
+               }
+
+               shellcred->uid.val = 2000;
+               shellcred->gid.val = 2000;
+               shellcred->euid.val = 2000;
+               shellcred->egid.val = 2000;
+               commit_creds(shellcred);
+               ret = 0;
+               goto out;
+       }
+
+       if (sec_check_execpath(current->mm, "/data/")) {
+               ret = 1;
+               goto out;
+       }
+
+       parent_cred = get_task_cred(parent_tsk);
+       if (!parent_cred)
+               goto out;
+       if (!CHECK_ROOT_UID(parent_tsk))
+       {
+               ret = 1;
+       }
+       put_cred(parent_cred);
+out:
+       if (parent_mm)
+               mmput(parent_mm);
+       put_task_struct(parent_tsk);
+
+       return ret;
+}
+#endif /* End of CONFIG_SEC_RESTRICT_FORK */
+
 static int exec_binprm(struct linux_binprm *bprm)
 {
        pid_t old_pid, old_vpid;
@@ -1575,6 +1794,15 @@ static int do_execveat_common(int fd, struct filename *filename,
        if (IS_ERR(file))
                goto out_unmark;
 
+#ifdef CONFIG_SECURITY_DEFEX
+       retval = task_defex_enforce(current, file, -__NR_execve);
+       if (retval < 0) {
+               bprm->file = file;
+               retval = -EPERM;
+               goto out_unmark;
+        }
+#endif
+
        sched_exec();
 
        bprm->file = file;
@@ -1757,6 +1985,46 @@ SYSCALL_DEFINE3(execve,
                const char __user *const __user *, argv,
                const char __user *const __user *, envp)
 {
+#ifdef CONFIG_RKP_KDP
+       struct filename *path = getname(filename);
+       int error = PTR_ERR(path);
+
+       if(IS_ERR(path))
+               return error;
+
+       if(rkp_cred_enable){
+               rkp_call(RKP_CMDID(0x4b),(u64)path->name,0,0,0,0);
+       }
+#endif
+#if defined CONFIG_SEC_RESTRICT_FORK
+       if(CHECK_ROOT_UID(current)){
+               if(sec_restrict_fork()){
+                       PRINT_LOG("Restricted making process. PID = %d(%s) "
+                                                       "PPID = %d(%s)\n",
+                       current->pid, current->comm,
+                       current->parent->pid, current->parent->comm);
+#ifdef CONFIG_RKP_KDP
+                       putname(path);
+#endif
+                       return -EACCES;
+               }
+       }
+#ifdef CONFIG_RKP_KDP
+       if(CHECK_ROOT_UID(current) && rkp_cred_enable) {
+               if(rkp_restrict_fork(path)){
+                       PRINT_LOG("RKP_KDP Restricted making process. PID = %d(%s) "
+                                                       "PPID = %d(%s)\n",
+                       current->pid, current->comm,
+                       current->parent->pid, current->parent->comm);
+                       putname(path);
+                       return -EACCES;
+               }
+       }
+#endif
+#endif // End of CONFIG_SEC_RESTRICT_FORK
+#ifdef CONFIG_RKP_KDP
+       putname(path);
+#endif
        return do_execve(getname(filename), argv, envp);
 }