execi.stack_size = 32 * 1024; /* not too crazy as it must be preallocated */
execi.proc_e = ip->endpoint;
execi.hdr = (char *) mod->mod_start; /* phys mem direct */
- execi.hdr_len = mod->mod_end - mod->mod_start;
+ execi.filesize = execi.hdr_len = mod->mod_end - mod->mod_start;
strcpy(execi.progname, ip->proc_name);
execi.frame_len = 0;
execi.stack_size = 16 * 1024; /* not too crazy as it must be preallocated */
execi.proc_e = ip->endpoint;
execi.hdr = (char *) mod->mod_start; /* phys mem direct */
- execi.hdr_len = mod->mod_end - mod->mod_start;
+ execi.filesize = execi.hdr_len = mod->mod_end - mod->mod_start;
strlcpy(execi.progname, ip->proc_name, sizeof(execi.progname));
execi.frame_len = 0;
assert(execi->allocmem_prealloc);
assert(execi->allocmem_ondemand);
+ for (i = 0; i < hdr->e_phnum; i++) {
+ Elf_Phdr *ph = &phdr[i];
+ off_t file_limit = ph->p_offset + ph->p_filesz;
+ /* sanity check binary before wiping out the target process */
+ if(execi->filesize < file_limit) {
+ return ENOEXEC;
+ }
+ }
+
if(execi->clearproc) execi->clearproc(execi);
for (i = 0; i < hdr->e_phnum; i++) {
int allow_setuid; /* Allow set{u,g}id execution? */
vir_bytes stack_size; /* Desired stack size */
vir_bytes load_offset; /* Desired load offset */
+ off_t filesize; /* How big is the file */
/* Callback pointers for use by libexec */
libexec_loadfunc_t copymem; /* Copy callback */
execi.stack_size = DEFAULT_STACK_LIMIT;
execi.proc_e = proc_e;
execi.hdr = exec;
- execi.hdr_len = exec_len;
+ execi.filesize = execi.hdr_len = exec_len;
strncpy(execi.progname, progname, PROC_NAME_LEN-1);
execi.progname[PROC_NAME_LEN-1] = '\0';
execi.frame_len = frame_len;
execi.args.proc_e = proc_e;
execi.args.frame_len = frame_len;
+ execi.args.filesize = execi.vp->v_size;
for (i = 0; exec_loaders[i].load_object != NULL; i++) {
r = (*exec_loaders[i].load_object)(&execi.args);
strlcpy(execi->progname, ip->proc_name, sizeof(execi->progname));
execi->frame_len = 0;
execi->opaque = &vmexeci;
+ execi->filesize = ip->len;
vmexeci.ip = ip;
vmexeci.vmp = vmp;
if ((pid = fork()) != 0) {
wait(&n); /* wait for some child (any one) */
} else {
- execl(name[n], name[n], (char *) 0);
+ /* a successful exec or a successful detection of a broken executable
+ * is ok
+ */
+ if(execl(name[n], name[n], (char *) 0) < 0 && errno == ENOEXEC)
+ exit(0);
errct++;
printf("Child execl didn't take. file=%s errno=%d\n", name[n], errno);
rmfiles();