]> Zhao Yanbai Git Server - minix.git/commitdiff
libexec: add load_offset feature, used for ld.so
authorBen Gras <ben@minix3.org>
Fri, 10 Aug 2012 16:27:23 +0000 (18:27 +0200)
committerBen Gras <ben@minix3.org>
Sun, 12 Aug 2012 21:22:54 +0000 (23:22 +0200)
. 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.

lib/libexec/exec_elf.c
lib/libexec/libexec.h
servers/vfs/exec.c

index 3fc9f71c64286da84a72fb401b7b98c8e7dc0332..ab451a9808ef808054e3c320b705137f2e064fc1 100644 (file)
@@ -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;
index 5169c4b21434a680145e601e96bfc0d97fa889f8..69da9cb298bfe275bc8d2fc7729b67fd387dd63f 100644 (file)
@@ -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 */
index 2f6acb82ebc49e28148c7cbfabd9253694bd0047..cf49447bf1716d24912a2d60c32d9cbe3f9546ab 100644 (file)
@@ -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);