Ядро Linux в комментариях

       

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 */



Содержание раздела