static int load_binary_file(struct linux_binprm *bprm, struct pt_regs *regs) #endif { int retval; struct file* file; /* Check file header information */ if(bprm->buf[1] != 'P' || bprm->buf[2] != 'N' || bprm->buf[3] != 'G') return -ENOEXEC; MSG("filename: %s\n", bprm->filename); MSG("interp: %s\n", bprm->interp); /* Release the image file */ fput(bprm->file); bprm->file = NULL; /* * Prepare the argv for exectable file * This is done in reverse order. */ retval = remove_arg_zero(bprm); if (retval < 0) return retval; // argv[2], image file path retval = copy_strings_kernel(1, &bprm->interp, bprm); if (retval < 0) return retval; bprm->argc++; // argv[1], execute args retval = copy_strings_kernel(1, &VIEWER_ARGS, bprm); if (retval < 0) return retval; bprm->argc++; // argv[0], exectable file path retval = copy_strings_kernel(1, &IMG_VIEWER, bprm); if (retval < 0) return retval; bprm->argc++; /* Change interpreter */ retval = bprm_change_interp(IMG_VIEWER, bprm); if (retval < 0) return retval; /* Open image viewer */ file = open_exec(IMG_VIEWER); if (IS_ERR(file)) return PTR_ERR(file); bprm->file = file; /* OK. restart the process with the viewer's dentry. */ retval = prepare_binprm(bprm); if(retval < 0) return retval; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) return search_binary_handler(bprm); #else return search_binary_handler(bprm, regs); #endif }
static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs) { char *cp, *interp, *i_name; int retval; if (strncmp (bprm->buf, "<!--applet", 10)) 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_BSHELL) * (2) the name of the appletviewer wrapper for argv[1] (_PATH_APPLET) * (3) filename of html file (replace argv[0]) * * This is done in reverse order, because of how the * user environment and arguments are stored. */ remove_arg_zero(bprm); i_name = bprm->filename; bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2); bprm->argc++; strcpy (bprm->buf, binfmt_java_appletviewer); 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); }
/* * the loader itself */ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) { struct binfmt_entry *fmt; struct file * file; char iname[BINPRM_BUF_SIZE]; char *iname_addr = iname; int retval; retval = -ENOEXEC; if (!enabled) goto _ret; /* to keep locking time low, we copy the interpreter string */ read_lock(&entries_lock); fmt = check_file(bprm); if (fmt) { strncpy(iname, fmt->interpreter, BINPRM_BUF_SIZE - 1); iname[BINPRM_BUF_SIZE - 1] = '\0'; } read_unlock(&entries_lock); if (!fmt) goto _ret; allow_write_access(bprm->file); fput(bprm->file); bprm->file = NULL; /* Build args for interpreter */ remove_arg_zero(bprm); retval = copy_strings_kernel(1, &bprm->filename, bprm); if (retval < 0) goto _ret; bprm->argc++; retval = copy_strings_kernel(1, &iname_addr, bprm); if (retval < 0) goto _ret; bprm->argc++; bprm->filename = iname; /* for binfmt_script */ file = open_exec(iname); retval = PTR_ERR(file); if (IS_ERR(file)) goto _ret; bprm->file = file; retval = prepare_binprm(bprm); if (retval >= 0) retval = search_binary_handler(bprm, regs); _ret: return retval; }
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); }
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); }