aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 2a892b20d68f..5ca99fbe9f44 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -126,8 +126,11 @@ extern const struct kernel_symbol __start___ksymtab[];
126extern const struct kernel_symbol __stop___ksymtab[]; 126extern const struct kernel_symbol __stop___ksymtab[];
127extern const struct kernel_symbol __start___ksymtab_gpl[]; 127extern const struct kernel_symbol __start___ksymtab_gpl[];
128extern const struct kernel_symbol __stop___ksymtab_gpl[]; 128extern const struct kernel_symbol __stop___ksymtab_gpl[];
129extern const struct kernel_symbol __start___ksymtab_gpl_future[];
130extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
129extern const unsigned long __start___kcrctab[]; 131extern const unsigned long __start___kcrctab[];
130extern const unsigned long __start___kcrctab_gpl[]; 132extern const unsigned long __start___kcrctab_gpl[];
133extern const unsigned long __start___kcrctab_gpl_future[];
131 134
132#ifndef CONFIG_MODVERSIONS 135#ifndef CONFIG_MODVERSIONS
133#define symversion(base, idx) NULL 136#define symversion(base, idx) NULL
@@ -172,6 +175,22 @@ static unsigned long __find_symbol(const char *name,
172 return ks->value; 175 return ks->value;
173 } 176 }
174 } 177 }
178 ks = lookup_symbol(name, __start___ksymtab_gpl_future,
179 __stop___ksymtab_gpl_future);
180 if (ks) {
181 if (!gplok) {
182 printk(KERN_WARNING "Symbol %s is being used "
183 "by a non-GPL module, which will not "
184 "be allowed in the future\n", name);
185 printk(KERN_WARNING "Please see the file "
186 "Documentation/feature-removal-schedule.txt "
187 "in the kernel source tree for more "
188 "details.\n");
189 }
190 *crc = symversion(__start___kcrctab_gpl_future,
191 (ks - __start___ksymtab_gpl_future));
192 return ks->value;
193 }
175 194
176 /* Now try modules. */ 195 /* Now try modules. */
177 list_for_each_entry(mod, &modules, list) { 196 list_for_each_entry(mod, &modules, list) {
@@ -191,6 +210,23 @@ static unsigned long __find_symbol(const char *name,
191 return ks->value; 210 return ks->value;
192 } 211 }
193 } 212 }
213 ks = lookup_symbol(name, mod->gpl_future_syms,
214 (mod->gpl_future_syms +
215 mod->num_gpl_future_syms));
216 if (ks) {
217 if (!gplok) {
218 printk(KERN_WARNING "Symbol %s is being used "
219 "by a non-GPL module, which will not "
220 "be allowed in the future\n", name);
221 printk(KERN_WARNING "Please see the file "
222 "Documentation/feature-removal-schedule.txt "
223 "in the kernel source tree for more "
224 "details.\n");
225 }
226 *crc = symversion(mod->gpl_future_crcs,
227 (ks - mod->gpl_future_syms));
228 return ks->value;
229 }
194 } 230 }
195 DEBUGP("Failed to find symbol %s\n", name); 231 DEBUGP("Failed to find symbol %s\n", name);
196 return 0; 232 return 0;
@@ -1546,7 +1582,8 @@ static struct module *load_module(void __user *umod,
1546 char *secstrings, *args, *modmagic, *strtab = NULL; 1582 char *secstrings, *args, *modmagic, *strtab = NULL;
1547 unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, 1583 unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
1548 exportindex, modindex, obsparmindex, infoindex, gplindex, 1584 exportindex, modindex, obsparmindex, infoindex, gplindex,
1549 crcindex, gplcrcindex, versindex, pcpuindex; 1585 crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
1586 gplfuturecrcindex;
1550 long arglen; 1587 long arglen;
1551 struct module *mod; 1588 struct module *mod;
1552 long err = 0; 1589 long err = 0;
@@ -1627,8 +1664,10 @@ static struct module *load_module(void __user *umod,
1627 /* Optional sections */ 1664 /* Optional sections */
1628 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); 1665 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
1629 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); 1666 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
1667 gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
1630 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); 1668 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
1631 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); 1669 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
1670 gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
1632 setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); 1671 setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
1633 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); 1672 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
1634 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); 1673 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
@@ -1784,10 +1823,16 @@ static struct module *load_module(void __user *umod,
1784 mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr; 1823 mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
1785 if (gplcrcindex) 1824 if (gplcrcindex)
1786 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; 1825 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
1826 mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
1827 sizeof(*mod->gpl_future_syms);
1828 mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
1829 if (gplfuturecrcindex)
1830 mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
1787 1831
1788#ifdef CONFIG_MODVERSIONS 1832#ifdef CONFIG_MODVERSIONS
1789 if ((mod->num_syms && !crcindex) || 1833 if ((mod->num_syms && !crcindex) ||
1790 (mod->num_gpl_syms && !gplcrcindex)) { 1834 (mod->num_gpl_syms && !gplcrcindex) ||
1835 (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
1791 printk(KERN_WARNING "%s: No versions for exported symbols." 1836 printk(KERN_WARNING "%s: No versions for exported symbols."
1792 " Tainting kernel.\n", mod->name); 1837 " Tainting kernel.\n", mod->name);
1793 add_taint(TAINT_FORCED_MODULE); 1838 add_taint(TAINT_FORCED_MODULE);