From 64c2e437c630cda261609c84258a67a395a20485 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Wed, 19 Jul 2017 11:37:55 +0900 Subject: [PATCH] open: check filename address (re-commit) --- arch/x86/kernel/memory.c | 29 +++++------------------------ kernel/syscall.c | 20 +++++++++++++++++--- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/arch/x86/kernel/memory.c b/arch/x86/kernel/memory.c index f05dba8b..c4e0869d 100644 --- a/arch/x86/kernel/memory.c +++ b/arch/x86/kernel/memory.c @@ -2171,26 +2171,18 @@ int copy_from_user(void *dst, const void *src, size_t siz) int strlen_user(const char *s) { struct process_vm *vm = cpu_local_var(current)->vm; - struct vm_range *range; unsigned long pgstart; int maxlen; const char *head = s; + int err; maxlen = 4096 - (((unsigned long)s) & 0x0000000000000fffUL); pgstart = ((unsigned long)s) & 0xfffffffffffff000UL; if(!pgstart || pgstart >= MAP_KERNEL_START) return -EFAULT; - ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock); for(;;){ - range = lookup_process_memory_range(vm, pgstart, pgstart+1); - if(range == NULL){ - ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock); - return -EFAULT; - } - if((range->flag & VR_PROT_MASK) == VR_PROT_NONE){ - ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock); - return -EFAULT; - } + if ((err = verify_process_vm(vm, s, 1))) + return err; while(*s && maxlen > 0){ s++; maxlen--; @@ -2200,14 +2192,12 @@ int strlen_user(const char *s) maxlen = 4096; pgstart += 4096; } - ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock); return s - head; } int strcpy_from_user(char *dst, const char *src) { struct process_vm *vm = cpu_local_var(current)->vm; - struct vm_range *range; unsigned long pgstart; int maxlen; int err = 0; @@ -2216,17 +2206,9 @@ int strcpy_from_user(char *dst, const char *src) pgstart = ((unsigned long)src) & 0xfffffffffffff000UL; if(!pgstart || pgstart >= MAP_KERNEL_START) return -EFAULT; - ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock); for(;;){ - range = lookup_process_memory_range(vm, pgstart, pgstart + 1); - if(range == NULL){ - err = -EFAULT; - break; - } - if((range->flag & VR_PROT_MASK) == VR_PROT_NONE){ - err = -EFAULT; - break; - } + if ((err = verify_process_vm(vm, src, 1))) + return err; while(*src && maxlen > 0){ *(dst++) = *(src++); maxlen--; @@ -2238,7 +2220,6 @@ int strcpy_from_user(char *dst, const char *src) maxlen = 4096; pgstart += 4096; } - ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock); return err; } diff --git a/kernel/syscall.c b/kernel/syscall.c index 5e2bc395..c6cb8359 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2834,12 +2834,26 @@ SYSCALL_DECLARE(ioctl) SYSCALL_DECLARE(open) { const char *pathname = (const char *)ihk_mc_syscall_arg0(ctx); + int len; + char *xpmem_wk; long rc; - dkprintf("open(): pathname=%s\n", pathname); - if (!strcmp(pathname, XPMEM_DEV_PATH)) { + len = strlen_user(pathname); + if (len < 0) + return len; + if (!(xpmem_wk = kmalloc(len + 1, IHK_MC_AP_NOWAIT))) + return -ENOMEM; + if (copy_from_user(xpmem_wk, pathname, len + 1)) { + kfree(xpmem_wk); + return -EFAULT; + } + dkprintf("open(): pathname=%s\n", xpmem_wk); + rc = strcmp(xpmem_wk, XPMEM_DEV_PATH); + kfree(xpmem_wk); + if (!rc) { rc = xpmem_open(ctx); - } else { + } + else { rc = syscall_generic_forwarding(__NR_open, ctx); }