diff options
Diffstat (limited to 'fs/binfmt_em86.c')
-rw-r--r-- | fs/binfmt_em86.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c new file mode 100644 index 000000000000..1f2d1ad63319 --- /dev/null +++ b/fs/binfmt_em86.c | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * linux/fs/binfmt_em86.c | ||
3 | * | ||
4 | * Based on linux/fs/binfmt_script.c | ||
5 | * Copyright (C) 1996 Martin von Löwis | ||
6 | * original #!-checking implemented by tytso. | ||
7 | * | ||
8 | * em86 changes Copyright (C) 1997 Jim Paradis | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/stat.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/binfmts.h> | ||
17 | #include <linux/elf.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/fs.h> | ||
20 | #include <linux/file.h> | ||
21 | #include <linux/errno.h> | ||
22 | |||
23 | |||
24 | #define EM86_INTERP "/usr/bin/em86" | ||
25 | #define EM86_I_NAME "em86" | ||
26 | |||
27 | static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs) | ||
28 | { | ||
29 | char *interp, *i_name, *i_arg; | ||
30 | struct file * file; | ||
31 | int retval; | ||
32 | struct elfhdr elf_ex; | ||
33 | |||
34 | /* Make sure this is a Linux/Intel ELF executable... */ | ||
35 | elf_ex = *((struct elfhdr *)bprm->buf); | ||
36 | |||
37 | if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0) | ||
38 | return -ENOEXEC; | ||
39 | |||
40 | /* First of all, some simple consistency checks */ | ||
41 | if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || | ||
42 | (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) || | ||
43 | (!bprm->file->f_op || !bprm->file->f_op->mmap)) { | ||
44 | return -ENOEXEC; | ||
45 | } | ||
46 | |||
47 | bprm->sh_bang++; /* Well, the bang-shell is implicit... */ | ||
48 | allow_write_access(bprm->file); | ||
49 | fput(bprm->file); | ||
50 | bprm->file = NULL; | ||
51 | |||
52 | /* Unlike in the script case, we don't have to do any hairy | ||
53 | * parsing to find our interpreter... it's hardcoded! | ||
54 | */ | ||
55 | interp = EM86_INTERP; | ||
56 | i_name = EM86_I_NAME; | ||
57 | i_arg = NULL; /* We reserve the right to add an arg later */ | ||
58 | |||
59 | /* | ||
60 | * Splice in (1) the interpreter's name for argv[0] | ||
61 | * (2) (optional) argument to interpreter | ||
62 | * (3) filename of emulated file (replace argv[0]) | ||
63 | * | ||
64 | * This is done in reverse order, because of how the | ||
65 | * user environment and arguments are stored. | ||
66 | */ | ||
67 | remove_arg_zero(bprm); | ||
68 | retval = copy_strings_kernel(1, &bprm->filename, bprm); | ||
69 | if (retval < 0) return retval; | ||
70 | bprm->argc++; | ||
71 | if (i_arg) { | ||
72 | retval = copy_strings_kernel(1, &i_arg, bprm); | ||
73 | if (retval < 0) return retval; | ||
74 | bprm->argc++; | ||
75 | } | ||
76 | retval = copy_strings_kernel(1, &i_name, bprm); | ||
77 | if (retval < 0) return retval; | ||
78 | bprm->argc++; | ||
79 | |||
80 | /* | ||
81 | * OK, now restart the process with the interpreter's inode. | ||
82 | * Note that we use open_exec() as the name is now in kernel | ||
83 | * space, and we don't need to copy it. | ||
84 | */ | ||
85 | file = open_exec(interp); | ||
86 | if (IS_ERR(file)) | ||
87 | return PTR_ERR(file); | ||
88 | |||
89 | bprm->file = file; | ||
90 | |||
91 | retval = prepare_binprm(bprm); | ||
92 | if (retval < 0) | ||
93 | return retval; | ||
94 | |||
95 | return search_binary_handler(bprm, regs); | ||
96 | } | ||
97 | |||
98 | static struct linux_binfmt em86_format = { | ||
99 | .module = THIS_MODULE, | ||
100 | .load_binary = load_em86, | ||
101 | }; | ||
102 | |||
103 | static int __init init_em86_binfmt(void) | ||
104 | { | ||
105 | return register_binfmt(&em86_format); | ||
106 | } | ||
107 | |||
108 | static void __exit exit_em86_binfmt(void) | ||
109 | { | ||
110 | unregister_binfmt(&em86_format); | ||
111 | } | ||
112 | |||
113 | core_initcall(init_em86_binfmt); | ||
114 | module_exit(exit_em86_binfmt); | ||
115 | MODULE_LICENSE("GPL"); | ||