From 59ee251e1cda08e02692d07e763003f837defc9d Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Thu, 2 Jul 2015 00:22:35 +0900 Subject: [PATCH] fix /proc/pid/mem, /proc/pid/status, /proc/pid/cmdline --- executer/include/uprotocol.h | 11 +- executer/kernel/control.c | 41 ++++++++ executer/kernel/driver.c | 2 + executer/user/mcexec.c | 33 +++--- kernel/host.c | 19 ++-- kernel/include/syscall.h | 9 +- kernel/procfs.c | 84 ++++++++++++--- kernel/syscall.c | 198 +++++++++++------------------------ 8 files changed, 207 insertions(+), 190 deletions(-) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index eae817ca..59ef7ee1 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -39,6 +39,8 @@ #define MCEXEC_UP_GET_CPU 0x30a02907 #define MCEXEC_UP_STRNCPY_FROM_USER 0x30a02908 #define MCEXEC_UP_NEW_PROCESS 0x30a02909 +#define MCEXEC_UP_GET_CRED 0x30a0290a +#define MCEXEC_UP_GET_CREDV 0x30a0290b #define MCEXEC_UP_PREPARE_DMA 0x30a02910 #define MCEXEC_UP_FREE_DMA 0x30a02911 @@ -80,14 +82,7 @@ struct program_load_desc { int err; int stack_prot; int pgid; - int ruid; - int euid; - int suid; - int fsuid; - int rgid; - int egid; - int sgid; - int fsgid; + int cred[8]; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/executer/kernel/control.c b/executer/kernel/control.c index 2288a6b5..8247b350 100644 --- a/executer/kernel/control.c +++ b/executer/kernel/control.c @@ -786,6 +786,40 @@ struct mckernel_exec_file { struct list_head list; }; +int +mcexec_getcred(unsigned long phys) +{ + int *virt = phys_to_virt(phys); + + virt[0] = current_uid(); + virt[1] = current_euid(); + virt[2] = current_suid(); + virt[3] = current_fsuid(); + virt[4] = current_gid(); + virt[5] = current_egid(); + virt[6] = current_sgid(); + virt[7] = current_fsgid(); + return 0; +} + +int +mcexec_getcredv(int __user *virt) +{ + int wk[8]; + + wk[0] = current_uid(); + wk[1] = current_euid(); + wk[2] = current_suid(); + wk[3] = current_fsuid(); + wk[4] = current_gid(); + wk[5] = current_egid(); + wk[6] = current_sgid(); + wk[7] = current_fsgid(); + if(copy_to_user(virt, wk, sizeof(int) * 8)) + return -EFAULT; + return 0; +} + int mcexec_open_exec(ihk_os_t os, char * __user filename) { struct file *file; @@ -957,6 +991,13 @@ long __mcctrl_control(ihk_os_t os, unsigned int req, unsigned long arg, case MCEXEC_UP_FREE_DMA: return mcexec_free_region(os, (unsigned long *)arg); + + case MCEXEC_UP_GET_CRED: + return mcexec_getcred((unsigned long)arg); + + case MCEXEC_UP_GET_CREDV: + return mcexec_getcredv((int *)arg); + case MCEXEC_UP_DEBUG_LOG: return mcexec_debug_log(os, arg); } diff --git a/executer/kernel/driver.c b/executer/kernel/driver.c index bcdb72c5..5d088487 100644 --- a/executer/kernel/driver.c +++ b/executer/kernel/driver.c @@ -65,6 +65,8 @@ static struct ihk_os_user_call_handler mcctrl_uchs[] = { { .request = MCEXEC_UP_FREE_DMA, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_OPEN_EXEC, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_CLOSE_EXEC, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_GET_CRED, .func = mcctrl_ioctl }, + { .request = MCEXEC_UP_GET_CREDV, .func = mcctrl_ioctl }, { .request = MCEXEC_UP_DEBUG_LOG, .func = mcctrl_ioctl }, }; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 59609cd7..5f603f91 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -159,12 +159,6 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) int load_addr_set = 0; static char interp_path[PATH_MAX]; ssize_t ss; - uid_t ruid; - uid_t euid; - uid_t suid; - gid_t rgid; - gid_t egid; - gid_t sgid; *interp_pathp = NULL; @@ -248,18 +242,8 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) } desc->pid = getpid(); desc->pgid = getpgid(0); - getresuid(&ruid, &euid, &suid); - getresgid(&rgid, &egid, &sgid); - desc->ruid = ruid; - desc->euid = euid; - desc->suid = suid; -// desc->fsuid = setfsuid(-1); - desc->rgid = rgid; - desc->egid = egid; - desc->sgid = sgid; -// desc->fsgid = setfsgid(-1); desc->entry = hdr.e_entry; - + ioctl(fd, MCEXEC_UP_GET_CREDV, desc->cred); desc->at_phdr = load_addr + hdr.e_phoff; desc->at_phent = sizeof(phdr); desc->at_phnum = hdr.e_phnum; @@ -2046,6 +2030,17 @@ return_execve2: do_syscall_return(fd, cpu, 0, 0, 0, 0, 0); break; + case __NR_setfsuid: + if(w.sr.args[1] == 1){ + ioctl(fd, MCEXEC_UP_GET_CRED, w.sr.args[0]); + ret = 0; + } + else{ + ret = setfsuid(w.sr.args[0]); + } + do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); + break; + case __NR_close: if(w.sr.args[0] == fd) ret = -EBADF; @@ -2055,8 +2050,8 @@ return_execve2: break; default: - ret = do_generic_syscall(&w); - do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); + ret = do_generic_syscall(&w); + do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); break; } diff --git a/kernel/host.c b/kernel/host.c index a45a33bb..fb37d290 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -359,14 +359,16 @@ static int process_msg_prepare_process(unsigned long rphys) } proc->ftn->pid = pn->pid; proc->ftn->pgid = pn->pgid; - proc->ftn->ruid = pn->ruid; - proc->ftn->euid = pn->euid; - proc->ftn->suid = pn->suid; - proc->ftn->fsuid = pn->fsuid; - proc->ftn->rgid = pn->rgid; - proc->ftn->egid = pn->egid; - proc->ftn->sgid = pn->sgid; - proc->ftn->fsgid = pn->fsgid; + + proc->ftn->ruid = pn->cred[0]; + proc->ftn->euid = pn->cred[1]; + proc->ftn->suid = pn->cred[2]; + proc->ftn->fsuid = pn->cred[3]; + proc->ftn->rgid = pn->cred[4]; + proc->ftn->egid = pn->cred[5]; + proc->ftn->sgid = pn->cred[6]; + proc->ftn->fsgid = pn->cred[7]; + proc->vm->region.user_start = pn->user_start; proc->vm->region.user_end = pn->user_end; proc->vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK; @@ -390,6 +392,7 @@ static int process_msg_prepare_process(unsigned long rphys) ihk_mc_unmap_virtual(p, npages, 1); ihk_mc_unmap_memory(NULL, phys, sz); flush_tlb(); + return 0; err: ihk_mc_free(pn); diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 64fc3483..a2417a88 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -140,14 +140,7 @@ struct program_load_desc { int err; int stack_prot; int pgid; - int ruid; - int euid; - int suid; - int fsuid; - int rgid; - int egid; - int sgid; - int fsgid; + int cred[8]; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/kernel/procfs.c b/kernel/procfs.c index 4dc56999..b1742b8c 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -47,6 +47,9 @@ static void create_proc_procfs_file(int pid, char *fname, int mode, int cpuid); static void delete_proc_procfs_file(int pid, char *fname); static void operate_proc_procfs_file(int pid, char *fname, int msg, int mode, int cpuid); +int copy_from_user(void *dst, const void *src, size_t siz); +int copy_to_user(void *dst, const void *src, size_t siz); + /** * \brief Create all procfs files for process. * @@ -404,19 +407,69 @@ void process_procfs_request(unsigned long rarg) struct process_vm *vm = proc->vm; if (!is_current) { - goto end; - } - list_for_each_entry(range, &vm->vm_range_list, list) { - dprintf("range: %lx - %lx\n", range->start, range->end); - if ((range->start <= r->offset) && - (r->offset < range->end)) { - unsigned int len = r->count; - if (range->end < r->offset + r->count) { - len = range->end - r->offset; + uint64_t reason = PF_POPULATE | PF_WRITE | PF_USER; + unsigned long offset = r->offset; + unsigned long left = r->count; + int ret; + + ans = 0; + if(left == 0) + goto end; + + while(left){ + unsigned long pa; + char *va; + int pos = offset & (PAGE_SIZE - 1); + int size = PAGE_SIZE - pos; + + if(size > left) + size = left; + ret = page_fault_process_vm(proc->vm, + (void *)offset, reason); + if(ret){ + if(ans == 0) + ans = -EIO; + goto end; + } + ret = ihk_mc_pt_virt_to_phys(vm->page_table, + (void *)offset, &pa); + if(ret){ + if(ans == 0) + ans = -EIO; + goto end; + } + va = phys_to_virt(pa); + memcpy(buf + ans, va, size); + offset += size; + left -= size; + ans += size; + } + } + else{ + unsigned long offset = r->offset; + unsigned long left = r->count; + unsigned long pos; + unsigned long l; + ans = 0; + list_for_each_entry(range, &vm->vm_range_list, list) { + dprintf("range: %lx - %lx\n", range->start, range->end); + while (left && + (range->start <= offset) && + (offset < range->end)) { + pos = offset & (PAGE_SIZE - 1); + l = PAGE_SIZE - pos; + if(l > left) + l = left; + if(copy_from_user(buf, (void *)offset, l)){ + if(ans == 0) + ans = -EIO; + goto end; + } + buf += l; + ans += l; + offset += l; + left -= l; } - memcpy((void *)buf, (void *)range->start, len); - ans = len; - break; } } goto end; @@ -593,6 +646,13 @@ void process_procfs_request(unsigned long rarg) if (strcmp(p, "cmdline") == 0) { unsigned int limit = proc->saved_cmdline_len; unsigned int len = r->count; + + if(!proc->saved_cmdline){ + ans = 0; + eof = 1; + goto end; + } + if (r->offset < limit) { if (limit < r->offset + r->count) { len = limit - r->offset; diff --git a/kernel/syscall.c b/kernel/syscall.c index 85b1c009..406ae260 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2034,9 +2034,31 @@ SYSCALL_DECLARE(tgkill) return do_kill(tgid, tid, sig, &info, 0); } -void -do_setresuid(int ruid, int euid, int suid, int fsuid) +int * +getcred(int *_buf) { + int *buf; + struct syscall_request request IHK_DMA_ALIGN; + unsigned long phys; + + if(((unsigned long)_buf) & ((unsigned long)(_buf + 8)) & ~4095) + buf = _buf + 8; + else + buf = _buf; + phys = virt_to_phys(buf); + request.number = __NR_setfsuid; + request.args[0] = phys; + request.args[1] = 1; + do_syscall(&request, ihk_mc_get_processor_id(), 0); + + return buf; +} + +void +do_setresuid() +{ + int _buf[16]; + int *buf; struct process *proc = cpu_local_var(current); int pid = proc->ftn->pid; struct cpu_local_var *v; @@ -2044,21 +2066,17 @@ do_setresuid(int ruid, int euid, int suid, int fsuid) int i; unsigned long irqstate; + buf = getcred(_buf); + for(i = 0; i < num_processors; i++){ v = get_cpu_local_var(i); irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); list_for_each_entry(p, &(v->runq), sched_list){ if(p->ftn->pid == pid){ - if(ruid != -1) - p->ftn->ruid = ruid; - if(euid != -1) - p->ftn->euid = euid; - if(suid != -1) - p->ftn->suid = suid; -#if 0 - if(fsuid != -1) - p->ftn->fsuid = fsuid; -#endif + p->ftn->ruid = buf[0]; + p->ftn->euid = buf[1]; + p->ftn->suid = buf[2]; + p->ftn->fsuid = buf[3]; } } ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); @@ -2066,8 +2084,10 @@ do_setresuid(int ruid, int euid, int suid, int fsuid) } void -do_setresgid(int rgid, int egid, int sgid, int fsgid) +do_setresgid() { + int _buf[16]; + int *buf; struct process *proc = cpu_local_var(current); int pid = proc->ftn->pid; struct cpu_local_var *v; @@ -2075,21 +2095,17 @@ do_setresgid(int rgid, int egid, int sgid, int fsgid) int i; unsigned long irqstate; + buf = getcred(_buf); + for(i = 0; i < num_processors; i++){ v = get_cpu_local_var(i); irqstate = ihk_mc_spinlock_lock(&(v->runq_lock)); list_for_each_entry(p, &(v->runq), sched_list){ if(p->ftn->pid == pid){ - if(rgid != -1) - p->ftn->rgid = rgid; - if(egid != -1) - p->ftn->egid = egid; - if(sgid != -1) - p->ftn->sgid = sgid; -#if 0 - if(fsgid != -1) - p->ftn->fsgid = fsgid; -#endif + p->ftn->rgid = buf[4]; + p->ftn->egid = buf[5]; + p->ftn->sgid = buf[6]; + p->ftn->fsgid = buf[7]; } } ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); @@ -2098,184 +2114,96 @@ do_setresgid(int rgid, int egid, int sgid, int fsgid) SYSCALL_DECLARE(setresuid) { - int ruid = ihk_mc_syscall_arg0(ctx); - int euid = ihk_mc_syscall_arg1(ctx); - int suid = ihk_mc_syscall_arg2(ctx); int rc; rc = syscall_generic_forwarding(__NR_setresuid, ctx); if(rc == 0){ - struct syscall_request request IHK_DMA_ALIGN; - int fsuid = 0; - - request.number = __NR_setfsuid; - request.args[0] = -1; -#if 0 - fsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); -#endif - do_setresuid(ruid, euid, suid, fsuid); + do_setresuid(); } return rc; } SYSCALL_DECLARE(setreuid) { - int ruid = ihk_mc_syscall_arg0(ctx); - int euid = ihk_mc_syscall_arg1(ctx); - int suid = -1; int rc; - struct process *proc = cpu_local_var(current); -// int euid_bak = proc->ftn->euid; - int ruid_bak = proc->ftn->ruid; rc = syscall_generic_forwarding(__NR_setreuid, ctx); if(rc == 0){ - struct syscall_request request IHK_DMA_ALIGN; - int fsuid = 0; - - if(euid != -1){ - if(euid != ruid_bak){ - suid = euid; - } - } - else if(ruid != -1){ - } - request.number = __NR_setfsuid; - request.args[0] = -1; -#if 0 - fsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); -#endif - do_setresuid(ruid, euid, suid, fsuid); + do_setresuid(); } return rc; } SYSCALL_DECLARE(setuid) { - int euid = ihk_mc_syscall_arg0(ctx); - int ruid = -1; - int suid = -1; long rc; - struct process *proc = cpu_local_var(current); - int euid_bak = proc->ftn->euid; rc = syscall_generic_forwarding(__NR_setuid, ctx); if(rc == 0){ - struct syscall_request request IHK_DMA_ALIGN; - int fsuid = 0; - - if(euid_bak == 0){ - ruid = euid; - suid = euid; - } - request.number = __NR_setfsuid; - request.args[0] = -1; -#if 0 - fsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); -#endif - do_setresuid(ruid, euid, suid, fsuid); + do_setresuid(); } return rc; } SYSCALL_DECLARE(setfsuid) { - int fsuid; + int fsuid = (int)ihk_mc_syscall_arg0(ctx);; + unsigned long newfsuid; + struct syscall_request request IHK_DMA_ALIGN; - fsuid = syscall_generic_forwarding(__NR_setfsuid, ctx); - do_setresuid(-1, -1, -1, fsuid); - return fsuid; + request.number = __NR_setfsuid; + request.args[0] = fsuid; + request.args[1] = 0; + newfsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresuid(); + return newfsuid; } SYSCALL_DECLARE(setresgid) { - int rgid = ihk_mc_syscall_arg0(ctx); - int egid = ihk_mc_syscall_arg1(ctx); - int sgid = ihk_mc_syscall_arg2(ctx); int rc; rc = syscall_generic_forwarding(__NR_setresgid, ctx); if(rc == 0){ - struct syscall_request request IHK_DMA_ALIGN; - int fsgid = 0; - - request.number = __NR_setfsgid; - request.args[0] = -1; -#if 0 - fsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); -#endif - do_setresgid(rgid, egid, sgid, fsgid); + do_setresgid(); } return rc; } SYSCALL_DECLARE(setregid) { - int rgid = ihk_mc_syscall_arg0(ctx); - int egid = ihk_mc_syscall_arg1(ctx); - int sgid = -1; int rc; - struct process *proc = cpu_local_var(current); -// int egid_bak = proc->ftn->egid; - int rgid_bak = proc->ftn->rgid; rc = syscall_generic_forwarding(__NR_setregid, ctx); if(rc == 0){ - struct syscall_request request IHK_DMA_ALIGN; - int fsgid = 0; - - if(egid != -1){ - if(egid != rgid_bak){ - sgid = egid; - } - } - else if(rgid != -1){ - } - request.number = __NR_setfsgid; - request.args[0] = -1; -#if 0 - fsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); -#endif - do_setresgid(rgid, egid, sgid, fsgid); + do_setresgid(); } return rc; } SYSCALL_DECLARE(setgid) { - int egid = ihk_mc_syscall_arg0(ctx); - int rgid = -1; - int sgid = -1; long rc; - struct process *proc = cpu_local_var(current); - int egid_bak = proc->ftn->egid; rc = syscall_generic_forwarding(__NR_setgid, ctx); if(rc == 0){ - struct syscall_request request IHK_DMA_ALIGN; - int fsgid = 0; - - if(egid_bak == 0){ - rgid = egid; - sgid = egid; - } - request.number = __NR_setfsgid; - request.args[0] = -1; -#if 0 - fsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); -#endif - do_setresgid(rgid, egid, sgid, fsgid); + do_setresgid(); } return rc; } SYSCALL_DECLARE(setfsgid) { - int fsgid; + int fsgid = (int)ihk_mc_syscall_arg0(ctx);; + unsigned long newfsgid; + struct syscall_request request IHK_DMA_ALIGN; - fsgid = syscall_generic_forwarding(__NR_setfsgid, ctx); - do_setresgid(-1, -1, -1, fsgid); - return fsgid; + request.number = __NR_setfsuid; + request.args[0] = fsgid; + request.args[1] = 0; + newfsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresgid(); + return newfsgid; } SYSCALL_DECLARE(getuid)