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 entry @ 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 (GET_USE_COUNT(mp) != 0)
124 return -EBUSY;
125 if (mp->state == MOD_RUNNING)
126 (*mp->cleanup)();
127 mp->state = MOD_DELETED;
128 }
129 free_modules();
130 return 0;
131 }
132
133
134
135
136
137 asmlinkage int
138 sys_get_kernel_syms(struct kernel_sym *table)
139 {
140 struct symbol {
141 unsigned long addr;
142 char *name;
143 };
144 extern int symbol_table_size;
145 extern struct symbol symbol_table[];
146 int i;
147 struct symbol *from;
148 struct kernel_sym *to;
149 struct kernel_sym sym;
150
151 if (table != NULL) {
152 from = symbol_table;
153 to = table;
154 i = verify_area(VERIFY_WRITE, to, symbol_table_size * sizeof *table);
155 if (i)
156 return i;
157 for (i = symbol_table_size ; --i >= 0 ; ) {
158 sym.value = from->addr;
159 strncpy(sym.name, from->name, sizeof sym.name);
160 memcpy_tofs(to, &sym, sizeof sym);
161 from++, to++;
162 }
163 }
164 return symbol_table_size;
165 }
166
167
168
169
170
171 int
172 get_mod_name(char *user_name, char *buf)
173 {
174 int i;
175
176 i = 0;
177 for (i = 0 ; (buf[i] = get_fs_byte(user_name + i)) != '\0' ; ) {
178 if (++i >= MOD_MAX_NAME)
179 return -E2BIG;
180 }
181 return 0;
182 }
183
184
185
186
187
188 struct module *
189 find_module( const char *name)
190 {
191 struct module *mp;
192
193 for (mp = module_list ; mp ; mp = mp->next) {
194 if (mp->state == MOD_DELETED)
195 continue;
196 if (!strcmp(mp->name, name))
197 break;
198 }
199 return mp;
200 }
201
202
203
204
205
206
207 int
208 free_modules( void)
209 {
210 struct module *mp;
211 struct module **mpp;
212 int did_deletion;
213
214 did_deletion = 0;
215 freeing_modules = 0;
216 mpp = &module_list;
217 while ((mp = *mpp) != NULL) {
218 if (mp->state != MOD_DELETED) {
219 mpp = &mp->next;
220 } else if (GET_USE_COUNT(mp) != 0) {
221 freeing_modules = 1;
222 mpp = &mp->next;
223 } else {
224 *mpp = mp->next;
225 vfree(mp->addr);
226 kfree(mp->name);
227 kfree_s(mp, sizeof *mp);
228 did_deletion = 1;
229 }
230 }
231 return did_deletion;
232 }
233
234
235
236
237
238 int get_module_list(char *buf)
239 {
240 char *p;
241 char *q;
242 int i;
243 struct module *mp;
244 char size[32];
245
246 p = buf;
247 for (mp = module_list ; mp ; mp = mp->next) {
248 if (p - buf > 4096 - 100)
249 break;
250 q = mp->name;
251 i = 20;
252 while (*q) {
253 *p++ = *q++;
254 i--;
255 }
256 sprintf(size, "%d", mp->size);
257 i -= strlen(size);
258 if (i <= 0)
259 i = 1;
260 while (--i >= 0)
261 *p++ = ' ';
262 q = size;
263 while (*q)
264 *p++ = *q++;
265 if (mp->state == MOD_UNINITIALIZED)
266 q = " (uninitialized)";
267 else if (mp->state == MOD_RUNNING)
268 q = "";
269 else if (mp->state == MOD_DELETED)
270 q = " (deleted)";
271 else
272 q = " (bad state)";
273 while (*q)
274 *p++ = *q++;
275 *p++ = '\n';
276 }
277 return p - buf;
278 }