#include <linux/config.h> #include <linux/mm.h> #include <linux/module.h> #include <asm/module.h> #include <asm/uaccess.h> #include <linux/vmalloc.h> #include <linux/smp_lock.h> #include <asm/pgalloc.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/kmod.h> /* * Originally by Anonymous (as far as I know...) * Linux version by Bas Laarhoven <bas@vimec.nl> * 0.99.14 version by Jon Tombs <jon@gtex02.us.es>, * Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C) * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996 * Add MOD_INITIALIZING Keith Owens <kaos@ocs.com.au> Nov 1999 * Add kallsyms support, Keith Owens <kaos@ocs.com.au> Apr 2000 * Add asm/module support, IA64 has special requirements. Keith Owens <kaos@ocs.com.au> Sep 2000 * Fix assorted bugs in module verification. Keith Owens <kaos@ocs.com.au> Sep 2000 * Fix sys_init_module race, Andrew Morton <andrewm@uow.edu.au> Oct 2000 * http://www.uwsg.iu.edu/hypermail/linux/kernel/0008.3/0379.html * Replace xxx_module_symbol with inter_module_xxx. Keith Owens <kaos@ocs.com.au> Oct 2000 * * This source is covered by the GNU GPL, the same as all kernel sources. */ #if defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS) extern struct module_symbol __start___ksymtab[]; extern struct module_symbol __stop___ksymtab[]; extern const struct exception_table_entry __start___ex_table[]; extern const struct exception_table_entry __stop___ex_table[]; extern const char __start___kallsyms[] __attribute__ ((weak)); extern const char __stop___kallsyms[] __attribute__ ((weak)); static struct module kernel_module = { size_of_struct: sizeof(struct module), name: "", uc: {ATOMIC_INIT(1)}, flags: MOD_RUNNING, syms: __start___ksymtab, ex_table_start: __start___ex_table, ex_table_end: __stop___ex_table, kallsyms_start: __start___kallsyms, kallsyms_end: __stop___kallsyms, }; struct module *module_list = &kernel_module; #endif /* defined(CONFIG_MODULES) || defined(CONFIG_KALLSYMS) */ /* inter_module functions are always available, even when the kernel is * compiled without modules. Consumers of inter_module_xxx routines * will always work, even when both are built into the kernel, this * approach removes lots of #ifdefs in mainline code. */ static struct list_head ime_list = LIST_HEAD_INIT(ime_list); static spinlock_t ime_lock = SPIN_LOCK_UNLOCKED; static int kmalloc_failed; /** * inter_module_register - register a new set of inter module data. * @im_name: an arbitrary string to identify the data, must be unique * @owner: module that is registering the data, always use THIS_MODULE * @userdata: pointer to arbitrary userdata to be registered * * Description: Check that the im_name has not already been registered, * complain if it has. For new data, add it to the inter_module_entry * list. */ 78 void inter_module_register(const char *im_name, struct module *owner, const void *userdata) { struct list_head *tmp; struct inter_module_entry *ime, *ime_new; 83 if (!(ime_new = kmalloc(sizeof(*ime), GFP_KERNEL))) { /* Overloaded kernel, not fatal */ printk(KERN_ERR "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n", im_name); kmalloc_failed = 1; 89 return; } memset(ime_new, 0, sizeof(*ime_new)); ime_new->im_name = im_name; ime_new->owner = owner; ime_new->userdata = userdata; spin_lock(&ime_lock); 97 list_for_each(tmp, &ime_list) { ime = list_entry(tmp, struct inter_module_entry, list); 99 if (strcmp(ime->im_name, im_name) == 0) { 100 spin_unlock(&ime_lock); kfree(ime_new); /* Program logic error, fatal */ printk(KERN_ERR "inter_module_register: duplicate im_name '%s'", im_name); 104 BUG(); } } list_add(&(ime_new->list), &ime_list); 108 spin_unlock(&ime_lock); } /** * inter_module_unregister - unregister a set of inter module data. * @im_name: an arbitrary string to identify the data, must be unique * * Description: Check that the im_name has been registered, complain if * it has not. For existing data, remove it from the * inter_module_entry list. */ 119 void inter_module_unregister(const char *im_name) { struct list_head *tmp; struct inter_module_entry *ime; spin_lock(&ime_lock); 125 list_for_each(tmp, &ime_list) { ime = list_entry(tmp, struct inter_module_entry, list); 127 if (strcmp(ime->im_name, im_name) == 0) { list_del(&(ime->list)); 129 spin_unlock(&ime_lock); kfree(ime); 131 return; } } 134 spin_unlock(&ime_lock); 135 if (kmalloc_failed) { printk(KERN_ERR "inter_module_unregister: no entry for '%s', " "probably caused by previous kmalloc failure\n", im_name); 140 return; } 142 else { /* Program logic error, fatal */ printk(KERN_ERR "inter_module_unregister: no entry for '%s'", im_name); 145 BUG(); } } /** * inter_module_get - return arbitrary userdata from another module. * @im_name: an arbitrary string to identify the data, must be unique * * Description: If the im_name has not been registered, return NULL. * Try to increment the use count on the owning module, if that fails * then return NULL. Otherwise return the userdata. */ 157 const void *inter_module_get(const char *im_name) { struct list_head *tmp; struct inter_module_entry *ime; const void *result = NULL; spin_lock(&ime_lock); 164 list_for_each(tmp, &ime_list) { ime = list_entry(tmp, struct inter_module_entry, list); 166 if (strcmp(ime->im_name, im_name) == 0) { 167 if (try_inc_mod_count(ime->owner)) result = ime->userdata; 169 break; } } 172 spin_unlock(&ime_lock); 173 return(result); } /** * inter_module_get_request - im get with automatic request_module. * @im_name: an arbitrary string to identify the data, must be unique * @modname: module that is expected to register im_name * * Description: If inter_module_get fails, do request_module then retry. */ 183 const void *inter_module_get_request(const char *im_name, const char *modname) { const void *result = inter_module_get(im_name); 186 if (!result) { request_module(modname); result = inter_module_get(im_name); } 190 return(result); } /** * inter_module_put - release use of data from another module. * @im_name: an arbitrary string to identify the data, must be unique * * Description: If the im_name has not been registered, complain, * otherwise decrement the use count on the owning module. */ 200 void inter_module_put(const char *im_name) { struct list_head *tmp; struct inter_module_entry *ime; spin_lock(&ime_lock); 206 list_for_each(tmp, &ime_list) { ime = list_entry(tmp, struct inter_module_entry, list); 208 if (strcmp(ime->im_name, im_name) == 0) { 209 if (ime->owner) __MOD_DEC_USE_COUNT(ime->owner); 211 spin_unlock(&ime_lock); 212 return; } } 215 spin_unlock(&ime_lock); printk(KERN_ERR "inter_module_put: no entry for '%s'", im_name); 217 BUG(); } #if defined(CONFIG_MODULES) /* The rest of the source */ static long get_mod_name(const char *user_name, char **buf); static void put_mod_name(char *buf); struct module *find_module(const char *name); void free_module(struct module *, int tag_freed); /* * Called at boot time */ 233 void __init init_modules(void) { kernel_module.nsyms = __stop___ksymtab - __start___ksymtab; #ifdef __alpha__ __asm__("stq $29,%0" : "=m"(kernel_module.gp)); #endif } /* * Copy the name of a module from user space. */ static inline long 247 get_mod_name(const char *user_name, char **buf) { unsigned long page; long retval; page = __get_free_page(GFP_KERNEL); 253 if (!page) 254 return -ENOMEM; retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE); 257 if (retval > 0) { 258 if (retval < PAGE_SIZE) { *buf = (char *)page; 260 return retval; } retval = -ENAMETOOLONG; 263 } else if (!retval) retval = -EINVAL; free_page(page); 267 return retval; } static inline void 271 put_mod_name(char *buf) { free_page((unsigned long)buf); } /* * Allocate space for a module. */ asmlinkage unsigned long 281 sys_create_module(const char *name_user, size_t size) { char *name; long namelen, error; struct module *mod; 287 if (!capable(CAP_SYS_MODULE)) 288 return -EPERM; 289 lock_kernel(); 290 if ((namelen = get_mod_name(name_user, &name)) < 0) { error = namelen; 292 goto err0; } 294 if (size < sizeof(struct module)+namelen) { error = -EINVAL; 296 goto err1; } 298 if (find_module(name) != NULL) { error = -EEXIST; 300 goto err1; } 302 if ((mod = (struct module *)module_map(size)) == NULL) { error = -ENOMEM; 304 goto err1; } memset(mod, 0, sizeof(*mod)); mod->size_of_struct = sizeof(*mod); mod->next = module_list; mod->name = (char *)(mod + 1); mod->size = size; memcpy((char*)(mod+1), name, namelen+1); put_mod_name(name); module_list = mod; /* link it in */ error = (long) mod; 319 goto err0; err1: put_mod_name(name); err0: 323 unlock_kernel(); 324 return error; } /* * Initialize a module. */ asmlinkage long 332 sys_init_module(const char *name_user, struct module *mod_user) { struct module mod_tmp, *mod; char *name, *n_name, *name_tmp = NULL; long namelen, n_namelen, i, error; unsigned long mod_user_size; struct module_ref *dep; 340 if (!capable(CAP_SYS_MODULE)) 341 return -EPERM; 342 lock_kernel(); 343 if ((namelen = get_mod_name(name_user, &name)) < 0) { error = namelen; 345 goto err0; } 347 if ((mod = find_module(name)) == NULL) { error = -ENOENT; 349 goto err1; } /* Check module header size. We allow a bit of slop over the size we are familiar with to cope with a version of insmod for a newer kernel. But don't over do it. */ 355 if ((error = get_user(mod_user_size, &mod_user->size_of_struct)) != 0) 356 goto err1; if (mod_user_size < (unsigned long)&((struct module *)0L)->persist_start 358 || mod_user_size > sizeof(struct module) + 16*sizeof(void*)) { printk(KERN_ERR "init_module: Invalid module header size.\n" KERN_ERR "A new version of the modutils is likely " "needed.\n"); error = -EINVAL; 363 goto err1; } /* Hold the current contents while we play with the user's idea of righteousness. */ mod_tmp = *mod; name_tmp = kmalloc(strlen(mod->name) + 1, GFP_KERNEL); /* Where's kstrdup()? */ 370 if (name_tmp == NULL) { error = -ENOMEM; 372 goto err1; } strcpy(name_tmp, mod->name); error = copy_from_user(mod, mod_user, mod_user_size); 377 if (error) { error = -EFAULT; 379 goto err2; } /* Sanity check the size of the module. */ error = -EINVAL; 385 if (mod->size > mod_tmp.size) { printk(KERN_ERR "init_module: Size of initialized module " "exceeds size of created module.\n"); 388 goto err2; } /* Make sure all interesting pointers are sane. */ 393 if (!mod_bound(mod->name, namelen, mod)) { printk(KERN_ERR "init_module: mod->name out of bounds.\n"); 395 goto err2; } 397 if (mod->nsyms && !mod_bound(mod->syms, mod->nsyms, mod)) { printk(KERN_ERR "init_module: mod->syms out of bounds.\n"); 399 goto err2; } 401 if (mod->ndeps && !mod_bound(mod->deps, mod->ndeps, mod)) { printk(KERN_ERR "init_module: mod->deps out of bounds.\n"); 403 goto err2; } 405 if (mod->init && !mod_bound(mod->init, 0, mod)) { printk(KERN_ERR "init_module: mod->init out of bounds.\n"); 407 goto err2; } 409 if (mod->cleanup && !mod_bound(mod->cleanup, 0, mod)) { printk(KERN_ERR "init_module: mod->cleanup out of bounds.\n"); 411 goto err2; } if (mod->ex_table_start > mod->ex_table_end || (mod->ex_table_start && !((unsigned long)mod->ex_table_start >= ((unsigned long)mod + mod->size_of_struct) && ((unsigned long)mod->ex_table_end < (unsigned long)mod + mod->size))) || (((unsigned long)mod->ex_table_start - (unsigned long)mod->ex_table_end) 420 % sizeof(struct exception_table_entry))) { printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n"); 422 goto err2; } 424 if (mod->flags & ~MOD_AUTOCLEAN) { printk(KERN_ERR "init_module: mod->flags invalid.\n"); 426 goto err2; } #ifdef __alpha__ if (!mod_bound(mod->gp - 0x8000, 0, mod)) { printk(KERN_ERR "init_module: mod->gp out of bounds.\n"); goto err2; } #endif if (mod_member_present(mod, can_unload) 435 && mod->can_unload && !mod_bound(mod->can_unload, 0, mod)) { printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n"); 437 goto err2; } 439 if (mod_member_present(mod, kallsyms_end)) { if (mod->kallsyms_end && (!mod_bound(mod->kallsyms_start, 0, mod) || 442 !mod_bound(mod->kallsyms_end, 0, mod))) { printk(KERN_ERR "init_module: mod->kallsyms out of bounds.\n"); 444 goto err2; } 446 if (mod->kallsyms_start > mod->kallsyms_end) { printk(KERN_ERR "init_module: mod->kallsyms invalid.\n"); 448 goto err2; } } 451 if (mod_member_present(mod, archdata_end)) { if (mod->archdata_end && (!mod_bound(mod->archdata_start, 0, mod) || 454 !mod_bound(mod->archdata_end, 0, mod))) { printk(KERN_ERR "init_module: mod->archdata out of bounds.\n"); 456 goto err2; } 458 if (mod->archdata_start > mod->archdata_end) { printk(KERN_ERR "init_module: mod->archdata invalid.\n"); 460 goto err2; } } 463 if (mod_member_present(mod, kernel_data) && mod->kernel_data) { printk(KERN_ERR "init_module: mod->kernel_data must be zero.\n"); 465 goto err2; } /* Check that the user isn't doing something silly with the name. */ if ((n_namelen = get_mod_name(mod->name - (unsigned long)mod + (unsigned long)mod_user, 472 &n_name)) < 0) { printk(KERN_ERR "init_module: get_mod_name failure.\n"); error = n_namelen; 475 goto err2; } 477 if (namelen != n_namelen || strcmp(n_name, mod_tmp.name) != 0) { printk(KERN_ERR "init_module: changed module name to " "`%s' from `%s'\n", n_name, mod_tmp.name); 481 goto err3; } /* Ok, that's about all the sanity we can stomach; copy the rest. */ if (copy_from_user((char *)mod+mod_user_size, (char *)mod_user+mod_user_size, 488 mod->size-mod_user_size)) { error = -EFAULT; 490 goto err3; } 493 if (module_arch_init(mod)) 494 goto err3; /* On some machines it is necessary to do something here to make the I and D caches consistent. */ 498 flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size); mod->next = mod_tmp.next; mod->refs = NULL; /* Sanity check the module's dependents */ 504 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) { struct module *o, *d = dep->dep; /* Make sure the indicated dependencies are really modules. */ 508 if (d == mod) { printk(KERN_ERR "init_module: self-referential " "dependency in mod->deps.\n"); 511 goto err3; } /* Scan the current modules for this dependency */ 515 for (o = module_list; o != &kernel_module && o != d; o = o->next) ; 518 if (o != d) { printk(KERN_ERR "init_module: found dependency that is " "(no longer?) a module.\n"); 521 goto err3; } } /* Update module references. */ 526 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) { struct module *d = dep->dep; dep->ref = mod; dep->next_ref = d->refs; d->refs = dep; /* Being referenced by a dependent module counts as a use as far as kmod is concerned. */ d->flags |= MOD_USED_ONCE; } /* Free our temporary memory. */ put_mod_name(n_name); put_mod_name(name); /* Initialize the module. */ mod->flags |= MOD_INITIALIZING; atomic_set(&mod->uc.usecount,1); 544 if (mod->init && (error = mod->init()) != 0) { atomic_set(&mod->uc.usecount,0); mod->flags &= ~MOD_INITIALIZING; 547 if (error > 0) /* Buggy module */ error = -EBUSY; 549 goto err0; } atomic_dec(&mod->uc.usecount); /* And set it running. */ mod->flags = (mod->flags | MOD_RUNNING) & ~MOD_INITIALIZING; error = 0; 556 goto err0; err3: put_mod_name(n_name); err2: *mod = mod_tmp; strcpy((char *)mod->name, name_tmp); /* We know there is room for this */ err1: put_mod_name(name); err0: 566 unlock_kernel(); kfree(name_tmp); 568 return error; } static spinlock_t unload_lock = SPIN_LOCK_UNLOCKED; 572 int try_inc_mod_count(struct module *mod) { int res = 1; 575 if (mod) { spin_lock(&unload_lock); 577 if (mod->flags & MOD_DELETED) res = 0; 579 else __MOD_INC_USE_COUNT(mod); 581 spin_unlock(&unload_lock); } 583 return res; } asmlinkage long 587 sys_delete_module(const char *name_user) { struct module *mod, *next; char *name; long error; int something_changed; 594 if (!capable(CAP_SYS_MODULE)) 595 return -EPERM; 597 lock_kernel(); 598 if (name_user) { 599 if ((error = get_mod_name(name_user, &name)) < 0) 600 goto out; 601 if (error == 0) { error = -EINVAL; put_mod_name(name); 604 goto out; } error = -ENOENT; 607 if ((mod = find_module(name)) == NULL) { put_mod_name(name); 609 goto out; } put_mod_name(name); error = -EBUSY; 613 if (mod->refs != NULL) 614 goto out; spin_lock(&unload_lock); 617 if (!__MOD_IN_USE(mod)) { mod->flags |= MOD_DELETED; 619 spin_unlock(&unload_lock); free_module(mod, 0); error = 0; 622 } else { 623 spin_unlock(&unload_lock); } 625 goto out; } /* Do automatic reaping */ restart: something_changed = 0; 631 for (mod = module_list; mod != &kernel_module; mod = next) { next = mod->next; spin_lock(&unload_lock); if (mod->refs == NULL && (mod->flags & MOD_AUTOCLEAN) && (mod->flags & MOD_RUNNING) && !(mod->flags & MOD_DELETED) && (mod->flags & MOD_USED_ONCE) 639 && !__MOD_IN_USE(mod)) { if ((mod->flags & MOD_VISITED) 641 && !(mod->flags & MOD_JUST_FREED)) { 642 spin_unlock(&unload_lock); mod->flags &= ~MOD_VISITED; 644 } else { mod->flags |= MOD_DELETED; 646 spin_unlock(&unload_lock); free_module(mod, 1); something_changed = 1; } 650 } else { 651 spin_unlock(&unload_lock); } } 654 if (something_changed) 655 goto restart; 656 for (mod = module_list; mod != &kernel_module; mod = mod->next) mod->flags &= ~MOD_JUST_FREED; error = 0; out: 660 unlock_kernel(); 661 return error; } /* Query various bits about modules. */ static int 667 qm_modules(char *buf, size_t bufsize, size_t *ret) { struct module *mod; size_t nmod, space, len; nmod = space = 0; 674 for (mod=module_list; mod != &kernel_module; mod=mod->next, ++nmod) { len = strlen(mod->name)+1; 676 if (len > bufsize) 677 goto calc_space_needed; 678 if (copy_to_user(buf, mod->name, len)) 679 return -EFAULT; buf += len; bufsize -= len; space += len; } 685 if (put_user(nmod, ret)) 686 return -EFAULT; 687 else 688 return 0; calc_space_needed: space += len; 692 while ((mod = mod->next) != &kernel_module) space += strlen(mod->name)+1; 695 if (put_user(space, ret)) 696 return -EFAULT; 697 else 698 return -ENOSPC; } static int 702 qm_deps(struct module *mod, char *buf, size_t bufsize, size_t *ret) { size_t i, space, len; 706 if (mod == &kernel_module) 707 return -EINVAL; 708 if (!MOD_CAN_QUERY(mod)) 709 if (put_user(0, ret)) 710 return -EFAULT; 711 else 712 return 0; space = 0; 715 for (i = 0; i < mod->ndeps; ++i) { const char *dep_name = mod->deps[i].dep->name; len = strlen(dep_name)+1; 719 if (len > bufsize) 720 goto calc_space_needed; 721 if (copy_to_user(buf, dep_name, len)) 722 return -EFAULT; buf += len; bufsize -= len; space += len; } 728 if (put_user(i, ret)) 729 return -EFAULT; 730 else 731 return 0; calc_space_needed: space += len; 735 while (++i < mod->ndeps) space += strlen(mod->deps[i].dep->name)+1; 738 if (put_user(space, ret)) 739 return -EFAULT; 740 else 741 return -ENOSPC; } static int 745 qm_refs(struct module *mod, char *buf, size_t bufsize, size_t *ret) { size_t nrefs, space, len; struct module_ref *ref; 750 if (mod == &kernel_module) 751 return -EINVAL; 752 if (!MOD_CAN_QUERY(mod)) 753 if (put_user(0, ret)) 754 return -EFAULT; 755 else 756 return 0; space = 0; 759 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) { const char *ref_name = ref->ref->name; len = strlen(ref_name)+1; 763 if (len > bufsize) 764 goto calc_space_needed; 765 if (copy_to_user(buf, ref_name, len)) 766 return -EFAULT; buf += len; bufsize -= len; space += len; } 772 if (put_user(nrefs, ret)) 773 return -EFAULT; 774 else 775 return 0; calc_space_needed: space += len; 779 while ((ref = ref->next_ref) != NULL) space += strlen(ref->ref->name)+1; 782 if (put_user(space, ret)) 783 return -EFAULT; 784 else 785 return -ENOSPC; } static int 789 qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret) { size_t i, space, len; struct module_symbol *s; char *strings; unsigned long *vals; 796 if (!MOD_CAN_QUERY(mod)) 797 if (put_user(0, ret)) 798 return -EFAULT; 799 else 800 return 0; space = mod->nsyms * 2*sizeof(void *); i = len = 0; s = mod->syms; 807 if (space > bufsize) 808 goto calc_space_needed; 810 if (!access_ok(VERIFY_WRITE, buf, space)) 811 return -EFAULT; bufsize -= space; vals = (unsigned long *)buf; strings = buf+space; 817 for (; i < mod->nsyms ; ++i, ++s, vals += 2) { len = strlen(s->name)+1; 819 if (len > bufsize) 820 goto calc_space_needed; if (copy_to_user(strings, s->name, len) || __put_user(s->value, vals+0) 824 || __put_user(space, vals+1)) 825 return -EFAULT; strings += len; bufsize -= len; space += len; } 832 if (put_user(i, ret)) 833 return -EFAULT; 834 else 835 return 0; calc_space_needed: 838 for (; i < mod->nsyms; ++i, ++s) space += strlen(s->name)+1; 841 if (put_user(space, ret)) 842 return -EFAULT; 843 else 844 return -ENOSPC; } static int 848 qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret) { int error = 0; 852 if (mod == &kernel_module) 853 return -EINVAL; 855 if (sizeof(struct module_info) <= bufsize) { struct module_info info; info.addr = (unsigned long)mod; info.size = mod->size; info.flags = mod->flags; info.usecount = (mod_member_present(mod, can_unload) && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)); 863 if (copy_to_user(buf, &info, sizeof(struct module_info))) 864 return -EFAULT; 865 } else error = -ENOSPC; 868 if (put_user(sizeof(struct module_info), ret)) 869 return -EFAULT; 871 return error; } asmlinkage long 875 sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t *ret) { struct module *mod; int err; 881 lock_kernel(); 882 if (name_user == NULL) mod = &kernel_module; 884 else { long namelen; char *name; 888 if ((namelen = get_mod_name(name_user, &name)) < 0) { err = namelen; 890 goto out; } err = -ENOENT; 893 if (namelen == 0) mod = &kernel_module; 895 else if ((mod = find_module(name)) == NULL) { put_mod_name(name); 897 goto out; } put_mod_name(name); } 902 switch (which) { 904 case 0: err = 0; 906 break; 907 case QM_MODULES: err = qm_modules(buf, bufsize, ret); 909 break; 910 case QM_DEPS: err = qm_deps(mod, buf, bufsize, ret); 912 break; 913 case QM_REFS: err = qm_refs(mod, buf, bufsize, ret); 915 break; 916 case QM_SYMBOLS: err = qm_symbols(mod, buf, bufsize, ret); 918 break; 919 case QM_INFO: err = qm_info(mod, buf, bufsize, ret); 921 break; 922 default: err = -EINVAL; 924 break; } out: 927 unlock_kernel(); 928 return err; } /* * Copy the kernel symbol table to user space. If the argument is * NULL, just return the size of the table. * * This call is obsolete. New programs should use query_module+QM_SYMBOLS * which does not arbitrarily limit the length of symbols. */ asmlinkage long 940 sys_get_kernel_syms(struct kernel_sym *table) { struct module *mod; int i; struct kernel_sym ksym; 946 lock_kernel(); 947 for (mod = module_list, i = 0; mod; mod = mod->next) { /* include the count for the module name! */ i += mod->nsyms + 1; } 952 if (table == NULL) 953 goto out; /* So that we don't give the user our stack content */ memset (&ksym, 0, sizeof (ksym)); 958 for (mod = module_list, i = 0; mod; mod = mod->next) { struct module_symbol *msym; unsigned int j; 962 if (!MOD_CAN_QUERY(mod)) 963 continue; /* magic: write module info as a pseudo symbol */ ksym.value = (unsigned long)mod; ksym.name[0] = '#'; strncpy(ksym.name+1, mod->name, sizeof(ksym.name)-1); ksym.name[sizeof(ksym.name)-1] = '\0'; 971 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0) 972 goto out; ++i, ++table; 975 if (mod->nsyms == 0) 976 continue; 978 for (j = 0, msym = mod->syms; j < mod->nsyms; ++j, ++msym) { ksym.value = msym->value; strncpy(ksym.name, msym->name, sizeof(ksym.name)); ksym.name[sizeof(ksym.name)-1] = '\0'; 983 if (copy_to_user(table, &ksym, sizeof(ksym)) != 0) 984 goto out; ++i, ++table; } } out: 989 unlock_kernel(); 990 return i; } /* * Look for a module by name, ignoring modules marked for deletion. */ struct module * 998 find_module(const char *name) { struct module *mod; 1002 for (mod = module_list; mod ; mod = mod->next) { 1003 if (mod->flags & MOD_DELETED) 1004 continue; 1005 if (!strcmp(mod->name, name)) 1006 break; } 1009 return mod; } /* * Free the given module. */ void 1017 free_module(struct module *mod, int tag_freed) { struct module_ref *dep; unsigned i; /* Let the module clean up. */ 1024 if (mod->flags & MOD_RUNNING) { 1026 if(mod->cleanup) mod->cleanup(); mod->flags &= ~MOD_RUNNING; } /* Remove the module from the dependency lists. */ 1033 for (i = 0, dep = mod->deps; i < mod->ndeps; ++i, ++dep) { struct module_ref **pp; 1035 for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref) 1036 continue; *pp = dep->next_ref; 1038 if (tag_freed && dep->dep->refs == NULL) dep->dep->flags |= MOD_JUST_FREED; } /* And from the main module list. */ 1044 if (mod == module_list) { module_list = mod->next; 1046 } else { struct module *p; 1048 for (p = module_list; p->next != mod; p = p->next) 1049 continue; p->next = mod->next; } /* And free the memory. */ module_unmap(mod); } /* * Called by the /proc file system to return a current list of modules. */ 1062 int get_module_list(char *p) { size_t left = PAGE_SIZE; struct module *mod; char tmpstr[64]; struct module_ref *ref; 1069 for (mod = module_list; mod != &kernel_module; mod = mod->next) { long len; const char *q; #define safe_copy_str(str, len) \ do { \ if (left < len) \ goto fini; \ memcpy(p, str, len); p += len, left -= len; \ } while (0) #define safe_copy_cstr(str) safe_copy_str(str, sizeof(str)-1) len = strlen(mod->name); 1082 safe_copy_str(mod->name, len); 1084 if ((len = 20 - len) > 0) { 1085 if (left < len) 1086 goto fini; memset(p, ' ', len); p += len; left -= len; } len = sprintf(tmpstr, "%8lu", mod->size); 1093 safe_copy_str(tmpstr, len); 1095 if (mod->flags & MOD_RUNNING) { len = sprintf(tmpstr, "%4ld", (mod_member_present(mod, can_unload) && mod->can_unload ? -1L : (long)atomic_read(&mod->uc.usecount))); 1100 safe_copy_str(tmpstr, len); } 1103 if (mod->flags & MOD_DELETED) 1104 safe_copy_cstr(" (deleted)"); 1105 else if (mod->flags & MOD_RUNNING) { 1106 if (mod->flags & MOD_AUTOCLEAN) 1107 safe_copy_cstr(" (autoclean)"); 1108 if (!(mod->flags & MOD_USED_ONCE)) 1109 safe_copy_cstr(" (unused)"); } 1111 else if (mod->flags & MOD_INITIALIZING) 1112 safe_copy_cstr(" (initializing)"); 1113 else 1114 safe_copy_cstr(" (uninitialized)"); 1116 if ((ref = mod->refs) != NULL) { 1117 safe_copy_cstr(" ["); 1118 while (1) { q = ref->ref->name; len = strlen(q); 1121 safe_copy_str(q, len); 1123 if ((ref = ref->next_ref) != NULL) 1124 safe_copy_cstr(" "); 1125 else 1126 break; } 1128 safe_copy_cstr("]"); } 1130 safe_copy_cstr("\n"); #undef safe_copy_str #undef safe_copy_cstr } fini: 1137 return PAGE_SIZE - left; } /* * Called by the /proc file system to return a current list of ksyms. */ int 1145 get_ksyms_list(char *buf, char **start, off_t offset, int length) { struct module *mod; char *p = buf; int len = 0; /* code from net/ipv4/proc.c */ off_t pos = 0; off_t begin = 0; 1153 for (mod = module_list; mod; mod = mod->next) { unsigned i; struct module_symbol *sym; 1157 if (!MOD_CAN_QUERY(mod)) 1158 continue; 1160 for (i = mod->nsyms, sym = mod->syms; i > 0; --i, ++sym) { p = buf + len; 1162 if (*mod->name) { len += sprintf(p, "%0*lx %s\t[%s]\n", (int)(2*sizeof(void*)), sym->value, sym->name, mod->name); 1167 } else { len += sprintf(p, "%0*lx %s\n", (int)(2*sizeof(void*)), sym->value, sym->name); } pos = begin + len; 1173 if (pos < offset) { len = 0; begin = pos; } pos = begin + len; 1178 if (pos > offset+length) 1179 goto leave_the_loop; } } leave_the_loop: *start = buf + (offset - begin); len -= (offset - begin); 1185 if (len > length) len = length; 1187 return len; } #else /* CONFIG_MODULES */ /* Dummy syscalls for people who don't want modules */ asmlinkage unsigned long sys_create_module(const char *name_user, size_t size) { return -ENOSYS; } asmlinkage long sys_init_module(const char *name_user, struct module *mod_user) { return -ENOSYS; } asmlinkage long sys_delete_module(const char *name_user) { return -ENOSYS; } asmlinkage long sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t *ret) { /* Let the program know about the new interface. Not that it'll do them much good. */ if (which == 0) return 0; return -ENOSYS; } asmlinkage long sys_get_kernel_syms(struct kernel_sym *table) { return -ENOSYS; } int try_inc_mod_count(struct module *mod) { return 1; } #endif /* CONFIG_MODULES */