move freeinit allocation after do_one_initcall in case do_one_initcall crashes.
Otherwise, freeinit would leak memory after every initalization of a crashed 
module.
I could not find a reason for why freeinit allocation happened before 
do_one_initcall.

Signed-off-by: julian-lagattuta <[email protected]>
---
 kernel/module/main.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/kernel/module/main.c b/kernel/module/main.c
index 2277c53aef2e..2825ac177c62 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -3021,21 +3021,13 @@ static noinline int do_init_module(struct module *mod)
        }
 #endif
 
-       freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
-       if (!freeinit) {
-               ret = -ENOMEM;
-               goto fail;
-       }
-       freeinit->init_text = mod->mem[MOD_INIT_TEXT].base;
-       freeinit->init_data = mod->mem[MOD_INIT_DATA].base;
-       freeinit->init_rodata = mod->mem[MOD_INIT_RODATA].base;
 
        do_mod_ctors(mod);
        /* Start the module */
        if (mod->init != NULL)
                ret = do_one_initcall(mod->init);
        if (ret < 0) {
-               goto fail_free_freeinit;
+               goto fail;
        }
        if (ret > 0) {
                pr_warn("%s: '%s'->init suspiciously returned %d, it should "
@@ -3045,6 +3037,14 @@ static noinline int do_init_module(struct module *mod)
                dump_stack();
        }
 
+       freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL);
+       if (!freeinit) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+       freeinit->init_text = mod->mem[MOD_INIT_TEXT].base;
+       freeinit->init_data = mod->mem[MOD_INIT_DATA].base;
+       freeinit->init_rodata = mod->mem[MOD_INIT_RODATA].base;
        /* Now it's a first class citizen! */
        mod->state = MODULE_STATE_LIVE;
        blocking_notifier_call_chain(&module_notify_list,
@@ -3123,8 +3123,6 @@ static noinline int do_init_module(struct module *mod)
 
        return 0;
 
-fail_free_freeinit:
-       kfree(freeinit);
 fail:
        /* Try to protect us from buggy refcounters. */
        mod->state = MODULE_STATE_GOING;
-- 
2.45.2


Reply via email to