• Rusty Russell's avatar
    modules: fix longstanding /proc/kallsyms vs module insertion race. · 8244062e
    Rusty Russell authored
    For CONFIG_KALLSYMS, we keep two symbol tables and two string tables.
    There's one full copy, marked SHF_ALLOC and laid out at the end of the
    module's init section.  There's also a cut-down version that only
    contains core symbols and strings, and lives in the module's core
    section.
    
    After module init (and before we free the module memory), we switch
    the mod->symtab, mod->num_symtab and mod->strtab to point to the core
    versions.  We do this under the module_mutex.
    
    However, kallsyms doesn't take the module_mutex: it uses
    preempt_disable() and rcu tricks to walk through the modules, because
    it's used in the oops path.  It's also used in /proc/kallsyms.
    There's nothing atomic about the change of these variables, so we can
    get the old (larger!) num_symtab and the new symtab pointer; in fact
    this is what I saw when trying to reproduce.
    
    By grouping these variables together, we can use a
    carefully-dereferenced pointer to ensure we always get one or the
    other (the free of the module init section is already done in an RCU
    callback, so that's safe).  We allocate the init one at the end of the
    module init section, and keep the core one inside the struct module
    itself (it could also have been allocated at the end of the module
    core, but that's probably overkill).
    Reported-by: default avatarWeilong Chen <chenweilong@huawei.com>
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=111541
    Cc: stable@kernel.org
    Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
    8244062e
module.c 104 KB