lkml.org 
[lkml]   [2005]   [Dec]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [RFC][PATCH] Prevent overriding of Symbols in the Kernel, avoiding Undefined behaviour
    On 12/13/05, Rusty Russell <rusty@rustcorp.com.au> wrote:
    >
    > How about something like:
    >
    > const struct kernel_symbol *sym;
    > unsigned int i;
    > const unsigned long *crc;
    > struct module *owner;
    >
    > spin_lock_irq(&modlist_lock);
    > for (i = 0; i < mod->num_syms; i++)
    > if (__find_symbol(mod->syms[i].name, &owner, &crc, 1))
    > goto dup;
    > for (i = 0; i < num->num_gpl_syms; i++)
    > if (__find_symbol(mod->gpl_syms[i].name,&owner,&crc,1))
    > goto dup;
    > spin_unlock_irq(&modlist_lock);
    > return 0;
    > dup:
    > printk("%s: exports duplicate symbol (owned by %s)\n",
    > mod->name, module_name(owner));
    > return -ENOEXEC;
    > }

    Have tried that in the attached patch. However, mod->syms[i].name
    would be valid only after a long relocation for loop has run through.
    While this adds a wee bit extra overhead, that overhead is only in the
    case where the module does actually export a Duplicate Symbol.

    This its a question, whether we do the search before relocation ( A
    little messier ) or after ( More straight forward)

    Regards
    Ashutosh
    --- /usr/src/linux-2.6.15-rc5-vanilla/kernel/module.c 2005-12-07 19:32:23.000000000 +0530
    +++ /usr/src/linux-2.6.15-rc5/kernel/module.c 2005-12-13 19:44:43.000000000 +0530
    @@ -1204,6 +1204,42 @@ void *__symbol_get(const char *symbol)
    }
    EXPORT_SYMBOL_GPL(__symbol_get);

    +/*
    + * Ensure that an exported symbol [global namespace] does not already exist
    + * in the Kernel or in some other modules exported symbol table.
    + */
    +static int verify_export_symbols(struct module *mod)
    +{
    + const char *name=0;
    + unsigned long i, ret = 0;
    + struct module *owner;
    + const unsigned long *crc;
    +
    + spin_lock_irq(&modlist_lock);
    + for (i = 0; i < mod->num_syms; i++)
    + if (unlikely(__find_symbol(mod->syms[i].name, &owner, &crc,1))) {
    + name = mod->syms[i].name;
    + ret = -ENOEXEC;
    + goto dup;
    + }
    +
    + for (i = 0; i < mod->num_gpl_syms; i++)
    + if (unlikely(__find_symbol(mod->gpl_syms[i].name, &owner, &crc,1))) {
    + name = mod->gpl_syms[i].name;
    + ret = -ENOEXEC;
    + goto dup;
    + }
    +
    +dup:
    + spin_unlock_irq(&modlist_lock);
    +
    + if (ret)
    + printk("%s: exports duplicate symbol %s (owned by %s)\n",
    + mod->name, name, module_name(owner));
    +
    + return ret;
    +}
    +
    /* Change all symbols so that sh_value encodes the pointer directly. */
    static int simplify_symbols(Elf_Shdr *sechdrs,
    unsigned int symindex,
    @@ -1767,6 +1804,12 @@ static struct module *load_module(void _
    goto cleanup;
    }

    + /* Find duplicate symbols */
    + err = verify_export_symbols(mod);
    +
    + if (err < 0)
    + goto cleanup;
    +
    /* Set up and sort exception table */
    mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
    mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
    \
     
     \ /
      Last update: 2005-12-13 15:30    [W:2.851 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site