From 63703589e55a49178b49526390a00348bd152aac Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Tue, 4 Sep 2018 09:57:02 +0900 Subject: [PATCH] uti: Clear user space PTEs after first fork in create_tracer() Change-Id: I60755f0cb5e84c3a5a5cd91515411a30f0995822 --- executer/include/uprotocol.h | 7 ++++- executer/kernel/mcctrl/control.c | 23 +++++++++------ executer/kernel/mcctrl/driver.c | 2 +- executer/kernel/mcctrl/mcctrl.h | 1 + executer/kernel/mcctrl/syscall.c | 37 ++++++++++++++++++++++++ executer/user/mcexec.c | 48 ++++++++++++++++++++++---------- 6 files changed, 92 insertions(+), 26 deletions(-) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 6b64db4f..66f0395c 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -62,7 +62,7 @@ #define MCEXEC_UP_TERMINATE_THREAD 0x30a02925 #define MCEXEC_UP_GET_NUM_POOL_THREADS 0x30a02926 #define MCEXEC_UP_UTI_ATTR 0x30a02927 -#define MCEXEC_UP_UNMAP_PSEUDO_FILEMAP 0x30a02928 +#define MCEXEC_UP_RELEASE_USER_SPACE 0x30a02928 #define MCEXEC_UP_DEBUG_LOG 0x40000000 @@ -245,6 +245,11 @@ struct sys_unshare_desc { unsigned long unshare_flags; }; +struct release_user_space_desc { + unsigned long user_start; + unsigned long user_end; +}; + enum perf_ctrl_type { PERF_CTRL_SET, PERF_CTRL_GET, diff --git a/executer/kernel/mcctrl/control.c b/executer/kernel/mcctrl/control.c index d566d169..d716c0fc 100644 --- a/executer/kernel/mcctrl/control.c +++ b/executer/kernel/mcctrl/control.c @@ -2517,14 +2517,19 @@ err: return 0; } -long mcexec_unmap_pseudo_filemap(ihk_os_t os, struct file *file) +static long mcexec_release_user_space(struct release_user_space_desc *__user arg) { - long rc = -1; - struct mcos_handler_info *info; - info = ihk_os_get_mcos_private_data(file); - dprintk("%s: clear_pte_range %p-%p\n", __FUNCTION__, (void*)info->user_start, (void*)info->user_end); - rc = clear_pte_range(info->user_start, info->user_end - info->user_start); - return rc; + struct release_user_space_desc desc; + + if (copy_from_user(&desc, arg, sizeof(desc))) { + return -EFAULT; + } + +#if 1 + return clear_pte_range(desc.user_start, desc.user_end - desc.user_start); +#else + return release_user_space(desc.user_start, desc.user_end - desc.user_start); +#endif } static long (*mckernel_do_futex)(int n, unsigned long arg0, unsigned long arg1, @@ -3017,8 +3022,8 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, case MCEXEC_UP_TERMINATE_THREAD: return mcexec_terminate_thread(os, (unsigned long *)arg, file); - case MCEXEC_UP_UNMAP_PSEUDO_FILEMAP: - return mcexec_unmap_pseudo_filemap(os, file); + case MCEXEC_UP_RELEASE_USER_SPACE: + return mcexec_release_user_space((struct release_user_space_desc *)arg); case MCEXEC_UP_GET_NUM_POOL_THREADS: return mcctrl_get_num_pool_threads(os); diff --git a/executer/kernel/mcctrl/driver.c b/executer/kernel/mcctrl/driver.c index eb7a672d..17c6c71c 100644 --- a/executer/kernel/mcctrl/driver.c +++ b/executer/kernel/mcctrl/driver.c @@ -90,7 +90,7 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_TERMINATE_THREAD, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_GET_NUM_POOL_THREADS, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_UTI_ATTR, .func = mcctrl_ioctl }, - { .request = MCEXEC_UP_UNMAP_PSEUDO_FILEMAP, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_RELEASE_USER_SPACE, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_DEBUG_LOG, .func = mcctrl_ioctl }, { .request = IHK_OS_AUX_PERF_NUM, .func = mcctrl_ioctl }, { .request = IHK_OS_AUX_PERF_SET, .func = mcctrl_ioctl }, diff --git a/executer/kernel/mcctrl/mcctrl.h b/executer/kernel/mcctrl/mcctrl.h index 6e449239..178f1d9a 100644 --- a/executer/kernel/mcctrl/mcctrl.h +++ b/executer/kernel/mcctrl/mcctrl.h @@ -539,6 +539,7 @@ struct vdso { int reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsigned long *endp); +int release_user_space(uintptr_t start, uintptr_t len); void get_vdso_info(ihk_os_t os, long vdso_pa); int arch_symbols_init(void); diff --git a/executer/kernel/mcctrl/syscall.c b/executer/kernel/mcctrl/syscall.c index db40954a..5afcf4e2 100644 --- a/executer/kernel/mcctrl/syscall.c +++ b/executer/kernel/mcctrl/syscall.c @@ -2028,6 +2028,43 @@ int clear_pte_range(uintptr_t start, uintptr_t len) return ret; } +int release_user_space(uintptr_t start, uintptr_t len) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + uintptr_t addr; + uintptr_t end; + int error; + int ret; + + ret = 0; + //down_read(&mm->mmap_sem); + addr = start; + while (addr < (start + len)) { + vma = find_vma(mm, addr); + if (!vma) { + break; + } + + if (addr < vma->vm_start) { + addr = vma->vm_start; + } + + end = vma->vm_end; + if (addr < end) { + if ((error = vm_munmap(addr, end - addr))) { + printk("%s: ERROR: vm_munmap failed (%d)\n", __func__, error); + } + if (ret == 0) { + ret = error; + } + } + addr = vma->vm_end; + } + //up_read(&mm->mmap_sem); + return ret; +} + /** * \brief Write out the core file image to a core file. * diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index b73be069..986e6346 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -1962,14 +1962,14 @@ struct uti_desc { int exit; /* Used to tell the tracer to exit */ }; -static int create_tracer(); +static int create_tracer(unsigned long user_start, unsigned long user_end); int uti_pfd[2]; struct uti_desc *uti_desc = (void*)-1; +static struct program_load_desc *desc; int main(int argc, char **argv) { int ret = 0; - struct program_load_desc *desc; int envs_len; char *envs; char *args; @@ -2144,9 +2144,9 @@ int main(int argc, char **argv) if (opendev() == -1) exit(EXIT_FAILURE); -#if 1 - /* Create tracer before anonymous inode is mapped */ - if ((error = create_tracer())) { +#if 0 + /* TODO: Remove this after memory corruption bug is fixed */ + if ((error = create_tracer(0, 0))) { fprintf(stderr, "%s: create tracer returned %d\n", __FUNCTION__, error); return error; } @@ -2875,7 +2875,7 @@ debug_sig(int s) #endif static int -create_tracer() +create_tracer(unsigned long user_start, unsigned long user_end) { int tpid; int rc; @@ -2888,6 +2888,10 @@ create_tracer() int exited = 0; int mode = 0; unsigned long buf; + struct release_user_space_desc release_desc = { + .user_start = desc->user_start, + .user_end = desc->user_end + }; /* Perform mmap() before fork() in create_tracer() */ uti_desc = mmap(NULL, sizeof(struct uti_desc), PROT_READ | PROT_WRITE, @@ -2942,6 +2946,12 @@ create_tracer() return 0; } close(uti_pfd[0]); +#if 1 /* debug */ + if (ioctl(fd, MCEXEC_UP_RELEASE_USER_SPACE, &release_desc) != 0) { + fprintf(stderr, "%s: ERROR: MCEXEC_UP_RELEASE_USER_SPACE returned %d\n", __FUNCTION__, errno); + exit(1); + } +#endif tpid = fork(); if (tpid) { if (tpid == -1) { @@ -2966,9 +2976,14 @@ create_tracer() } #endif +#if 0 + if (ioctl(fd, MCEXEC_UP_RELEASE_USER_SPACE, &release_desc) != 0) { + fprintf(stderr, "%s: ERROR: MCEXEC_UP_RELEASE_USER_SPACE returned %d\n", __FUNCTION__, errno); + exit(1); + } +#endif sem_wait(&uti_desc->arg); if (uti_desc->exit) { /* When uti is not used */ - fprintf(stderr, "%s: exiting tid=%d\n", __FUNCTION__, gettid()); exit(0); } @@ -3047,7 +3062,7 @@ create_tracer() return_syscall() */ if (exited == 1 || exited == 2) { - fprintf(stderr, "%s: calling MCEXEC_UP_TERMINATE_THREAD,exited=%d,code=%lx\n", __FUNCTION__, exited, code); + __dprintf("calling MCEXEC_UP_TERMINATE_THREAD,exited=%d,code=%lx\n", exited, code); if (ioctl(fd, MCEXEC_UP_TERMINATE_THREAD, term_param) != 0) { fprintf(stderr, "%s: INFO: MCEXEC_UP_TERMINATE_THREAD returned %d\n", __FUNCTION__, errno); } @@ -3191,11 +3206,12 @@ util_thread(struct thread_data_s *my_thread, unsigned long uctx_pa, int remote_t void *param[6]; int rc = 0; unsigned long buf; - -#if 0 - if ((error = create_tracer())) { - fprintf(stderr, "%s: create_tracer returned %d\n", __FUNCTION__, error); - rc = error; goto out; + +#if 1 + /* Create tracer */ + if ((rc = create_tracer(desc->user_start, desc->user_end))) { + fprintf(stderr, "%s: create_tracer returned %d\n", __FUNCTION__, rc); + goto out; } #endif #ifdef POSTK_DEBUG_ARCH_DEP_35 @@ -3774,12 +3790,14 @@ gettid_out: goto fork_child_sync_pipe; } - /* Create tracer before anonymous inode is mapped */ - if ((ret = create_tracer())) { +#if 1 + /* Create tracer */ + if ((ret = create_tracer(desc->user_start, desc->user_end))) { fs->status = ret; fprintf(stderr, "%s: create tracer returned %d\n", __FUNCTION__, ret); goto fork_child_sync_pipe; } +#endif if (ioctl(fd, MCEXEC_UP_CREATE_PPD) != 0) { fs->status = -errno;