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