fix /proc/pid/mem, /proc/pid/status, /proc/pid/cmdline

This commit is contained in:
Tomoki Shirasawa
2015-07-02 00:22:35 +09:00
parent fa79db3bcc
commit 59ee251e1c
8 changed files with 207 additions and 190 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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 },
};

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)