lkml.org 
[lkml]   [2006]   [Feb]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 01/03] add EXPORT_SYMBOL_GPL_FUTURE()
    This patch adds the ability to mark symbols that will be changed in the
    future, so that non-GPL usage of them is flagged by the kernel and
    printed out to the system log.

    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    include/asm-generic/vmlinux.lds.h | 14 +++++++++++
    include/linux/module.h | 8 ++++++
    kernel/module.c | 46 ++++++++++++++++++++++++++++++++++++--
    3 files changed, 66 insertions(+), 2 deletions(-)

    --- gregkh-2.6.orig/include/asm-generic/vmlinux.lds.h
    +++ gregkh-2.6/include/asm-generic/vmlinux.lds.h
    @@ -58,6 +58,13 @@
    VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
    } \
    \
    + /* Kernel symbol table: GPL-future-only symbols */ \
    + __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
    + VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
    + *(__ksymtab_gpl_future) \
    + VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
    + } \
    + \
    /* Kernel symbol table: Normal symbols */ \
    __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
    VMLINUX_SYMBOL(__start___kcrctab) = .; \
    @@ -72,6 +79,13 @@
    VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
    } \
    \
    + /* Kernel symbol table: GPL-future-only symbols */ \
    + __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
    + VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
    + *(__kcrctab_gpl_future) \
    + VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \
    + } \
    + \
    /* Kernel symbol table: strings */ \
    __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
    *(__ksymtab_strings) \
    --- gregkh-2.6.orig/include/linux/module.h
    +++ gregkh-2.6/include/linux/module.h
    @@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbo
    #define EXPORT_SYMBOL_GPL(sym) \
    __EXPORT_SYMBOL(sym, "_gpl")

    +#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
    + __EXPORT_SYMBOL(sym, "_gpl_future")
    +
    #endif

    struct module_ref
    @@ -255,6 +258,11 @@ struct module
    unsigned int num_gpl_syms;
    const unsigned long *gpl_crcs;

    + /* symbols that will be GPL-only in the near future. */
    + const struct kernel_symbol *gpl_future_syms;
    + unsigned int num_gpl_future_syms;
    + const unsigned long *gpl_future_crcs;
    +
    /* Exception table */
    unsigned int num_exentries;
    const struct exception_table_entry *extable;
    --- gregkh-2.6.orig/kernel/module.c
    +++ gregkh-2.6/kernel/module.c
    @@ -126,8 +126,11 @@ extern const struct kernel_symbol __star
    extern const struct kernel_symbol __stop___ksymtab[];
    extern const struct kernel_symbol __start___ksymtab_gpl[];
    extern const struct kernel_symbol __stop___ksymtab_gpl[];
    +extern const struct kernel_symbol __start___ksymtab_gpl_future[];
    +extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
    extern const unsigned long __start___kcrctab[];
    extern const unsigned long __start___kcrctab_gpl[];
    +extern const unsigned long __start___kcrctab_gpl_future[];

    #ifndef CONFIG_MODVERSIONS
    #define symversion(base, idx) NULL
    @@ -159,6 +162,21 @@ static unsigned long __find_symbol(const
    return __start___ksymtab_gpl[i].value;
    }
    }
    + for (i = 0; __start___ksymtab_gpl_future+i < __stop___ksymtab_gpl_future; i++) {
    + if (strcmp(__start___ksymtab_gpl_future[i].name, name) == 0) {
    + *crc = symversion(__start___kcrctab_gpl_future, i);
    + if (!gplok) {
    + printk(KERN_WARNING "Symbol %s is being used "
    + "by a non-GPL module, which will not "
    + "be allowed in the future\n", name);
    + printk(KERN_WARNING "Please see the file, "
    + "Documentation/feature-removal-schedule.txt, "
    + "in the kernel source tree, for more "
    + "details.\n");
    + }
    + return __start___ksymtab_gpl_future[i].value;
    + }
    + }

    /* Now try modules. */
    list_for_each_entry(mod, &modules, list) {
    @@ -177,6 +195,21 @@ static unsigned long __find_symbol(const
    }
    }
    }
    + for (i = 0; i < mod->num_gpl_future_syms; i++) {
    + if (strcmp(mod->gpl_future_syms[i].name, name) == 0) {
    + *crc = symversion(mod->gpl_future_crcs, i);
    + if (!gplok) {
    + printk(KERN_WARNING "Symbol %s is being used "
    + "by a non-GPL module, which will not "
    + "be allowed in the future\n", name);
    + printk(KERN_WARNING "Please see the file, "
    + "Documentation/feature-removal-schedule.txt, "
    + "in the kernel source tree, for more "
    + "details.\n");
    + }
    + return mod->gpl_future_syms[i].value;
    + }
    + }
    }
    DEBUGP("Failed to find symbol %s\n", name);
    return 0;
    @@ -1537,7 +1570,8 @@ static struct module *load_module(void _
    char *secstrings, *args, *modmagic, *strtab = NULL;
    unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
    exportindex, modindex, obsparmindex, infoindex, gplindex,
    - crcindex, gplcrcindex, versindex, pcpuindex;
    + crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
    + gplfuturecrcindex;
    long arglen;
    struct module *mod;
    long err = 0;
    @@ -1618,8 +1652,10 @@ static struct module *load_module(void _
    /* Optional sections */
    exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
    gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
    + gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
    crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
    gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
    + gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
    setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
    exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
    obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
    @@ -1775,10 +1811,16 @@ static struct module *load_module(void _
    mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
    if (gplcrcindex)
    mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
    + mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
    + sizeof(*mod->gpl_future_syms);
    + mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
    + if (gplfuturecrcindex)
    + mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;

    #ifdef CONFIG_MODVERSIONS
    if ((mod->num_syms && !crcindex) ||
    - (mod->num_gpl_syms && !gplcrcindex)) {
    + (mod->num_gpl_syms && !gplcrcindex) ||
    + (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
    printk(KERN_WARNING "%s: No versions for exported symbols."
    " Tainting kernel.\n", mod->name);
    add_taint(TAINT_FORCED_MODULE);
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2006-02-08 19:51    [W:0.032 / U:30.068 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site