[原创] 绕过android内核模块加载验证 | 宜武汇-ag真人国际厅网站

/* allocate and load the module: note that size of section 0 is always

   zero, and we rely on this for optional sections. */

static int load_module(struct load_info *info, const char __user *uargs,

               int flags)

    struct module *mod;

    long err = 0;

    char *after_dashes;

 

    /*

     * do the signature check (if any) first. all that

     * the signature check needs is info->len, it does

     * not need any of the section info. that can be

     * set up later. this will minimize the chances

     * of a corrupt module causing problems before

     * we even get to the signature check.

     *

     * the check will also adjust info->len by stripping

     * off the sig length at the end of the module, making

     * checks against info->len more correct.

     */

    err = module_sig_check(info, flags); // 第一处签名校验

    if (err)

        goto free_copy;

 

    /*

     * do basic sanity checks against the elf header and

     * sections.

     */

    err = elf_validity_check(info);

    if (err) {

        pr_err("module has invalid elf structures\n");

        goto free_copy;

    }

 

    /*

     * everything checks out, so set up the section info

     * in the info structure.

     */

    err = setup_load_info(info, flags);

    if (err)

        goto free_copy;

 

    /*

     * now that we know we have the correct module name, check

     * if it's blacklisted.

     */

    if (blacklisted(info->name)) {

        err = -eperm;

        goto free_copy;

    }

 

    err = rewrite_section_headers(info, flags);

    if (err)

        goto free_copy;

 

    // modstruct 版本校验

    /* check module struct version now, before we try to use module. */

    if (!check_modstruct_version(info, info->mod)) {

        err = -enoexec;

        goto free_copy;

    }

 

    /* figure out module layout, and allocate all the memory. */

    mod = layout_and_allocate(info, flags);

    if (is_err(mod)) {

        err = ptr_err(mod);

        goto free_copy;

    }

 

    audit_log_kern_module(mod->name);

 

    /* reserve our place in the list. */

    err = add_unformed_module(mod);

    if (err)

        goto free_module;

 

/*第二处签名校验*/

#ifdef config_module_sig

    mod->sig_ok = info->sig_ok;

    if (!mod->sig_ok) {

        pr_notice_once("%s: module verification failed: signature "

                   "and/or required key missing - tainting "

                   "kernel\n", mod->name);

        add_taint_module(mod, taint_unsigned_module, lockdep_still_ok);

    }

#endif

 

    /* to avoid stressing percpu allocator, do this once we're unique. */

    err = percpu_modalloc(mod, info);

    if (err)

        goto unlink_mod;

 

    /* now module is in final location, initialize linked lists, etc. */

    err = module_unload_init(mod);

    if (err)

        goto unlink_mod;

 

    init_param_lock(mod);

 

    /* now we've got everything in the final locations, we can

     * find optional sections. */

    err = find_module_sections(mod, info);

    if (err)

        goto free_unload;

 

    err = check_module_license_and_versions(mod);

    if (err)

        goto free_unload;

 

    /* set up modinfo_attr fields */

    setup_modinfo(mod, info);

 

    /* fix up syms, so that st_value is a pointer to location. */

    err = simplify_symbols(mod, info);

    if (err < 0)

        goto free_modinfo;

 

    err = apply_relocations(mod, info);

    if (err < 0)

        goto free_modinfo;

 

    err = post_relocation(mod, info);

    if (err < 0)

        goto free_modinfo;

 

    flush_module_icache(mod);

 

    /* now copy in args */

    mod->args = strndup_user(uargs, ~0ul >> 1);

    if (is_err(mod->args)) {

        err = ptr_err(mod->args);

        goto free_arch_cleanup;

    }

 

    dynamic_debug_setup(mod, info->debug, info->num_debug);

 

    /* ftrace init must be called in the module_state_unformed state */

    ftrace_module_init(mod);

 

    /* finally it's fully formed, ready to start executing. */

    err = complete_formation(mod, info);

    if (err)

        goto ddebug_cleanup;

 

    err = prepare_coming_module(mod);

    if (err)

        goto bug_cleanup;

 

    /* module is ready to execute: parsing args may do that. */

    after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,

                  -32768, 32767, mod,

                  unknown_module_param_cb);

    if (is_err(after_dashes)) {

        err = ptr_err(after_dashes);

        goto coming_cleanup;

    } else if (after_dashes) {

        pr_warn("%s: parameters '%s' after `--' ignored\n",

               mod->name, after_dashes);

    }

 

    /* link in to sysfs. */

    err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);

    if (err < 0)

        goto coming_cleanup;

 

    if (is_livepatch_module(mod)) {

        err = copy_module_elf(mod, info);

        if (err < 0)

            goto sysfs_cleanup;

    }

 

    /* get rid of temporary copy. */

    free_copy(info);

 

    /* done! */

    trace_module_load(mod);

 

    return do_init_module(mod);

 

 sysfs_cleanup:

    mod_sysfs_teardown(mod);

 coming_cleanup:

    mod->state = module_state_going;

    destroy_params(mod->kp, mod->num_kp);

    blocking_notifier_call_chain(&module_notify_list,

                     module_state_going, mod);

    klp_module_going(mod);

 bug_cleanup:

    mod->state = module_state_going;

    /* module_bug_cleanup needs module_mutex protection */

    mutex_lock(&module_mutex);

    module_bug_cleanup(mod);

    mutex_unlock(&module_mutex);

 

 ddebug_cleanup:

    ftrace_release_mod(mod);

    dynamic_debug_remove(mod, info->debug);

    synchronize_rcu();

    kfree(mod->args);

 free_arch_cleanup:

    module_arch_cleanup(mod);

 free_modinfo:

    free_modinfo(mod);

 free_unload:

    module_unload_free(mod);

 unlink_mod:

    mutex_lock(&module_mutex);

    /* unlink carefully: kallsyms could be walking list. */

    list_del_rcu(&mod->list);

    mod_tree_remove(mod);

    wake_up_all(&module_wq);

    /* wait for rcu-sched synchronizing before releasing mod->list. */

    synchronize_rcu();

    mutex_unlock(&module_mutex);

 free_module:

    /* free lock-classes; relies on the preceding sync_rcu() */

    lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);

 

    module_deallocate(mod, info);

 free_copy:

    free_copy(info);

    return err;

原文链接:https://bbs.kanxue.com/thread-271179.htm

网络摘文,本文作者:15h,如若转载,请注明出处:https://www.15cov.cn/2023/08/27/原创-绕过android内核模块加载验证/

发表评论

邮箱地址不会被公开。 必填项已用*标注

网站地图