This source file includes following definitions.
- sys_create_module
- sys_init_module
- sys_delete_module
- sys_get_kernel_syms
- get_mod_name
- find_module
- free_modules
- get_module_list
1 #include <linux/errno.h>
2 #include <linux/kernel.h>
3 #include <asm/segment.h>
4 #include <linux/mm.h>
5 #include <linux/string.h>
6 #include <linux/module.h>
7 #include <linux/sched.h>
8 #include <linux/malloc.h>
9
10 struct module *module_list = NULL;
11 int freeing_modules;
12
13 struct module *find_module( const char *name);
14 int get_mod_name( char *user_name, char *buf);
15 int free_modules( void);
16
17
18
19
20 asmlinkage int
21 sys_create_module(char *module_name, unsigned long size)
22 {
23 int npages;
24 void* addr;
25 int len;
26 char name[MOD_MAX_NAME];
27 char *savename;
28 struct module *mp;
29 int error;
30
31 if (!suser())
32 return -EPERM;
33 if (module_name == NULL || size == 0)
34 return -EINVAL;
35 if ((error = get_mod_name(module_name, name)) != 0)
36 return error;
37 if (find_module(name) != NULL) {
38 return -EEXIST;
39 }
40 len = strlen(name) + 1;
41 if ((savename = (char*) kmalloc(len, GFP_KERNEL)) == NULL)
42 return -ENOMEM;
43 memcpy(savename, name, len);
44 if ((mp = (struct module*) kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) {
45 kfree(savename);
46 return -ENOMEM;
47 }
48 npages = (size + sizeof (int) + 4095) / 4096;
49 if ((addr = vmalloc(npages * 4096)) == 0) {
50 kfree_s(mp, sizeof *mp);
51 kfree(savename);
52 return -ENOMEM;
53 }
54 mp->name = savename;
55 mp->size = npages;
56 mp->addr = addr;
57 mp->state = MOD_UNINITIALIZED;
58 * (int *) addr = 0;
59 mp->cleanup = NULL;
60 mp->next = module_list;
61 module_list = mp;
62 printk("module `%s' (%lu pages @ 0x%08lx) created\n",
63 mp->name, (unsigned long) mp->size, (unsigned long) mp->addr);
64 return (int) addr;
65 }
66
67
68
69
70 asmlinkage int
71 sys_init_module(char *module_name, char *code, unsigned codesize,
72 struct mod_routines *routines)
73 {
74 struct module *mp;
75 char name[MOD_MAX_NAME];
76 int error;
77 struct mod_routines rt;
78
79 if (!suser())
80 return -EPERM;
81
82
83
84
85
86 free_modules();
87
88 if ((error = get_mod_name(module_name, name)) != 0)
89 return error;
90 printk( "initializing module `%s', %d (0x%x) bytes\n",
91 name, codesize, codesize);
92 memcpy_fromfs(&rt, routines, sizeof rt);
93 if ((mp = find_module(name)) == NULL)
94 return -ENOENT;
95 if ((codesize + sizeof (int) + 4095) / 4096 > mp->size)
96 return -EINVAL;
97 memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize);
98 memset((char *)mp->addr + sizeof (int) + codesize, 0,
99 mp->size * 4096 - (codesize + sizeof (int)));
100 printk( " init enty @ 0x%08lx, cleanup entry @ 0x%08lx\n",
101 (unsigned long) rt.init, (unsigned long) rt.cleanup);
102 mp->cleanup = rt.cleanup;
103 if ((*rt.init)() != 0)
104 return -EBUSY;
105 mp->state = MOD_RUNNING;
106 return 0;
107 }
108
109 asmlinkage int
110 sys_delete_module(char *module_name)
111 {
112 struct module *mp;
113 char name[MOD_MAX_NAME];
114 int error;
115
116 if (!suser())
117 return -EPERM;
118 if (module_name != NULL) {
119 if ((error = get_mod_name(module_name, name)) != 0)
120 return error;
121 if ((mp = find_module(name)) == NULL)
122 return -ENOENT;
123 if (mp->state == MOD_RUNNING)
124 (*mp->cleanup)();
125 mp->state = MOD_DELETED;
126 }
127 free_modules();
128 return 0;
129 }
130
131
132
133
134
135 asmlinkage int
136 sys_get_kernel_syms(struct kernel_sym *table)
137 {
138 struct symbol {
139 unsigned long addr;
140 char *name;
141 };
142 extern int symbol_table_size;
143 extern struct symbol symbol_table[];
144 int i;
145 struct symbol *from;
146 struct kernel_sym *to;
147 struct kernel_sym sym;
148
149 if (table != NULL) {
150 from = symbol_table;
151 to = table;
152 verify_area(VERIFY_WRITE, to, symbol_table_size * sizeof *table);
153 for (i = symbol_table_size ; --i >= 0 ; ) {
154 sym.value = from->addr;
155 strncpy(sym.name, from->name, sizeof sym.name);
156 memcpy_tofs(to, &sym, sizeof sym);
157 from++, to++;
158 }
159 }
160 return symbol_table_size;
161 }
162
163
164
165
166
167 int
168 get_mod_name(char *user_name, char *buf)
169 {
170 int i;
171
172 i = 0;
173 for (i = 0 ; (buf[i] = get_fs_byte(user_name + i)) != '\0' ; ) {
174 if (++i >= MOD_MAX_NAME)
175 return -E2BIG;
176 }
177 return 0;
178 }
179
180
181
182
183
184 struct module *
185 find_module( const char *name)
186 {
187 struct module *mp;
188
189 for (mp = module_list ; mp ; mp = mp->next) {
190 if (mp->state == MOD_DELETED)
191 continue;
192 if (!strcmp(mp->name, name))
193 break;
194 }
195 return mp;
196 }
197
198
199
200
201
202
203 int
204 free_modules( void)
205 {
206 struct module *mp;
207 struct module **mpp;
208 int did_deletion;
209
210 did_deletion = 0;
211 freeing_modules = 0;
212 mpp = &module_list;
213 while ((mp = *mpp) != NULL) {
214 if (mp->state != MOD_DELETED) {
215 mpp = &mp->next;
216 } else if (GET_USE_COUNT(mp) != 0) {
217 freeing_modules = 1;
218 mpp = &mp->next;
219 } else {
220 *mpp = mp->next;
221 vfree(mp->addr);
222 kfree(mp->name);
223 kfree_s(mp, sizeof *mp);
224 did_deletion = 1;
225 }
226 }
227 return did_deletion;
228 }
229
230
231
232
233
234 int
235 get_module_list( char *buf)
236 {
237 char *p;
238 char *q;
239 int i;
240 struct module *mp;
241 char size[32];
242
243 p = buf;
244 for (mp = module_list ; mp ; mp = mp->next) {
245 if (p - buf > 4096 - 100)
246 break;
247 q = mp->name;
248 i = 20;
249 while (*q) {
250 *p++ = *q++;
251 i--;
252 }
253 sprintf(size, "%d", mp->size);
254 i -= strlen(size);
255 if (i <= 0)
256 i = 1;
257 while (--i >= 0)
258 *p++ = ' ';
259 q = size;
260 while (*q)
261 *p++ = *q++;
262 if (mp->state == MOD_UNINITIALIZED)
263 q = " (uninitialized)";
264 else if (mp->state == MOD_RUNNING)
265 q = "";
266 else if (mp->state == MOD_DELETED)
267 q = " (deleted)";
268 else
269 q = " (bad state)";
270 while (*q)
271 *p++ = *q++;
272 *p++ = '\n';
273 }
274 return p - buf;
275 }