diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index c65fe68f..ca9d08e8 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -64,16 +64,23 @@ SYSCALL_DELEGATED(89, readlink) SYSCALL_DELEGATED(96, gettimeofday) SYSCALL_HANDLED(97, getrlimit) SYSCALL_HANDLED(101, ptrace) -SYSCALL_DELEGATED(102, getuid) -SYSCALL_DELEGATED(104, getgid) +SYSCALL_HANDLED(102, getuid) +SYSCALL_HANDLED(104, getgid) SYSCALL_HANDLED(105, setuid) -SYSCALL_DELEGATED(107, geteuid) -SYSCALL_DELEGATED(108, getegid) +SYSCALL_HANDLED(106, setgid) +SYSCALL_HANDLED(107, geteuid) +SYSCALL_HANDLED(108, getegid) SYSCALL_HANDLED(109, setpgid) SYSCALL_HANDLED(110, getppid) SYSCALL_DELEGATED(111, getpgrp) SYSCALL_HANDLED(113, setreuid) +SYSCALL_HANDLED(114, setregid) SYSCALL_HANDLED(117, setresuid) +SYSCALL_HANDLED(118, getresuid) +SYSCALL_HANDLED(119, setresgid) +SYSCALL_HANDLED(120, getresgid) +SYSCALL_HANDLED(122, setfsuid) +SYSCALL_HANDLED(123, setfsgid) SYSCALL_HANDLED(127, rt_sigpending) SYSCALL_HANDLED(128, rt_sigtimedwait) SYSCALL_HANDLED(129, rt_sigqueueinfo) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index e79a3d76..eae817ca 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -83,6 +83,11 @@ struct program_load_desc { int ruid; int euid; int suid; + int fsuid; + int rgid; + int egid; + int sgid; + int fsgid; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 459970bf..7f59ad5d 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,9 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) uid_t ruid; uid_t euid; uid_t suid; + gid_t rgid; + gid_t egid; + gid_t sgid; *interp_pathp = NULL; @@ -245,9 +249,15 @@ 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; desc->at_phdr = load_addr + hdr.e_phoff; diff --git a/kernel/host.c b/kernel/host.c index 61d06b85..a45a33bb 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -29,6 +29,7 @@ #include #include #include +#include //#define DEBUG_PRINT_HOST @@ -70,7 +71,8 @@ int prepare_process_ranges_args_envs(struct process *proc, unsigned long args_envs_p, args_envs_rp; unsigned long s, e, up; char **argv; - int i, n, argc, envc, args_envs_npages; + char **a; + int i, n, argc, envc, args_envs_npages, l; char **env; int range_npages; void *up_v; @@ -270,13 +272,21 @@ int prepare_process_ranges_args_envs(struct process *proc, dkprintf("argc: %d\n", argc); argv = (char **)(args_envs + (sizeof(int))); - while (*argv) { - char **_argv = argv; - dkprintf("%s\n", args_envs + (unsigned long)*argv); - *argv = (char *)addr + (unsigned long)*argv; // Process' address space! - argv = ++_argv; + if(proc->saved_cmdline){ + kfree(proc->saved_cmdline); + proc->saved_cmdline_len = 0; + } + for(a = argv, l = 0; *a; a++) + l += strlen(args_envs + (unsigned long)*a) + 1; + proc->saved_cmdline = kmalloc(p->args_len, IHK_MC_AP_NOWAIT); + if(!proc->saved_cmdline) + goto err; + proc->saved_cmdline_len = l; + for(a = argv, l = 0; *a; a++){ + strcpy(proc->saved_cmdline + l, args_envs + (unsigned long)*a); + l += strlen(args_envs + (unsigned long)*a) + 1; + *a = (char *)addr + (unsigned long)*a; // Process' address space! } - argv = (char **)(args_envs + (sizeof(int))); envc = *((int*)(args_envs + p->args_len)); dkprintf("envc: %d\n", envc); @@ -294,7 +304,7 @@ int prepare_process_ranges_args_envs(struct process *proc, p->rprocess = (unsigned long)proc; p->rpgtable = virt_to_phys(proc->vm->page_table); - + if (init_process_stack(proc, pn, argc, argv, envc, env) != 0) { goto err; } @@ -352,6 +362,11 @@ static int process_msg_prepare_process(unsigned long rphys) 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->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; diff --git a/kernel/include/process.h b/kernel/include/process.h index ed4c24b2..ba8052d8 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -291,6 +291,11 @@ struct fork_tree_node { int ruid; int euid; int suid; + int fsuid; + int rgid; + int egid; + int sgid; + int fsgid; struct fork_tree_node *parent; struct list_head children; @@ -404,6 +409,8 @@ struct process { struct sig_pending *ptrace_recvsig; struct sig_pending *ptrace_sendsig; fp_regs_struct *fp_regs; + char *saved_cmdline; + long saved_cmdline_len; }; struct process_vm { diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index c9095099..64fc3483 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -143,6 +143,11 @@ struct program_load_desc { int ruid; int euid; int suid; + int fsuid; + int rgid; + int egid; + int sgid; + int fsgid; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/kernel/process.c b/kernel/process.c index fbc3ec40..fc4f5405 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -1998,6 +1998,9 @@ void destroy_process(struct process *proc) if (proc->fp_regs) { release_fp_regs(proc); } + if (proc->saved_cmdline) { + kfree(proc->saved_cmdline); + } ihk_mc_free_pages(proc, KERNEL_STACK_NR_PAGES); } diff --git a/kernel/procfs.c b/kernel/procfs.c index af7cff8e..4dc56999 100644 --- a/kernel/procfs.c +++ b/kernel/procfs.c @@ -63,17 +63,20 @@ void create_proc_procfs_files(int pid, int cpuid) snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid); create_proc_procfs_file(pid, fname, 0400, cpuid); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/cmdline", osnum, pid); + create_proc_procfs_file(pid, fname, 0444, cpuid); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/mem", osnum, pid); create_proc_procfs_file(pid, fname, 0400, cpuid); snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/maps", osnum, pid); - create_proc_procfs_file(pid, fname, 0400, cpuid); + create_proc_procfs_file(pid, fname, 0444, cpuid); snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/pagemap", osnum, pid); - create_proc_procfs_file(pid, fname, 0400, cpuid); + create_proc_procfs_file(pid, fname, 0444, cpuid); snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/status", osnum, pid); - create_proc_procfs_file(pid, fname, 0400, cpuid); + create_proc_procfs_file(pid, fname, 0444, cpuid); snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/task/%d/mem", osnum, pid, pid); create_proc_procfs_file(pid, fname, 0400, cpuid); @@ -134,6 +137,9 @@ void delete_proc_procfs_files(int pid) snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/pagemap", osnum, pid); delete_proc_procfs_file(pid, fname); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/cmdline", osnum, pid); + delete_proc_procfs_file(pid, fname); + snprintf(fname, PROCFS_NAME_MAX, "mcos%d/%d/auxv", osnum, pid); delete_proc_procfs_file(pid, fname); @@ -525,8 +531,9 @@ void process_procfs_request(unsigned long rarg) if (strcmp(p, "status") == 0) { struct vm_range *range; unsigned long lockedsize = 0; - char tmp[80]; + char tmp[1024]; int len; + struct fork_tree_node *ftn = proc->ftn; ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock); list_for_each_entry(range, &proc->vm->vm_range_list, list) { @@ -535,7 +542,13 @@ void process_procfs_request(unsigned long rarg) } ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock); - sprintf(tmp, "VmLck: %9lu kB\n", (lockedsize + 1023) >> 10); + sprintf(tmp, + "Uid:\t%d\t%d\t%d\t%d\n" + "Gid:\t%d\t%d\t%d\t%d\n" + "VmLck:\t%9lu kB\n", + ftn->ruid, ftn->euid, ftn->suid, ftn->fsuid, + ftn->rgid, ftn->egid, ftn->sgid, ftn->fsgid, + (lockedsize + 1023) >> 10); len = strlen(tmp); if (r->offset < len) { if (r->offset + r->count < len) { @@ -574,6 +587,28 @@ void process_procfs_request(unsigned long rarg) goto end; } + /* + * mcos%d/PID/cmdline + */ + if (strcmp(p, "cmdline") == 0) { + unsigned int limit = proc->saved_cmdline_len; + unsigned int len = r->count; + if (r->offset < limit) { + if (limit < r->offset + r->count) { + len = limit - r->offset; + } + memcpy((void *)buf, ((char *) proc->saved_cmdline) + r->offset, len); + ans = len; + if (r->offset + len == limit) { + eof = 1; + } + } else if (r->offset == limit) { + ans = 0; + eof = 1; + } + goto end; + } + /* * mcos%d/PID/taks/PID/mem * diff --git a/kernel/syscall.c b/kernel/syscall.c index 41401023..5eac503f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2035,7 +2035,7 @@ SYSCALL_DECLARE(tgkill) } void -do_setresuid(int ruid, int euid, int suid) +do_setresuid(int ruid, int euid, int suid, int fsuid) { struct process *proc = cpu_local_var(current); int pid = proc->ftn->pid; @@ -2055,6 +2055,37 @@ do_setresuid(int ruid, int euid, int suid) p->ftn->euid = euid; if(suid != -1) p->ftn->suid = suid; + if(fsuid != -1) + p->ftn->fsuid = fsuid; + } + } + ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); + } +} + +void +do_setresgid(int rgid, int egid, int sgid, int fsgid) +{ + struct process *proc = cpu_local_var(current); + int pid = proc->ftn->pid; + struct cpu_local_var *v; + struct process *p; + int i; + unsigned long irqstate; + + 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(fsgid != -1) + p->ftn->fsgid = fsgid; } } ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); @@ -2070,7 +2101,13 @@ SYSCALL_DECLARE(setresuid) rc = syscall_generic_forwarding(__NR_setresuid, ctx); if(rc == 0){ - do_setresuid(ruid, euid, suid); + struct syscall_request request IHK_DMA_ALIGN; + int fsuid; + + request.number = __NR_setfsuid; + request.args[0] = -1; + fsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresuid(ruid, euid, suid, fsuid); } return rc; } @@ -2087,6 +2124,9 @@ SYSCALL_DECLARE(setreuid) rc = syscall_generic_forwarding(__NR_setreuid, ctx); if(rc == 0){ + struct syscall_request request IHK_DMA_ALIGN; + int fsuid; + if(euid != -1){ if(euid != ruid_bak){ suid = euid; @@ -2094,7 +2134,10 @@ SYSCALL_DECLARE(setreuid) } else if(ruid != -1){ } - do_setresuid(ruid, euid, suid); + request.number = __NR_setfsuid; + request.args[0] = -1; + fsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresuid(ruid, euid, suid, fsuid); } return rc; } @@ -2110,15 +2153,183 @@ SYSCALL_DECLARE(setuid) rc = syscall_generic_forwarding(__NR_setuid, ctx); if(rc == 0){ + struct syscall_request request IHK_DMA_ALIGN; + int fsuid; + if(euid_bak == 0){ ruid = euid; suid = euid; } - do_setresuid(ruid, euid, suid); + request.number = __NR_setfsuid; + request.args[0] = -1; + fsuid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresuid(ruid, euid, suid, fsuid); } return rc; } +SYSCALL_DECLARE(setfsuid) +{ + int fsuid; + + fsuid = syscall_generic_forwarding(__NR_setfsuid, ctx); + do_setresuid(-1, -1, -1, fsuid); + return fsuid; +} + +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; + + request.number = __NR_setfsgid; + request.args[0] = -1; + fsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresgid(rgid, egid, sgid, fsgid); + } + 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; + + if(egid != -1){ + if(egid != rgid_bak){ + sgid = egid; + } + } + else if(rgid != -1){ + } + request.number = __NR_setfsgid; + request.args[0] = -1; + fsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresgid(rgid, egid, sgid, fsgid); + } + 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; + + if(egid_bak == 0){ + rgid = egid; + sgid = egid; + } + request.number = __NR_setfsgid; + request.args[0] = -1; + fsgid = do_syscall(&request, ihk_mc_get_processor_id(), 0); + do_setresgid(rgid, egid, sgid, fsgid); + } + return rc; +} + +SYSCALL_DECLARE(setfsgid) +{ + int fsgid; + + fsgid = syscall_generic_forwarding(__NR_setfsgid, ctx); + do_setresgid(-1, -1, -1, fsgid); + return fsgid; +} + +SYSCALL_DECLARE(getuid) +{ + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn; + + return ftn->ruid; +} + +SYSCALL_DECLARE(geteuid) +{ + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn; + + return ftn->euid; +} + +SYSCALL_DECLARE(getresuid) +{ + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn; + int *ruid = (int *)ihk_mc_syscall_arg0(ctx); + int *euid = (int *)ihk_mc_syscall_arg1(ctx); + int *suid = (int *)ihk_mc_syscall_arg2(ctx); + + if(copy_to_user(ruid, &ftn->ruid, sizeof(int))) + return -EFAULT; + if(copy_to_user(euid, &ftn->euid, sizeof(int))) + return -EFAULT; + if(copy_to_user(suid, &ftn->suid, sizeof(int))) + return -EFAULT; + + return 0; +} + +SYSCALL_DECLARE(getgid) +{ + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn; + + return ftn->rgid; +} + +SYSCALL_DECLARE(getegid) +{ + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn; + + return ftn->egid; +} + +SYSCALL_DECLARE(getresgid) +{ + struct process *proc = cpu_local_var(current); + struct fork_tree_node *ftn = proc->ftn; + int *rgid = (int *)ihk_mc_syscall_arg0(ctx); + int *egid = (int *)ihk_mc_syscall_arg1(ctx); + int *sgid = (int *)ihk_mc_syscall_arg2(ctx); + + if(copy_to_user(rgid, &ftn->rgid, sizeof(int))) + return -EFAULT; + if(copy_to_user(egid, &ftn->egid, sizeof(int))) + return -EFAULT; + if(copy_to_user(sgid, &ftn->sgid, sizeof(int))) + return -EFAULT; + + return 0; +} + SYSCALL_DECLARE(setpgid) { int pid = ihk_mc_syscall_arg0(ctx);