relocate a program interpreter to the map_start
This commit makes a system call that dereferences a NULL pointer fail.
This commit is contained in:
@ -80,6 +80,7 @@ struct program_load_desc {
|
|||||||
unsigned long envs_len;
|
unsigned long envs_len;
|
||||||
unsigned long rlimit_stack_cur;
|
unsigned long rlimit_stack_cur;
|
||||||
unsigned long rlimit_stack_max;
|
unsigned long rlimit_stack_max;
|
||||||
|
unsigned long interp_align;
|
||||||
struct program_image_section sections[0];
|
struct program_image_section sections[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -248,6 +248,7 @@ struct program_load_desc *load_interp(struct program_load_desc *desc0, FILE *fp)
|
|||||||
int i, j, nhdrs = 0;
|
int i, j, nhdrs = 0;
|
||||||
struct program_load_desc *desc = desc0;
|
struct program_load_desc *desc = desc0;
|
||||||
size_t newsize;
|
size_t newsize;
|
||||||
|
unsigned long align;
|
||||||
|
|
||||||
if (fread(&hdr, sizeof(hdr), 1, fp) < 1) {
|
if (fread(&hdr, sizeof(hdr), 1, fp) < 1) {
|
||||||
__eprint("Cannot read Ehdr.\n");
|
__eprint("Cannot read Ehdr.\n");
|
||||||
@ -278,6 +279,7 @@ struct program_load_desc *load_interp(struct program_load_desc *desc0, FILE *fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fseek(fp, hdr.e_phoff, SEEK_SET);
|
fseek(fp, hdr.e_phoff, SEEK_SET);
|
||||||
|
align = 1;
|
||||||
j = desc->num_sections;
|
j = desc->num_sections;
|
||||||
for (i = 0; i < hdr.e_phnum; i++) {
|
for (i = 0; i < hdr.e_phnum; i++) {
|
||||||
if (fread(&phdr, sizeof(phdr), 1, fp) < 1) {
|
if (fread(&phdr, sizeof(phdr), 1, fp) < 1) {
|
||||||
@ -301,6 +303,10 @@ struct program_load_desc *load_interp(struct program_load_desc *desc0, FILE *fp)
|
|||||||
desc->sections[j].prot |= (phdr.p_flags & PF_W)? PROT_WRITE: 0;
|
desc->sections[j].prot |= (phdr.p_flags & PF_W)? PROT_WRITE: 0;
|
||||||
desc->sections[j].prot |= (phdr.p_flags & PF_X)? PROT_EXEC: 0;
|
desc->sections[j].prot |= (phdr.p_flags & PF_X)? PROT_EXEC: 0;
|
||||||
|
|
||||||
|
if (phdr.p_align > align) {
|
||||||
|
align = phdr.p_align;
|
||||||
|
}
|
||||||
|
|
||||||
__dprintf("%d: (%s) %lx, %lx, %lx, %lx, %x\n",
|
__dprintf("%d: (%s) %lx, %lx, %lx, %lx, %x\n",
|
||||||
j, (phdr.p_type == PT_LOAD ? "PT_LOAD" : "PT_TLS"),
|
j, (phdr.p_type == PT_LOAD ? "PT_LOAD" : "PT_TLS"),
|
||||||
desc->sections[j].vaddr,
|
desc->sections[j].vaddr,
|
||||||
@ -314,6 +320,7 @@ struct program_load_desc *load_interp(struct program_load_desc *desc0, FILE *fp)
|
|||||||
desc->num_sections = j;
|
desc->num_sections = j;
|
||||||
|
|
||||||
desc->entry = hdr.e_entry;
|
desc->entry = hdr.e_entry;
|
||||||
|
desc->interp_align = align;
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,6 +67,8 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
int range_npages;
|
int range_npages;
|
||||||
void *up_v;
|
void *up_v;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
uintptr_t interp_obase = -1;
|
||||||
|
uintptr_t interp_nbase = -1;
|
||||||
|
|
||||||
sz = sizeof(struct program_load_desc)
|
sz = sizeof(struct program_load_desc)
|
||||||
+ sizeof(struct program_image_section) * 16;
|
+ sizeof(struct program_image_section) * 16;
|
||||||
@ -100,6 +102,8 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
proc->tid = pn->pid;
|
proc->tid = pn->pid;
|
||||||
proc->vm->region.user_start = pn->user_start;
|
proc->vm->region.user_start = pn->user_start;
|
||||||
proc->vm->region.user_end = pn->user_end;
|
proc->vm->region.user_end = pn->user_end;
|
||||||
|
proc->vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK;
|
||||||
|
proc->vm->region.map_end = proc->vm->region.map_start;
|
||||||
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
|
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
|
||||||
proc->rlimit_stack.rlim_max = pn->rlimit_stack_max;
|
proc->rlimit_stack.rlim_max = pn->rlimit_stack_max;
|
||||||
|
|
||||||
@ -107,6 +111,18 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
cpu_local_var(scp).post_idx = 0;
|
cpu_local_var(scp).post_idx = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
if (pn->sections[i].interp && (interp_nbase == (uintptr_t)-1)) {
|
||||||
|
interp_obase = pn->sections[i].vaddr;
|
||||||
|
interp_obase -= (interp_obase % pn->interp_align);
|
||||||
|
interp_nbase = proc->vm->region.map_start;
|
||||||
|
interp_nbase = (interp_nbase + pn->interp_align - 1)
|
||||||
|
& ~(pn->interp_align - 1);
|
||||||
|
}
|
||||||
|
if (pn->sections[i].interp) {
|
||||||
|
pn->sections[i].vaddr -= interp_obase;
|
||||||
|
pn->sections[i].vaddr += interp_nbase;
|
||||||
|
p->sections[i].vaddr = pn->sections[i].vaddr;
|
||||||
|
}
|
||||||
s = (pn->sections[i].vaddr) & PAGE_MASK;
|
s = (pn->sections[i].vaddr) & PAGE_MASK;
|
||||||
e = (pn->sections[i].vaddr + pn->sections[i].len
|
e = (pn->sections[i].vaddr + pn->sections[i].len
|
||||||
+ PAGE_SIZE - 1) & PAGE_MASK;
|
+ PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
@ -153,7 +169,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
|
|
||||||
/* TODO: Maybe we need flag */
|
/* TODO: Maybe we need flag */
|
||||||
if (pn->sections[i].interp) {
|
if (pn->sections[i].interp) {
|
||||||
/* nothing to do */
|
proc->vm->region.map_end = e;
|
||||||
}
|
}
|
||||||
else if (i == 0) {
|
else if (i == 0) {
|
||||||
proc->vm->region.text_start = s;
|
proc->vm->region.text_start = s;
|
||||||
@ -171,6 +187,13 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (interp_nbase != (uintptr_t)-1) {
|
||||||
|
pn->entry -= interp_obase;
|
||||||
|
pn->entry += interp_nbase;
|
||||||
|
p->entry = pn->entry;
|
||||||
|
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER, pn->entry);
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
/*
|
/*
|
||||||
Fix for the problem where brk grows to hit .bss section
|
Fix for the problem where brk grows to hit .bss section
|
||||||
@ -188,8 +211,6 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
proc->vm->region.brk_start = proc->vm->region.brk_end =
|
proc->vm->region.brk_start = proc->vm->region.brk_end =
|
||||||
proc->vm->region.data_end;
|
proc->vm->region.data_end;
|
||||||
#endif
|
#endif
|
||||||
proc->vm->region.map_start = proc->vm->region.map_end =
|
|
||||||
(USER_END / 3) & LARGE_PAGE_MASK;
|
|
||||||
|
|
||||||
/* Map system call stuffs */
|
/* Map system call stuffs */
|
||||||
flags = VR_RESERVED | VR_PROT_READ | VR_PROT_WRITE;
|
flags = VR_RESERVED | VR_PROT_READ | VR_PROT_WRITE;
|
||||||
|
|||||||
@ -122,6 +122,7 @@ struct program_load_desc {
|
|||||||
unsigned long envs_len;
|
unsigned long envs_len;
|
||||||
unsigned long rlimit_stack_cur;
|
unsigned long rlimit_stack_cur;
|
||||||
unsigned long rlimit_stack_max;
|
unsigned long rlimit_stack_max;
|
||||||
|
unsigned long interp_align;
|
||||||
struct program_image_section sections[0];
|
struct program_image_section sections[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user