kernel/module.c
24476 #include <linux/config.h>
24477 #include <linux/mm.h>
24478 #include <linux/module.h>
24479 #include <asm/uaccess.h>
24480 #include <linux/vmalloc.h>
24481 #include <linux/smp_lock.h>
24482 #include <asm/pgtable.h>
24483 #include <linux/init.h>
24484
24485 /* Originally by Anonymous (as far as I know...)
24486 * Linux version by Bas Laarhoven <bas@vimec.nl>
24487 * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>,
24488 * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May
24489 * 1994 (C)
24490 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
24491 *
24492 * This source is covered by the GNU GPL, the same as all
24493 * kernel sources. */
24494
24495 #ifdef CONFIG_MODULES /* a *big* #ifdef block... */
24496
24497 extern struct module_symbol __start___ksymtab[];
24498 extern struct module_symbol __stop___ksymtab[];
24499
24500 extern const struct exception_table_entry
24501 __start___ex_table[];
24502 extern const struct exception_table_entry
24503 __stop___ex_table[];
24504
24505 static struct module kernel_module =
24506 {
24507 sizeof(struct module), /* size_of_struct */
24508 NULL, /* next */
24509 "", /* name */
24510 0, /* size */
24511 {ATOMIC_INIT(1)}, /* usecount */
24512 MOD_RUNNING, /* flags */
24513 0, /* nsyms -- filled in in init_modules */
24514 0, /* ndeps */
24515 __start___ksymtab, /* syms */
24516 NULL, /* deps */
24517 NULL, /* refs */
24518 NULL, /* init */
24519 NULL, /* cleanup */
24520 __start___ex_table, /* ex_table_start */
24521 __stop___ex_table, /* ex_table_end */
24522 /* Rest are NULL */
24523 };
24524
24525 struct module *module_list = &kernel_module;
24526
24527 static long get_mod_name(const char *user_name,
24528 char **buf);
24529 static void put_mod_name(char *buf);
24530 static struct module *find_module(const char *name);
24531 static void free_module(struct module *, int tag_freed);
24532
24533
24534 /* Called at boot time */
24535
24536 __initfunc(void init_modules(void))
24537 {
24538 kernel_module.nsyms =
24539 __stop___ksymtab - __start___ksymtab;
24540
24541 #ifdef __alpha__
24542 __asm__("stq $29,%0" : "=m"(kernel_module.gp));
24543 #endif
24544 }
24545
24546 /* Copy the name of a module from user space. */
24547
24548 static inline long
24549 get_mod_name(const char *user_name, char **buf)
24550 {
24551 unsigned long page;
24552 long retval;
24553
24554 if ((unsigned long)user_name >= TASK_SIZE
24555 && !segment_eq(get_fs (), KERNEL_DS))
24556 return -EFAULT;
24557
24558 page = __get_free_page(GFP_KERNEL);
24559 if (!page)
24560 return -ENOMEM;
24561
24562 retval = strncpy_from_user((char *)page, user_name,
24563 PAGE_SIZE);
24564 if (retval > 0) {
24565 if (retval < PAGE_SIZE) {
24566 *buf = (char *)page;
24567 return retval;
24568 }
24569 retval = -ENAMETOOLONG;
24570 } else if (!retval)
24571 retval = -EINVAL;
24572
24573 free_page(page);
24574 return retval;
24575 }
24576
24577 static inline void
24578 put_mod_name(char *buf)
24579 {
24580 free_page((unsigned long)buf);
24581 }
24582
24583 /* Allocate space for a module. */
24584
24585 asmlinkage unsigned long
24586 sys_create_module(const char *name_user, size_t size)
24587 {
24588 char *name;
24589 long namelen, error;
24590 struct module *mod;
24591
24592 lock_kernel();
24593 if (!capable(CAP_SYS_MODULE)) {
24594 error = -EPERM;
24595 goto err0;
24596 }
24597 if ((namelen = get_mod_name(name_user, &name)) < 0) {
24598 error = namelen;
24599 goto err0;
24600 }
24601 if (size < sizeof(struct module)+namelen) {
24602 error = -EINVAL;
24603 goto err1;
24604 }
24605 if (find_module(name) != NULL) {
24606 error = -EEXIST;
24607 goto err1;
24608 }
24609 if ((mod = (struct module *)module_map(size)) == NULL){
24610 error = -ENOMEM;
24611 goto err1;
24612 }
24613
24614 memset(mod, 0, sizeof(*mod));
24615 mod->size_of_struct = sizeof(*mod);
24616 mod->next = module_list;
24617 mod->name = (char *)(mod + 1);
24618 mod->size = size;
24619 memcpy((char*)(mod+1), name, namelen+1);
24620
24621 put_mod_name(name);
24622
24623 module_list = mod; /* link it in */
24624
24625 error = (long) mod;
24626 goto err0;
24627 err1:
24628 put_mod_name(name);
24629 err0:
24630 unlock_kernel();
24631 return error;
24632 }
24633
24634 /* Initialize a module. */
24635
24636 asmlinkage int
24637 sys_init_module(const char *name_user,
24638 struct module *mod_user)
24639 {
24640 struct module mod_tmp, *mod;
24641 char *name, *n_name;
24642 long namelen, n_namelen, i, error = -EPERM;
24643 unsigned long mod_user_size;
24644 struct module_ref *dep;
24645
24646 lock_kernel();
24647 if (!capable(CAP_SYS_MODULE))
24648 goto err0;
24649 if ((namelen = get_mod_name(name_user, &name)) < 0) {
24650 error = namelen;
24651 goto err0;
24652 }
24653 if ((mod = find_module(name)) == NULL) {
24654 error = -ENOENT;
24655 goto err1;
24656 }
24657
24658 /* Check module header size. We allow a bit of slop
24659 * over the size we are familiar with to cope with a
24660 * version of insmod for a newer kernel. But don't
24661 * over do it. */
24662 if ((error = get_user(mod_user_size,
24663 &mod_user->size_of_struct)) != 0)
24664 goto err1;
24665 if (mod_user_size <
24666 (unsigned long)&((struct module *)0L)->persist_start
24667 || mod_user_size >
24668 sizeof(struct module) + 16*sizeof(void*)) {
24669 printk(KERN_ERR
24670 "init_module: Invalid module header size.\n"
24671 KERN_ERR
24672 "A new version of the modutils is likely "
24673 "needed.\n");
24674 error = -EINVAL;
24675 goto err1;
24676 }
24677
24678 /* Hold the current contents while we play with the
24679 * user's idea of righteousness. */
24680 mod_tmp = *mod;
24681
24682 error = copy_from_user(mod, mod_user,
24683 sizeof(struct module));
24684 if (error) {
24685 error = -EFAULT;
24686 goto err2;
24687 }
24688
24689 /* Sanity check the size of the module. */
24690 error = -EINVAL;
24691
24692 if (mod->size > mod_tmp.size) {
24693 printk(KERN_ERR
24694 "init_module: Size of initialized module "
24695 "exceeds size of created module.\n");
24696 goto err2;
24697 }
24698
24699 /* Make sure all interesting pointers are sane. */
24700
24701 #define bound(p, n, m) \
24702 ((unsigned long)(p) >= (unsigned long)(m+1) && \
24703 (unsigned long)((p)+(n)) <= \
24704 (unsigned long)(m) + (m)->size)
24705
24706 if (!bound(mod->name, namelen, mod)) {
24707 printk(KERN_ERR
24708 "init_module: mod->name out of bounds.\n");
24709 goto err2;
24710 }
24711 if (mod->nsyms && !bound(mod->syms, mod->nsyms, mod)) {
24712 printk(KERN_ERR
24713 "init_module: mod->syms out of bounds.\n");
24714 goto err2;
24715 }
24716 if (mod->ndeps && !bound(mod->deps, mod->ndeps, mod)) {
24717 printk(KERN_ERR
24718 "init_module: mod->deps out of bounds.\n");
24719 goto err2;
24720 }
24721 if (mod->init && !bound(mod->init, 0, mod)) {
24722 printk(KERN_ERR
24723 "init_module: mod->init out of bounds.\n");
24724 goto err2;
24725 }
24726 if (mod->cleanup && !bound(mod->cleanup, 0, mod)) {
24727 printk(KERN_ERR
24728 "init_module: mod->cleanup out of bounds.\n");
24729 goto err2;
24730 }
24731 if (mod->ex_table_start > mod->ex_table_end
24732 || (mod->ex_table_start &&
24733 !((unsigned long)mod->ex_table_start >=
24734 (unsigned long)(mod+1)
24735 && ((unsigned long)mod->ex_table_end
24736 < (unsigned long)mod + mod->size)))
24737 || (((unsigned long)mod->ex_table_start
24738 - (unsigned long)mod->ex_table_end)
24739 % sizeof(struct exception_table_entry))) {
24740 printk(KERN_ERR
24741 "init_module: mod->ex_table_* invalid.\n");
24742 goto err2;
24743 }
24744 if (mod->flags & ~MOD_AUTOCLEAN) {
24745 printk(KERN_ERR
24746 "init_module: mod->flags invalid.\n");
24747 goto err2;
24748 }
24749 #ifdef __alpha__
24750 if (!bound(mod->gp - 0x8000, 0, mod)) {
24751 printk(KERN_ERR
24752 "init_module: mod->gp out of bounds.\n");
24753 goto err2;
24754 }
24755 #endif
24756 if (mod_member_present(mod, can_unload) &&
24757 mod->can_unload &&
24758 !bound(mod->can_unload, 0, mod)) {
24759 printk(KERN_ERR "init_module: mod->can_unload out "
24760 "of bounds.\n");
24761 goto err2;
24762 }
24763
24764 #undef bound
24765
24766 /* Check that the user isn't doing something silly with
24767 * the name. */
24768
24769 if ((n_namelen =
24770 get_mod_name(mod->name - (unsigned long) mod
24771 + (unsigned long) mod_user,
24772 &n_name)) < 0) {
24773 error = n_namelen;
24774 goto err2;
24775 }
24776 if (namelen != n_namelen ||
24777 strcmp(n_name, mod_tmp.name) != 0) {
24778 printk(KERN_ERR
24779 "init_module: changed module name to "
24780 "`%s' from `%s'\n", n_name, mod_tmp.name);
24781 goto err3;
24782 }
24783
24784 /* Ok, that's about all the sanity we can stomach; copy
24785 * the rest. */
24786 if (copy_from_user(mod+1, mod_user+1,
24787 mod->size - sizeof(*mod))) {
24788 error = -EFAULT;
24789 goto err3;
24790 }
24791
24792 /* On some machines it is necessary to do something
24793 here to make the I and D caches consistent. */
24794 flush_icache_range((unsigned long)mod,
24795 (unsigned long)mod + mod->size);
24796
24797 /* Update module references. */
24798 mod->next = mod_tmp.next;
24799 mod->refs = NULL;
24800 for (i = 0, dep = mod->deps; i < mod->ndeps;
24801 ++i, ++dep) {
24802 struct module *o, *d = dep->dep;
24803
24804 /* Make sure the indicated dependencies are really
24805 * modules. */
24806 if (d == mod) {
24807 printk(KERN_ERR "init_module: self-referential "
24808 "dependency in mod->deps.\n");
24809 goto err3;
24810 }
24811
24812 for (o = module_list; o != &kernel_module;
24813 o = o->next)
24814 if (o == d) goto found_dep;
24815
24816 printk(KERN_ERR
24817 "init_module: found dependency that is "
24818 "(no longer?) a module.\n");
24819 goto err3;
24820
24821 found_dep:
24822 dep->ref = mod;
24823 dep->next_ref = d->refs;
24824 d->refs = dep;
24825 /* Being referenced by a dependent module counts as a
24826 * use as far as kmod is concerned. */
24827 d->flags |= MOD_USED_ONCE;
24828 }
24829
24830 /* Free our temporary memory. */
24831 put_mod_name(n_name);
24832 put_mod_name(name);
24833
24834 /* Initialize the module. */
24835 atomic_set(&mod->uc.usecount,1);
24836 if (mod->init && mod->init() != 0) {
24837 atomic_set(&mod->uc.usecount,0);
24838 error = -EBUSY;
24839 goto err0;
24840 }
24841 atomic_dec(&mod->uc.usecount);
24842
24843 /* And set it running. */
24844 mod->flags |= MOD_RUNNING;
24845 error = 0;
24846 goto err0;
24847
24848 err3:
24849 put_mod_name(n_name);
24850 err2:
24851 *mod = mod_tmp;
24852 err1:
24853 put_mod_name(name);
24854 err0:
24855 unlock_kernel();
24856 return error;
24857 }
24858
24859 asmlinkage int
24860 sys_delete_module(const char *name_user)
24861 {
24862 struct module *mod, *next;
24863 char *name;
24864 long error = -EPERM;
24865 int something_changed;
24866
24867 lock_kernel();
24868 if (!capable(CAP_SYS_MODULE))
24869 goto out;
24870
24871 if (name_user) {
24872 if ((error = get_mod_name(name_user, &name)) < 0)
24873 goto out;
24874 if (error == 0) {
24875 error = -EINVAL;
24876 put_mod_name(name);
24877 goto out;
24878 }
24879 error = -ENOENT;
24880 if ((mod = find_module(name)) == NULL) {
24881 put_mod_name(name);
24882 goto out;
24883 }
24884 put_mod_name(name);
24885 error = -EBUSY;
24886 if (mod->refs != NULL || __MOD_IN_USE(mod))
24887 goto out;
24888
24889 free_module(mod, 0);
24890 error = 0;
24891 goto out;
24892 }
24893
24894 /* Do automatic reaping */
24895 restart:
24896 something_changed = 0;
24897 for (mod = module_list; mod != &kernel_module;
24898 mod = next) {
24899 next = mod->next;
24900 if (mod->refs == NULL
24901 && (mod->flags & MOD_AUTOCLEAN)
24902 && (mod->flags & MOD_RUNNING)
24903 && !(mod->flags & MOD_DELETED)
24904 && (mod->flags & MOD_USED_ONCE)
24905 && !__MOD_IN_USE(mod)) {
24906 if ((mod->flags & MOD_VISITED)
24907 && !(mod->flags & MOD_JUST_FREED)) {
24908 mod->flags &= ~MOD_VISITED;
24909 } else {
24910 free_module(mod, 1);
24911 something_changed = 1;
24912 }
24913 }
24914 }
24915 if (something_changed)
24916 goto restart;
24917 for (mod = module_list; mod != &kernel_module;
24918 mod = mod->next)
24919 mod->flags &= ~MOD_JUST_FREED;
24920 error = 0;
24921 out:
24922 unlock_kernel();
24923 return error;
24924 }
24925
24926 /* Query various bits about modules. */
24927
24928 static int
24929 qm_modules(char *buf, size_t bufsize, size_t *ret)
24930 {
24931 struct module *mod;
24932 size_t nmod, space, len;
24933
24934 nmod = space = 0;
24935
24936 for (mod = module_list; mod != &kernel_module;
24937 mod = mod->next, ++nmod) {
24938 len = strlen(mod->name)+1;
24939 if (len > bufsize)
24940 goto calc_space_needed;
24941 if (copy_to_user(buf, mod->name, len))
24942 return -EFAULT;
24943 buf += len;
24944 bufsize -= len;
24945 space += len;
24946 }
24947
24948 if (put_user(nmod, ret))
24949 return -EFAULT;
24950 else
24951 return 0;
24952
24953 calc_space_needed:
24954 space += len;
24955 while ((mod = mod->next) != &kernel_module)
24956 space += strlen(mod->name)+1;
24957
24958 if (put_user(space, ret))
24959 return -EFAULT;
24960 else
24961 return -ENOSPC;
24962 }
24963
24964 static int
24965 qm_deps(struct module *mod, char *buf, size_t bufsize,
24966 size_t *ret)
24967 {
24968 size_t i, space, len;
24969
24970 if (mod == &kernel_module)
24971 return -EINVAL;
24972 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_
24973 RUNNING)
24974 if (put_user(0, ret))
24975 return -EFAULT;
24976 else
24977 return 0;
24978
24979 space = 0;
24980 for (i = 0; i < mod->ndeps; ++i) {
24981 const char *dep_name = mod->deps[i].dep->name;
24982
24983 len = strlen(dep_name)+1;
24984 if (len > bufsize)
24985 goto calc_space_needed;
24986 if (copy_to_user(buf, dep_name, len))
24987 return -EFAULT;
24988 buf += len;
24989 bufsize -= len;
24990 space += len;
24991 }
24992
24993 if (put_user(i, ret))
24994 return -EFAULT;
24995 else
24996 return 0;
24997
24998 calc_space_needed:
24999 space += len;
25000 while (++i < mod->ndeps)
25001 space += strlen(mod->deps[i].dep->name)+1;
25002
25003 if (put_user(space, ret))
25004 return -EFAULT;
25005 else
25006 return -ENOSPC;
25007 }
25008
25009 static int
25010 qm_refs(struct module *mod, char *buf, size_t bufsize,
25011 size_t *ret)
25012 {
25013 size_t nrefs, space, len;
25014 struct module_ref *ref;
25015
25016 if (mod == &kernel_module)
25017 return -EINVAL;
25018 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) !=
25019 MOD_RUNNING)
25020 if (put_user(0, ret))
25021 return -EFAULT;
25022 else
25023 return 0;
25024
25025 space = 0;
25026 for (nrefs = 0, ref = mod->refs; ref;
25027 ++nrefs, ref = ref->next_ref) {
25028 const char *ref_name = ref->ref->name;
25029
25030 len = strlen(ref_name)+1;
25031 if (len > bufsize)
25032 goto calc_space_needed;
25033 if (copy_to_user(buf, ref_name, len))
25034 return -EFAULT;
25035 buf += len;
25036 bufsize -= len;
25037 space += len;
25038 }
25039
25040 if (put_user(nrefs, ret))
25041 return -EFAULT;
25042 else
25043 return 0;
25044
25045 calc_space_needed:
25046 space += len;
25047 while ((ref = ref->next_ref) != NULL)
25048 space += strlen(ref->ref->name)+1;
25049
25050 if (put_user(space, ret))
25051 return -EFAULT;
25052 else
25053 return -ENOSPC;
25054 }
25055
25056 static int
25057 qm_symbols(struct module *mod, char *buf, size_t bufsize,
25058 size_t *ret)
25059 {
25060 size_t i, space, len;
25061 struct module_symbol *s;
25062 char *strings;
25063 unsigned long *vals;
25064
25065 if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) !=
25066 MOD_RUNNING)
25067 if (put_user(0, ret))
25068 return -EFAULT;
25069 else
25070 return 0;
25071
25072 space = mod->nsyms * 2*sizeof(void *);
25073
25074 i = len = 0;
25075 s = mod->syms;
25076
25077 if (space > bufsize)
25078 goto calc_space_needed;
25079
25080 if (!access_ok(VERIFY_WRITE, buf, space))
25081 return -EFAULT;
25082
25083 bufsize -= space;
25084 vals = (unsigned long *)buf;
25085 strings = buf+space;
25086
25087 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
25088 len = strlen(s->name)+1;
25089 if (len > bufsize)
25090 goto calc_space_needed;
25091
25092 if (copy_to_user(strings, s->name, len)
25093 || __put_user(s->value, vals+0)
25094 || __put_user(space, vals+1))
25095 return -EFAULT;
25096
25097 strings += len;
25098 bufsize -= len;
25099 space += len;
25100 }
25101
25102 if (put_user(i, ret))
25103 return -EFAULT;
25104 else
25105 return 0;
25106
25107 calc_space_needed:
25108 for (; i < mod->nsyms; ++i, ++s)
25109 space += strlen(s->name)+1;
25110
25111 if (put_user(space, ret))
25112 return -EFAULT;
25113 else
25114 return -ENOSPC;
25115 }
25116
25117 static int
25118 qm_info(struct module *mod, char *buf, size_t bufsize,
25119 size_t *ret)
25120 {
25121 int error = 0;
25122
25123 if (mod == &kernel_module)
25124 return -EINVAL;
25125
25126 if (sizeof(struct module_info) <= bufsize) {
25127 struct module_info info;
25128 info.addr = (unsigned long)mod;
25129 info.size = mod->size;
25130 info.flags = mod->flags;
25131 info.usecount = (mod_member_present(mod, can_unload)
25132 && mod->can_unload
25133 ? -1 : atomic_read(&mod->uc.usecount));
25134
25135 if (copy_to_user(buf, &info,
25136 sizeof(struct module_info)))
25137 return -EFAULT;
25138 } else
25139 error = -ENOSPC;
25140
25141 if (put_user(sizeof(struct module_info), ret))
25142 return -EFAULT;
25143
25144 return error;
25145 }
25146
25147 asmlinkage int
25148 sys_query_module(const char *name_user, int which,
25149 char *buf, size_t bufsize, size_t *ret)
25150 {
25151 struct module *mod;
25152 int err;
25153
25154 lock_kernel();
25155 if (name_user == NULL)
25156 mod = &kernel_module;
25157 else {
25158 long namelen;
25159 char *name;
25160
25161 if ((namelen = get_mod_name(name_user, &name)) < 0) {
25162 err = namelen;
25163 goto out;
25164 }
25165 err = -ENOENT;
25166 if (namelen == 0)
25167 mod = &kernel_module;
25168 else if ((mod = find_module(name)) == NULL) {
25169 put_mod_name(name);
25170 goto out;
25171 }
25172 put_mod_name(name);
25173 }
25174
25175 switch (which)
25176 {
25177 case 0:
25178 err = 0;
25179 break;
25180 case QM_MODULES:
25181 err = qm_modules(buf, bufsize, ret);
25182 break;
25183 case QM_DEPS:
25184 err = qm_deps(mod, buf, bufsize, ret);
25185 break;
25186 case QM_REFS:
25187 err = qm_refs(mod, buf, bufsize, ret);
25188 break;
25189 case QM_SYMBOLS:
25190 err = qm_symbols(mod, buf, bufsize, ret);
25191 break;
25192 case QM_INFO:
25193 err = qm_info(mod, buf, bufsize, ret);
25194 break;
25195 default:
25196 err = -EINVAL;
25197 break;
25198 }
25199 out:
25200 unlock_kernel();
25201 return err;
25202 }
25203
25204 /* Copy the kernel symbol table to user space. If the
25205 * argument is NULL, just return the size of the table.
25206 *
25207 * This call is obsolete. New programs should use
25208 * query_module+QM_SYMBOLS which does not arbitrarily
25209 * limit the length of symbols. */
25210 asmlinkage int
25211 sys_get_kernel_syms(struct kernel_sym *table)
25212 {
25213 struct module *mod;
25214 int i;
25215 struct kernel_sym ksym;
25216
25217 lock_kernel();
25218 for (mod = module_list, i = 0; mod; mod = mod->next) {
25219 /* include the count for the module name! */
25220 i += mod->nsyms + 1;
25221 }
25222
25223 if (table == NULL)
25224 goto out;
25225
25226 /* So that we don't give the user our stack content */
25227 memset (&ksym, 0, sizeof (ksym));
25228
25229 for (mod = module_list, i = 0; mod; mod = mod->next) {
25230 struct module_symbol *msym;
25231 unsigned int j;
25232
25233 if ((mod->flags & (MOD_RUNNING|MOD_DELETED)) !=
25234 MOD_RUNNING)
25235 continue;
25236
25237 /* magic: write module info as a pseudo symbol */
25238 ksym.value = (unsigned long)mod;
25239 ksym.name[0] = '#';
25240 strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1);
25241 ksym.name[sizeof(ksym.name)-1] = '\0';
25242
25243 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
25244 goto out;
25245 ++i, ++table;
25246
25247 if (mod->nsyms == 0)
25248 continue;
25249
25250 for (j = 0, msym = mod->syms; j < mod->nsyms;
25251 ++j, ++msym) {
25252 ksym.value = msym->value;
25253 strncpy(ksym.name, msym->name, sizeof(ksym.name));
25254 ksym.name[sizeof(ksym.name)-1] = '\0';
25255
25256 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0)
25257 goto out;
25258 ++i, ++table;
25259 }
25260 }
25261 out:
25262 unlock_kernel();
25263 return i;
25264 }
25265
25266 /* Look for a module by name, ignoring modules marked for
25267 * deletion. */
25268 static struct module *
25269 find_module(const char *name)
25270 {
25271 struct module *mod;
25272
25273 for (mod = module_list; mod ; mod = mod->next) {
25274 if (mod->flags & MOD_DELETED)
25275 continue;
25276 if (!strcmp(mod->name, name))
25277 break;
25278 }
25279
25280 return mod;
25281 }
25282
25283 /* Free the given module. */
25284
25285 static void
25286 free_module(struct module *mod, int tag_freed)
25287 {
25288 struct module_ref *dep;
25289 unsigned i;
25290
25291 /* Let the module clean up. */
25292
25293 mod->flags |= MOD_DELETED;
25294 if (mod->flags & MOD_RUNNING)
25295 {
25296 if(mod->cleanup)
25297 mod->cleanup();
25298 mod->flags &= ~MOD_RUNNING;
25299 }
25300
25301 /* Remove the module from the dependency lists. */
25302
25303 for (i = 0, dep = mod->deps; i < mod->ndeps;
25304 ++i, ++dep) {
25305 struct module_ref **pp;
25306 for (pp = &dep->dep->refs; *pp != dep;
25307 pp = &(*pp)->next_ref)
25308 continue;
25309 *pp = dep->next_ref;
25310 if (tag_freed && dep->dep->refs == NULL)
25311 dep->dep->flags |= MOD_JUST_FREED;
25312 }
25313
25314 /* And from the main module list. */
25315
25316 if (mod == module_list) {
25317 module_list = mod->next;
25318 } else {
25319 struct module *p;
25320 for (p = module_list; p->next != mod; p = p->next)
25321 continue;
25322 p->next = mod->next;
25323 }
25324
25325 /* And free the memory. */
25326
25327 module_unmap(mod);
25328 }
25329
25330 /* Called by the /proc file system to return a current
25331 * list of modules. */
25332 int get_module_list(char *p)
25333 {
25334 size_t left = PAGE_SIZE;
25335 struct module *mod;
25336 char tmpstr[64];
25337 struct module_ref *ref;
25338
25339 for (mod = module_list; mod != &kernel_module;
25340 mod = mod->next) {
25341 long len;
25342 const char *q;
25343
25344 #define safe_copy_str(str, len) \
25345 do { \
25346 if (left < len) \
25347 goto fini; \
25348 memcpy(p, str, len); p += len, left -= len; \
25349 } while (0)
25350 #define safe_copy_cstr(str) \
25351 safe_copy_str(str, sizeof(str)-1)
25352
25353 len = strlen(mod->name);
25354 safe_copy_str(mod->name, len);
25355
25356 if ((len = 20 - len) > 0) {
25357 if (left < len)
25358 goto fini;
25359 memset(p, ' ', len);
25360 p += len;
25361 left -= len;
25362 }
25363
25364 len = sprintf(tmpstr, "%8lu", mod->size);
25365 safe_copy_str(tmpstr, len);
25366
25367 if (mod->flags & MOD_RUNNING) {
25368 len = sprintf(tmpstr, "%4ld",
25369 (mod_member_present(mod, can_unload)
25370 && mod->can_unload
25371 ? -1L
25372 : (long)atomic_read(&mod->uc.usecount)));
25373 safe_copy_str(tmpstr, len);
25374 }
25375
25376 if (mod->flags & MOD_DELETED)
25377 safe_copy_cstr(" (deleted)");
25378 else if (mod->flags & MOD_RUNNING) {
25379 if (mod->flags & MOD_AUTOCLEAN)
25380 safe_copy_cstr(" (autoclean)");
25381 if (!(mod->flags & MOD_USED_ONCE))
25382 safe_copy_cstr(" (unused)");
25383 } else
25384 safe_copy_cstr(" (uninitialized)");
25385
25386 if ((ref = mod->refs) != NULL) {
25387 safe_copy_cstr(" [");
25388 while (1) {
25389 q = ref->ref->name;
25390 len = strlen(q);
25391 safe_copy_str(q, len);
25392
25393 if ((ref = ref->next_ref) != NULL)
25394 safe_copy_cstr(" ");
25395 else
25396 break;
25397 }
25398 safe_copy_cstr("]");
25399 }
25400 safe_copy_cstr("\n");
25401
25402 #undef safe_copy_str
25403 #undef safe_copy_cstr
25404 }
25405
25406 fini:
25407 return PAGE_SIZE - left;
25408 }
25409
25410 /* Called by the /proc file system to return a current
25411 * list of ksyms. */
25412 int
25413 get_ksyms_list(char *buf, char **start, off_t offset,
25414 int length)
25415 {
25416 struct module *mod;
25417 char *p = buf;
25418 int len = 0; /* code from net/ipv4/proc.c */
25419 off_t pos = 0;
25420 off_t begin = 0;
25421
25422 for (mod = module_list; mod; mod = mod->next) {
25423 unsigned i;
25424 struct module_symbol *sym;
25425
25426 if (!(mod->flags & MOD_RUNNING) ||
25427 (mod->flags & MOD_DELETED))
25428 continue;
25429
25430 for (i = mod->nsyms, sym = mod->syms; i > 0;
25431 --i, ++sym) {
25432 p = buf + len;
25433 if (*mod->name) {
25434 len += sprintf(p, "%0*lx %s\t[%s]\n",
25435 (int)(2*sizeof(void*)),
25436 sym->value, sym->name,
25437 mod->name);
25438 } else {
25439 len += sprintf(p, "%0*lx %s\n",
25440 (int)(2*sizeof(void*)),
25441 sym->value, sym->name);
25442 }
25443 pos = begin + len;
25444 if (pos < offset) {
25445 len = 0;
25446 begin = pos;
25447 }
25448 pos = begin + len;
25449 if (pos > offset+length)
25450 goto leave_the_loop;
25451 }
25452 }
25453 leave_the_loop:
25454 *start = buf + (offset - begin);
25455 len -= (offset - begin);
25456 if (len > length)
25457 len = length;
25458 return len;
25459 }
25460
25461 /* Gets the address for a symbol in the given module. If
25462 * modname is NULL, it looks for the name in any
25463 * registered symbol table. If the modname is an empty
25464 * string, it looks for the symbol in kernel exported
25465 * symbol tables. */
25466 unsigned long
25467 get_module_symbol(char *modname, char *symname)
25468 {
25469 struct module *mp;
25470 struct module_symbol *sym;
25471 int i;
25472
25473 for (mp = module_list; mp; mp = mp->next) {
25474 if (((modname == NULL) ||
25475 (strcmp(mp->name, modname) == 0)) &&
25476 (mp->flags & (MOD_RUNNING | MOD_DELETED)) ==
25477 MOD_RUNNING && (mp->nsyms > 0)) {
25478 for (i = mp->nsyms, sym = mp->syms;
25479 i > 0; --i, ++sym) {
25480
25481 if (strcmp(sym->name, symname) == 0) {
25482 return sym->value;
25483 }
25484 }
25485 }
25486 }
25487 return 0;
25488 }
25489
25490 #else /* CONFIG_MODULES */
25491
25492 /* Dummy syscalls for people who don't want modules */
25493
25494 asmlinkage unsigned long
25495 sys_create_module(const char *name_user, size_t size)
25496 {
25497 return -ENOSYS;
25498 }
25499
25500 asmlinkage int
25501 sys_init_module(const char *name_user,
25502 struct module *mod_user)
25503 {
25504 return -ENOSYS;
25505 }
25506
25507 asmlinkage int
25508 sys_delete_module(const char *name_user)
25509 {
25510 return -ENOSYS;
25511 }
25512
25513 asmlinkage int
25514 sys_query_module(const char *name_user, int which,
25515 char *buf, size_t bufsize, size_t *ret)
25516 {
25517 /* Let the program know about the new interface. Not
25518 * that it'll do them much good. */
25519 if (which == 0)
25520 return 0;
25521
25522 return -ENOSYS;
25523 }
25524
25525 asmlinkage int
25526 sys_get_kernel_syms(struct kernel_sym *table)
25527 {
25528 return -ENOSYS;
25529 }
25530
25531 #endif /* CONFIG_MODULES */
Сайт управляется системой
uCoz