Re: [PATCH 0/7] livepatch,module: Remove .klp.arch and module_disable_ro()
From: Peter Zijlstra
Date: Wed Apr 15 2020 - 10:24:45 EST
On Tue, Apr 14, 2020 at 02:08:14PM -0500, Josh Poimboeuf wrote:
> On Tue, Apr 14, 2020 at 08:27:26PM +0200, Peter Zijlstra wrote:
> > On Tue, Apr 14, 2020 at 11:28:36AM -0500, Josh Poimboeuf wrote:
> > > Better late than never, these patches add simplifications and
> > > improvements for some issues Peter found six months ago, as part of his
> > > non-writable text code (W^X) cleanups.
> >
> > Excellent stuff, thanks!!
> >
> > I'll go brush up these two patches then:
> >
> > https://lkml.kernel.org/r/20191018074634.801435443@xxxxxxxxxxxxx
> > https://lkml.kernel.org/r/20191018074634.858645375@xxxxxxxxxxxxx
>
> Ah right, I meant to bring that up. I actually played around with those
> patches. While it would be nice to figure out a way to converge the
> ftrace module init, I didn't really like the first patch.
ftrace only needs it done after ftrace_module_enable(), which is before
the notifier chain happens, so we can simply do something like so
instead:
diff --git a/kernel/module.c b/kernel/module.c
index a3a8f6d0e144..89f8d02c3c3e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3700,6 +3700,10 @@ static int prepare_coming_module(struct module *mod)
if (err)
return err;
+ module_enable_ro(mod, false);
+ module_enable_nx(mod);
+ module_enable_x(mod);
+
err = blocking_notifier_call_chain_robust(&module_notify_list,
MODULE_STATE_COMING, MODULE_STATE_GOING, mod);
err = notifier_to_errno(err);
@@ -3845,10 +3849,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
if (err)
goto bug_cleanup;
- module_enable_ro(mod, false);
- module_enable_nx(mod);
- module_enable_x(mod);
-
/* 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,
> It bothers me that both the notifiers and the module init() both see the
> same MODULE_STATE_COMING state, but only in the former case is the text
> writable.
>
> I think it's cognitively simpler if MODULE_STATE_COMING always means the
> same thing, like the comments imply, "fully formed" and thus
> not-writable:
>
> enum module_state {
> MODULE_STATE_LIVE, /* Normal state. */
> MODULE_STATE_COMING, /* Full formed, running module_init. */
> MODULE_STATE_GOING, /* Going away. */
> MODULE_STATE_UNFORMED, /* Still setting it up. */
> };
>
> And, it keeps tighter constraints on what a notifier can do, which is a
> good thing if we can get away with it.
Moo! -- but jump_label and static_call are on the notifier chain and I
was hoping to make it cheaper for them. Should we perhaps weane them off the
notifier and, like ftrace/klp put in explicit calls?
It'd make the error handling in prepare_coming_module() a bigger mess,
but it should work.