1
2
3
4
5
6
7
8
9
10
11#include <linux/module.h>
12#include <linux/string.h>
13#include <linux/stat.h>
14#include <linux/malloc.h>
15#include <linux/binfmts.h>
16#include <linux/elf.h>
17#include <linux/init.h>
18
19
20#define EM86_INTERP "/usr/bin/em86"
21#define EM86_I_NAME "em86"
22
23static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
24{
25 char *interp, *i_name, *i_arg;
26 struct dentry * dentry;
27 int retval;
28 struct elfhdr elf_ex;
29
30
31 elf_ex = *((struct elfhdr *)bprm->buf);
32
33 if (elf_ex.e_ident[0] != 0x7f ||
34 strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
35 return -ENOEXEC;
36 }
37
38
39
40 if ((elf_ex.e_type != ET_EXEC &&
41 elf_ex.e_type != ET_DYN) ||
42 (!((elf_ex.e_machine == EM_386) || (elf_ex.e_machine == EM_486))) ||
43 (!bprm->dentry->d_inode->i_op || !bprm->dentry->d_inode->i_op->default_file_ops ||
44 !bprm->dentry->d_inode->i_op->default_file_ops->mmap)){
45 return -ENOEXEC;
46 }
47
48 bprm->sh_bang++;
49 dput(bprm->dentry);
50 bprm->dentry = NULL;
51
52
53
54
55 interp = EM86_INTERP;
56 i_name = EM86_I_NAME;
57 i_arg = NULL;
58
59
60
61
62
63
64
65
66
67 remove_arg_zero(bprm);
68 bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
69 bprm->argc++;
70 if (i_arg) {
71 bprm->p = copy_strings(1, &i_arg, bprm->page, bprm->p, 2);
72 bprm->argc++;
73 }
74 bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
75 bprm->argc++;
76 if ((long)bprm->p < 0)
77 return (long)bprm->p;
78
79
80
81
82
83 dentry = open_namei(interp, 0, 0);
84 if (IS_ERR(dentry))
85 return PTR_ERR(dentry);
86
87 bprm->dentry = dentry;
88
89 retval = prepare_binprm(bprm);
90 if (retval < 0)
91 return retval;
92
93 return search_binary_handler(bprm, regs);
94}
95
96struct linux_binfmt em86_format = {
97 module: THIS_MODULE,
98 load_binary: load_em86,
99};
100
101int __init init_em86_binfmt(void)
102{
103 return register_binfmt(&em86_format);
104}
105
106#ifdef MODULE
107int init_module(void)
108{
109 return init_em86_binfmt();
110}
111
112void cleanup_module( void) {
113 unregister_binfmt(&em86_format);
114}
115#endif
116