From bb81f84709b45c4a00b71d0b5f63ac4736b26290 Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Mon, 14 Dec 2015 11:05:28 +0900 Subject: [PATCH] support PIE executable for PVAS --- executer/include/uprotocol.h | 1 + executer/user/mcexec.c | 3 +++ kernel/host.c | 22 ++++++++++++++++++++++ kernel/include/syscall.h | 1 + 4 files changed, 27 insertions(+) diff --git a/executer/include/uprotocol.h b/executer/include/uprotocol.h index 59ef7ee1..57cda78d 100644 --- a/executer/include/uprotocol.h +++ b/executer/include/uprotocol.h @@ -83,6 +83,7 @@ struct program_load_desc { int stack_prot; int pgid; int cred[8]; + int reloc; unsigned long entry; unsigned long user_start; unsigned long user_end; diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 771a5310..13b1100d 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -183,6 +183,7 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) desc = malloc(sizeof(struct program_load_desc) + sizeof(struct program_image_section) * nhdrs); + memset(desc, '\0', sizeof(struct program_load_desc)); desc->shell_path[0] = '\0'; fseek(fp, hdr.e_phoff, SEEK_SET); j = 0; @@ -243,6 +244,8 @@ struct program_load_desc *load_elf(FILE *fp, char **interp_pathp) } desc->pid = getpid(); desc->pgid = getpgid(0); + if(*interp_pathp) + desc->reloc = hdr.e_type == ET_DYN; desc->entry = hdr.e_entry; ioctl(fd, MCEXEC_UP_GET_CREDV, desc->cred); desc->at_phdr = load_addr + hdr.e_phoff; diff --git a/kernel/host.c b/kernel/host.c index 847cab2b..93d6d1c5 100644 --- a/kernel/host.c +++ b/kernel/host.c @@ -84,6 +84,7 @@ int prepare_process_ranges_args_envs(struct thread *thread, struct process *proc = thread->proc; struct process_vm *vm = proc->vm; struct address_space *as = vm->address_space; + long delta = -1; n = p->num_sections; @@ -102,6 +103,19 @@ int prepare_process_ranges_args_envs(struct thread *thread, pn->sections[i].vaddr += interp_nbase; p->sections[i].vaddr = pn->sections[i].vaddr; } + else{ + if(delta == -1){ + if(pn->reloc){ + delta = vm->region.user_start; + pn->at_phdr += delta; + pn->at_entry += delta; + } + else + delta = 0; + } + pn->sections[i].vaddr += delta; + p->sections[i].vaddr = pn->sections[i].vaddr; + } s = (pn->sections[i].vaddr) & PAGE_MASK; e = (pn->sections[i].vaddr + pn->sections[i].len + PAGE_SIZE - 1) & PAGE_MASK; @@ -382,6 +396,14 @@ static int process_msg_prepare_process(unsigned long rphys) vm->region.user_start = pn->user_start; vm->region.user_end = pn->user_end; + /* TODO: review this code + if(vm->region.user_end > USER_END) + vm->region.user_end = USER_END; + vm->region.map_start = + (vm->region.user_start + + (vm->region.user_end - vm->region.user_start) / 3) & + LARGE_PAGE_MASK; + */ vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK; vm->region.map_end = proc->vm->region.map_start; memcpy(proc->rlimit, pn->rlimit, sizeof(struct rlimit) * MCK_RLIM_MAX); diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 4290cc50..eb70283c 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -143,6 +143,7 @@ struct program_load_desc { int stack_prot; int pgid; int cred[8]; + int reloc; unsigned long entry; unsigned long user_start; unsigned long user_end;