LKML Archive mirror
 help / color / mirror / Atom feed
From: Miroslav Benes <mbenes@suse.cz>
To: Jessica Yu <jeyu@redhat.com>
Cc: Petr Mladek <pmladek@suse.com>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Seth Jennings <sjenning@redhat.com>,
	Jiri Kosina <jikos@kernel.org>, Vojtech Pavlik <vojtech@suse.com>,
	Rusty Russell <rusty@rustcorp.com.au>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ingo Molnar <mingo@redhat.com>,
	live-patching@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: livepatch/module: remove livepatch module notifier
Date: Fri, 5 Feb 2016 10:15:56 +0100 (CET)	[thread overview]
Message-ID: <alpine.LNX.2.00.1602051004000.25516@pobox.suse.cz> (raw)
In-Reply-To: <20160205041157.GB24068@packer-debian-8-amd64.digitalocean.com>

On Thu, 4 Feb 2016, Jessica Yu wrote:

> +++ Petr Mladek [04/02/16 15:39 +0100]:
> > On Mon 2016-02-01 20:17:36, Jessica Yu wrote:
> [ snipped since email is getting long ]
> > > diff --git a/kernel/module.c b/kernel/module.c
> > > index b05d466..71c77ed 100644
> > > --- a/kernel/module.c
> > > +++ b/kernel/module.c
> > > @@ -53,6 +53,7 @@
> > >  #include <asm/sections.h>
> > >  #include <linux/tracepoint.h>
> > >  #include <linux/ftrace.h>
> > > +#include <linux/livepatch.h>
> > >  #include <linux/async.h>
> > >  #include <linux/percpu.h>
> > >  #include <linux/kmemleak.h>
> > > @@ -981,6 +982,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *,
> > > name_user,
> > >  		mod->exit();
> > >  	blocking_notifier_call_chain(&module_notify_list,
> > >  				     MODULE_STATE_GOING, mod);
> > > +	klp_module_disable(mod);
> > >  	ftrace_release_mod(mod);
> > > 
> > >  	async_synchronize_full();
> > > @@ -3297,6 +3299,7 @@ fail:
> > >  	module_put(mod);
> > >  	blocking_notifier_call_chain(&module_notify_list,
> > >  				     MODULE_STATE_GOING, mod);
> > > +	klp_module_disable(mod);
> > >  	ftrace_release_mod(mod);
> > >  	free_module(mod);
> > >  	wake_up_all(&module_wq);
> > > @@ -3375,6 +3378,10 @@ static int complete_formation(struct module *mod,
> > > struct load_info *info)
> > >  	mutex_unlock(&module_mutex);
> > > 
> > >  	ftrace_module_enable(mod);
> > > +	err = klp_module_enable(mod);
> > > +	if (err)
> > > +		goto out;
> > 
> > If you go out here, you need to revert some some operations
> > that are normally done in the bug_cleanup: goto target
> > in load_module(). In particular, you need to do:
> > 
> > 	/* module_bug_cleanup needs module_mutex protection */
> > 	mutex_lock(&module_mutex);
> > 	module_bug_cleanup(mod);
> > 	mutex_unlock(&module_mutex);
> > 
> > 	ftrace_release_mod(mod);
> > 
> > 	/* we can't deallocate the module until we clear memory protection */
> > 	module_disable_ro(mod);
> > 	module_disable_nx(mod);
> > 
> > 
> > IMHO, it would make sense to somehow split the complete_formation() function
> > and avoid a code duplication in the error paths.
> 
> Argh, thank you for catching that. I think we could split up
> complete_formation()
> into two functions in order to make the error handling work. 
> We could probably take out the coming notifier calls, ftrace_module_enable(),
> and klp_module_enable() out of complete_formation(), and put them in another
> function, maybe called prepare_coming_module(), that would be called right
> after complete_formation(). It might look something like this:
> 
> @@ -3614,6 +3621,9 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
>        err = complete_formation(mod, info);        if (err)
>                goto ddebug_cleanup;
> +       err = prepare_coming_module(mod); // calls ftrace_module_enable(),
> klp_module_enable(), then coming notifiers
> +       if (err) // means that klp_module_enable failed
> +               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,
> @@ -3621,7 +3631,7 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
>                                  unknown_module_param_cb);
>        if (IS_ERR(after_dashes)) {
>                err = PTR_ERR(after_dashes);
> -               goto bug_cleanup;
> +               goto coming_cleanup;
>        } else if (after_dashes) {
>                pr_warn("%s: parameters '%s' after `--' ignored\n",
>                       mod->name, after_dashes);
> 
> Now for the error conditions. If complete_formation() fails, goto
> ddebug_cleanup. If prepare_coming_module() fails (at that point,
> module_enable_{ro,nx} and module_bug_finalize() have already finished), goto
> bug_cleanup. Everything else that fails afterwards (meaning klp_module_enable,
> ftrace_module_enable, and the coming notifiers have finished) goto
> coming_cleanup. ftrace_release_mod() gets called in the goto free_module label
> so we don't have to call it in coming_module.
> 
> @@ -3649,16 +3659,16 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
> 
> + coming_cleanup:
> +       blocking_notifier_call_chain(&module_notify_list,
> +                                    MODULE_STATE_GOING, mod);
> +       klp_module_disable(mod);
>  bug_cleanup:
>        /* module_bug_cleanup needs module_mutex protection */
>        mutex_lock(&module_mutex);
>        module_bug_cleanup(mod);
>        mutex_unlock(&module_mutex);
> 
> -       blocking_notifier_call_chain(&module_notify_list,
> -                                    MODULE_STATE_GOING, mod);
> -       klp_module_disable(mod);
> -
>        /* we can't deallocate the module until we clear memory protection */
>        module_disable_ro(mod);
>        module_disable_nx(mod);
> 
> Does all this look ok? 

Hm, there is an another option. We can cover the needed error handling in 
complete_formation(). So for the first error there 
(verify_export_symbols() fails) we need to only release module_mutex. For 
our second error we need more. We would call module_bug_cleanup() under 
module_mutex, module_disable_{ro,nx} and going notifiers. Is this correct? 
It would be hidden in complete_formation() this way and cleaner in my 
opinion. There is some code duplication though.

> Also, one last thing, I noticed that module->state
> isn't
> set to MODULE_STATE_GOING anywhere before the going notifier chain is called
> in
> the bug_cleanup label (I think it is still COMING at that point), so the
> klp_module_disable call right afterwards would have bailed out because of
> that.
> To be consistent, shouldn't it be set before the going notifiers are called?

This could break something or introduce a race somewhere. Git grep says 
there are several checks for MODULE_STATE_GOING through out the kernel 
which need to be checked.

Regards,
Miroslav

  reply	other threads:[~2016-02-05  9:16 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-02  1:17 [PATCH v2 0/2] Fix ordering of ftrace/livepatch calls on module load and unload Jessica Yu
2016-02-02  1:17 ` [PATCH v2 1/2] ftrace/module: remove ftrace module notifier Jessica Yu
2016-02-04 13:27   ` Petr Mladek
2016-02-04 14:18     ` Steven Rostedt
2016-02-04 15:21       ` Petr Mladek
2016-02-04 15:33         ` Steven Rostedt
2016-02-02  1:17 ` [PATCH v2 2/2] livepatch/module: remove livepatch " Jessica Yu
2016-02-04 14:39   ` Petr Mladek
2016-02-04 14:56     ` Steven Rostedt
2016-02-04 16:47     ` Miroslav Benes
2016-02-05  4:11     ` Jessica Yu
2016-02-05  9:15       ` Miroslav Benes [this message]
2016-02-05 10:06         ` Petr Mladek
2016-02-08  0:34       ` Rusty Russell
2016-02-04 17:29   ` [PATCH v2 2/2] " Miroslav Benes
2016-02-04 20:55   ` Josh Poimboeuf
2016-02-05  8:59     ` Miroslav Benes
2016-02-04 10:43 ` [PATCH v2 0/2] Fix ordering of ftrace/livepatch calls on module load and unload Jiri Kosina
2016-02-04 13:29   ` Steven Rostedt
2016-02-05  1:17     ` Rusty Russell
  -- strict thread matches above, loose matches on Subject: below --
2016-02-09  4:50 [PATCH v4 0/4] " Jessica Yu
2016-02-09  4:50 ` [PATCH v4 4/4] livepatch/module: remove livepatch module notifier Jessica Yu
2016-02-09 23:43   ` Rusty Russell
2016-02-10 10:18     ` Jiri Kosina
2016-02-14 22:59       ` Jiri Kosina
2016-02-15 23:27         ` Josh Poimboeuf
2016-02-15 23:42           ` Jiri Kosina
2016-02-16  0:48             ` Jessica Yu
2016-02-16  8:41               ` Miroslav Benes
2016-02-16 19:51                 ` Jessica Yu
2016-02-29  0:30       ` [PATCH v4 4/4] " Rusty Russell
2016-03-01  3:00         ` Jessica Yu
2016-03-11 20:03 [PATCH v2 0/2] Livepatch module notifier cleanup Jessica Yu
2016-03-11 20:03 ` [PATCH v2 2/2] livepatch/module: remove livepatch module notifier Jessica Yu
2016-03-14 15:06   ` Petr Mladek
2016-03-14 17:50     ` Jessica Yu
2016-03-15  9:10       ` Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LNX.2.00.1602051004000.25516@pobox.suse.cz \
    --to=mbenes@suse.cz \
    --cc=jeyu@redhat.com \
    --cc=jikos@kernel.org \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pmladek@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=rusty@rustcorp.com.au \
    --cc=sjenning@redhat.com \
    --cc=vojtech@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).