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