1#include <linux/errno.h>
2#include <linux/kernel.h>
3#include <linux/mm.h>
4#include <linux/string.h>
5#include <linux/module.h>
6#include <linux/sched.h>
7#include <linux/config.h>
8#include <asm/uaccess.h>
9#include <linux/vmalloc.h>
10#include <linux/smp.h>
11#include <linux/smp_lock.h>
12#include <asm/pgtable.h>
13
14
15
16
17
18
19
20
21
22
23
24#ifdef CONFIG_MODULES
25
26extern struct module_symbol __start___ksymtab[];
27extern struct module_symbol __stop___ksymtab[];
28
29extern const struct exception_table_entry __start___ex_table[];
30extern const struct exception_table_entry __stop___ex_table[];
31
32static struct module kernel_module =
33{
34 sizeof(struct module),
35 NULL,
36 "",
37 0,
38 1,
39 MOD_RUNNING,
40 0,
41 0,
42 __start___ksymtab,
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 __start___ex_table,
48 __stop___ex_table,
49
50};
51
52struct module *module_list = &kernel_module;
53
54static long get_mod_name(const char *user_name, char **buf);
55static void put_mod_name(char *buf);
56static struct module *find_module(const char *name);
57static void free_module(struct module *);
58
59
60
61
62
63
64void init_modules(void)
65{
66 kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
67
68#ifdef __alpha__
69 __asm__("stq $29,%0" : "=m"(kernel_module.gp));
70#endif
71}
72
73
74
75
76
77static inline long
78get_mod_name(const char *user_name, char **buf)
79{
80 unsigned long page;
81 long retval;
82
83 if ((unsigned long)user_name >= TASK_SIZE
84 && get_fs () != KERNEL_DS)
85 return -EFAULT;
86
87 page = __get_free_page(GFP_KERNEL);
88 if (!page)
89 return -ENOMEM;
90
91 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
92 if (retval > 0) {
93 if (retval < PAGE_SIZE) {
94 *buf = (char *)page;
95 return retval;
96 }
97 retval = -ENAMETOOLONG;
98 } else if (!retval)
99 retval = -EINVAL;
100
101 free_page(page);
102 return retval;
103}
104
105static inline void
106put_mod_name(char *buf)
107{
108 free_page((unsigned long)buf);
109}
110
111
112
113
114
115asmlinkage unsigned long
116sys_create_module(const char *name_user, size_t size)
117{
118 char *name;
119 long namelen, error;
120 struct module *mod;
121
122 lock_kernel();
123 if (!suser()) {
124 error = -EPERM;
125 goto err0;
126 }
127 if ((namelen = get_mod_name(name_user, &name)) < 0) {
128 error = namelen;
129 goto err0;
130 }
131 if (size < sizeof(struct module)+namelen) {
132 error = -EINVAL;
133 goto err1;
134 }
135 if (find_module(name) != NULL) {
136 error = -EEXIST;
137 goto err1;
138 }
139 if ((mod = (struct module *)module_map(size)) == NULL) {
140 error = -ENOMEM;
141 goto err1;
142 }
143
144 memset(mod, 0, sizeof(*mod));
145 mod->size_of_struct = sizeof(*mod);
146 mod->next = module_list;
147 mod->name = (char *)(mod + 1);
148 mod->size = size;
149 memcpy((char*)(mod+1), name, namelen+1);
150
151 put_mod_name(name);
152
153 module_list = mod;
154
155 error = (long) mod;
156 goto err0;
157err1:
158 put_mod_name(name);
159err0:
160 unlock_kernel();
161 return error;
162}
163
164
165
166
167
168asmlinkage int
169sys_init_module(const char *name_user, struct module *mod_user)
170{
171 struct module mod_tmp, *mod;
172 char *name, *n_name;
173 long namelen, n_namelen, i, error = -EPERM;
174 unsigned long mod_user_size;
175 struct module_ref *dep;
176
177 lock_kernel();
178 if (!suser())
179 goto err0;
180 if ((namelen = get_mod_name(name_user, &name)) < 0) {
181 error = namelen;
182 goto err0;
183 }
184 if ((mod = find_module(name)) == NULL) {
185 error = -ENOENT;
186 goto err1;
187 }
188
189
190
191
192 if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0)
193 goto err1;
194 if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start
195 || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) {
196 printk(KERN_ERR "init_module: Invalid module header size.\n"
197 KERN_ERR "A new version of the modutils is likely "
198 "needed.\n");
199 error = -EINVAL;
200 goto err1;
201 }
202
203
204
205 mod_tmp = *mod;
206
207 error = copy_from_user(mod, mod_user, sizeof(struct module));
208 if (error) {
209 error = -EFAULT;
210 goto err2;
211 }
212
213
214 error = -EINVAL;
215
216 if (mod->size > mod_tmp.size) {
217 printk(KERN_ERR "init_module: Size of initialized module "
218 "exceeds size of created module.\n");
219 goto err2;
220 }
221
222
223
224#define bound(p, n, m) ((unsigned long)(p) >= (unsigned long)(m+1) && \
225 (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
226
227 if (!bound(mod->name, namelen, mod)) {
228 printk(KERN_ERR "init_module: mod->name out of bounds.\n");
229 goto err2;
230 }
231 if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
232 printk(KERN_ERR "init_module: mod->syms out of bounds.\n");
233 goto err2;
234 }
235 if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
236 printk(KERN_ERR "init_module: mod->deps out of bounds.\n");
237 goto err2;
238 }
239 if (mod->init && !bound(mod->init, 0, mod)) {
240 printk(KERN_ERR "init_module: mod->init out of bounds.\n");
241 goto err2;
242 }
243 if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
244 printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n");
245 goto err2;
246 }
247 if (mod->ex_table_start > mod->ex_table_end
248 || (mod->ex_table_start &&
249 !((unsigned long)mod->ex_table_start >= (unsigned long)(mod+1)
250 && ((unsigned long)mod->ex_table_end
251 < (unsigned long)mod + mod->size)))
252 || (((unsigned long)mod->ex_table_start
253 - (unsigned long)mod->ex_table_end)
254 % sizeof(struct exception_table_entry))) {
255 printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
256 goto err2;
257 }
258 if (mod->flags & ~MOD_AUTOCLEAN) {
259 printk(KERN_ERR "init_module: mod->flags invalid.\n");
260 goto err2;
261 }
262#ifdef __alpha__
263 if (!bound(mod->gp - 0x8000, 0, mod)) {
264 printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
265 goto err2;
266 }
267#endif
268 if (mod_member_present(mod, can_unload)
269 && mod->can_unload && !bound(mod->can_unload, 0, mod)) {
270 printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");
271 goto err2;
272 }
273
274#undef bound
275
276
277
278 if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod
279 + (unsigned long)mod_user,
280 &n_name)) < 0) {
281 error = n_namelen;
282 goto err2;
283 }
284 if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) {
285 printk(KERN_ERR "init_module: changed module name to "
286 "`%s' from `%s'\n",
287 n_name, mod_tmp.name);
288 goto err3;
289 }
290
291
292
293 if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
294 error = -EFAULT;
295 goto err3;
296 }
297
298
299
300 flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
301
302
303 mod->next = mod_tmp.next;
304 mod->refs = NULL;
305 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
306 struct module *o, *d = dep->dep;
307
308
309 if (d == mod) {
310 printk(KERN_ERR "init_module: self-referential "
311 "dependancy in mod->deps.\n");
312 goto err3;
313 }
314
315 for (o = module_list; o != &kernel_module; o = o->next)
316 if (o == d) goto found_dep;
317
318 printk(KERN_ERR "init_module: found dependancy that is "
319 "(no longer?) a module.\n");
320 goto err3;
321
322 found_dep:
323 dep->ref = mod;
324 dep->next_ref = d->refs;
325 d->refs = dep;
326
327
328 d->flags |= MOD_USED_ONCE;
329 }
330
331
332 put_mod_name(n_name);
333 put_mod_name(name);
334
335
336 mod->usecount = 1;
337 if (mod->init && mod->init() != 0) {
338 mod->usecount = 0;
339 error = -EBUSY;
340 goto err0;
341 }
342 mod->usecount--;
343
344
345 mod->flags |= MOD_RUNNING;
346 error = 0;
347 goto err0;
348
349err3:
350 put_mod_name(n_name);
351err2:
352 *mod = mod_tmp;
353err1:
354 put_mod_name(name);
355err0:
356 unlock_kernel();
357 return error;
358}
359
360asmlinkage int
361sys_delete_module(const char *name_user)
362{
363 struct module *mod, *next;
364 char *name;
365 long error = -EPERM;
366
367 lock_kernel();
368 if (!suser())
369 goto out;
370
371 if (name_user) {
372 if ((error = get_mod_name(name_user, &name)) < 0)
373 goto out;
374 if (error == 0) {
375 error = -EINVAL;
376 put_mod_name(name);
377 goto out;
378 }
379 error = -ENOENT;
380 if ((mod = find_module(name)) == NULL) {
381 put_mod_name(name);
382 goto out;
383 }
384 put_mod_name(name);
385 error = -EBUSY;
386 if (mod->refs != NULL || __MOD_IN_USE(mod))
387 goto out;
388
389 free_module(mod);
390 error = 0;
391 goto out;
392 }
393
394
395 for (mod = module_list; mod != &kernel_module; mod = next) {
396 next = mod->next;
397 if (mod->refs == NULL &&
398 ((mod->flags
399 & (MOD_AUTOCLEAN|MOD_RUNNING|MOD_DELETED|MOD_USED_ONCE))
400 == (MOD_AUTOCLEAN|MOD_RUNNING|MOD_USED_ONCE)) &&
401 !__MOD_IN_USE(mod)) {
402 if (mod->flags & MOD_VISITED)
403 mod->flags &= ~MOD_VISITED;
404 else
405 free_module(mod);
406 }
407 }
408 error = 0;
409out:
410 unlock_kernel();
411 return error;
412}
413
414
415
416static int
417qm_modules(char *buf, size_t bufsize, size_t *ret)
418{
419 struct module *mod;
420 size_t nmod, space, len;
421
422 nmod = space = 0;
423
424 for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) {
425 len = strlen(mod->name)+1;
426 if (len > bufsize)
427 goto calc_space_needed;
428 if (copy_to_user(buf, mod->name, len))
429 return -EFAULT;
430 buf += len;
431 bufsize -= len;
432 space += len;
433 }
434
435 if (put_user(nmod, ret))
436 return -EFAULT;
437 else
438 return 0;
439
440calc_space_needed:
441 space += len;
442 while ((mod = mod->next) != &kernel_module)
443 space += strlen(mod->name)+1;
444
445 if (put_user(space, ret))
446 return -EFAULT;
447 else
448 return -ENOSPC;
449}
450
451static int
452qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret)
453{
454 size_t i, space, len;
455
456 if (mod == &kernel_module)
457 return -EINVAL;
458 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
459 if (put_user(0, ret))
460 return -EFAULT;
461 else
462 return 0;
463
464 space = 0;
465 for (i = 0; i < mod->ndeps; ++i) {
466 const char *dep_name = mod->deps[i].dep->name;
467
468 len = strlen(dep_name)+1;
469 if (len > bufsize)
470 goto calc_space_needed;
471 if (copy_to_user(buf, dep_name, len))
472 return -EFAULT;
473 buf += len;
474 bufsize -= len;
475 space += len;
476 }
477
478 if (put_user(i, ret))
479 return -EFAULT;
480 else
481 return 0;
482
483calc_space_needed:
484 space += len;
485 while (++i < mod->ndeps)
486 space += strlen(mod->deps[i].dep->name)+1;
487
488 if (put_user(space, ret))
489 return -EFAULT;
490 else
491 return -ENOSPC;
492}
493
494static int
495qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret)
496{
497 size_t nrefs, space, len;
498 struct module_ref *ref;
499
500 if (mod == &kernel_module)
501 return -EINVAL;
502 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
503 if (put_user(0, ret))
504 return -EFAULT;
505 else
506 return 0;
507
508 space = 0;
509 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
510 const char *ref_name = ref->ref->name;
511
512 len = strlen(ref_name)+1;
513 if (len > bufsize)
514 goto calc_space_needed;
515 if (copy_to_user(buf, ref_name, len))
516 return -EFAULT;
517 buf += len;
518 bufsize -= len;
519 space += len;
520 }
521
522 if (put_user(nrefs, ret))
523 return -EFAULT;
524 else
525 return 0;
526
527calc_space_needed:
528 space += len;
529 while ((ref = ref->next_ref) != NULL)
530 space += strlen(ref->ref->name)+1;
531
532 if (put_user(space, ret))
533 return -EFAULT;
534 else
535 return -ENOSPC;
536}
537
538static int
539qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret)
540{
541 size_t i, space, len;
542 struct module_symbol *s;
543 char *strings;
544 unsigned long *vals;
545
546 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
547 if (put_user(0, ret))
548 return -EFAULT;
549 else
550 return 0;
551
552 space = mod->nsyms * 2*sizeof(void *);
553
554 i = len = 0;
555 s = mod->syms;
556
557 if (space > bufsize)
558 goto calc_space_needed;
559
560 if (!access_ok(VERIFY_WRITE, buf, space))
561 return -EFAULT;
562
563 bufsize -= space;
564 vals = (unsigned long *)buf;
565 strings = buf+space;
566
567 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
568 len = strlen(s->name)+1;
569 if (len > bufsize)
570 goto calc_space_needed;
571
572 if (copy_to_user(strings, s->name, len)
573 || __put_user(s->value, vals+0)
574 || __put_user(space, vals+1))
575 return -EFAULT;
576
577 strings += len;
578 bufsize -= len;
579 space += len;
580 }
581
582 if (put_user(i, ret))
583 return -EFAULT;
584 else
585 return 0;
586
587calc_space_needed:
588 for (; i < mod->nsyms; ++i, ++s)
589 space += strlen(s->name)+1;
590
591 if (put_user(space, ret))
592 return -EFAULT;
593 else
594 return -ENOSPC;
595}
596
597static int
598qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret)
599{
600 int error = 0;
601
602 if (mod == &kernel_module)
603 return -EINVAL;
604
605 if (sizeof(struct module_info) <= bufsize) {
606 struct module_info info;
607 info.addr = (unsigned long)mod;
608 info.size = mod->size;
609 info.flags = mod->flags;
610 info.usecount = (mod_member_present(mod, can_unload)
611 && mod->can_unload ? -1 : mod->usecount);
612
613 if (copy_to_user(buf, &info, sizeof(struct module_info)))
614 return -EFAULT;
615 } else
616 error = -ENOSPC;
617
618 if (put_user(sizeof(struct module_info), ret))
619 return -EFAULT;
620
621 return error;
622}
623
624asmlinkage int
625sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
626 size_t *ret)
627{
628 struct module *mod;
629 int err;
630
631 lock_kernel();
632 if (name_user == NULL)
633 mod = &kernel_module;
634 else {
635 long namelen;
636 char *name;
637
638 if ((namelen = get_mod_name(name_user, &name)) < 0) {
639 err = namelen;
640 goto out;
641 }
642 err = -ENOENT;
643 if (namelen == 0)
644 mod = &kernel_module;
645 else if ((mod = find_module(name)) == NULL) {
646 put_mod_name(name);
647 goto out;
648 }
649 put_mod_name(name);
650 }
651
652 switch (which)
653 {
654 case 0:
655 err = 0;
656 break;
657 case QM_MODULES:
658 err = qm_modules(buf, bufsize, ret);
659 break;
660 case QM_DEPS:
661 err = qm_deps(mod, buf, bufsize, ret);
662 break;
663 case QM_REFS:
664 err = qm_refs(mod, buf, bufsize, ret);
665 break;
666 case QM_SYMBOLS:
667 err = qm_symbols(mod, buf, bufsize, ret);
668 break;
669 case QM_INFO:
670 err = qm_info(mod, buf, bufsize, ret);
671 break;
672 default:
673 err = -EINVAL;
674 break;
675 }
676out:
677 unlock_kernel();
678 return err;
679}
680
681
682
683
684
685
686
687
688
689asmlinkage int
690sys_get_kernel_syms(struct kernel_sym *table)
691{
692 struct module *mod;
693 int i;
694 struct kernel_sym ksym;
695
696 lock_kernel();
697 for (mod = module_list, i = 0; mod; mod = mod->next) {
698
699 i += mod->nsyms + 1;
700 }
701
702 if (table == NULL)
703 goto out;
704
705
706 memset (&ksym, 0, sizeof (ksym));
707
708 for (mod = module_list, i = 0; mod; mod = mod->next) {
709 struct module_symbol *msym;
710 unsigned int j;
711
712 if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) != MOD_RUNNING)
713 continue;
714
715
716 ksym.value = (unsigned long)mod;
717 ksym.name[0] = '#';
718 strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
719 ksym.name[sizeof(ksym.name)-1] = '\0';
720
721 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
722 goto out;
723 ++i, ++table;
724
725 if (mod->nsyms == 0)
726 continue;
727
728 for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) {
729 ksym.value = msym->value;
730 strncpy(ksym.name, msym->name, sizeof(ksym.name));
731 ksym.name[sizeof(ksym.name)-1] = '\0';
732
733 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
734 goto out;
735 ++i, ++table;
736 }
737 }
738out:
739 unlock_kernel();
740 return i;
741}
742
743
744
745
746
747static struct module *
748find_module(const char *name)
749{
750 struct module *mod;
751
752 for (mod = module_list; mod ; mod = mod->next) {
753 if (mod->flags & MOD_DELETED)
754 continue;
755 if (!strcmp(mod->name, name))
756 break;
757 }
758
759 return mod;
760}
761
762
763
764
765
766static void
767free_module(struct module *mod)
768{
769 struct module_ref *dep;
770 unsigned i;
771
772
773
774 mod->flags |= MOD_DELETED;
775 if (mod->flags & MOD_RUNNING) {
776 mod->cleanup();
777 mod->flags &= ~MOD_RUNNING;
778 }
779
780
781
782 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) {
783 struct module_ref **pp;
784 for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
785 continue;
786 *pp = dep->next_ref;
787 }
788
789
790
791 if (mod == module_list) {
792 module_list = mod->next;
793 } else {
794 struct module *p;
795 for (p = module_list; p->next != mod; p = p->next)
796 continue;
797 p->next = mod->next;
798 }
799
800
801
802 module_unmap(mod);
803}
804
805
806
807
808
809int get_module_list(char *p)
810{
811 size_t left = PAGE_SIZE;
812 struct module *mod;
813 char tmpstr[64];
814 struct module_ref *ref;
815
816 for (mod = module_list; mod != &kernel_module; mod = mod->next) {
817 long len;
818 const char *q;
819
820#define safe_copy_str(str, len) \
821 do { \
822 if (left < len) \
823 goto fini; \
824 memcpy(p, str, len); p += len, left -= len; \
825 } while (0)
826#define safe_copy_cstr(str) safe_copy_str(str, sizeof(str)-1)
827
828 len = strlen(mod->name);
829 safe_copy_str(mod->name, len);
830
831 if ((len = 20 - len) > 0) {
832 if (left < len)
833 goto fini;
834 memset(p, ' ', len);
835 p += len;
836 left -= len;
837 }
838
839 len = sprintf(tmpstr, "%8lu", mod->size);
840 safe_copy_str(tmpstr, len);
841
842 if (mod->flags & MOD_RUNNING) {
843 len = sprintf(tmpstr, "%4ld",
844 (mod_member_present(mod, can_unload)
845 && mod->can_unload
846 ? -1 : mod->usecount));
847 safe_copy_str(tmpstr, len);
848 }
849
850 if (mod->flags & MOD_DELETED)
851 safe_copy_cstr(" (deleted)");
852 else if (mod->flags & MOD_RUNNING) {
853 if (mod->flags & MOD_AUTOCLEAN)
854 safe_copy_cstr(" (autoclean)");
855 if (!(mod->flags & MOD_USED_ONCE))
856 safe_copy_cstr(" (unused)");
857 } else
858 safe_copy_cstr(" (uninitialized)");
859
860 if ((ref = mod->refs) != NULL) {
861 safe_copy_cstr(" [");
862 while (1) {
863 q = ref->ref->name;
864 len = strlen(q);
865 safe_copy_str(q, len);
866
867 if ((ref = ref->next_ref) != NULL)
868 safe_copy_cstr(" ");
869 else
870 break;
871 }
872 safe_copy_cstr("]");
873 }
874
875 safe_copy_cstr("\n");
876
877#undef safe_copy_str
878#undef safe_copy_cstr
879 }
880
881fini:
882 return PAGE_SIZE - left;
883}
884
885
886
887
888
889int
890get_ksyms_list(char *buf, char **start, off_t offset, int length)
891{
892 struct module *mod;
893 char *p = buf;
894 int len = 0;
895 off_t pos = 0;
896 off_t begin = 0;
897
898 for (mod = module_list; mod; mod = mod->next) {
899 unsigned i;
900 struct module_symbol *sym;
901
902 if (!(mod->flags & MOD_RUNNING) || (mod->flags & MOD_DELETED))
903 continue;
904
905 for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) {
906 p = buf + len;
907 if (*mod->name) {
908 len += sprintf(p, "%0*lx %s\t[%s]\n",
909 (int)(2*sizeof(void*)),
910 sym->value, sym->name,
911 mod->name);
912 } else {
913 len += sprintf(p, "%0*lx %s\n",
914 (int)(2*sizeof(void*)),
915 sym->value, sym->name);
916 }
917 pos = begin + len;
918 if (pos < offset) {
919 len = 0;
920 begin = pos;
921 }
922 pos = begin + len;
923 if (pos > offset+length)
924 goto leave_the_loop;
925 }
926 }
927leave_the_loop:
928 *start = buf + (offset - begin);
929 len -= (offset - begin);
930 if (len > length)
931 len = length;
932 return len;
933}
934
935#else
936
937
938
939asmlinkage unsigned long
940sys_create_module(const char *name_user, size_t size)
941{
942 return -ENOSYS;
943}
944
945asmlinkage int
946sys_init_module(const char *name_user, struct module *mod_user)
947{
948 return -ENOSYS;
949}
950
951asmlinkage int
952sys_delete_module(const char *name_user)
953{
954 return -ENOSYS;
955}
956
957asmlinkage int
958sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
959 size_t *ret)
960{
961
962
963 if (which == 0)
964 return 0;
965
966 return -ENOSYS;
967}
968
969asmlinkage int
970sys_get_kernel_syms(struct kernel_sym *table)
971{
972 return -ENOSYS;
973}
974
975#endif
976