1#include <linux/config.h>
2#include <linux/mm.h>
3#include <linux/module.h>
4#include <asm/module.h>
5#include <asm/uaccess.h>
6#include <linux/vmalloc.h>
7#include <linux/smp_lock.h>
8#include <asm/pgalloc.h>
9#include <linux/init.h>
10#include <linux/slab.h>
11#include <linux/kmod.h>
12#include <linux/seq_file.h>
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS)
33
34extern struct module_symbol __start___ksymtab[];
35extern struct module_symbol __stop___ksymtab[];
36
37extern const struct exception_table_entry __start___ex_table[];
38extern const struct exception_table_entry __stop___ex_table[];
39
40extern const char __start___kallsyms[] __attribute__ ((weak));
41extern const char __stop___kallsyms[] __attribute__ ((weak));
42
43struct module kernel_module =
44{
45 size_of_struct: sizeof(struct module),
46 name: "",
47 uc: {ATOMIC_INIT(1)},
48 flags: MOD_RUNNING,
49 syms: __start___ksymtab,
50 ex_table_start: __start___ex_table,
51 ex_table_end: __stop___ex_table,
52 kallsyms_start: __start___kallsyms,
53 kallsyms_end: __stop___kallsyms,
54};
55
56struct module *module_list = &kernel_module;
57
58#endif
59
60
61
62
63
64
65
66static struct list_head ime_list = LIST_HEAD_INIT(ime_list);
67static spinlock_t ime_lock = SPIN_LOCK_UNLOCKED;
68static int kmalloc_failed;
69
70
71
72
73
74
75
76
77
78
79spinlock_t modlist_lock = SPIN_LOCK_UNLOCKED;
80
81
82
83
84
85
86
87
88
89
90
91void inter_module_register(const char *im_name, struct module *owner, const void *userdata)
92{
93 struct list_head *tmp;
94 struct inter_module_entry *ime, *ime_new;
95
96 if (!(ime_new = kmalloc(sizeof(*ime), GFP_KERNEL))) {
97
98 printk(KERN_ERR
99 "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
100 im_name);
101 kmalloc_failed = 1;
102 return;
103 }
104 memset(ime_new, 0, sizeof(*ime_new));
105 ime_new->im_name = im_name;
106 ime_new->owner = owner;
107 ime_new->userdata = userdata;
108
109 spin_lock(&ime_lock);
110 list_for_each(tmp, &ime_list) {
111 ime = list_entry(tmp, struct inter_module_entry, list);
112 if (strcmp(ime->im_name, im_name) == 0) {
113 spin_unlock(&ime_lock);
114 kfree(ime_new);
115
116 printk(KERN_ERR "inter_module_register: duplicate im_name '%s'", im_name);
117 BUG();
118 }
119 }
120 list_add(&(ime_new->list), &ime_list);
121 spin_unlock(&ime_lock);
122}
123
124
125
126
127
128
129
130
131
132void inter_module_unregister(const char *im_name)
133{
134 struct list_head *tmp;
135 struct inter_module_entry *ime;
136
137 spin_lock(&ime_lock);
138 list_for_each(tmp, &ime_list) {
139 ime = list_entry(tmp, struct inter_module_entry, list);
140 if (strcmp(ime->im_name, im_name) == 0) {
141 list_del(&(ime->list));
142 spin_unlock(&ime_lock);
143 kfree(ime);
144 return;
145 }
146 }
147 spin_unlock(&ime_lock);
148 if (kmalloc_failed) {
149 printk(KERN_ERR
150 "inter_module_unregister: no entry for '%s', "
151 "probably caused by previous kmalloc failure\n",
152 im_name);
153 return;
154 }
155 else {
156
157 printk(KERN_ERR "inter_module_unregister: no entry for '%s'", im_name);
158 BUG();
159 }
160}
161
162
163
164
165
166
167
168
169
170const void *inter_module_get(const char *im_name)
171{
172 struct list_head *tmp;
173 struct inter_module_entry *ime;
174 const void *result = NULL;
175
176 spin_lock(&ime_lock);
177 list_for_each(tmp, &ime_list) {
178 ime = list_entry(tmp, struct inter_module_entry, list);
179 if (strcmp(ime->im_name, im_name) == 0) {
180 if (try_inc_mod_count(ime->owner))
181 result = ime->userdata;
182 break;
183 }
184 }
185 spin_unlock(&ime_lock);
186 return(result);
187}
188
189
190
191
192
193
194
195
196const void *inter_module_get_request(const char *im_name, const char *modname)
197{
198 const void *result = inter_module_get(im_name);
199 if (!result) {
200 request_module(modname);
201 result = inter_module_get(im_name);
202 }
203 return(result);
204}
205
206
207
208
209
210
211
212
213void inter_module_put(const char *im_name)
214{
215 struct list_head *tmp;
216 struct inter_module_entry *ime;
217
218 spin_lock(&ime_lock);
219 list_for_each(tmp, &ime_list) {
220 ime = list_entry(tmp, struct inter_module_entry, list);
221 if (strcmp(ime->im_name, im_name) == 0) {
222 if (ime->owner)
223 __MOD_DEC_USE_COUNT(ime->owner);
224 spin_unlock(&ime_lock);
225 return;
226 }
227 }
228 spin_unlock(&ime_lock);
229 printk(KERN_ERR "inter_module_put: no entry for '%s'", im_name);
230 BUG();
231}
232
233
234#if defined(CONFIG_MODULES)
235
236static long get_mod_name(const char *user_name, char **buf);
237static void put_mod_name(char *buf);
238struct module *find_module(const char *name);
239void free_module(struct module *, int tag_freed);
240
241
242
243
244
245
246void __init init_modules(void)
247{
248 kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
249
250 arch_init_modules(&kernel_module);
251}
252
253
254
255
256
257static inline long
258get_mod_name(const char *user_name, char **buf)
259{
260 unsigned long page;
261 long retval;
262
263 page = __get_free_page(GFP_KERNEL);
264 if (!page)
265 return -ENOMEM;
266
267 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
268 if (retval > 0) {
269 if (retval < PAGE_SIZE) {
270 *buf = (char *)page;
271 return retval;
272 }
273 retval = -ENAMETOOLONG;
274 } else if (!retval)
275 retval = -EINVAL;
276
277 free_page(page);
278 return retval;
279}
280
281static inline void
282put_mod_name(char *buf)
283{
284 free_page((unsigned long)buf);
285}
286
287
288
289
290
291asmlinkage unsigned long
292sys_create_module(const char *name_user, size_t size)
293{
294 char *name;
295 long namelen, error;
296 struct module *mod;
297 unsigned long flags;
298
299 if (!capable(CAP_SYS_MODULE))
300 return -EPERM;
301 lock_kernel();
302 if ((namelen = get_mod_name(name_user, &name)) < 0) {
303 error = namelen;
304 goto err0;
305 }
306 if (size < sizeof(struct module)+namelen+1) {
307 error = -EINVAL;
308 goto err1;
309 }
310 if (find_module(name) != NULL) {
311 error = -EEXIST;
312 goto err1;
313 }
314 if ((mod = (struct module *)module_map(size)) == NULL) {
315 error = -ENOMEM;
316 goto err1;
317 }
318
319 memset(mod, 0, sizeof(*mod));
320 mod->size_of_struct = sizeof(*mod);
321 mod->name = (char *)(mod + 1);
322 mod->size = size;
323 memcpy((char*)(mod+1), name, namelen+1);
324
325 put_mod_name(name);
326
327 spin_lock_irqsave(&modlist_lock, flags);
328 mod->next = module_list;
329 module_list = mod;
330 spin_unlock_irqrestore(&modlist_lock, flags);
331
332 error = (long) mod;
333 goto err0;
334err1:
335 put_mod_name(name);
336err0:
337 unlock_kernel();
338 return error;
339}
340
341
342
343
344
345asmlinkage long
346sys_init_module(const char *name_user, struct module *mod_user)
347{
348 struct module mod_tmp, *mod, *mod2 = NULL;
349 char *name, *n_name, *name_tmp = NULL;
350 long namelen, n_namelen, i, error;
351 unsigned long mod_user_size, flags;
352 struct module_ref *dep;
353
354 if (!capable(CAP_SYS_MODULE))
355 return -EPERM;
356 lock_kernel();
357 if ((namelen = get_mod_name(name_user, &name)) < 0) {
358 error = namelen;
359 goto err0;
360 }
361 if ((mod = find_module(name)) == NULL) {
362 error = -ENOENT;
363 goto err1;
364 }
365
366
367
368
369 if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
370 goto err1;
371 if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
372 || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
373 printk(KERN_ERR "init_module: Invalid module header size.\n"
374 KERN_ERR "A new version of the modutils is likely "
375 "needed.\n");
376 error = -EINVAL;
377 goto err1;
378 }
379
380
381
382 mod_tmp = *mod;
383 name_tmp = kmalloc(strlen(mod->name) + 1, GFP_KERNEL);
384 if (name_tmp == NULL) {
385 error = -ENOMEM;
386 goto err1;
387 }
388 strcpy(name_tmp, mod->name);
389
390
391
392
393
394 if (!(mod2 = vmalloc(mod_user_size))) {
395 error = -ENOMEM;
396 goto err2;
397 }
398 error = copy_from_user(mod2, mod_user, mod_user_size);
399 if (error) {
400 error = -EFAULT;
401 goto err2;
402 }
403 spin_lock_irqsave(&modlist_lock, flags);
404 memcpy(mod, mod2, mod_user_size);
405 mod->next = mod_tmp.next;
406 spin_unlock_irqrestore(&modlist_lock, flags);
407
408
409 error = -EINVAL;
410
411 if (mod->size > mod_tmp.size) {
412 printk(KERN_ERR "init_module: Size of initialized module "
413 "exceeds size of created module.\n");
414 goto err2;
415 }
416
417
418
419 if (!mod_bound(mod->name, namelen, mod)) {
420 printk(KERN_ERR "init_module: mod->name out of bounds.\n");
421 goto err2;
422 }
423 if (mod->nsyms && !mod_bound(mod->syms, mod->nsyms, mod)) {
424 printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
425 goto err2;
426 }
427 if (mod->ndeps && !mod_bound(mod->deps, mod->ndeps, mod)) {
428 printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
429 goto err2;
430 }
431 if (mod->init && !mod_bound(mod->init, 0, mod)) {
432 printk(KERN_ERR "init_module: mod->init out of bounds.\n");
433 goto err2;
434 }
435 if (mod->cleanup && !mod_bound(mod->cleanup, 0, mod)) {
436 printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
437 goto err2;
438 }
439 if (mod->ex_table_start > mod->ex_table_end
440 || (mod->ex_table_start &&
441 !((unsigned long)mod->ex_table_start >= ((unsigned long)mod + mod->size_of_struct)
442 && ((unsigned long)mod->ex_table_end
443 < (unsigned long)mod + mod->size)))
444 || (((unsigned long)mod->ex_table_start
445 - (unsigned long)mod->ex_table_end)
446 % sizeof(struct exception_table_entry))) {
447 printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
448 goto err2;
449 }
450 if (mod->flags & ~MOD_AUTOCLEAN) {
451 printk(KERN_ERR "init_module: mod->flags invalid.\n");
452 goto err2;
453 }
454 if (mod_member_present(mod, can_unload)
455 && mod->can_unload && !mod_bound(mod->can_unload, 0, mod)) {
456 printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
457 goto err2;
458 }
459 if (mod_member_present(mod, kallsyms_end)) {
460 if (mod->kallsyms_end &&
461 (!mod_bound(mod->kallsyms_start, 0, mod) ||
462 !mod_bound(mod->kallsyms_end, 0, mod))) {
463 printk(KERN_ERR "init_module: mod->kallsyms out of bounds.\n");
464 goto err2;
465 }
466 if (mod->kallsyms_start > mod->kallsyms_end) {
467 printk(KERN_ERR "init_module: mod->kallsyms invalid.\n");
468 goto err2;
469 }
470 }
471 if (mod_member_present(mod, archdata_end)) {
472 if (mod->archdata_end &&
473 (!mod_bound(mod->archdata_start, 0, mod) ||
474 !mod_bound(mod->archdata_end, 0, mod))) {
475 printk(KERN_ERR "init_module: mod->archdata out of bounds.\n");
476 goto err2;
477 }
478 if (mod->archdata_start > mod->archdata_end) {
479 printk(KERN_ERR "init_module: mod->archdata invalid.\n");
480 goto err2;
481 }
482 }
483 if (mod_member_present(mod, kernel_data) && mod->kernel_data) {
484 printk(KERN_ERR "init_module: mod->kernel_data must be zero.\n");
485 goto err2;
486 }
487
488
489
490 if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
491 + (unsigned long)mod_user,
492 &n_name)) < 0) {
493 printk(KERN_ERR "init_module: get_mod_name failure.\n");
494 error = n_namelen;
495 goto err2;
496 }
497 if (namelen != n_namelen || strcmp(n_name, name_tmp) != 0) {
498 printk(KERN_ERR "init_module: changed module name to "
499 "`%s' from `%s'\n",
500 n_name, name_tmp);
501 goto err3;
502 }
503
504
505
506 if (copy_from_user((char *)mod+mod_user_size,
507 (char *)mod_user+mod_user_size,
508 mod->size-mod_user_size)) {
509 error = -EFAULT;
510 goto err3;
511 }
512
513 if (module_arch_init(mod))
514 goto err3;
515
516
517
518 flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
519
520 mod->refs = NULL;
521
522
523 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
524 struct module *o, *d = dep->dep;
525
526
527 if (d == mod) {
528 printk(KERN_ERR "init_module: self-referential "
529 "dependency in mod->deps.\n");
530 goto err3;
531 }
532
533
534 for (o = module_list; o != &kernel_module && o != d; o = o->next)
535 ;
536
537 if (o != d) {
538 printk(KERN_ERR "init_module: found dependency that is "
539 "(no longer?) a module.\n");
540 goto err3;
541 }
542 }
543
544
545 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
546 struct module *d = dep->dep;
547
548 dep->ref = mod;
549 dep->next_ref = d->refs;
550 d->refs = dep;
551
552
553 d->flags |= MOD_USED_ONCE;
554 }
555
556
557 put_mod_name(n_name);
558 put_mod_name(name);
559
560
561 atomic_set(&mod->uc.usecount,1);
562 mod->flags |= MOD_INITIALIZING;
563 if (mod->init && (error = mod->init()) != 0) {
564 atomic_set(&mod->uc.usecount,0);
565 mod->flags &= ~MOD_INITIALIZING;
566 if (error > 0)
567 error = -EBUSY;
568 goto err0;
569 }
570 atomic_dec(&mod->uc.usecount);
571
572
573 mod->flags = (mod->flags | MOD_RUNNING) & ~MOD_INITIALIZING;
574 error = 0;
575 goto err0;
576
577err3:
578 put_mod_name(n_name);
579err2:
580 *mod = mod_tmp;
581 strcpy((char *)mod->name, name_tmp);
582err1:
583 put_mod_name(name);
584err0:
585 if (mod2)
586 vfree(mod2);
587 unlock_kernel();
588 kfree(name_tmp);
589 return error;
590}
591
592static spinlock_t unload_lock = SPIN_LOCK_UNLOCKED;
593int try_inc_mod_count(struct module *mod)
594{
595 int res = 1;
596 if (mod) {
597 spin_lock(&unload_lock);
598 if (mod->flags & MOD_DELETED)
599 res = 0;
600 else
601 __MOD_INC_USE_COUNT(mod);
602 spin_unlock(&unload_lock);
603 }
604 return res;
605}
606
607asmlinkage long
608sys_delete_module(const char *name_user)
609{
610 struct module *mod, *next;
611 char *name;
612 long error;
613 int something_changed;
614
615 if (!capable(CAP_SYS_MODULE))
616 return -EPERM;
617
618 lock_kernel();
619 if (name_user) {
620 if ((error = get_mod_name(name_user, &name)) < 0)
621 goto out;
622 error = -ENOENT;
623 if ((mod = find_module(name)) == NULL) {
624 put_mod_name(name);
625 goto out;
626 }
627 put_mod_name(name);
628 error = -EBUSY;
629 if (mod->refs != NULL)
630 goto out;
631
632 spin_lock(&unload_lock);
633 if (!__MOD_IN_USE(mod)) {
634 mod->flags |= MOD_DELETED;
635 spin_unlock(&unload_lock);
636 free_module(mod, 0);
637 error = 0;
638 } else {
639 spin_unlock(&unload_lock);
640 }
641 goto out;
642 }
643
644
645restart:
646 something_changed = 0;
647
648 for (mod = module_list; mod != &kernel_module; mod = next) {
649 next = mod->next;
650 spin_lock(&unload_lock);
651 if (mod->refs == NULL
652 && (mod->flags & MOD_AUTOCLEAN)
653 && (mod->flags & MOD_RUNNING)
654 && !(mod->flags & MOD_DELETED)
655 && (mod->flags & MOD_USED_ONCE)
656 && !__MOD_IN_USE(mod)) {
657 if ((mod->flags & MOD_VISITED)
658 && !(mod->flags & MOD_JUST_FREED)) {
659 spin_unlock(&unload_lock);
660 mod->flags &= ~MOD_VISITED;
661 } else {
662 mod->flags |= MOD_DELETED;
663 spin_unlock(&unload_lock);
664 free_module(mod, 1);
665 something_changed = 1;
666 }
667 } else {
668 spin_unlock(&unload_lock);
669 }
670 }
671
672 if (something_changed)
673 goto restart;
674
675 for (mod = module_list; mod != &kernel_module; mod = mod->next)
676 mod->flags &= ~MOD_JUST_FREED;
677
678 error = 0;
679out:
680 unlock_kernel();
681 return error;
682}
683
684
685
686static int
687qm_modules(char *buf, size_t bufsize, size_t *ret)
688{
689 struct module *mod;
690 size_t nmod, space, len;
691
692 nmod = space = 0;
693
694 for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
695 len = strlen(mod->name)+1;
696 if (len > bufsize)
697 goto calc_space_needed;
698 if (copy_to_user(buf, mod->name, len))
699 return -EFAULT;
700 buf += len;
701 bufsize -= len;
702 space += len;
703 }
704
705 if (put_user(nmod, ret))
706 return -EFAULT;
707 else
708 return 0;
709
710calc_space_needed:
711 space += len;
712 while ((mod = mod->next) != &kernel_module)
713 space += strlen(mod->name)+1;
714
715 if (put_user(space, ret))
716 return -EFAULT;
717 else
718 return -ENOSPC;
719}
720
721static int
722qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
723{
724 size_t i, space, len;
725
726 if (mod == &kernel_module)
727 return -EINVAL;
728 if (!MOD_CAN_QUERY(mod))
729 if (put_user(0, ret))
730 return -EFAULT;
731 else
732 return 0;
733
734 space = 0;
735 for (i = 0; i < mod->ndeps; ++i) {
736 const char *dep_name = mod->deps[i].dep->name;
737
738 len = strlen(dep_name)+1;
739 if (len > bufsize)
740 goto calc_space_needed;
741 if (copy_to_user(buf, dep_name, len))
742 return -EFAULT;
743 buf += len;
744 bufsize -= len;
745 space += len;
746 }
747
748 if (put_user(i, ret))
749 return -EFAULT;
750 else
751 return 0;
752
753calc_space_needed:
754 space += len;
755 while (++i < mod->ndeps)
756 space += strlen(mod->deps[i].dep->name)+1;
757
758 if (put_user(space, ret))
759 return -EFAULT;
760 else
761 return -ENOSPC;
762}
763
764static int
765qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
766{
767 size_t nrefs, space, len;
768 struct module_ref *ref;
769
770 if (mod == &kernel_module)
771 return -EINVAL;
772 if (!MOD_CAN_QUERY(mod))
773 if (put_user(0, ret))
774 return -EFAULT;
775 else
776 return 0;
777
778 space = 0;
779 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
780 const char *ref_name = ref->ref->name;
781
782 len = strlen(ref_name)+1;
783 if (len > bufsize)
784 goto calc_space_needed;
785 if (copy_to_user(buf, ref_name, len))
786 return -EFAULT;
787 buf += len;
788 bufsize -= len;
789 space += len;
790 }
791
792 if (put_user(nrefs, ret))
793 return -EFAULT;
794 else
795 return 0;
796
797calc_space_needed:
798 space += len;
799 while ((ref = ref->next_ref) != NULL)
800 space += strlen(ref->ref->name)+1;
801
802 if (put_user(space, ret))
803 return -EFAULT;
804 else
805 return -ENOSPC;
806}
807
808static int
809qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
810{
811 size_t i, space, len;
812 struct module_symbol *s;
813 char *strings;
814 unsigned long *vals;
815
816 if (!MOD_CAN_QUERY(mod))
817 if (put_user(0, ret))
818 return -EFAULT;
819 else
820 return 0;
821
822 space = mod->nsyms * 2*sizeof(void *);
823
824 i = len = 0;
825 s = mod->syms;
826
827 if (space > bufsize)
828 goto calc_space_needed;
829
830 if (!access_ok(VERIFY_WRITE, buf, space))
831 return -EFAULT;
832
833 bufsize -= space;
834 vals = (unsigned long *)buf;
835 strings = buf+space;
836
837 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
838 len = strlen(s->name)+1;
839 if (len > bufsize)
840 goto calc_space_needed;
841
842 if (copy_to_user(strings, s->name, len)
843 || __put_user(s->value, vals+0)
844 || __put_user(space, vals+1))
845 return -EFAULT;
846
847 strings += len;
848 bufsize -= len;
849 space += len;
850 }
851 if (put_user(i, ret))
852 return -EFAULT;
853 else
854 return 0;
855
856calc_space_needed:
857 for (; i < mod->nsyms; ++i, ++s)
858 space += strlen(s->name)+1;
859
860 if (put_user(space, ret))
861 return -EFAULT;
862 else
863 return -ENOSPC;
864}
865
866static int
867qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
868{
869 int error = 0;
870
871 if (mod == &kernel_module)
872 return -EINVAL;
873
874 if (sizeof(struct module_info) <= bufsize) {
875 struct module_info info;
876 info.addr = (unsigned long)mod;
877 info.size = mod->size;
878 info.flags = mod->flags;
879
880
881
882 info.usecount = (mod_member_present(mod, can_unload)
883 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)-1);
884
885 if (copy_to_user(buf, &info, sizeof(struct module_info)))
886 return -EFAULT;
887 } else
888 error = -ENOSPC;
889
890 if (put_user(sizeof(struct module_info), ret))
891 return -EFAULT;
892
893 return error;
894}
895
896asmlinkage long
897sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
898 size_t *ret)
899{
900 struct module *mod;
901 int err;
902
903 lock_kernel();
904 if (name_user == NULL)
905 mod = &kernel_module;
906 else {
907 long namelen;
908 char *name;
909
910 if ((namelen = get_mod_name(name_user, &name)) < 0) {
911 err = namelen;
912 goto out;
913 }
914 err = -ENOENT;
915 if ((mod = find_module(name)) == NULL) {
916 put_mod_name(name);
917 goto out;
918 }
919 put_mod_name(name);
920 }
921
922
923
924 atomic_inc(&mod->uc.usecount);
925
926 switch (which)
927 {
928 case 0:
929 err = 0;
930 break;
931 case QM_MODULES:
932 err = qm_modules(buf, bufsize, ret);
933 break;
934 case QM_DEPS:
935 err = qm_deps(mod, buf, bufsize, ret);
936 break;
937 case QM_REFS:
938 err = qm_refs(mod, buf, bufsize, ret);
939 break;
940 case QM_SYMBOLS:
941 err = qm_symbols(mod, buf, bufsize, ret);
942 break;
943 case QM_INFO:
944 err = qm_info(mod, buf, bufsize, ret);
945 break;
946 default:
947 err = -EINVAL;
948 break;
949 }
950 atomic_dec(&mod->uc.usecount);
951
952out:
953 unlock_kernel();
954 return err;
955}
956
957
958
959
960
961
962
963
964
965asmlinkage long
966sys_get_kernel_syms(struct kernel_sym *table)
967{
968 struct module *mod;
969 int i;
970 struct kernel_sym ksym;
971
972 lock_kernel();
973 for (mod = module_list, i = 0; mod; mod = mod->next) {
974
975 i += mod->nsyms + 1;
976 }
977
978 if (table == NULL)
979 goto out;
980
981
982 memset (&ksym, 0, sizeof (ksym));
983
984 for (mod = module_list, i = 0; mod; mod = mod->next) {
985 struct module_symbol *msym;
986 unsigned int j;
987
988 if (!MOD_CAN_QUERY(mod))
989 continue;
990
991
992 ksym.value = (unsigned long)mod;
993 ksym.name[0] = '#';
994 strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
995 ksym.name[sizeof(ksym.name)-1] = '\0';
996
997 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
998 goto out;
999 ++i, ++table;
1000
1001 if (mod->nsyms == 0)
1002 continue;
1003
1004 for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
1005 ksym.value = msym->value;
1006 strncpy(ksym.name, msym->name, sizeof(ksym.name));
1007 ksym.name[sizeof(ksym.name)-1] = '\0';
1008
1009 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
1010 goto out;
1011 ++i, ++table;
1012 }
1013 }
1014out:
1015 unlock_kernel();
1016 return i;
1017}
1018
1019
1020
1021
1022
1023struct module *
1024find_module(const char *name)
1025{
1026 struct module *mod;
1027
1028 for (mod = module_list; mod ; mod = mod->next) {
1029 if (mod->flags & MOD_DELETED)
1030 continue;
1031 if (!strcmp(mod->name, name))
1032 break;
1033 }
1034
1035 return mod;
1036}
1037
1038
1039
1040
1041
1042void
1043free_module(struct module *mod, int tag_freed)
1044{
1045 struct module_ref *dep;
1046 unsigned i;
1047 unsigned long flags;
1048
1049
1050
1051 if (mod->flags & MOD_RUNNING)
1052 {
1053 if(mod->cleanup)
1054 mod->cleanup();
1055 mod->flags &= ~MOD_RUNNING;
1056 }
1057
1058
1059
1060 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
1061 struct module_ref **pp;
1062 for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
1063 continue;
1064 *pp = dep->next_ref;
1065 if (tag_freed && dep->dep->refs == NULL)
1066 dep->dep->flags |= MOD_JUST_FREED;
1067 }
1068
1069
1070
1071 spin_lock_irqsave(&modlist_lock, flags);
1072 if (mod == module_list) {
1073 module_list = mod->next;
1074 } else {
1075 struct module *p;
1076 for (p = module_list; p->next != mod; p = p->next)
1077 continue;
1078 p->next = mod->next;
1079 }
1080 spin_unlock_irqrestore(&modlist_lock, flags);
1081
1082
1083
1084 module_unmap(mod);
1085}
1086
1087
1088
1089
1090
1091int get_module_list(char *p)
1092{
1093 size_t left = PAGE_SIZE;
1094 struct module *mod;
1095 char tmpstr[64];
1096 struct module_ref *ref;
1097
1098 for (mod = module_list; mod != &kernel_module; mod = mod->next) {
1099 long len;
1100 const char *q;
1101
1102#define safe_copy_str(str, len) \
1103 do { \
1104 if (left < len) \
1105 goto fini; \
1106 memcpy(p, str, len); p += len, left -= len; \
1107 } while (0)
1108#define safe_copy_cstr(str) safe_copy_str(str, sizeof(str)-1)
1109
1110 len = strlen(mod->name);
1111 safe_copy_str(mod->name, len);
1112
1113 if ((len = 20 - len) > 0) {
1114 if (left < len)
1115 goto fini;
1116 memset(p, ' ', len);
1117 p += len;
1118 left -= len;
1119 }
1120
1121 len = sprintf(tmpstr, "%8lu", mod->size);
1122 safe_copy_str(tmpstr, len);
1123
1124 if (mod->flags & MOD_RUNNING) {
1125 len = sprintf(tmpstr, "%4ld",
1126 (mod_member_present(mod, can_unload)
1127 && mod->can_unload
1128 ? -1L : (long)atomic_read(&mod->uc.usecount)));
1129 safe_copy_str(tmpstr, len);
1130 }
1131
1132 if (mod->flags & MOD_DELETED)
1133 safe_copy_cstr(" (deleted)");
1134 else if (mod->flags & MOD_RUNNING) {
1135 if (mod->flags & MOD_AUTOCLEAN)
1136 safe_copy_cstr(" (autoclean)");
1137 if (!(mod->flags & MOD_USED_ONCE))
1138 safe_copy_cstr(" (unused)");
1139 }
1140 else if (mod->flags & MOD_INITIALIZING)
1141 safe_copy_cstr(" (initializing)");
1142 else
1143 safe_copy_cstr(" (uninitialized)");
1144
1145 if ((ref = mod->refs) != NULL) {
1146 safe_copy_cstr(" [");
1147 while (1) {
1148 q = ref->ref->name;
1149 len = strlen(q);
1150 safe_copy_str(q, len);
1151
1152 if ((ref = ref->next_ref) != NULL)
1153 safe_copy_cstr(" ");
1154 else
1155 break;
1156 }
1157 safe_copy_cstr("]");
1158 }
1159 safe_copy_cstr("\n");
1160
1161#undef safe_copy_str
1162#undef safe_copy_cstr
1163 }
1164
1165fini:
1166 return PAGE_SIZE - left;
1167}
1168
1169
1170
1171
1172
1173struct mod_sym {
1174 struct module *mod;
1175 int index;
1176};
1177
1178
1179
1180static void *s_start(struct seq_file *m, loff_t *pos)
1181{
1182 struct mod_sym *p = kmalloc(sizeof(*p), GFP_KERNEL);
1183 struct module *v;
1184 loff_t n = *pos;
1185
1186 if (!p)
1187 return ERR_PTR(-ENOMEM);
1188 lock_kernel();
1189 for (v = module_list, n = *pos; v; n -= v->nsyms, v = v->next) {
1190 if (n < v->nsyms) {
1191 p->mod = v;
1192 p->index = n;
1193 return p;
1194 }
1195 }
1196 unlock_kernel();
1197 kfree(p);
1198 return NULL;
1199}
1200
1201static void *s_next(struct seq_file *m, void *p, loff_t *pos)
1202{
1203 struct mod_sym *v = p;
1204 (*pos)++;
1205 if (++v->index >= v->mod->nsyms) {
1206 do {
1207 v->mod = v->mod->next;
1208 if (!v->mod) {
1209 unlock_kernel();
1210 kfree(p);
1211 return NULL;
1212 }
1213 } while (!v->mod->nsyms);
1214 v->index = 0;
1215 }
1216 return p;
1217}
1218
1219static void s_stop(struct seq_file *m, void *p)
1220{
1221 if (p && !IS_ERR(p)) {
1222 unlock_kernel();
1223 kfree(p);
1224 }
1225}
1226
1227static int s_show(struct seq_file *m, void *p)
1228{
1229 struct mod_sym *v = p;
1230 struct module_symbol *sym;
1231
1232 if (!MOD_CAN_QUERY(v->mod))
1233 return 0;
1234 sym = &v->mod->syms[v->index];
1235 if (*v->mod->name)
1236 seq_printf(m, "%0*lx %s\t[%s]\n", (int)(2*sizeof(void*)),
1237 sym->value, sym->name, v->mod->name);
1238 else
1239 seq_printf(m, "%0*lx %s\n", (int)(2*sizeof(void*)),
1240 sym->value, sym->name);
1241 return 0;
1242}
1243
1244struct seq_operations ksyms_op = {
1245 start: s_start,
1246 next: s_next,
1247 stop: s_stop,
1248 show: s_show
1249};
1250
1251#else
1252
1253
1254
1255asmlinkage unsigned long
1256sys_create_module(const char *name_user, size_t size)
1257{
1258 return -ENOSYS;
1259}
1260
1261asmlinkage long
1262sys_init_module(const char *name_user, struct module *mod_user)
1263{
1264 return -ENOSYS;
1265}
1266
1267asmlinkage long
1268sys_delete_module(const char *name_user)
1269{
1270 return -ENOSYS;
1271}
1272
1273asmlinkage long
1274sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
1275 size_t *ret)
1276{
1277
1278
1279 if (which == 0)
1280 return 0;
1281
1282 return -ENOSYS;
1283}
1284
1285asmlinkage long
1286sys_get_kernel_syms(struct kernel_sym *table)
1287{
1288 return -ENOSYS;
1289}
1290
1291int try_inc_mod_count(struct module *mod)
1292{
1293 return 1;
1294}
1295
1296#endif
1297