Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /*
* linux/fs/binfmt_em86.c
*
* Based on linux/fs/binfmt_script.c
* Copyright (C) 1996 Martin von Löwis
* original #!-checking implemented by tytso.
*
* em86 changes Copyright (C) 1997 Jim Paradis
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/malloc.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#define EM86_INTERP "/usr/bin/em86"
#define EM86_I_NAME "em86"
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 ((long)bprm->p < 0)
return (long)bprm->p;
/*
* 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);
}
static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
{
int retval;
MOD_INC_USE_COUNT;
retval = do_load_em86(bprm,regs);
MOD_DEC_USE_COUNT;
return retval;
}
struct linux_binfmt em86_format = {
#ifndef MODULE
NULL, 0, load_em86, NULL, NULL
#else
NULL, &mod_use_count_, load_em86, NULL, NULL
#endif
};
int init_em86_binfmt(void) {
return register_binfmt(&em86_format);
}
#ifdef MODULE
int init_module(void)
{
return init_em86_binfmt();
}
void cleanup_module( void) {
unregister_binfmt(&em86_format);
}
#endif
|