This source file includes following definitions.
- init_modules
- rename_module_symbol
- sys_create_module
- sys_init_module
- sys_delete_module
- sys_get_kernel_syms
- get_mod_name
- find_module
- drop_refs
- free_modules
- get_module_list
- get_ksyms_list
- register_symtab
- sys_create_module
- sys_init_module
- sys_delete_module
- sys_get_kernel_syms
- register_symtab
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 #include <linux/config.h>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 #ifdef CONFIG_MODULES
48
49 #ifdef DEBUG_MODULE
50 #define PRINTK(a) printk a
51 #else
52 #define PRINTK(a)
53 #endif
54
55 static struct module kernel_module;
56 static struct module *module_list = &kernel_module;
57
58 static int freeing_modules;
59
60 static struct module *find_module( const char *name);
61 static int get_mod_name( char *user_name, char *buf);
62 static int free_modules( void);
63
64 static int module_init_flag = 0;
65
66 extern struct symbol_table symbol_table;
67
68
69
70
71 void init_modules(void) {
72 struct internal_symbol *sym;
73 int i;
74
75 for (i = 0, sym = symbol_table.symbol; sym->name; ++sym, ++i)
76 ;
77 symbol_table.n_symbols = i;
78
79 kernel_module.symtab = &symbol_table;
80 kernel_module.state = MOD_RUNNING;
81 kernel_module.name = "";
82 }
83
84 int
85 rename_module_symbol(char *old_name, char *new_name)
86 {
87 struct internal_symbol *sym;
88 int i = 0;
89
90 if (module_list->symtab) {
91 sym = module_list->symtab->symbol;
92 for (i = module_list->symtab->n_symbols; i > 0; ++sym, --i) {
93 if (strcmp(sym->name, old_name) == 0) {
94 sym->name = new_name;
95 PRINTK(("renamed %s to %s\n", old_name, new_name));
96 return 1;
97 }
98 }
99 }
100 printk("rename %s to %s failed!\n", old_name, new_name);
101 return 0;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 }
139
140
141
142
143 asmlinkage unsigned long
144 sys_create_module(char *module_name, unsigned long size)
145 {
146 struct module *mp;
147 void* addr;
148 int error;
149 int npages;
150 int sspace = sizeof(struct module) + MOD_MAX_NAME;
151 char name[MOD_MAX_NAME];
152
153 if (!suser())
154 return -EPERM;
155 if (module_name == NULL || size == 0)
156 return -EINVAL;
157 if ((error = get_mod_name(module_name, name)) != 0)
158 return error;
159 if (find_module(name) != NULL) {
160 return -EEXIST;
161 }
162
163 if ((mp = (struct module*) kmalloc(sspace, GFP_KERNEL)) == NULL) {
164 return -ENOMEM;
165 }
166 strcpy((char *)(mp + 1), name);
167
168 npages = (size + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE;
169 if ((addr = vmalloc(npages * PAGE_SIZE)) == 0) {
170 kfree_s(mp, sspace);
171 return -ENOMEM;
172 }
173
174 mp->next = module_list;
175 mp->ref = NULL;
176 mp->symtab = NULL;
177 mp->name = (char *)(mp + 1);
178 mp->size = npages;
179 mp->addr = addr;
180 mp->state = MOD_UNINITIALIZED;
181 mp->cleanup = NULL;
182
183 * (long *) addr = 0;
184 module_list = mp;
185
186 PRINTK(("module `%s' (%lu pages @ 0x%08lx) created\n",
187 mp->name, (unsigned long) mp->size, (unsigned long) mp->addr));
188 return (unsigned long) addr;
189 }
190
191
192
193
194 asmlinkage int
195 sys_init_module(char *module_name, char *code, unsigned codesize,
196 struct mod_routines *routines,
197 struct symbol_table *symtab)
198 {
199 struct module *mp;
200 struct symbol_table *newtab;
201 char name[MOD_MAX_NAME];
202 int error;
203 struct mod_routines rt;
204
205 if (!suser())
206 return -EPERM;
207
208 #ifdef __i386__
209
210
211 if (symtab && ((unsigned long)symtab > 0xb0000000)) {
212 printk("warning: you are using an old insmod, no symbols will be inserted!\n");
213 symtab = NULL;
214 }
215 #endif
216
217
218
219
220
221
222 free_modules();
223
224 if ((error = get_mod_name(module_name, name)) != 0)
225 return error;
226 PRINTK(("initializing module `%s', %d (0x%x) bytes\n",
227 name, codesize, codesize));
228 memcpy_fromfs(&rt, routines, sizeof rt);
229 if ((mp = find_module(name)) == NULL)
230 return -ENOENT;
231 if (codesize & MOD_AUTOCLEAN) {
232
233
234
235
236 codesize &= ~MOD_AUTOCLEAN;
237 GET_USE_COUNT(mp) = MOD_AUTOCLEAN;
238 }
239 if ((codesize + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE > mp->size)
240 return -EINVAL;
241 memcpy_fromfs((char *)mp->addr + sizeof (long), code, codesize);
242 memset((char *)mp->addr + sizeof (long) + codesize, 0,
243 mp->size * PAGE_SIZE - (codesize + sizeof (long)));
244 PRINTK(( "module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
245 (unsigned long) rt.init, (unsigned long) rt.cleanup));
246 mp->cleanup = rt.cleanup;
247
248
249 if (symtab) {
250 struct internal_symbol *sym;
251 struct module_ref *ref;
252 int size;
253 int i;
254 int legal_start;
255
256 if ((error = verify_area(VERIFY_READ, &symtab->size, sizeof(symtab->size))))
257 return error;
258 size = get_user(&symtab->size);
259
260 if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
261 return -ENOMEM;
262 }
263
264 if ((error = verify_area(VERIFY_READ, symtab, size))) {
265 kfree_s(newtab, size);
266 return error;
267 }
268 memcpy_fromfs((char *)(newtab), symtab, size);
269
270
271 legal_start = sizeof(struct symbol_table) +
272 newtab->n_symbols * sizeof(struct internal_symbol) +
273 newtab->n_refs * sizeof(struct module_ref);
274
275 if ((newtab->n_symbols < 0) || (newtab->n_refs < 0) || (legal_start > size)) {
276 printk("Rejecting illegal symbol table (n_symbols=%d,n_refs=%d)\n",
277 newtab->n_symbols, newtab->n_refs);
278 kfree_s(newtab, size);
279 return -EINVAL;
280 }
281
282
283 for (sym = &(newtab->symbol[0]), i = 0; i < newtab->n_symbols; ++sym, ++i) {
284 if ((unsigned long)sym->name < legal_start || size <= (unsigned long)sym->name) {
285 printk("Rejecting illegal symbol table\n");
286 kfree_s(newtab, size);
287 return -EINVAL;
288 }
289
290 sym->name += (long)newtab;
291 }
292 mp->symtab = newtab;
293
294
295
296
297
298
299
300
301
302 for (ref = (struct module_ref *)sym, i = 0;
303 i < newtab->n_refs; ++ref, ++i) {
304
305
306 struct module *link = module_list;
307 while (link && (ref->module != link))
308 link = link->next;
309
310 if (link == (struct module *)0) {
311 printk("Non-module reference! Rejected!\n");
312 return -EINVAL;
313 }
314
315 ref->next = ref->module->ref;
316 ref->module->ref = ref;
317 ref->module = mp;
318 }
319 }
320
321 module_init_flag = 1;
322 if ((*rt.init)() != 0) {
323 module_init_flag = 0;
324 return -EBUSY;
325 }
326 module_init_flag = 0;
327 mp->state = MOD_RUNNING;
328
329 return 0;
330 }
331
332 asmlinkage int
333 sys_delete_module(char *module_name)
334 {
335 struct module *mp;
336 char name[MOD_MAX_NAME];
337 int error;
338
339 if (!suser())
340 return -EPERM;
341
342 if (module_name != NULL) {
343 if ((error = get_mod_name(module_name, name)) != 0)
344 return error;
345 if ((mp = find_module(name)) == NULL)
346 return -ENOENT;
347 if ((mp->ref != NULL) || ((GET_USE_COUNT(mp) & ~MOD_AUTOCLEAN) != 0))
348 return -EBUSY;
349 GET_USE_COUNT(mp) &= ~MOD_AUTOCLEAN;
350 if (mp->state == MOD_RUNNING)
351 (*mp->cleanup)();
352 mp->state = MOD_DELETED;
353 free_modules();
354 }
355
356 else {
357 for (mp = module_list; mp != &kernel_module; mp = mp->next) {
358 if ((mp->ref == NULL) && (GET_USE_COUNT(mp) == MOD_AUTOCLEAN) &&
359 (mp->state == MOD_RUNNING)) {
360 GET_USE_COUNT(mp) &= ~MOD_AUTOCLEAN;
361 (*mp->cleanup)();
362 mp->state = MOD_DELETED;
363 free_modules();
364 }
365 }
366 }
367 return 0;
368 }
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392 asmlinkage int
393 sys_get_kernel_syms(struct kernel_sym *table)
394 {
395 struct internal_symbol *from;
396 struct kernel_sym isym;
397 struct kernel_sym *to;
398 struct module *mp = module_list;
399 int i;
400 int nmodsyms = 0;
401
402 for (mp = module_list; mp; mp = mp->next) {
403 if (mp->symtab && mp->symtab->n_symbols) {
404
405 nmodsyms += mp->symtab->n_symbols + 1;
406 }
407 else
408
409 nmodsyms += 1;
410 }
411
412 if (table != NULL) {
413 to = table;
414
415 if ((i = verify_area(VERIFY_WRITE, to, nmodsyms * sizeof(*table))))
416 return i;
417
418
419 for (mp = module_list; mp; mp = mp->next) {
420 if (mp->state == MOD_RUNNING) {
421
422 isym.value = (unsigned long)mp;
423 sprintf(isym.name, "#%s", mp->name);
424 memcpy_tofs(to, &isym, sizeof isym);
425 ++to;
426
427 if (mp->symtab != NULL) {
428 for (i = mp->symtab->n_symbols,
429 from = mp->symtab->symbol;
430 i > 0; --i, ++from, ++to) {
431
432 isym.value = (unsigned long)from->addr;
433 strncpy(isym.name, from->name, sizeof isym.name);
434 memcpy_tofs(to, &isym, sizeof isym);
435 }
436 }
437 }
438 }
439 }
440
441 return nmodsyms;
442 }
443
444
445
446
447
448 int
449 get_mod_name(char *user_name, char *buf)
450 {
451 int i;
452
453 i = 0;
454 for (i = 0 ; (buf[i] = get_user(user_name + i)) != '\0' ; ) {
455 if (++i >= MOD_MAX_NAME)
456 return -E2BIG;
457 }
458 return 0;
459 }
460
461
462
463
464
465 struct module *
466 find_module( const char *name)
467 {
468 struct module *mp;
469
470 for (mp = module_list ; mp ; mp = mp->next) {
471 if (mp->state == MOD_DELETED)
472 continue;
473 if (!strcmp(mp->name, name))
474 break;
475 }
476 return mp;
477 }
478
479 static void
480 drop_refs(struct module *mp)
481 {
482 struct module *step;
483 struct module_ref *prev;
484 struct module_ref *ref;
485
486 for (step = module_list; step; step = step->next) {
487 for (prev = ref = step->ref; ref; ref = prev->next) {
488 if (ref->module == mp) {
489 if (ref == step->ref)
490 step->ref = ref->next;
491 else
492 prev->next = ref->next;
493 break;
494 }
495 else
496 prev = ref;
497 }
498 }
499 }
500
501
502
503
504
505 int
506 free_modules( void)
507 {
508 struct module *mp;
509 struct module **mpp;
510 int did_deletion;
511
512 did_deletion = 0;
513 freeing_modules = 0;
514 mpp = &module_list;
515 while ((mp = *mpp) != NULL) {
516 if (mp->state != MOD_DELETED) {
517 mpp = &mp->next;
518 } else {
519 if ((GET_USE_COUNT(mp) != 0) || (mp->ref != NULL)) {
520 freeing_modules = 1;
521 mpp = &mp->next;
522 } else {
523 *mpp = mp->next;
524 if (mp->symtab) {
525 if (mp->symtab->n_refs)
526 drop_refs(mp);
527 if (mp->symtab->size)
528 kfree_s(mp->symtab, mp->symtab->size);
529 }
530 vfree(mp->addr);
531 kfree_s(mp, sizeof(struct module) + MOD_MAX_NAME);
532 did_deletion = 1;
533 }
534 }
535 }
536 return did_deletion;
537 }
538
539
540
541
542
543 int get_module_list(char *buf)
544 {
545 char *p;
546 const char *q;
547 int i;
548 struct module *mp;
549 struct module_ref *ref;
550 char size[32];
551
552 p = buf;
553
554 for (mp = module_list ; mp && mp->next; mp = mp->next) {
555 if (p - buf > 4096 - 100)
556 break;
557 q = mp->name;
558 if (*q == '\0' && mp->size == 0 && mp->ref == NULL)
559 continue;
560 i = 20;
561 while (*q) {
562 *p++ = *q++;
563 i--;
564 }
565 sprintf(size, "%d", mp->size);
566 i -= strlen(size);
567 if (i <= 0)
568 i = 1;
569 while (--i >= 0)
570 *p++ = ' ';
571 q = size;
572 while (*q)
573 *p++ = *q++;
574 if (mp->state == MOD_UNINITIALIZED)
575 q = " (uninitialized)";
576 else if (mp->state == MOD_RUNNING)
577 q = "";
578 else if (mp->state == MOD_DELETED)
579 q = " (deleted)";
580 else
581 q = " (bad state)";
582 while (*q)
583 *p++ = *q++;
584
585 if ((ref = mp->ref) != NULL) {
586 *p++ = '\t';
587 *p++ = '[';
588 for (; ref; ref = ref->next) {
589 q = ref->module->name;
590 while (*q)
591 *p++ = *q++;
592 if (ref->next)
593 *p++ = ' ';
594 }
595 *p++ = ']';
596 }
597 if (mp->state == MOD_RUNNING) {
598 sprintf(size,"\t%ld%s",
599 GET_USE_COUNT(mp) & ~MOD_AUTOCLEAN,
600 ((GET_USE_COUNT(mp) & MOD_AUTOCLEAN)?
601 " (autoclean)":""));
602 q = size;
603 while (*q)
604 *p++ = *q++;
605 }
606 *p++ = '\n';
607 }
608 return p - buf;
609 }
610
611
612
613
614
615 int get_ksyms_list(char *buf, char **start, off_t offset, int length)
616 {
617 struct module *mp;
618 struct internal_symbol *sym;
619 int i;
620 char *p = buf;
621 int len = 0;
622 off_t pos = 0;
623 off_t begin = 0;
624
625 for (mp = module_list; mp; mp = mp->next) {
626 if ((mp->state == MOD_RUNNING) &&
627 (mp->symtab != NULL) &&
628 (mp->symtab->n_symbols > 0)) {
629 for (i = mp->symtab->n_symbols,
630 sym = mp->symtab->symbol;
631 i > 0; --i, ++sym) {
632
633 p = buf + len;
634 if (mp->name[0]) {
635 len += sprintf(p, "%08lx %s\t[%s]\n",
636 (long)sym->addr,
637 sym->name, mp->name);
638 } else {
639 len += sprintf(p, "%08lx %s\n",
640 (long)sym->addr,
641 sym->name);
642 }
643 pos = begin + len;
644 if (pos < offset) {
645 len = 0;
646 begin = pos;
647 }
648 pos = begin + len;
649 if (pos > offset+length)
650 goto leave_the_loop;
651 }
652 }
653 }
654 leave_the_loop:
655 *start = buf + (offset - begin);
656 len -= (offset - begin);
657 if (len > length)
658 len = length;
659 return len;
660 }
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680 #define INTSIZ sizeof(struct internal_symbol)
681 #define REFSIZ sizeof(struct module_ref)
682 #define SYMSIZ sizeof(struct symbol_table)
683 #define MODSIZ sizeof(struct module)
684 static struct symbol_table nulltab;
685
686 int
687 register_symtab(struct symbol_table *intab)
688 {
689 struct module *mp;
690 struct module *link;
691 struct symbol_table *oldtab;
692 struct symbol_table *newtab;
693 struct module_ref *newref;
694 int size;
695
696 if (intab && (intab->n_symbols == 0)) {
697 struct internal_symbol *sym;
698
699
700 for (sym = intab->symbol; sym->name; ++sym)
701 intab->n_symbols +=1;
702 }
703
704 #if 1
705 if (module_init_flag == 0) {
706 #else
707 if (module_list == &kernel_module) {
708 #endif
709
710 if (!intab)
711 return 0;
712
713
714 if (!(mp = (struct module*) kmalloc(MODSIZ, GFP_KERNEL))) {
715
716 printk("Out of memory for new symbol table!\n");
717 return -ENOMEM;
718 }
719
720 memset(mp, 0, MODSIZ);
721 mp->state = MOD_RUNNING;
722 mp->name = "";
723 mp->symtab = intab;
724
725
726 mp->next = kernel_module.next;
727 kernel_module.next = mp;
728
729 return 0;
730 }
731
732
733
734
735
736
737
738
739 mp = module_list;
740
741
742 if ((oldtab = mp->symtab) == (struct symbol_table*)0) {
743
744 mp->symtab = intab;
745 return 0;
746 }
747
748
749 #if 0
750 if (oldtab->n_symbols > 0) {
751
752 printk("Warning, dropping old symbols\n");
753 }
754 #endif
755
756 if (oldtab->n_refs == 0) {
757 mp->symtab = intab;
758
759 if (oldtab->size > 0)
760 kfree_s(oldtab, oldtab->size);
761
762 return 0;
763 }
764
765
766
767
768 if (intab == (struct symbol_table*)0)
769 intab = &nulltab;
770
771
772
773
774 if (!(newtab = (struct symbol_table*)kmalloc(
775 size = SYMSIZ + intab->n_symbols * INTSIZ +
776 oldtab->n_refs * REFSIZ,
777 GFP_KERNEL))) {
778
779 printk("Out of memory for new symbol table!\n");
780 return -ENOMEM;
781 }
782
783
784 memcpy(newtab, intab, SYMSIZ + intab->n_symbols * INTSIZ);
785
786 newtab->size = size;
787 newtab->n_refs = oldtab->n_refs;
788
789
790 memcpy( ((char *)newtab) + SYMSIZ + intab->n_symbols * INTSIZ,
791 ((char *)oldtab) + SYMSIZ + oldtab->n_symbols * INTSIZ,
792 oldtab->n_refs * REFSIZ);
793
794
795
796
797 newref = (struct module_ref*) &(newtab->symbol[newtab->n_symbols]);
798
799
800 for ( link = module_list;
801 link && (link != &kernel_module);
802 link = link->next) {
803
804 if (link->ref && (link->ref->module == mp))
805 link->ref = newref++;
806 }
807
808 mp->symtab = newtab;
809
810
811
812
813 if (oldtab->size > 0)
814 kfree_s(oldtab, oldtab->size);
815
816 return 0;
817 }
818
819 #else
820
821
822
823 asmlinkage unsigned long sys_create_module(void)
824 {
825 return -ENOSYS;
826 }
827
828 asmlinkage int sys_init_module(void)
829 {
830 return -ENOSYS;
831 }
832
833 asmlinkage int sys_delete_module(void)
834 {
835 return -ENOSYS;
836 }
837
838 asmlinkage int sys_get_kernel_syms(void)
839 {
840 return -ENOSYS;
841 }
842
843 int register_symtab(struct symbol_table *intab)
844 {
845 return 0;
846 }
847
848 #endif
849