libexec: add load_offset feature, used for ld.so
. ld.so is linked at 0 but it can relocate itself; we wish to load ld.so higher though to trap NULL dereferences. if we know we have to execute ld.so, vfs tells libexec to put it higher.
This commit is contained in:
		
							parent
							
								
									ad898517ac
								
							
						
					
					
						commit
						31d8526346
					
				@ -159,11 +159,11 @@ int libexec_load_elf(struct exec_info *execi)
 | 
			
		||||
	if(execi->clearproc) execi->clearproc(execi);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < hdr->e_phnum; i++) {
 | 
			
		||||
		vir_bytes seg_membytes, page_offset, vaddr;
 | 
			
		||||
		vir_bytes seg_membytes, page_offset, p_vaddr, vaddr;
 | 
			
		||||
		vir_bytes chunk, vfileend, vmemend;
 | 
			
		||||
		Elf_Phdr *ph = &phdr[i];
 | 
			
		||||
		if (ph->p_type != PT_LOAD || ph->p_memsz == 0) continue;
 | 
			
		||||
		vaddr =  ph->p_vaddr;
 | 
			
		||||
		vaddr = p_vaddr = ph->p_vaddr + execi->load_offset;
 | 
			
		||||
		seg_membytes = ph->p_memsz;
 | 
			
		||||
		page_offset = vaddr % PAGE_SIZE;
 | 
			
		||||
		vaddr -= page_offset;
 | 
			
		||||
@ -183,19 +183,19 @@ int libexec_load_elf(struct exec_info *execi)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* Copy executable section into it */
 | 
			
		||||
		if(execi->copymem(execi, ph->p_offset, ph->p_vaddr, ph->p_filesz) != OK) {
 | 
			
		||||
		if(execi->copymem(execi, ph->p_offset, p_vaddr, ph->p_filesz) != OK) {
 | 
			
		||||
			if(execi->clearproc) execi->clearproc(execi);
 | 
			
		||||
			return ENOMEM;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if ELF_DEBUG
 | 
			
		||||
		printf("copied 0x%lx-0x%lx\n", ph->p_vaddr, ph->p_vaddr+ph->p_filesz);
 | 
			
		||||
		printf("copied 0x%lx-0x%lx\n", p_vaddr, p_vaddr+ph->p_filesz);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* Clear remaining bits */
 | 
			
		||||
		vfileend  = ph->p_vaddr + ph->p_filesz;
 | 
			
		||||
		vfileend  = p_vaddr + ph->p_filesz;
 | 
			
		||||
		vmemend = vaddr + seg_membytes;
 | 
			
		||||
		if((chunk = ph->p_vaddr - vaddr) > 0) {
 | 
			
		||||
		if((chunk = p_vaddr - vaddr) > 0) {
 | 
			
		||||
#if ELF_DEBUG
 | 
			
		||||
			printf("start clearing 0x%lx-0x%lx\n", vaddr, vaddr+chunk);
 | 
			
		||||
#endif
 | 
			
		||||
@ -220,7 +220,7 @@ int libexec_load_elf(struct exec_info *execi)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* record entry point and lowest load vaddr for caller */
 | 
			
		||||
	execi->pc = hdr->e_entry;
 | 
			
		||||
	execi->pc = hdr->e_entry + execi->load_offset;
 | 
			
		||||
	execi->load_base = startv;
 | 
			
		||||
 | 
			
		||||
	return OK;
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ struct exec_info {
 | 
			
		||||
    gid_t new_gid;                      /* Process GID after exec */
 | 
			
		||||
    int allow_setuid;                   /* Allow set{u,g}id execution? */
 | 
			
		||||
    vir_bytes stack_size;		/* Desired stack size */
 | 
			
		||||
    vir_bytes load_offset;		/* Desired load offset */
 | 
			
		||||
 | 
			
		||||
    /* Callback pointers for use by libexec */
 | 
			
		||||
    libexec_loadfunc_t copymem;		/* Copy callback */
 | 
			
		||||
 | 
			
		||||
@ -286,6 +286,11 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
 | 
			
		||||
		FAILCHECK(r);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* ld.so is linked at 0, but it can relocate itself; we
 | 
			
		||||
	 * want it higher to trap NULL pointer dereferences. 
 | 
			
		||||
	 */
 | 
			
		||||
	execi.args.load_offset = 0x10000;
 | 
			
		||||
 | 
			
		||||
	/* Remember it */
 | 
			
		||||
	strlcpy(execi.execname, finalexec, PATH_MAX);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user