Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-30 Thread Miroslav Benes
On Fri, 30 Jun 2017, Josh Poimboeuf wrote:

> On Mon, Jun 19, 2017 at 06:56:37PM +0200, Miroslav Benes wrote:
> > 
> > > > > I often wonder whether it's really a good idea to even allow the
> > > > > unloading of patch modules at all.  It adds complexity to the 
> > > > > livepatch
> > > > > code.  Is it worth it?  I don't have an answer but I'd be interested 
> > > > > in
> > > > > other people's opinion.
> > > > 
> > > > I could imagine a situation when a livepatch causes, for example,
> > > > performance, problems on a server because of the redirection
> > > > to the new code. Then it might be handy to disable the patch
> > > > and ftrace handlers completely.
> > > 
> > > Fair enough, though it sounds theoretical.  It would be good to know
> > > we're supporting actual real world use cases.
> > 
> > We distribute cumulative "replace_all" patches at SUSE. replace_all means 
> > that all previous patches are reverted in the process of application. All 
> > livepatch modules with zero refcount are removed. This keeps a number of 
> > loaded modules low and system's state well defined, which is always a good 
> > thing, because a customer might run into problems and we'd have to debug 
> > it.
> 
> We used to have something similar in kpatch.  And we recently discovered
> that this "replace_all" feature would also be nice to have in livepatch.
> 
> We had a patch B which needed to partially revert patch A.  We had to
> manually do the revert at a function level, which basically means
> repatching the function so that it resembles its original state.
> 
> It would be much more straightforward to be able to tell klp to revert
> everything in patch A while applying patch B.  Then the func stack would
> never have more than one entry.  And that would be good for performance
> as well.

Exactly.

It is on my TODO list right after the fake signal. I've been occupied by 
different things recently but I'll definitely return to it soon.

Regards,
Miroslav


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-30 Thread Josh Poimboeuf
On Mon, Jun 19, 2017 at 06:56:37PM +0200, Miroslav Benes wrote:
> 
> > > > I often wonder whether it's really a good idea to even allow the
> > > > unloading of patch modules at all.  It adds complexity to the livepatch
> > > > code.  Is it worth it?  I don't have an answer but I'd be interested in
> > > > other people's opinion.
> > > 
> > > I could imagine a situation when a livepatch causes, for example,
> > > performance, problems on a server because of the redirection
> > > to the new code. Then it might be handy to disable the patch
> > > and ftrace handlers completely.
> > 
> > Fair enough, though it sounds theoretical.  It would be good to know
> > we're supporting actual real world use cases.
> 
> We distribute cumulative "replace_all" patches at SUSE. replace_all means 
> that all previous patches are reverted in the process of application. All 
> livepatch modules with zero refcount are removed. This keeps a number of 
> loaded modules low and system's state well defined, which is always a good 
> thing, because a customer might run into problems and we'd have to debug 
> it.

We used to have something similar in kpatch.  And we recently discovered
that this "replace_all" feature would also be nice to have in livepatch.

We had a patch B which needed to partially revert patch A.  We had to
manually do the revert at a function level, which basically means
repatching the function so that it resembles its original state.

It would be much more straightforward to be able to tell klp to revert
everything in patch A while applying patch B.  Then the func stack would
never have more than one entry.  And that would be good for performance
as well.

-- 
Josh


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-19 Thread Miroslav Benes

> > > I often wonder whether it's really a good idea to even allow the
> > > unloading of patch modules at all.  It adds complexity to the livepatch
> > > code.  Is it worth it?  I don't have an answer but I'd be interested in
> > > other people's opinion.
> > 
> > I could imagine a situation when a livepatch causes, for example,
> > performance, problems on a server because of the redirection
> > to the new code. Then it might be handy to disable the patch
> > and ftrace handlers completely.
> 
> Fair enough, though it sounds theoretical.  It would be good to know
> we're supporting actual real world use cases.

We distribute cumulative "replace_all" patches at SUSE. replace_all means 
that all previous patches are reverted in the process of application. All 
livepatch modules with zero refcount are removed. This keeps a number of 
loaded modules low and system's state well defined, which is always a good 
thing, because a customer might run into problems and we'd have to debug 
it.

It is true that it is a limitation too. Especially for state changes and 
data structure modifications. Sometimes it is easy to patch a system, but 
impossible to unpatch it. Because we don't have a consistency on a state 
level, only on a task/process level. But I perceive this also as an 
advantage. I have to always know what a livepatch does exactly and I 
discovered couple of problems just because I had to think about unloading 
of modules.

Miroslav


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-19 Thread Miroslav Benes

> Good catch.  Let me add a disclaimer here and state that this example is
> definitely contrived as I was trying to minimize its size.  Applying
> shadow variables to a more real life use case would drag in a bunch of
> "changed" function dependencies.  I didn't want to work around those
> with a pile of kallsyms workarounds.  It did lead you to ask an
> interesting question though:

You can always create a completely artificial sample based on a real life 
use case. I mean, you can create a module with functions and data 
structures you need and then patch one of those functions. You control 
everything and you can limit dependencies and kallsyms workarounds (or 
avoid them completely).

Miroslav


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-15 Thread Josh Poimboeuf
On Thu, Jun 15, 2017 at 10:38:00AM -0400, Joe Lawrence wrote:
> On Thu, Jun 15, 2017 at 08:49:27AM -0500, Josh Poimboeuf wrote:
> > Date: Thu, 15 Jun 2017 08:49:27 -0500
> > From: Josh Poimboeuf 
> > To: Petr Mladek 
> > Cc: Joe Lawrence , live-patch...@vger.kernel.org,
> >  linux-kernel@vger.kernel.org, Jessica Yu , Jiri Kosina
> >  , Miroslav Benes 
> > Subject: Re: [PATCH 3/3] livepatch: add shadow variable sample program
> > User-Agent: Mutt/1.6.0.1 (2016-04-01)
> > 
> > On Thu, Jun 15, 2017 at 12:59:43PM +0200, Petr Mladek wrote:
> > > On Wed 2017-06-14 09:57:56, Josh Poimboeuf wrote:
> > > > On Wed, Jun 14, 2017 at 04:21:02PM +0200, Petr Mladek wrote:
> > > > > But it is racy in general. The question is if the API
> > > > > could help here. A possibility might be to allow to
> > > > > define a callback function that would create the shadow
> > > > > structure when it does not exist. I mean something like
> > > > > 
> > > > > typedef void (*klp_shadow_create_obj_func_t)(void * obj);
> > > > > 
> > > > > void *klp_shadow_get_or_create(void *obj, int key, gfp_t gfp,
> > > > >   klp_shadow_create_obj_fun_t *create)
> > > > > {
> > > > >   struct klp_shadow *shadow;
> > > > > 
> > > > >   shadow = klp_shadow_get(obj, key);
> > > > > 
> > > > >   if (!shadow && create) {
> > > > >   void *shadow_obj;
> > > > > 
> > > > >   spin_lock_irqsave(&klp_shadow_lock, flags);
> > > > >   shadow = klp_shadow_get(obj, key);
> > > > >   if (shadow)
> > > > >   goto out;
> > > > > 
> > > > >   shadow_obj = create(obj);
> > > > >   shadow = __klp_shadow_attach(obj, key, gfp,
> > > > >   shadow_obj);
> > > > > out:
> > > > >   spin_unlock_irqrestore(&klp_shadow_lock, flags);
> > > > >   }
> > > > > 
> > > > >   return shadow;
> > > > > }
> > > > > 
> > > > > I do not know. Maybe it is too ugly. Or will it safe a duplicated code
> > > > > in many cases?
> > > > 
> > > > I think this sample module is confusing because it uses the API in a
> > > > contrived way.  In reality, we use it more like the API documentation
> > > > describes: klp_shadow_attach() is called right after the parent struct
> > > > is allocated and klp_shadow_detach() is called right before the parent
> > > > struct is freed.  So the above race wouldn't normally exist.
> > > 
> > > But it kind of limits the usage only for short-living objects.
> > > I mean that it does not help much to patch only the
> > > allocation()/destroy() path when many affected objects
> > > are created during boot or right after boot.
> > > 
> > > Well, I admit that my opinion is rather theoretical. You have more
> > > experience with real life scenarios.
> > 
> > Yes, maybe something like the above (create shadow var on read) would be
> > useful in some cases.  You'd have to be careful about allocating memory;
> > maybe GFP_NOWAIT would be needed.
> 
> I think we tossed around an idea like this, sans callbacks, for one our
> CVE-research patches.  As for the GFP flags, isn't that going to depend
> on the context of the patched code?

Right, the caller would need to specify the GFP flags for the klp_shadow
struct allocation, just like with klp_shadow_attach().

> Also, the caller can choose to allocate the new shadow data, but not
> the tracking struct klp_shadow, however it sees fit... pre-allocate a
> pool, whatever.  That is one distinction between this implementation
> and the kpatch counterpart.
> 
> > > > I often wonder whether it's really a good idea to even allow the
> > > > unloading of patch modules at all.  It adds complexity to the livepatch
> > > > code.  Is it worth it?  I don't have an answer but I'd be interested in
> > > > other people's opinion.
> > > 
> > > I could imagine a situation when a livepatch causes, for example,
> > > performance, problems on a server because of the redirection
> > > to the new code. Then it might be handy to disable the patch
> > > and ftrace handlers completely.
> > 
> > Fair enough, though it sounds theoretical.  It would be good to know
> > we're supporting actual real world use cases.
> > 
> > Unloading a patch module which created shadow variables will cause
> > memory leaks.  So either the shadow code or the patch module will need
> > to keep track of all the module's shadow variables so they can be freed
> > when the patch module gets unloaded.
> 
> As Petr suggested earlier in the thread, maybe a klp_shadow_detach_all
> function that rips through the klp_shadow_hash cleaning everything up.
> This could be called on patch module exit.

Yeah, though it'd be nice if it didn't need a callback to allow the user
to free the shadow data.  Maybe we should just move the shadow data
allocation into the klp_shadow code, like kpatch.

-- 
Josh


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-15 Thread Josh Poimboeuf
On Thu, Jun 15, 2017 at 12:59:43PM +0200, Petr Mladek wrote:
> On Wed 2017-06-14 09:57:56, Josh Poimboeuf wrote:
> > On Wed, Jun 14, 2017 at 04:21:02PM +0200, Petr Mladek wrote:
> > > But it is racy in general. The question is if the API
> > > could help here. A possibility might be to allow to
> > > define a callback function that would create the shadow
> > > structure when it does not exist. I mean something like
> > > 
> > > typedef void (*klp_shadow_create_obj_func_t)(void * obj);
> > > 
> > > void *klp_shadow_get_or_create(void *obj, int key, gfp_t gfp,
> > >   klp_shadow_create_obj_fun_t *create)
> > > {
> > >   struct klp_shadow *shadow;
> > > 
> > >   shadow = klp_shadow_get(obj, key);
> > > 
> > >   if (!shadow && create) {
> > >   void *shadow_obj;
> > > 
> > >   spin_lock_irqsave(&klp_shadow_lock, flags);
> > >   shadow = klp_shadow_get(obj, key);
> > >   if (shadow)
> > >   goto out;
> > > 
> > >   shadow_obj = create(obj);
> > >   shadow = __klp_shadow_attach(obj, key, gfp,
> > >   shadow_obj);
> > > out:
> > >   spin_unlock_irqrestore(&klp_shadow_lock, flags);
> > >   }
> > > 
> > >   return shadow;
> > > }
> > > 
> > > I do not know. Maybe it is too ugly. Or will it safe a duplicated code
> > > in many cases?
> > 
> > I think this sample module is confusing because it uses the API in a
> > contrived way.  In reality, we use it more like the API documentation
> > describes: klp_shadow_attach() is called right after the parent struct
> > is allocated and klp_shadow_detach() is called right before the parent
> > struct is freed.  So the above race wouldn't normally exist.
> 
> But it kind of limits the usage only for short-living objects.
> I mean that it does not help much to patch only the
> allocation()/destroy() path when many affected objects
> are created during boot or right after boot.
> 
> Well, I admit that my opinion is rather theoretical. You have more
> experience with real life scenarios.

Yes, maybe something like the above (create shadow var on read) would be
useful in some cases.  You'd have to be careful about allocating memory;
maybe GFP_NOWAIT would be needed.

> > I think Joe implemented it this way in order to keep it simple, so it
> > wouldn't have to use kallsyms to do manual relocations, etc.  But maybe
> > a more realistic example would be better since it represents how things
> > should really be done in the absence of out-of-tree tooling like
> > kpatch-build or klp-convert.
> 
> BTW: It seems that the example works only by chance. I test it by
> 
>cat /proc/cmdline
> 
> It always forks a new process to run /usr/bin/cat. I guess that
> there is a cache (in the memory management) and a high chance
> that new process gets the last freed task_struct. But I got
> different pointers for the process when I tried it many times.
> 
> 
> > I often wonder whether it's really a good idea to even allow the
> > unloading of patch modules at all.  It adds complexity to the livepatch
> > code.  Is it worth it?  I don't have an answer but I'd be interested in
> > other people's opinion.
> 
> I could imagine a situation when a livepatch causes, for example,
> performance, problems on a server because of the redirection
> to the new code. Then it might be handy to disable the patch
> and ftrace handlers completely.

Fair enough, though it sounds theoretical.  It would be good to know
we're supporting actual real world use cases.

Unloading a patch module which created shadow variables will cause
memory leaks.  So either the shadow code or the patch module will need
to keep track of all the module's shadow variables so they can be freed
when the patch module gets unloaded.

-- 
Josh


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-15 Thread Petr Mladek
On Wed 2017-06-14 09:57:56, Josh Poimboeuf wrote:
> On Wed, Jun 14, 2017 at 04:21:02PM +0200, Petr Mladek wrote:
> > But it is racy in general. The question is if the API
> > could help here. A possibility might be to allow to
> > define a callback function that would create the shadow
> > structure when it does not exist. I mean something like
> > 
> > typedef void (*klp_shadow_create_obj_func_t)(void * obj);
> > 
> > void *klp_shadow_get_or_create(void *obj, int key, gfp_t gfp,
> > klp_shadow_create_obj_fun_t *create)
> > {
> > struct klp_shadow *shadow;
> > 
> > shadow = klp_shadow_get(obj, key);
> > 
> > if (!shadow && create) {
> > void *shadow_obj;
> > 
> > spin_lock_irqsave(&klp_shadow_lock, flags);
> > shadow = klp_shadow_get(obj, key);
> > if (shadow)
> > goto out;
> > 
> > shadow_obj = create(obj);
> > shadow = __klp_shadow_attach(obj, key, gfp,
> > shadow_obj);
> > out:
> > spin_unlock_irqrestore(&klp_shadow_lock, flags);
> > }
> > 
> > return shadow;
> > }
> > 
> > I do not know. Maybe it is too ugly. Or will it safe a duplicated code
> > in many cases?
> 
> I think this sample module is confusing because it uses the API in a
> contrived way.  In reality, we use it more like the API documentation
> describes: klp_shadow_attach() is called right after the parent struct
> is allocated and klp_shadow_detach() is called right before the parent
> struct is freed.  So the above race wouldn't normally exist.

But it kind of limits the usage only for short-living objects.
I mean that it does not help much to patch only the
allocation()/destroy() path when many affected objects
are created during boot or right after boot.

Well, I admit that my opinion is rather theoretical. You have more
experience with real life scenarios.

 
> I think Joe implemented it this way in order to keep it simple, so it
> wouldn't have to use kallsyms to do manual relocations, etc.  But maybe
> a more realistic example would be better since it represents how things
> should really be done in the absence of out-of-tree tooling like
> kpatch-build or klp-convert.

BTW: It seems that the example works only by chance. I test it by

   cat /proc/cmdline

It always forks a new process to run /usr/bin/cat. I guess that
there is a cache (in the memory management) and a high chance
that new process gets the last freed task_struct. But I got
different pointers for the process when I tried it many times.


> I often wonder whether it's really a good idea to even allow the
> unloading of patch modules at all.  It adds complexity to the livepatch
> code.  Is it worth it?  I don't have an answer but I'd be interested in
> other people's opinion.

I could imagine a situation when a livepatch causes, for example,
performance, problems on a server because of the redirection
to the new code. Then it might be handy to disable the patch
and ftrace handlers completely.

I know that disabling and removing patch are two different
things. Well, removing the patch is kind of test that the code
works as expected. If nothing else, this feature forced me
to understand various nasty things that help to be more
confident about the rest of the code ;-)

Best Regards,
Petr


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-14 Thread Joe Lawrence
On 06/14/2017 10:21 AM, Petr Mladek wrote:
> On Thu 2017-06-01 14:25:26, Joe Lawrence wrote:
>> Modify the sample livepatch to demonstrate the shadow variable API.
>>
>> Signed-off-by: Joe Lawrence 
>> ---
>>  samples/livepatch/livepatch-sample.c | 39 
>> +++-
>>  1 file changed, 38 insertions(+), 1 deletion(-)
>>
>> diff --git a/samples/livepatch/livepatch-sample.c 
>> b/samples/livepatch/livepatch-sample.c
>> index 84795223f15f..e0236750cefb 100644
>> --- a/samples/livepatch/livepatch-sample.c
>> +++ b/samples/livepatch/livepatch-sample.c
>> @@ -25,26 +25,57 @@
>>  
>>  /*
>>   * This (dumb) live patch overrides the function that prints the
>> - * kernel boot cmdline when /proc/cmdline is read.
>> + * kernel boot cmdline when /proc/cmdline is read.  It also
>> + * demonstrates a contrived shadow-variable usage.
>>   *
>>   * Example:
>>   *
>>   * $ cat /proc/cmdline
>>   * 
>> + * current= count=
>>   *
>>   * $ insmod livepatch-sample.ko
>>   * $ cat /proc/cmdline
>>   * this has been live patched
>> + * current=8800331c9540 count=1
>> + * $ cat /proc/cmdline
>> + * this has been live patched
>> + * current=8800331c9540 count=2
>>   *
>>   * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled
>>   * $ cat /proc/cmdline
>>   * 
>>   */
>>  
>> +static LIST_HEAD(shadow_list);
>> +
>> +struct task_ctr {
>> +struct list_head list;
>> +int count;
>> +};
>> +
>>  #include 
>> +#include 
>>  static int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
>>  {
>> +struct task_ctr *nd;
>> +
>> +nd = klp_shadow_get(current, "task_ctr");
>> +if (!nd) {
>> +nd = kzalloc(sizeof(*nd), GFP_KERNEL);
>> +if (nd) {
>> +list_add(&nd->list, &shadow_list);
>> +klp_shadow_attach(current, "task_ctr", GFP_KERNEL, nd);
>> +}
>> +}
> 
> Hmm, this looks racy:
> 
> CPU0  CPU1
> 
> klp_shadow_get()  klp_shadow_get()
> # returns NULL# returns NULL
> if (!nd) {if (!nd) {
>   nd = kzalloc();   nd = kzalloc();
>   list_add(&nd->list,   list_add(&nd->list,
>  &shadow_list);   &shadow_list);
> 
> BANG: This is one race. We add items into the shared shadow_list
> in parallel. The question is if we need it. IMHO, the API
> could help here, see the comments for livepatch_exit() below.
> 
>   klp_shadow_attach();klp_shadow_attach();
> 
> WARNING: This is fine because the shadow objects are for
> different objects. I mean that "current" must point
> to different processes on the two CPUs.
> 
> But it is racy in general.

Good catch.  Let me add a disclaimer here and state that this example is
definitely contrived as I was trying to minimize its size.  Applying
shadow variables to a more real life use case would drag in a bunch of
"changed" function dependencies.  I didn't want to work around those
with a pile of kallsyms workarounds.  It did lead you to ask an
interesting question though:

>The question is if the API
> could help here. A possibility might be to allow to
> define a callback function that would create the shadow
> structure when it does not exist. I mean something like
> 
> typedef void (*klp_shadow_create_obj_func_t)(void * obj);
> 
> void *klp_shadow_get_or_create(void *obj, int key, gfp_t gfp,
>   klp_shadow_create_obj_fun_t *create)
> {
>   struct klp_shadow *shadow;
> 
>   shadow = klp_shadow_get(obj, key);
> 
>   if (!shadow && create) {
>   void *shadow_obj;
> 
>   spin_lock_irqsave(&klp_shadow_lock, flags);
>   shadow = klp_shadow_get(obj, key);
>   if (shadow)
>   goto out;
> 
>   shadow_obj = create(obj);
>   shadow = __klp_shadow_attach(obj, key, gfp,
>   shadow_obj);
> out:
>   spin_unlock_irqrestore(&klp_shadow_lock, flags);
>   }
> 
>   return shadow;
> }
> 
> I do not know. Maybe it is too ugly. Or will it safe a duplicated code
> in many cases?

In the kpatch experience, we've typically created shadow variables when
new host variables are allocated.  That means that patched code must
handle instances of host variables with and without their shadow
counterparts.  It also avoids the race scenario above since we're not
calling klp_shadow_attach for the same  concurrently.

That said, I think we may have written a few test patches that create
new shadow vars if klp_shadow_get fails.

A callback would eliminate a potentially racy klp_shadow_get +
klp_shadow_attach combination.  One wrinkle would be initialization.
Once the callback creates the shadow variable, any subsequent
klp_shadow_get may return it...

Perhaps it would be sufficient to add additional argument to
klp_shadow_get_or_create that gets passed to the create(

Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-14 Thread Josh Poimboeuf
On Wed, Jun 14, 2017 at 04:21:02PM +0200, Petr Mladek wrote:
> On Thu 2017-06-01 14:25:26, Joe Lawrence wrote:
> > Modify the sample livepatch to demonstrate the shadow variable API.
> > 
> > Signed-off-by: Joe Lawrence 
> > ---
> >  samples/livepatch/livepatch-sample.c | 39 
> > +++-
> >  1 file changed, 38 insertions(+), 1 deletion(-)
> > 
> > diff --git a/samples/livepatch/livepatch-sample.c 
> > b/samples/livepatch/livepatch-sample.c
> > index 84795223f15f..e0236750cefb 100644
> > --- a/samples/livepatch/livepatch-sample.c
> > +++ b/samples/livepatch/livepatch-sample.c
> > @@ -25,26 +25,57 @@
> >  
> >  /*
> >   * This (dumb) live patch overrides the function that prints the
> > - * kernel boot cmdline when /proc/cmdline is read.
> > + * kernel boot cmdline when /proc/cmdline is read.  It also
> > + * demonstrates a contrived shadow-variable usage.
> >   *
> >   * Example:
> >   *
> >   * $ cat /proc/cmdline
> >   * 
> > + * current= count=
> >   *
> >   * $ insmod livepatch-sample.ko
> >   * $ cat /proc/cmdline
> >   * this has been live patched
> > + * current=8800331c9540 count=1
> > + * $ cat /proc/cmdline
> > + * this has been live patched
> > + * current=8800331c9540 count=2
> >   *
> >   * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled
> >   * $ cat /proc/cmdline
> >   * 
> >   */
> >  
> > +static LIST_HEAD(shadow_list);
> > +
> > +struct task_ctr {
> > +   struct list_head list;
> > +   int count;
> > +};
> > +
> >  #include 
> > +#include 
> >  static int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
> >  {
> > +   struct task_ctr *nd;
> > +
> > +   nd = klp_shadow_get(current, "task_ctr");
> > +   if (!nd) {
> > +   nd = kzalloc(sizeof(*nd), GFP_KERNEL);
> > +   if (nd) {
> > +   list_add(&nd->list, &shadow_list);
> > +   klp_shadow_attach(current, "task_ctr", GFP_KERNEL, nd);
> > +   }
> > +   }
> 
> Hmm, this looks racy:
> 
> CPU0  CPU1
> 
> klp_shadow_get()  klp_shadow_get()
> # returns NULL# returns NULL
> if (!nd) {if (!nd) {
>   nd = kzalloc();   nd = kzalloc();
>   list_add(&nd->list,   list_add(&nd->list,
>  &shadow_list);   &shadow_list);
> 
> BANG: This is one race. We add items into the shared shadow_list
> in parallel. The question is if we need it. IMHO, the API
> could help here, see the comments for livepatch_exit() below.
> 
>   klp_shadow_attach();klp_shadow_attach();
> 
> WARNING: This is fine because the shadow objects are for
> different objects. I mean that "current" must point
> to different processes on the two CPUs.
> 
> But it is racy in general. The question is if the API
> could help here. A possibility might be to allow to
> define a callback function that would create the shadow
> structure when it does not exist. I mean something like
> 
> typedef void (*klp_shadow_create_obj_func_t)(void * obj);
> 
> void *klp_shadow_get_or_create(void *obj, int key, gfp_t gfp,
>   klp_shadow_create_obj_fun_t *create)
> {
>   struct klp_shadow *shadow;
> 
>   shadow = klp_shadow_get(obj, key);
> 
>   if (!shadow && create) {
>   void *shadow_obj;
> 
>   spin_lock_irqsave(&klp_shadow_lock, flags);
>   shadow = klp_shadow_get(obj, key);
>   if (shadow)
>   goto out;
> 
>   shadow_obj = create(obj);
>   shadow = __klp_shadow_attach(obj, key, gfp,
>   shadow_obj);
> out:
>   spin_unlock_irqrestore(&klp_shadow_lock, flags);
>   }
> 
>   return shadow;
> }
> 
> I do not know. Maybe it is too ugly. Or will it safe a duplicated code
> in many cases?

I think this sample module is confusing because it uses the API in a
contrived way.  In reality, we use it more like the API documentation
describes: klp_shadow_attach() is called right after the parent struct
is allocated and klp_shadow_detach() is called right before the parent
struct is freed.  So the above race wouldn't normally exist.

I think Joe implemented it this way in order to keep it simple, so it
wouldn't have to use kallsyms to do manual relocations, etc.  But maybe
a more realistic example would be better since it represents how things
should really be done in the absence of out-of-tree tooling like
kpatch-build or klp-convert.

> > seq_printf(m, "%s\n", "this has been live patched");
> > +
> > +   if (nd) {
> > +   nd->count++;
> > +   seq_printf(m, "current=%p count=%d\n", current, nd->count);
> > +   }
> > +
> > return 0;
> >  }
> >  
> > @@ -99,6 +130,12 @@ static int livepatch_init(void)
> >  
> >  static void livepatch_exit(void)
> >  {
> > +   struct task_ctr *nd, *tmp;
> > +
> > +   list_for_each_entry_safe(nd, tmp, &shadow_list, list) {
> > +   list_d

Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-14 Thread Petr Mladek
On Thu 2017-06-01 14:25:26, Joe Lawrence wrote:
> Modify the sample livepatch to demonstrate the shadow variable API.
> 
> Signed-off-by: Joe Lawrence 
> ---
>  samples/livepatch/livepatch-sample.c | 39 
> +++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/samples/livepatch/livepatch-sample.c 
> b/samples/livepatch/livepatch-sample.c
> index 84795223f15f..e0236750cefb 100644
> --- a/samples/livepatch/livepatch-sample.c
> +++ b/samples/livepatch/livepatch-sample.c
> @@ -25,26 +25,57 @@
>  
>  /*
>   * This (dumb) live patch overrides the function that prints the
> - * kernel boot cmdline when /proc/cmdline is read.
> + * kernel boot cmdline when /proc/cmdline is read.  It also
> + * demonstrates a contrived shadow-variable usage.
>   *
>   * Example:
>   *
>   * $ cat /proc/cmdline
>   * 
> + * current= count=
>   *
>   * $ insmod livepatch-sample.ko
>   * $ cat /proc/cmdline
>   * this has been live patched
> + * current=8800331c9540 count=1
> + * $ cat /proc/cmdline
> + * this has been live patched
> + * current=8800331c9540 count=2
>   *
>   * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled
>   * $ cat /proc/cmdline
>   * 
>   */
>  
> +static LIST_HEAD(shadow_list);
> +
> +struct task_ctr {
> + struct list_head list;
> + int count;
> +};
> +
>  #include 
> +#include 
>  static int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
>  {
> + struct task_ctr *nd;
> +
> + nd = klp_shadow_get(current, "task_ctr");
> + if (!nd) {
> + nd = kzalloc(sizeof(*nd), GFP_KERNEL);
> + if (nd) {
> + list_add(&nd->list, &shadow_list);
> + klp_shadow_attach(current, "task_ctr", GFP_KERNEL, nd);
> + }
> + }

Hmm, this looks racy:

CPU0CPU1

klp_shadow_get()klp_shadow_get()
# returns NULL  # returns NULL
if (!nd) {  if (!nd) {
  nd = kzalloc(); nd = kzalloc();
  list_add(&nd->list, list_add(&nd->list,
   &shadow_list);   &shadow_list);

BANG: This is one race. We add items into the shared shadow_list
in parallel. The question is if we need it. IMHO, the API
could help here, see the comments for livepatch_exit() below.

  klp_shadow_attach();  klp_shadow_attach();

WARNING: This is fine because the shadow objects are for
different objects. I mean that "current" must point
to different processes on the two CPUs.

But it is racy in general. The question is if the API
could help here. A possibility might be to allow to
define a callback function that would create the shadow
structure when it does not exist. I mean something like

typedef void (*klp_shadow_create_obj_func_t)(void * obj);

void *klp_shadow_get_or_create(void *obj, int key, gfp_t gfp,
klp_shadow_create_obj_fun_t *create)
{
struct klp_shadow *shadow;

shadow = klp_shadow_get(obj, key);

if (!shadow && create) {
void *shadow_obj;

spin_lock_irqsave(&klp_shadow_lock, flags);
shadow = klp_shadow_get(obj, key);
if (shadow)
goto out;

shadow_obj = create(obj);
shadow = __klp_shadow_attach(obj, key, gfp,
shadow_obj);
out:
spin_unlock_irqrestore(&klp_shadow_lock, flags);
}

return shadow;
}

I do not know. Maybe it is too ugly. Or will it safe a duplicated code
in many cases?

>   seq_printf(m, "%s\n", "this has been live patched");
> +
> + if (nd) {
> + nd->count++;
> + seq_printf(m, "current=%p count=%d\n", current, nd->count);
> + }
> +
>   return 0;
>  }
>  
> @@ -99,6 +130,12 @@ static int livepatch_init(void)
>  
>  static void livepatch_exit(void)
>  {
> + struct task_ctr *nd, *tmp;
> +
> + list_for_each_entry_safe(nd, tmp, &shadow_list, list) {
> + list_del(&nd->list);
> + kfree(nd);

I think that this will be a rather common operation. Do we need
the extra list? It might be enough to delete all entries
in the hash table with a given key. Well, we might need
a callback again:

typedef void (*klp_shadow_free_obj_func_t)(void *shadow_obj);

void klp_shadow_free_all(int key, klp_shadow_free_obj_fun_t *shadow_free)
{
int i;
struct klp_shadow *shadow;

spin_lock_irqsave(&klp_shadow_lock, flags);

hash_for_each(klp_shadow_hash, i, shadow, node) {
hash_del_rcu(&shadow->node);
/* patch and shadow data are not longer used. */
shadow_free(shadow->shadow_obj);
/*
 * shadow structure might still be traversed
 * by someone
 */
kfree_

Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-14 Thread Miroslav Benes

> I'm not familiar with klp-convert, so I'll assume that will be handled
> as its own patch(set).

Correct.

Miroslav


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-13 Thread Joe Lawrence
On 06/13/2017 07:00 AM, Miroslav Benes wrote:
> On Thu, 1 Jun 2017, Joe Lawrence wrote:
> 
>> Modify the sample livepatch to demonstrate the shadow variable API.
>>
>> Signed-off-by: Joe Lawrence 
>> ---
>>  samples/livepatch/livepatch-sample.c | 39 
>> +++-
>>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> Would it make sense to make this our second sample module? I think we 
> should keep one as simple as possible, and illustrate new features in 
> separate sample modules.
> 
> I'd like to have another one for klp-convert patch set too.
> 
> What do you think?
> 
> Miroslav
> 

Yeah, adding this as a new sample module is a good idea.  I'll split
that out in v2.

I'm not familiar with klp-convert, so I'll assume that will be handled
as its own patch(set).

Thanks,

-- Joe


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-13 Thread Miroslav Benes
On Thu, 1 Jun 2017, Joe Lawrence wrote:

> Modify the sample livepatch to demonstrate the shadow variable API.
> 
> Signed-off-by: Joe Lawrence 
> ---
>  samples/livepatch/livepatch-sample.c | 39 
> +++-
>  1 file changed, 38 insertions(+), 1 deletion(-)

Would it make sense to make this our second sample module? I think we 
should keep one as simple as possible, and illustrate new features in 
separate sample modules.

I'd like to have another one for klp-convert patch set too.

What do you think?

Miroslav



Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-09 Thread Joe Lawrence
On 06/09/2017 02:38 PM, Josh Poimboeuf wrote:
> On Thu, Jun 01, 2017 at 02:25:26PM -0400, Joe Lawrence wrote:
>> [ ... snip ... ]  
>> @@ -99,6 +130,12 @@ static int livepatch_init(void)
>>  
>>  static void livepatch_exit(void)
>>  {
>> +struct task_ctr *nd, *tmp;
>> +
>> +list_for_each_entry_safe(nd, tmp, &shadow_list, list) {
>> +list_del(&nd->list);
>> +kfree(nd);
>> +}
>>  WARN_ON(klp_unregister_patch(&patch));
>>  }
> 
> What does 'nd' stand for?  I think a name like 'ctr' would be clearer.
> 

Ah, in an earlier draft (pre-post) that data structure was called
"new_data", so "nd" was simply a short hand abbreviation.  I'll update
for v2, thanks.

-- Joe


Re: [PATCH 3/3] livepatch: add shadow variable sample program

2017-06-09 Thread Josh Poimboeuf
On Thu, Jun 01, 2017 at 02:25:26PM -0400, Joe Lawrence wrote:
>  #include 
> +#include 
>  static int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
>  {
> + struct task_ctr *nd;
> +
> + nd = klp_shadow_get(current, "task_ctr");
> + if (!nd) {
> + nd = kzalloc(sizeof(*nd), GFP_KERNEL);
> + if (nd) {
> + list_add(&nd->list, &shadow_list);
> + klp_shadow_attach(current, "task_ctr", GFP_KERNEL, nd);
> + }
> + }
> +
>   seq_printf(m, "%s\n", "this has been live patched");
> +
> + if (nd) {
> + nd->count++;
> + seq_printf(m, "current=%p count=%d\n", current, nd->count);
> + }
> +
>   return 0;
>  }
>  
> @@ -99,6 +130,12 @@ static int livepatch_init(void)
>  
>  static void livepatch_exit(void)
>  {
> + struct task_ctr *nd, *tmp;
> +
> + list_for_each_entry_safe(nd, tmp, &shadow_list, list) {
> + list_del(&nd->list);
> + kfree(nd);
> + }
>   WARN_ON(klp_unregister_patch(&patch));
>  }

What does 'nd' stand for?  I think a name like 'ctr' would be clearer.

-- 
Josh