Back to home page

LXR

 
 

    


0001 /*
0002  *  linux/fs/binfmt_em86.c
0003  *
0004  *  Based on linux/fs/binfmt_script.c
0005  *  Copyright (C) 1996  Martin von Löwis
0006  *  original #!-checking implemented by tytso.
0007  *
0008  *  em86 changes Copyright (C) 1997  Jim Paradis
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/string.h>
0013 #include <linux/stat.h>
0014 #include <linux/binfmts.h>
0015 #include <linux/elf.h>
0016 #include <linux/init.h>
0017 #include <linux/fs.h>
0018 #include <linux/file.h>
0019 #include <linux/errno.h>
0020 
0021 
0022 #define EM86_INTERP "/usr/bin/em86"
0023 #define EM86_I_NAME "em86"
0024 
0025 static int load_em86(struct linux_binprm *bprm)
0026 {
0027     const char *i_name, *i_arg;
0028     char *interp;
0029     struct file * file;
0030     int retval;
0031     struct elfhdr   elf_ex;
0032 
0033     /* Make sure this is a Linux/Intel ELF executable... */
0034     elf_ex = *((struct elfhdr *)bprm->buf);
0035 
0036     if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
0037         return  -ENOEXEC;
0038 
0039     /* First of all, some simple consistency checks */
0040     if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) ||
0041         (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) ||
0042         !bprm->file->f_op->mmap) {
0043             return -ENOEXEC;
0044     }
0045 
0046     /* Need to be able to load the file after exec */
0047     if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
0048         return -ENOENT;
0049 
0050     allow_write_access(bprm->file);
0051     fput(bprm->file);
0052     bprm->file = NULL;
0053 
0054     /* Unlike in the script case, we don't have to do any hairy
0055      * parsing to find our interpreter... it's hardcoded!
0056      */
0057     interp = EM86_INTERP;
0058     i_name = EM86_I_NAME;
0059     i_arg = NULL;       /* We reserve the right to add an arg later */
0060 
0061     /*
0062      * Splice in (1) the interpreter's name for argv[0]
0063      *           (2) (optional) argument to interpreter
0064      *           (3) filename of emulated file (replace argv[0])
0065      *
0066      * This is done in reverse order, because of how the
0067      * user environment and arguments are stored.
0068      */
0069     remove_arg_zero(bprm);
0070     retval = copy_strings_kernel(1, &bprm->filename, bprm);
0071     if (retval < 0) return retval; 
0072     bprm->argc++;
0073     if (i_arg) {
0074         retval = copy_strings_kernel(1, &i_arg, bprm);
0075         if (retval < 0) return retval; 
0076         bprm->argc++;
0077     }
0078     retval = copy_strings_kernel(1, &i_name, bprm);
0079     if (retval < 0) return retval;
0080     bprm->argc++;
0081 
0082     /*
0083      * OK, now restart the process with the interpreter's inode.
0084      * Note that we use open_exec() as the name is now in kernel
0085      * space, and we don't need to copy it.
0086      */
0087     file = open_exec(interp);
0088     if (IS_ERR(file))
0089         return PTR_ERR(file);
0090 
0091     bprm->file = file;
0092 
0093     retval = prepare_binprm(bprm);
0094     if (retval < 0)
0095         return retval;
0096 
0097     return search_binary_handler(bprm);
0098 }
0099 
0100 static struct linux_binfmt em86_format = {
0101     .module     = THIS_MODULE,
0102     .load_binary    = load_em86,
0103 };
0104 
0105 static int __init init_em86_binfmt(void)
0106 {
0107     register_binfmt(&em86_format);
0108     return 0;
0109 }
0110 
0111 static void __exit exit_em86_binfmt(void)
0112 {
0113     unregister_binfmt(&em86_format);
0114 }
0115 
0116 core_initcall(init_em86_binfmt);
0117 module_exit(exit_em86_binfmt);
0118 MODULE_LICENSE("GPL");