diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-20 16:17:13 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-20 16:42:58 -0500 |
commit | 9f28bb7e1d0188a993403ab39b774785892805e1 (patch) | |
tree | 939660c2531335dc899cc66fa7f3f05aa343d1e0 /kernel/module.c | |
parent | 3fd6805f4dfb02bcfb5634972eabad0e790f119a (diff) |
[PATCH] add EXPORT_SYMBOL_GPL_FUTURE()
This patch adds the ability to mark symbols that will be changed in the
future, so that kernel modules that don't include MODULE_LICENSE("GPL")
and use the symbols, will be flagged and printed out to the system log.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/kernel/module.c b/kernel/module.c index 2a892b20d68..5ca99fbe9f4 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -126,8 +126,11 @@ extern const struct kernel_symbol __start___ksymtab[]; | |||
126 | extern const struct kernel_symbol __stop___ksymtab[]; | 126 | extern const struct kernel_symbol __stop___ksymtab[]; |
127 | extern const struct kernel_symbol __start___ksymtab_gpl[]; | 127 | extern const struct kernel_symbol __start___ksymtab_gpl[]; |
128 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; | 128 | extern const struct kernel_symbol __stop___ksymtab_gpl[]; |
129 | extern const struct kernel_symbol __start___ksymtab_gpl_future[]; | ||
130 | extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; | ||
129 | extern const unsigned long __start___kcrctab[]; | 131 | extern const unsigned long __start___kcrctab[]; |
130 | extern const unsigned long __start___kcrctab_gpl[]; | 132 | extern const unsigned long __start___kcrctab_gpl[]; |
133 | extern 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); |