aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/kernel/module.c b/kernel/module.c
index dd2a54155b54..f47cce910f25 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -757,8 +757,16 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
757 return -EFAULT; 757 return -EFAULT;
758 name[MODULE_NAME_LEN-1] = '\0'; 758 name[MODULE_NAME_LEN-1] = '\0';
759 759
760 if (mutex_lock_interruptible(&module_mutex) != 0) 760 /* Create stop_machine threads since free_module relies on
761 return -EINTR; 761 * a non-failing stop_machine call. */
762 ret = stop_machine_create();
763 if (ret)
764 return ret;
765
766 if (mutex_lock_interruptible(&module_mutex) != 0) {
767 ret = -EINTR;
768 goto out_stop;
769 }
762 770
763 mod = find_module(name); 771 mod = find_module(name);
764 if (!mod) { 772 if (!mod) {
@@ -817,10 +825,12 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
817 825
818 out: 826 out:
819 mutex_unlock(&module_mutex); 827 mutex_unlock(&module_mutex);
828out_stop:
829 stop_machine_destroy();
820 return ret; 830 return ret;
821} 831}
822 832
823static void print_unload_info(struct seq_file *m, struct module *mod) 833static inline void print_unload_info(struct seq_file *m, struct module *mod)
824{ 834{
825 struct module_use *use; 835 struct module_use *use;
826 int printed_something = 0; 836 int printed_something = 0;
@@ -893,7 +903,7 @@ void module_put(struct module *module)
893EXPORT_SYMBOL(module_put); 903EXPORT_SYMBOL(module_put);
894 904
895#else /* !CONFIG_MODULE_UNLOAD */ 905#else /* !CONFIG_MODULE_UNLOAD */
896static void print_unload_info(struct seq_file *m, struct module *mod) 906static inline void print_unload_info(struct seq_file *m, struct module *mod)
897{ 907{
898 /* We don't know the usage count, or what modules are using. */ 908 /* We don't know the usage count, or what modules are using. */
899 seq_printf(m, " - -"); 909 seq_printf(m, " - -");
@@ -1578,11 +1588,21 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
1578 return ret; 1588 return ret;
1579} 1589}
1580 1590
1591/* Additional bytes needed by arch in front of individual sections */
1592unsigned int __weak arch_mod_section_prepend(struct module *mod,
1593 unsigned int section)
1594{
1595 /* default implementation just returns zero */
1596 return 0;
1597}
1598
1581/* Update size with this section: return offset. */ 1599/* Update size with this section: return offset. */
1582static long get_offset(unsigned int *size, Elf_Shdr *sechdr) 1600static long get_offset(struct module *mod, unsigned int *size,
1601 Elf_Shdr *sechdr, unsigned int section)
1583{ 1602{
1584 long ret; 1603 long ret;
1585 1604
1605 *size += arch_mod_section_prepend(mod, section);
1586 ret = ALIGN(*size, sechdr->sh_addralign ?: 1); 1606 ret = ALIGN(*size, sechdr->sh_addralign ?: 1);
1587 *size = ret + sechdr->sh_size; 1607 *size = ret + sechdr->sh_size;
1588 return ret; 1608 return ret;
@@ -1622,7 +1642,7 @@ static void layout_sections(struct module *mod,
1622 || strncmp(secstrings + s->sh_name, 1642 || strncmp(secstrings + s->sh_name,
1623 ".init", 5) == 0) 1643 ".init", 5) == 0)
1624 continue; 1644 continue;
1625 s->sh_entsize = get_offset(&mod->core_size, s); 1645 s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
1626 DEBUGP("\t%s\n", secstrings + s->sh_name); 1646 DEBUGP("\t%s\n", secstrings + s->sh_name);
1627 } 1647 }
1628 if (m == 0) 1648 if (m == 0)
@@ -1640,7 +1660,7 @@ static void layout_sections(struct module *mod,
1640 || strncmp(secstrings + s->sh_name, 1660 || strncmp(secstrings + s->sh_name,
1641 ".init", 5) != 0) 1661 ".init", 5) != 0)
1642 continue; 1662 continue;
1643 s->sh_entsize = (get_offset(&mod->init_size, s) 1663 s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
1644 | INIT_OFFSET_MASK); 1664 | INIT_OFFSET_MASK);
1645 DEBUGP("\t%s\n", secstrings + s->sh_name); 1665 DEBUGP("\t%s\n", secstrings + s->sh_name);
1646 } 1666 }
@@ -1725,15 +1745,15 @@ static const struct kernel_symbol *lookup_symbol(const char *name,
1725 return NULL; 1745 return NULL;
1726} 1746}
1727 1747
1728static int is_exported(const char *name, const struct module *mod) 1748static int is_exported(const char *name, unsigned long value,
1749 const struct module *mod)
1729{ 1750{
1730 if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab)) 1751 const struct kernel_symbol *ks;
1731 return 1; 1752 if (!mod)
1753 ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
1732 else 1754 else
1733 if (mod && lookup_symbol(name, mod->syms, mod->syms + mod->num_syms)) 1755 ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
1734 return 1; 1756 return ks != NULL && ks->value == value;
1735 else
1736 return 0;
1737} 1757}
1738 1758
1739/* As per nm */ 1759/* As per nm */
@@ -1865,6 +1885,13 @@ static noinline struct module *load_module(void __user *umod,
1865 /* vmalloc barfs on "unusual" numbers. Check here */ 1885 /* vmalloc barfs on "unusual" numbers. Check here */
1866 if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL) 1886 if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
1867 return ERR_PTR(-ENOMEM); 1887 return ERR_PTR(-ENOMEM);
1888
1889 /* Create stop_machine threads since the error path relies on
1890 * a non-failing stop_machine call. */
1891 err = stop_machine_create();
1892 if (err)
1893 goto free_hdr;
1894
1868 if (copy_from_user(hdr, umod, len) != 0) { 1895 if (copy_from_user(hdr, umod, len) != 0) {
1869 err = -EFAULT; 1896 err = -EFAULT;
1870 goto free_hdr; 1897 goto free_hdr;
@@ -2248,6 +2275,7 @@ static noinline struct module *load_module(void __user *umod,
2248 /* Get rid of temporary copy */ 2275 /* Get rid of temporary copy */
2249 vfree(hdr); 2276 vfree(hdr);
2250 2277
2278 stop_machine_destroy();
2251 /* Done! */ 2279 /* Done! */
2252 return mod; 2280 return mod;
2253 2281
@@ -2270,6 +2298,7 @@ static noinline struct module *load_module(void __user *umod,
2270 kfree(args); 2298 kfree(args);
2271 free_hdr: 2299 free_hdr:
2272 vfree(hdr); 2300 vfree(hdr);
2301 stop_machine_destroy();
2273 return ERR_PTR(err); 2302 return ERR_PTR(err);
2274 2303
2275 truncated: 2304 truncated:
@@ -2504,7 +2533,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
2504 strlcpy(name, mod->strtab + mod->symtab[symnum].st_name, 2533 strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
2505 KSYM_NAME_LEN); 2534 KSYM_NAME_LEN);
2506 strlcpy(module_name, mod->name, MODULE_NAME_LEN); 2535 strlcpy(module_name, mod->name, MODULE_NAME_LEN);
2507 *exported = is_exported(name, mod); 2536 *exported = is_exported(name, *value, mod);
2508 preempt_enable(); 2537 preempt_enable();
2509 return 0; 2538 return 0;
2510 } 2539 }