diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h index 505cd03b..5b88646e 100644 --- a/arch/x86/kernel/include/syscall_list.h +++ b/arch/x86/kernel/include/syscall_list.h @@ -61,11 +61,14 @@ SYSCALL_HANDLED(97, getrlimit) SYSCALL_HANDLED(101, ptrace) SYSCALL_DELEGATED(102, getuid) SYSCALL_DELEGATED(104, getgid) +SYSCALL_HANDLED(105, setuid) SYSCALL_DELEGATED(107, geteuid) SYSCALL_DELEGATED(108, getegid) SYSCALL_HANDLED(109, setpgid) SYSCALL_HANDLED(110, getppid) SYSCALL_DELEGATED(111, getpgrp) +SYSCALL_HANDLED(113, setreuid) +SYSCALL_HANDLED(117, setresuid) SYSCALL_HANDLED(127, rt_sigpending) SYSCALL_HANDLED(128, rt_sigtimedwait) SYSCALL_HANDLED(129, rt_sigqueueinfo) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index 5873b1cb..f897f69d 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -932,6 +932,17 @@ do_kill(int pid, int tid, int sig, siginfo_t *info, int ptracecont) return 0; } + if(sig != SIGCONT && + proc->ftn->euid != 0 && + proc->ftn->ruid != tproc->ftn->ruid && + proc->ftn->euid != tproc->ftn->ruid && + proc->ftn->ruid != tproc->ftn->suid && + proc->ftn->euid != tproc->ftn->suid){ + ihk_mc_spinlock_unlock_noirq(savelock); + cpu_restore_interrupt(irqstate); + return -EPERM; + } + doint = 0; if(tid == -1){ ihk_mc_spinlock_lock_noirq(&tproc->sigshared->lock); diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index a3181d8c..e79a3d76 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -80,6 +80,9 @@ struct program_load_desc { int err; int stack_prot; int pgid; + int ruid; + int euid; + int suid; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 50741229..cce5e4ab 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -150,6 +150,9 @@ 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; *interp_pathp = NULL; @@ -233,6 +236,10 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) } desc->pid = getpid(); desc->pgid = getpgid(0); + getresuid(&ruid, &euid, &suid); + desc->ruid = ruid; + desc->euid = euid; + desc->suid = suid; desc->entry = hdr.e_entry; desc->at_phdr = load_addr + hdr.e_phoff; diff --git a/kernel/host.c b/kernel/host.c index 037eb1c6..61d06b85 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -349,6 +349,9 @@ 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->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 f4a5cae2..a0377975 100644 --- a/kernel/include/process.h +++ b/kernel/include/process.h @@ -279,6 +279,9 @@ struct fork_tree_node { int pid; int tid; int pgid; + int ruid; + int euid; + int suid; struct fork_tree_node *parent; struct list_head children; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 483805bf..c9095099 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -140,6 +140,9 @@ struct program_load_desc { int err; int stack_prot; int pgid; + int ruid; + int euid; + int suid; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/kernel/process.c b/kernel/process.c index 41abcf0a..4a1e5ded 100644 --- a/kernel/process.c +++ b/kernel/process.c @@ -106,6 +106,10 @@ void init_fork_tree_node(struct fork_tree_node *ftn, ftn->parent = NULL; if (parent) { ftn->parent = parent; + ftn->pgid = parent->pgid; + ftn->ruid = parent->ruid; + ftn->euid = parent->euid; + ftn->suid = parent->suid; } INIT_LIST_HEAD(&ftn->children); INIT_LIST_HEAD(&ftn->siblings_list); diff --git a/kernel/syscall.c b/kernel/syscall.c index 872febe4..89e129f0 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -104,6 +104,7 @@ int copy_to_user(void *, const void *, size_t); int patch_process_vm(struct process_vm *, void *, const void *, size_t); void do_setpgid(int, int); extern long alloc_debugreg(struct process *proc); +extern int num_processors; int prepare_process_ranges_args_envs(struct process *proc, struct program_load_desc *pn, @@ -1871,8 +1872,6 @@ unsigned long do_fork(int clone_flags, unsigned long newsp, return -ENOMEM; } - new->ftn->pgid = cpu_local_var(current)->ftn->pgid; - cpu_set(cpuid, &new->vm->cpu_set, &new->vm->cpu_set_lock); if (clone_flags & CLONE_VM) { @@ -2034,6 +2033,91 @@ SYSCALL_DECLARE(tgkill) return do_kill(tgid, tid, sig, &info, 0); } +void +do_setresuid(int ruid, int euid, int suid) +{ + 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(ruid != -1) + p->ftn->ruid = ruid; + if(euid != -1) + p->ftn->euid = euid; + if(suid != -1) + p->ftn->suid = suid; + } + } + ihk_mc_spinlock_unlock(&(v->runq_lock), irqstate); + } +} + +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){ + do_setresuid(ruid, euid, suid); + } + 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){ + if(euid != -1){ + if(euid != ruid_bak){ + suid = euid; + } + } + else if(ruid != -1){ + } + do_setresuid(ruid, euid, suid); + } + 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){ + if(euid_bak == 0){ + ruid = euid; + suid = euid; + } + do_setresuid(ruid, euid, suid); + } + return rc; +} + SYSCALL_DECLARE(setpgid) { int pid = ihk_mc_syscall_arg0(ctx);