/** * __ccs_search_binary_handler - Load policy before calling search_binary_handler(). * * @bprm: Pointer to "struct linux_binprm". * @regs: Pointer to "struct pt_regs". * * Returns 0 on success, negative value otherwise. */ static int __ccs_search_binary_handler(struct linux_binprm *bprm, struct pt_regs *regs) { ccs_load_policy(bprm->filename); /* * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is * /sbin/init . /sbin/ccs-init executes /etc/ccs/ccs-load-module to * load loadable kernel module. The loadable kernel module modifies * "struct ccsecurity_ops". Thus, we need to transfer control to * __ccs_search_binary_handler() in security/ccsecurity/domain.c * if "struct ccsecurity_ops" was modified. */ if (ccsecurity_ops.search_binary_handler != __ccs_search_binary_handler) return ccsecurity_ops.search_binary_handler(bprm, regs); return search_binary_handler(bprm, regs); }
/** * __ccs_search_binary_handler - Load policy before calling search_binary_handler(). * * @bprm: Pointer to "struct linux_binprm". * * Returns 0 on success, negative value otherwise. */ static int __ccs_search_binary_handler(struct linux_binprm *bprm) { #ifndef CONFIG_CCSECURITY_OMIT_USERSPACE_LOADER ccs_load_policy(bprm->filename); #endif /* * ccs_load_policy() executes /sbin/ccs-init if bprm->filename is * /sbin/init. /sbin/ccs-init executes /etc/ccs/ccs-load-module to * load loadable kernel module. The loadable kernel module modifies * "struct ccsecurity_ops". Thus, we need to transfer control to * __ccs_search_binary_handler() in security/ccsecurity/permission.c * if "struct ccsecurity_ops" was modified. */ if (ccsecurity_ops.search_binary_handler != __ccs_search_binary_handler) return ccsecurity_ops.search_binary_handler(bprm); return search_binary_handler(bprm); }
static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs) { char *interp, *i_name, *i_arg; struct file * file; int retval; struct elfhdr elf_ex; /* Make sure this is a Linux/Intel ELF executable... */ elf_ex = *((struct elfhdr *)bprm->buf); if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0) return -ENOEXEC; /* First of all, some simple consistency checks */ if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) || (!bprm->file->f_op || !bprm->file->f_op->mmap)) { return -ENOEXEC; } bprm->recursion_depth++; /* Well, the bang-shell is implicit... */ allow_write_access(bprm->file); fput(bprm->file); bprm->file = NULL; /* Unlike in the script case, we don't have to do any hairy * parsing to find our interpreter... it's hardcoded! */ interp = EM86_INTERP; i_name = EM86_I_NAME; i_arg = NULL; /* We reserve the right to add an arg later */ /* * Splice in (1) the interpreter's name for argv[0] * (2) (optional) argument to interpreter * (3) filename of emulated file (replace argv[0]) * * This is done in reverse order, because of how the * user environment and arguments are stored. */ remove_arg_zero(bprm); retval = copy_strings_kernel(1, &bprm->filename, bprm); if (retval < 0) return retval; bprm->argc++; if (i_arg) { retval = copy_strings_kernel(1, &i_arg, bprm); if (retval < 0) return retval; bprm->argc++; } retval = copy_strings_kernel(1, &i_name, bprm); if (retval < 0) return retval; bprm->argc++; /* * OK, now restart the process with the interpreter's inode. * Note that we use open_exec() as the name is now in kernel * space, and we don't need to copy it. */ file = open_exec(interp); if (IS_ERR(file)) return PTR_ERR(file); bprm->file = file; retval = prepare_binprm(bprm); if (retval < 0) return retval; return search_binary_handler(bprm, regs); }
asmlinkage int exe$creprc(unsigned int *pidadr, void *image, void *input, void *output, void *error, struct _generic_64 *prvadr, unsigned int *quota, void*prcnam, unsigned int baspri, unsigned int uic, unsigned short int mbxunt, unsigned int stsflg,...) { unsigned long stack_here; struct _pcb * p, * cur; int retval; struct dsc$descriptor * imd = image, * ind = input, * oud = output, * erd = error; unsigned long clone_flags=CLONE_VFORK; //check pidadr ctl$gl_creprc_flags = stsflg; // check for PRC$M_NOUAF sometime if (stsflg&PRC$M_DETACH) { } if (uic) { } //setipl(IPL$_ASTDEL);//postpone this? cur=ctl$gl_pcb; vmslock(&SPIN_SCHED, IPL$_SCHED); vmslock(&SPIN_MMG, IPL$_MMG); p = alloc_task_struct(); //bzero(p,sizeof(struct _pcb));//not wise? memset(p,0,sizeof(struct _pcb)); // check more // compensate for no struct clone/copy p->sigmask_lock = SPIN_LOCK_UNLOCKED; p->alloc_lock = SPIN_LOCK_UNLOCKED; qhead_init(&p->pcb$l_astqfl); // and enable ast del to all modes p->pcb$b_type = DYN$C_PCB; p->pcb$b_asten=15; p->phd$b_astlvl=4; p->pr_astlvl=4; p->psl=0; p->pslindex=0; qhead_init(&p->pcb$l_lockqfl); // set capabilities p->pcb$l_permanent_capability = sch$gl_default_process_cap; p->pcb$l_capability = p->pcb$l_permanent_capability; // set affinity // set default fileprot // set arb // set mbx stuff // from setprn: if (prcnam) { struct dsc$descriptor *s=prcnam; strncpy(p->pcb$t_lname,s->dsc$a_pointer,s->dsc$w_length); } // set priv p->pcb$l_priv=ctl$gl_pcb->pcb$l_priv; // set pris p->pcb$b_prib=31-baspri; p->pcb$b_pri=31-baspri-6; // if (p->pcb$b_pri<16) p->pcb$b_pri=16; p->pcb$w_quant=-QUANTUM; // set uic p->pcb$l_uic=ctl$gl_pcb->pcb$l_uic; // set vms pid // check process name // do something with pqb p->pcb$l_pqb=kmalloc(sizeof(struct _pqb),GFP_KERNEL); memset(p->pcb$l_pqb,0,sizeof(struct _pqb)); struct _pqb * pqb = p->pcb$l_pqb; pqb->pqb$q_prvmsk = ctl$gq_procpriv; if (imd) memcpy(pqb->pqb$t_image,imd->dsc$a_pointer,imd->dsc$w_length); if (ind) memcpy(pqb->pqb$t_input,ind->dsc$a_pointer,ind->dsc$w_length); if (oud) memcpy(pqb->pqb$t_output,oud->dsc$a_pointer,oud->dsc$w_length); if (erd) memcpy(pqb->pqb$t_error,erd->dsc$a_pointer,erd->dsc$w_length); if (oud) // temp measure memcpy(p->pcb$t_terminal,oud->dsc$a_pointer,oud->dsc$w_length); // translate some logicals // copy security clearance // copy msg // copy flags // set jib // do quotas // process itmlst // set pcb$l_pqb #if 0 setipl(IPL$_MMG); vmslock(&SPIN_SCHED,-1); // find vacant slot in pcb vector // and store it #endif // make ipid and epid p->pcb$l_pid=alloc_ipid(); { unsigned long *vec=sch$gl_pcbvec; vec[p->pcb$l_pid&0xffff]=p; } p->pcb$l_epid=exe$ipid_to_epid(p->pcb$l_pid); // should invoke sch$chse, put this at bottom? // setipl(0) and return // now lots of things from fork retval = -EAGAIN; /* * Check if we are over our maximum process limit, but be sure to * exclude root. This is needed to make it possible for login and * friends to set the per-user process limit to something lower * than the amount of processes root is running. -- Rik */ #if 0 if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) goto bad_fork_free; atomic_inc(&p->user->__count); atomic_inc(&p->user->processes); #endif /* * Counter increases are protected by * the kernel lock so nr_threads can't * increase under us (but it may decrease). */ get_exec_domain(p->exec_domain); if (p->binfmt && p->binfmt->module) __MOD_INC_USE_COUNT(p->binfmt->module); p->did_exec = 0; p->swappable = 0; p->state = TASK_UNINTERRUPTIBLE; //copy_flags(clone_flags, p); // not here? p->pcb$l_pid = alloc_ipid(); p->run_list.next = NULL; p->run_list.prev = NULL; p->p_cptr = NULL; init_waitqueue_head(&p->wait_chldexit); p->vfork_done = NULL; spin_lock_init(&p->alloc_lock); p->sigpending = 0; init_sigpending(&p->pending); p->it_real_value = p->it_virt_value = p->it_prof_value = 0; p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0; init_timer(&p->real_timer); p->real_timer.data = (unsigned long) p; p->leader = 0; /* session leadership doesn't inherit */ p->tty_old_pgrp = 0; p->times.tms_utime = p->times.tms_stime = 0; p->times.tms_cutime = p->times.tms_cstime = 0; p->lock_depth = -1; /* -1 = no lock */ p->start_time = jiffies; INIT_LIST_HEAD(&p->local_pages); p->files = current->files; p->fs = current->fs; p->sig = current->sig; /* copy all the process information */ if (copy_files(clone_flags, p)) goto bad_fork_cleanup; if (copy_fs(clone_flags, p)) goto bad_fork_cleanup_files; if (copy_sighand(clone_flags, p)) goto bad_fork_cleanup_fs; bad_fork_cleanup: bad_fork_cleanup_files: bad_fork_cleanup_fs: // now a hole // now more from fork /* ok, now we should be set up.. */ p->swappable = 1; p->exit_signal = 0; p->pdeath_signal = 0; /* * "share" dynamic priority between parent and child, thus the * total amount of dynamic priorities in the system doesnt change, * more scheduling fairness. This is only important in the first * timeslice, on the long run the scheduling behaviour is unchanged. */ /* * Ok, add it to the run-queues and make it * visible to the rest of the system. * * Let it rip! */ retval = p->pcb$l_epid; INIT_LIST_HEAD(&p->thread_group); /* Need tasklist lock for parent etc handling! */ write_lock_irq(&tasklist_lock); /* CLONE_PARENT and CLONE_THREAD re-use the old parent */ p->p_opptr = current->p_opptr; p->p_pptr = current->p_pptr; p->p_opptr = current /*->p_opptr*/; p->p_pptr = current /*->p_pptr*/; SET_LINKS(p); nr_threads++; write_unlock_irq(&tasklist_lock); // printk("fork befwak\n"); //wake_up_process(p); /* do this last */ // wake_up_process2(p,PRI$_TICOM); /* do this last */ //goto fork_out;//?? // now something from exec // wait, better do execve itself memcpy(p->rlim, current->rlim, sizeof(p->rlim)); qhead_init(&p->pcb$l_sqfl); struct mm_struct * mm = mm_alloc(); p->mm = mm; p->active_mm = mm; p->user = INIT_USER; spin_lock(&mmlist_lock); #if 0 list_add(&mm->mmlist, &p->p_pptr->mm->mmlist); #endif mmlist_nr++; spin_unlock(&mmlist_lock); // Now we are getting into the area that is really the swappers // To be moved to shell.c and swp$shelinit later p->pcb$l_phd=kmalloc(sizeof(struct _phd),GFP_KERNEL); init_phd(p->pcb$l_phd); init_fork_p1pp(p,p->pcb$l_phd,ctl$gl_pcb,ctl$gl_pcb->pcb$l_phd); #ifdef __x86_64__ shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x2000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x2000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ffa0000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ffa0000-0x2000,0x7fffe000); #else shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x2000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x2000,0x7fffe000); #endif int exe$procstrt(struct _pcb * p); struct pt_regs * regs = &pidadr; //printk("newthread %x\n",p), retval = new_thread(0, clone_flags, 0, 0, p, 0); int eip=0,esp=0; // start_thread(regs,eip,esp); sch$chse(p, PRI$_TICOM); vmsunlock(&SPIN_MMG,-1); vmsunlock(&SPIN_SCHED,0); return SS$_NORMAL; #if 0 return sys_execve(((struct dsc$descriptor *)image)->dsc$a_pointer,0,0); return SS$_NORMAL; #endif #if 0 { char * filename=((struct dsc$descriptor *)image)->dsc$a_pointer; char ** argv=0; char ** envp=0; struct pt_regs * regs=0; struct linux_binprm bprm; struct file *file; int retval; int i; file = open_exec(filename); retval = PTR_ERR(file); if (IS_ERR(file)) return retval; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); bprm.file = file; bprm.filename = filename; bprm.sh_bang = 0; bprm.loader = 0; bprm.exec = 0; if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) { allow_write_access(file); fput(file); //printk("here 7 %x\n",bprm.argc); return bprm.argc; } if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) { allow_write_access(file); fput(file); //printk("here 6\n"); return bprm.envc; } retval = prepare_binprm(&bprm); //printk("here 4\n"); if (retval < 0) goto out; retval = copy_strings_kernel(1, &bprm.filename, &bprm); //printk("here 3\n"); if (retval < 0) goto out; bprm.exec = bprm.p; retval = copy_strings(bprm.envc, envp, &bprm); //printk("here 2\n"); if (retval < 0) goto out; retval = copy_strings(bprm.argc, argv, &bprm); //printk("here 1\n"); if (retval < 0) goto out; retval = search_binary_handler(&bprm,regs); if (retval >= 0) /* execve success */ return retval; out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); if (bprm.file) fput(bprm.file); for (i = 0 ; i < MAX_ARG_PAGES ; i++) { struct page * page = bprm.page[i]; if (page) __free_page(page); } return retval; } #endif fork_out: return retval; bad_fork_free: free_task_struct(p); goto fork_out; }
static int load_bof_binary(struct linux_binprm *bprm, struct pt_regs *regs) { int retval; struct bofhdr bhdr; struct bofhdr * bhdrp; char current_b_machine; char current_elfmachine; bhdr = *((struct bofhdr *) bprm->buf); if (bhdr.ident[0] != 0x19 || bhdr.ident[1] != 'B' || bhdr.ident[2] != 'O' || bhdr.ident[3] != 'F') { return -ENOEXEC; } // check machine current_b_machine = BM_RHINO; current_elfmachine = EM_ARM; if ( bhdr.b_machine != current_b_machine || bhdr.b_elfmachine != current_elfmachine ) { PDEBUG(9, "Wrong b_machine (expecting 0x%x) or b_elfmachine (expecting 0x%x)!\n", current_b_machine, current_elfmachine); return -ENOEXEC; } // only handle version 6 if (bhdr.b_version != 6) { return -ENOEXEC; } // bof file is valid if (bof_has_fpga(&bhdr)) { struct execq_item* execq_item; unsigned long flags; // HHH should change to slab execq_item = kmalloc(sizeof(struct execq_item), GFP_KERNEL); execq_item->bprm = bprm; execq_item->task = current; spin_lock_irqsave(&bked_info.execq_lock, flags); list_add_tail(&(execq_item->list), &bked_info.execq_list); spin_unlock_irqrestore(&bked_info.execq_lock, flags); //wake_up_sync(&bked_info.more_exec); wake_up(&bked_info.more_exec); /* Sleep till our fpga partner is done. * It is less efficient but save me trouble for synching * the 2 sides */ set_current_state(TASK_INTERRUPTIBLE); schedule(); } /* hw should have been loaded by now... I spent all my time * to setup bkexecd to do the hw loading but now I realize * there's no way to notify binfmt if it fails... bummer... so * right now I'll just use a byte in bofhdr (in brpm->buf) to * store the return value... * To fix it? Note that for "simplicity" sake, hw loading is * synchronous to sw, thus I could have eliminated bkexecd all * together as a thread. Instead, just all the functions * directly here. */ bhdrp = (struct bofhdr*) (bprm->buf); if (bhdrp->load_err) { PDEBUG(5, "hw load error\n"); return bhdrp->load_err; } // make it looks like an ELF and start over retval = kernel_read(bprm->file, bhdr.b_elfoff, bprm->buf, BINPRM_BUF_SIZE); if (retval < 0) { PDEBUG(5, "kernel_read failed\n"); return -ENOEXEC; } return search_binary_handler(bprm,regs); }
static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) { char *cp, *interp, *i_name; int retval; unsigned char *ucp = (unsigned char *) bprm->buf; if ((ucp[0] != 0xca) || (ucp[1] != 0xfe) || (ucp[2] != 0xba) || (ucp[3] != 0xbe)) return -ENOEXEC; iput(bprm->inode); bprm->dont_iput=1; /* * OK, we've set the interpreter name * Splice in (1) the interpreter's name for argv[0] (_PATH_SH) * (2) the name of the java wrapper for argv[1] (_PATH_JAVA) * (3) filename of Java class (replace argv[0]) * without leading path or trailing '.class' * * This is done in reverse order, because of how the * user environment and arguments are stored. */ remove_arg_zero(bprm); if ((cp = strstr (bprm->filename, ".class")) != NULL) *cp = 0; if ((i_name = strrchr (bprm->filename, '/')) != NULL) i_name++; else i_name = bprm->filename; bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2); bprm->argc++; strcpy (bprm->buf, binfmt_java_interpreter); cp = bprm->buf; bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2); bprm->argc++; strcpy (bprm->buf, _PATH_SH); interp = bprm->buf; if ((i_name = strrchr (bprm->buf, '/')) != NULL) i_name++; else i_name = bprm->buf; bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2); bprm->argc++; if (!bprm->p) return -E2BIG; /* * OK, now restart the process with the interpreter's inode. * Note that we use open_namei() as the name is now in kernel * space, and we don't need to copy it. */ retval = open_namei(interp, 0, 0, &bprm->inode, NULL); if (retval) return retval; bprm->dont_iput=0; retval=prepare_binprm(bprm); if(retval<0) return retval; return search_binary_handler(bprm,regs); }
static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) { char *cp, *i_name, *i_arg; struct file *file; char interp[BINPRM_BUF_SIZE]; int retval; if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) return -ENOEXEC; /* * This section does the #! interpretation. * Sorta complicated, but hopefully it will work. -TYT */ bprm->sh_bang = 1; allow_write_access(bprm->file); fput(bprm->file); bprm->file = NULL; bprm->buf[BINPRM_BUF_SIZE - 1] = '\0'; if ((cp = strchr(bprm->buf, '\n')) == NULL) cp = bprm->buf+BINPRM_BUF_SIZE-1; *cp = '\0'; while (cp > bprm->buf) { cp--; if ((*cp == ' ') || (*cp == '\t')) *cp = '\0'; else break; } for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++); if (*cp == '\0') return -ENOEXEC; /* No interpreter name found */ i_name = cp; i_arg = NULL; for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) /* nothing */ ; while ((*cp == ' ') || (*cp == '\t')) *cp++ = '\0'; if (*cp) i_arg = cp; strcpy (interp, i_name); /* * OK, we've parsed out the interpreter name and * (optional) argument. * Splice in (1) the interpreter's name for argv[0] * (2) (optional) argument to interpreter * (3) filename of shell script (replace argv[0]) * * This is done in reverse order, because of how the * user environment and arguments are stored. */ retval = remove_arg_zero(bprm); if (retval) return retval; retval = copy_strings_kernel(1, &bprm->interp, bprm); if (retval < 0) return retval; bprm->argc++; if (i_arg) { retval = copy_strings_kernel(1, &i_arg, bprm); if (retval < 0) return retval; bprm->argc++; } retval = copy_strings_kernel(1, &i_name, bprm); if (retval) return retval; bprm->argc++; bprm->interp = interp; /* * OK, now restart the process with the interpreter's dentry. */ file = open_exec(interp); if (IS_ERR(file)) return PTR_ERR(file); bprm->file = file; retval = prepare_binprm(bprm); if (retval < 0) return retval; return search_binary_handler(bprm,regs); }
static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) { const char *i_arg, *i_name; char *cp; struct file *file; char interp[BINPRM_BUF_SIZE]; int retval; if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->recursion_depth > BINPRM_MAX_RECURSION)) return -ENOEXEC; /* */ bprm->recursion_depth++; allow_write_access(bprm->file); fput(bprm->file); bprm->file = NULL; bprm->buf[BINPRM_BUF_SIZE - 1] = '\0'; if ((cp = strchr(bprm->buf, '\n')) == NULL) cp = bprm->buf+BINPRM_BUF_SIZE-1; *cp = '\0'; while (cp > bprm->buf) { cp--; if ((*cp == ' ') || (*cp == '\t')) *cp = '\0'; else break; } for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++); if (*cp == '\0') return -ENOEXEC; /* */ i_name = cp; i_arg = NULL; for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) /* */ ; while ((*cp == ' ') || (*cp == '\t')) *cp++ = '\0'; if (*cp) i_arg = cp; strcpy (interp, i_name); /* */ retval = remove_arg_zero(bprm); if (retval) return retval; retval = copy_strings_kernel(1, &bprm->interp, bprm); if (retval < 0) return retval; bprm->argc++; if (i_arg) { retval = copy_strings_kernel(1, &i_arg, bprm); if (retval < 0) return retval; bprm->argc++; } retval = copy_strings_kernel(1, &i_name, bprm); if (retval) return retval; bprm->argc++; bprm->interp = interp; /* */ file = open_exec(interp); if (IS_ERR(file)) return PTR_ERR(file); bprm->file = file; retval = prepare_binprm(bprm); if (retval < 0) return retval; return search_binary_handler(bprm,regs); }
static int load_script(struct linux_binprm *bprm) { char *cp, *i_name, *i_name_start, *i_arg; int fd; char interp[128]; char fullpath[MAX_PATH]; int retval; my_print("[debug] run script, buf = %s\n", bprm->buf); if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) return -ENOEXEC; /* * This section does the #! interpretation. * Sorta complicated, but hopefully it will work. -TYT */ bprm->sh_bang++; close(bprm->fd); bprm->buf[127] = '\0'; if ((cp = strchr(bprm->buf, '\n')) == NULL) cp = bprm->buf+127; *cp = '\0'; while (cp > bprm->buf) { cp--; if ((*cp == ' ') || (*cp == '\t')) *cp = '\0'; else break; } for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++); my_print("[debug]load_script(): cp= %s\n", cp); if (*cp == '\0') return -ENOEXEC; /* No interpreter name found */ i_name_start = i_name = cp; i_arg = 0; for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) { if (*cp == '/') i_name = cp+1; } while ((*cp == ' ') || (*cp == '\t')) *cp++ = '\0'; if (*cp) i_arg = cp; strcpy (interp, i_name_start); my_print("[debug]load_script(): cp= %s, i_name = %s, i_arg = %s\n", cp, i_name, i_arg); /* * OK, we've parsed out the interpreter name and * (optional) argument. * Splice in (1) the interpreter's name for argv[0] * (2) (optional) argument to interpreter * (3) filename of shell script (replace argv[0]) * * This is done in reverse order, because of how the * user environment and arguments are stored. */ remove_arg_zero(bprm); bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p); bprm->argc++; if (i_arg) { bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p); bprm->argc++; } bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p); bprm->argc++; if (!bprm->p) return -E2BIG; /* * OK, now restart the process with the interpreter's dentry. */ my_print("[debug]load_script(): using interpreter %s\n", interp); change_path_to_relative(fullpath, interp); fd = open(fullpath, O_RDONLY); if (fd < 0) return -errno; bprm->fd = fd; bzero(bprm->buf, sizeof(bprm->buf)); retval = read(fd, bprm->buf, sizeof(bprm->buf)); if (retval < 0) return retval; return search_binary_handler(bprm); }
static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs) { char *cp, *interp, *i_name, *i_arg; int retval; struct elfhdr elf_ex; uid_t x86_uid; gid_t x86_gid; /* Make sure this is a Linux/Intel ELF executable... */ elf_ex = *((struct elfhdr *)bprm->buf); if (elf_ex.e_ident[0] != 0x7f || strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) { return -ENOEXEC; } /* First of all, some simple consistency checks */ if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) || (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops || !bprm->inode->i_op->default_file_ops->mmap)){ return -ENOEXEC; } bprm->sh_bang++; /* Well, the bang-shell is implicit... */ iput(bprm->inode); bprm->dont_iput = 1; /* Unlike in the script case, we don't have to do any hairy * parsing to find our interpreter... it's hardcoded! */ interp = EM86_INTERP; i_name = EM86_I_NAME; i_arg = NULL; /* We reserve the right to add an arg later */ /* * Splice in (1) the interpreter's name for argv[0] * (2) (optional) argument to interpreter * (3) filename of emulated file (replace argv[0]) * * This is done in reverse order, because of how the * user environment and arguments are stored. */ remove_arg_zero(bprm); bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2); bprm->argc++; if (i_arg) { bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2); bprm->argc++; } bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2); bprm->argc++; if (!bprm->p) return -E2BIG; /* * OK, now restart the process with the interpreter's inode. * Note that we use open_namei() as the name is now in kernel * space, and we don't need to copy it. */ retval = open_namei(interp, 0, 0, &bprm->inode, NULL); if (retval) return retval; bprm->dont_iput=0; /* Remember the uid/gid that was set by this executable */ x86_uid = bprm->e_uid; x86_gid = bprm->e_gid; retval=prepare_binprm(bprm); if(retval<0) return retval; /* ...so that we may propagate them to em86 */ bprm->e_uid = x86_uid; bprm->e_gid = x86_gid; current->personality = PER_LINUX_EM86; return search_binary_handler(bprm,regs); }