2018-12-13 14:12:12

by Nicholas Mc Guire

[permalink] [raw]
Subject: [PATCH 1/2 V2] livepatch: handle kzalloc failure properly

kzalloc() return should always be checked - notably in example code
where this may be seen as reference. On failure of allocation
livepatch_fix1_dummy_alloc() should return NULL.

Signed-off-by: Nicholas Mc Guire <[email protected]>
---

Problem was located with an experimental coccinelle script

V2: ...and since it is reference code the fix should be correct as well...
thanks to Petr Mladek <[email protected]> for catching the missing
kfree().

Patch was compile tested with: x86_64_defconfig + FTRACE=y
FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
(with some unrelated sparse warnings on symbols not being static)

Patch is against 4.20-rc6 (localversion-next is next-20181213)

samples/livepatch/livepatch-shadow-fix1.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/samples/livepatch/livepatch-shadow-fix1.c b/samples/livepatch/livepatch-shadow-fix1.c
index 49b1355..e8f1bd6 100644
--- a/samples/livepatch/livepatch-shadow-fix1.c
+++ b/samples/livepatch/livepatch-shadow-fix1.c
@@ -89,6 +89,11 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
* pointer to handle resource release.
*/
leak = kzalloc(sizeof(int), GFP_KERNEL);
+ if (!leak) {
+ kfree(d);
+ return NULL;
+ }
+
klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
shadow_leak_ctor, leak);

--
2.1.4



2018-12-13 14:11:42

by Nicholas Mc Guire

[permalink] [raw]
Subject: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

kzalloc() return should be checked. On dummy_alloc() failing
in kzalloc() NULL should be returned.

Signed-off-by: Nicholas Mc Guire <[email protected]>
---

Problem was located with an experimental coccinelle script

V2: returning NULL is ok but not without cleanup - thanks to
Petr Mladek <[email protected]> for catching this.

Patch was compile tested with: x86_64_defconfig + FTRACE=y
FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
(with a number of unrelated sparse warnings on symbols not being static)

Patch is against 4.20-rc6 (localversion-next is next-20181213)

samples/livepatch/livepatch-shadow-mod.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/samples/livepatch/livepatch-shadow-mod.c b/samples/livepatch/livepatch-shadow-mod.c
index 4c54b25..4aa8a88 100644
--- a/samples/livepatch/livepatch-shadow-mod.c
+++ b/samples/livepatch/livepatch-shadow-mod.c
@@ -118,6 +118,10 @@ noinline struct dummy *dummy_alloc(void)

/* Oops, forgot to save leak! */
leak = kzalloc(sizeof(int), GFP_KERNEL);
+ if (!leak) {
+ kfree(d);
+ return NULL;
+ }

pr_info("%s: dummy @ %p, expires @ %lx\n",
__func__, d, d->jiffies_expire);
--
2.1.4


2018-12-13 14:18:23

by Joe Lawrence

[permalink] [raw]
Subject: Re: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

On 12/13/2018 09:05 AM, Nicholas Mc Guire wrote:
> kzalloc() return should be checked. On dummy_alloc() failing
> in kzalloc() NULL should be returned.
>
> Signed-off-by: Nicholas Mc Guire <[email protected]>
> ---
>
> Problem was located with an experimental coccinelle script
>
> V2: returning NULL is ok but not without cleanup - thanks to
> Petr Mladek <[email protected]> for catching this.
>
> Patch was compile tested with: x86_64_defconfig + FTRACE=y
> FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
> (with a number of unrelated sparse warnings on symbols not being static)
>
> Patch is against 4.20-rc6 (localversion-next is next-20181213)
>
> samples/livepatch/livepatch-shadow-mod.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/samples/livepatch/livepatch-shadow-mod.c b/samples/livepatch/livepatch-shadow-mod.c
> index 4c54b25..4aa8a88 100644
> --- a/samples/livepatch/livepatch-shadow-mod.c
> +++ b/samples/livepatch/livepatch-shadow-mod.c
> @@ -118,6 +118,10 @@ noinline struct dummy *dummy_alloc(void)
>
> /* Oops, forgot to save leak! */
> leak = kzalloc(sizeof(int), GFP_KERNEL);
> + if (!leak) {
> + kfree(d);
> + return NULL;
> + }
>
> pr_info("%s: dummy @ %p, expires @ %lx\n",
> __func__, d, d->jiffies_expire);
>

Hi Nicholas,

Thanks for finding and fixing these up... can we either squash these two
patches into a single commit or give them unique subject lines? Code
looks good (including Petr's suggested fix) otherwise.

-- Joe

2018-12-13 15:42:27

by Nicholas Mc Guire

[permalink] [raw]
Subject: Re: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

On Thu, Dec 13, 2018 at 09:14:18AM -0500, Joe Lawrence wrote:
> On 12/13/2018 09:05 AM, Nicholas Mc Guire wrote:
> > kzalloc() return should be checked. On dummy_alloc() failing
> > in kzalloc() NULL should be returned.
> >
> > Signed-off-by: Nicholas Mc Guire <[email protected]>
> > ---
> >
> > Problem was located with an experimental coccinelle script
> >
> > V2: returning NULL is ok but not without cleanup - thanks to
> > Petr Mladek <[email protected]> for catching this.
> >
> > Patch was compile tested with: x86_64_defconfig + FTRACE=y
> > FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
> > (with a number of unrelated sparse warnings on symbols not being static)
> >
> > Patch is against 4.20-rc6 (localversion-next is next-20181213)
> >
> > samples/livepatch/livepatch-shadow-mod.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/samples/livepatch/livepatch-shadow-mod.c b/samples/livepatch/livepatch-shadow-mod.c
> > index 4c54b25..4aa8a88 100644
> > --- a/samples/livepatch/livepatch-shadow-mod.c
> > +++ b/samples/livepatch/livepatch-shadow-mod.c
> > @@ -118,6 +118,10 @@ noinline struct dummy *dummy_alloc(void)
> >
> > /* Oops, forgot to save leak! */
> > leak = kzalloc(sizeof(int), GFP_KERNEL);
> > + if (!leak) {
> > + kfree(d);
> > + return NULL;
> > + }
> >
> > pr_info("%s: dummy @ %p, expires @ %lx\n",
> > __func__, d, d->jiffies_expire);
> >
>
> Hi Nicholas,
>
> Thanks for finding and fixing these up... can we either squash these two
> patches into a single commit or give them unique subject lines? Code
> looks good (including Petr's suggested fix) otherwise.
>
yup - makes sense to pop it into a single patch - I assumed that this
would not be acceptable - so I actually split it up :)
I?ll send a V3 then.

BTW: wanted to fix up the sparse warnings but I think thats not going
to be that simple as the functions/structs sparse complains about
are actually being shared:

CHECK samples/livepatch/livepatch-shadow-fix1.c
samples/livepatch/livepatch-shadow-fix1.c:74:14: warning: symbol 'livepatch_fix1_dummy
alloc' was not declared. Should it be static?
samples/livepatch/livepatch-shadow-fix1.c:116:6: warning: symbol 'livepatch_fix1_dummy
free' was not declared. Should it be static?

CHECK samples/livepatch/livepatch-shadow-mod.c
samples/livepatch/livepatch-shadow-mod.c:99:1: warning: symbol 'dummy_list' was not declared. Should it be static?
samples/livepatch/livepatch-shadow-mod.c:100:1: warning: symbol 'dummy_list_mutex' was not declared. Should it be static?
samples/livepatch/livepatch-shadow-mod.c:107:23: warning: symbol 'dummy_alloc' was not declared. Should it be static?
samples/livepatch/livepatch-shadow-mod.c:132:15: warning: symbol 'dummy_free' was not declared. Should it be static?
samples/livepatch/livepatch-shadow-mod.c:140:15: warning: symbol 'dummy_check' was not declared. Should it be static?

so to clean that appropriate declarations should probably
go into a .h file. Technically its maybe not important as this
is not production code - it would though be nice if sample
code is sparse/smatch/cocci clean.

would it be acceptable to clean this up with an additional
livepatch-shadow-mod.h ?

thx!
hofrat

2018-12-13 16:41:05

by Joe Lawrence

[permalink] [raw]
Subject: Re: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

On 12/13/2018 10:39 AM, Nicholas Mc Guire wrote:
> On Thu, Dec 13, 2018 at 09:14:18AM -0500, Joe Lawrence wrote:
>> On 12/13/2018 09:05 AM, Nicholas Mc Guire wrote:
>>> kzalloc() return should be checked. On dummy_alloc() failing
>>> in kzalloc() NULL should be returned.
>>>
>>> Signed-off-by: Nicholas Mc Guire <[email protected]>
>>> ---
>>>
>>> Problem was located with an experimental coccinelle script
>>>
>>> V2: returning NULL is ok but not without cleanup - thanks to
>>> Petr Mladek <[email protected]> for catching this.
>>>
>>> Patch was compile tested with: x86_64_defconfig + FTRACE=y
>>> FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
>>> (with a number of unrelated sparse warnings on symbols not being static)
>>>
>>> Patch is against 4.20-rc6 (localversion-next is next-20181213)
>>>
>>> samples/livepatch/livepatch-shadow-mod.c | 4 ++++
>>> 1 file changed, 4 insertions(+)
>>>
>>> diff --git a/samples/livepatch/livepatch-shadow-mod.c b/samples/livepatch/livepatch-shadow-mod.c
>>> index 4c54b25..4aa8a88 100644
>>> --- a/samples/livepatch/livepatch-shadow-mod.c
>>> +++ b/samples/livepatch/livepatch-shadow-mod.c
>>> @@ -118,6 +118,10 @@ noinline struct dummy *dummy_alloc(void)
>>>
>>> /* Oops, forgot to save leak! */
>>> leak = kzalloc(sizeof(int), GFP_KERNEL);
>>> + if (!leak) {
>>> + kfree(d);
>>> + return NULL;
>>> + }
>>>
>>> pr_info("%s: dummy @ %p, expires @ %lx\n",
>>> __func__, d, d->jiffies_expire);
>>>
>>
>> Hi Nicholas,
>>
>> Thanks for finding and fixing these up... can we either squash these two
>> patches into a single commit or give them unique subject lines? Code
>> looks good (including Petr's suggested fix) otherwise.
>>
> yup - makes sense to pop it into a single patch - I assumed that this
> would not be acceptable - so I actually split it up :)
> I´ll send a V3 then.

I don't know if there is a hard rule, but I always thought that unique
subject lines were desired to avoid grep/search confusion.

As far as one or two commits, I'd prefer a single commit since these are
so small. Personal preference, you could just say that you're fixing
samples/livepatch as a whole.

>
> BTW: wanted to fix up the sparse warnings but I think thats not going
> to be that simple as the functions/structs sparse complains about
> are actually being shared:

Ok, these are welcome too, separate commit...

> CHECK samples/livepatch/livepatch-shadow-fix1.c
> samples/livepatch/livepatch-shadow-fix1.c:74:14: warning: symbol 'livepatch_fix1_dummy
> alloc' was not declared. Should it be static?
> samples/livepatch/livepatch-shadow-fix1.c:116:6: warning: symbol 'livepatch_fix1_dummy
> free' was not declared. Should it be static?
>
> CHECK samples/livepatch/livepatch-shadow-mod.c
> samples/livepatch/livepatch-shadow-mod.c:99:1: warning: symbol 'dummy_list' was not declared. Should it be static?
> samples/livepatch/livepatch-shadow-mod.c:100:1: warning: symbol 'dummy_list_mutex' was not declared. Should it be static?
> samples/livepatch/livepatch-shadow-mod.c:107:23: warning: symbol 'dummy_alloc' was not declared. Should it be static?
> samples/livepatch/livepatch-shadow-mod.c:132:15: warning: symbol 'dummy_free' was not declared. Should it be static?
> samples/livepatch/livepatch-shadow-mod.c:140:15: warning: symbol 'dummy_check' was not declared. Should it be static?
>
> so to clean that appropriate declarations should probably
> go into a .h file. Technically its maybe not important as this
> is not production code - it would though be nice if sample
> code is sparse/smatch/cocci clean.
>
> would it be acceptable to clean this up with an additional
> livepatch-shadow-mod.h ?

I'm not a C language expert, but as I understand it: static functions
are only a namespacing game for the compiler. So I think it is safe to
pass around and call function pointers to static functions between
compilation units. At least I see this throughout the kernel, so that
is my assumption :)

-- Joe

2018-12-13 18:52:52

by Nicholas Mc Guire

[permalink] [raw]
Subject: Re: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

On Thu, Dec 13, 2018 at 11:39:25AM -0500, Joe Lawrence wrote:
> On 12/13/2018 10:39 AM, Nicholas Mc Guire wrote:
> > On Thu, Dec 13, 2018 at 09:14:18AM -0500, Joe Lawrence wrote:
> >> On 12/13/2018 09:05 AM, Nicholas Mc Guire wrote:
> >>> kzalloc() return should be checked. On dummy_alloc() failing
> >>> in kzalloc() NULL should be returned.
> >>>
> >>> Signed-off-by: Nicholas Mc Guire <[email protected]>
> >>> ---
> >>>
> >>> Problem was located with an experimental coccinelle script
> >>>
> >>> V2: returning NULL is ok but not without cleanup - thanks to
> >>> Petr Mladek <[email protected]> for catching this.
> >>>
> >>> Patch was compile tested with: x86_64_defconfig + FTRACE=y
> >>> FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
> >>> (with a number of unrelated sparse warnings on symbols not being static)
> >>>
> >>> Patch is against 4.20-rc6 (localversion-next is next-20181213)
> >>>
> >>> samples/livepatch/livepatch-shadow-mod.c | 4 ++++
> >>> 1 file changed, 4 insertions(+)
> >>>
> >>> diff --git a/samples/livepatch/livepatch-shadow-mod.c b/samples/livepatch/livepatch-shadow-mod.c
> >>> index 4c54b25..4aa8a88 100644
> >>> --- a/samples/livepatch/livepatch-shadow-mod.c
> >>> +++ b/samples/livepatch/livepatch-shadow-mod.c
> >>> @@ -118,6 +118,10 @@ noinline struct dummy *dummy_alloc(void)
> >>>
> >>> /* Oops, forgot to save leak! */
> >>> leak = kzalloc(sizeof(int), GFP_KERNEL);
> >>> + if (!leak) {
> >>> + kfree(d);
> >>> + return NULL;
> >>> + }
> >>>
> >>> pr_info("%s: dummy @ %p, expires @ %lx\n",
> >>> __func__, d, d->jiffies_expire);
> >>>
> >>
> >> Hi Nicholas,
> >>
> >> Thanks for finding and fixing these up... can we either squash these two
> >> patches into a single commit or give them unique subject lines? Code
> >> looks good (including Petr's suggested fix) otherwise.
> >>
> > yup - makes sense to pop it into a single patch - I assumed that this
> > would not be acceptable - so I actually split it up :)
> > I?ll send a V3 then.
>
> I don't know if there is a hard rule, but I always thought that unique
> subject lines were desired to avoid grep/search confusion.
>
the duplicated subjectline was my mistake

> As far as one or two commits, I'd prefer a single commit since these are
> so small. Personal preference, you could just say that you're fixing
> samples/livepatch as a whole.
>
> >
> > BTW: wanted to fix up the sparse warnings but I think thats not going
> > to be that simple as the functions/structs sparse complains about
> > are actually being shared:
>
> Ok, these are welcome too, separate commit...
>
> > CHECK samples/livepatch/livepatch-shadow-fix1.c
> > samples/livepatch/livepatch-shadow-fix1.c:74:14: warning: symbol 'livepatch_fix1_dummy
> > alloc' was not declared. Should it be static?
> > samples/livepatch/livepatch-shadow-fix1.c:116:6: warning: symbol 'livepatch_fix1_dummy
> > free' was not declared. Should it be static?
> >
> > CHECK samples/livepatch/livepatch-shadow-mod.c
> > samples/livepatch/livepatch-shadow-mod.c:99:1: warning: symbol 'dummy_list' was not declared. Should it be static?
> > samples/livepatch/livepatch-shadow-mod.c:100:1: warning: symbol 'dummy_list_mutex' was not declared. Should it be static?
> > samples/livepatch/livepatch-shadow-mod.c:107:23: warning: symbol 'dummy_alloc' was not declared. Should it be static?
> > samples/livepatch/livepatch-shadow-mod.c:132:15: warning: symbol 'dummy_free' was not declared. Should it be static?
> > samples/livepatch/livepatch-shadow-mod.c:140:15: warning: symbol 'dummy_check' was not declared. Should it be static?
> >
> > so to clean that appropriate declarations should probably
> > go into a .h file. Technically its maybe not important as this
> > is not production code - it would though be nice if sample
> > code is sparse/smatch/cocci clean.
> >
> > would it be acceptable to clean this up with an additional
> > livepatch-shadow-mod.h ?
>
> I'm not a C language expert, but as I understand it: static functions
> are only a namespacing game for the compiler. So I think it is safe to
> pass around and call function pointers to static functions between
> compilation units. At least I see this throughout the kernel, so that
> is my assumption :)
>
I?m not into the details of livepatch but if I declare e.g. dummy_check
static as proposed by sparse and then check the relocs I no longer see
it:

Without the changes sparse proposes dummy_check is visible
hofrat@debian:~/linux-next/samples/livepatch# readelf --relocs livepatch-shadow-mod.ko | grep dummy_check
000000000193 002f00000002 R_X86_64_PC32 0000000000000110 dummy_check - 4

When I then try to load livepatch-shadow-fix1.ko which does not have
dummy_check in its klp_func array its ok but livepatch-shadow-fix2.ko
wich has an entry will fail to load. So while this may work with other modules
I think in the live-patch case its not that simple due to the inner workings
of resolving symbols via klp_object and klp_func array.

So I?ll leave that sparse cleanup to someone who understand the inner
workinsgs of livepatch - before I make a mess of it....

thx!
hofrat

2018-12-13 20:41:35

by Joe Lawrence

[permalink] [raw]
Subject: Re: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

On 12/13/2018 01:51 PM, Nicholas Mc Guire wrote:
> On Thu, Dec 13, 2018 at 11:39:25AM -0500, Joe Lawrence wrote:
>> On 12/13/2018 10:39 AM, Nicholas Mc Guire wrote:
>>> On Thu, Dec 13, 2018 at 09:14:18AM -0500, Joe Lawrence wrote:
>>>> On 12/13/2018 09:05 AM, Nicholas Mc Guire wrote:
>>>>> kzalloc() return should be checked. On dummy_alloc() failing
>>>>> in kzalloc() NULL should be returned.
>>>>>
>>>>> Signed-off-by: Nicholas Mc Guire <[email protected]>
>>>>> ---
>>>>>
>>>>> Problem was located with an experimental coccinelle script
>>>>>
>>>>> V2: returning NULL is ok but not without cleanup - thanks to
>>>>> Petr Mladek <[email protected]> for catching this.
>>>>>
>>>>> Patch was compile tested with: x86_64_defconfig + FTRACE=y
>>>>> FUNCTION_TRACER=y, EXPERT=y, LATENCYTOP=y, SAMPLES=y, SAMPLE_LIVEPATCH=y
>>>>> (with a number of unrelated sparse warnings on symbols not being static)
>>>>>
>>>>> Patch is against 4.20-rc6 (localversion-next is next-20181213)
>>>>>
>>>>> samples/livepatch/livepatch-shadow-mod.c | 4 ++++
>>>>> 1 file changed, 4 insertions(+)
>>>>>
>>>>> diff --git a/samples/livepatch/livepatch-shadow-mod.c b/samples/livepatch/livepatch-shadow-mod.c
>>>>> index 4c54b25..4aa8a88 100644
>>>>> --- a/samples/livepatch/livepatch-shadow-mod.c
>>>>> +++ b/samples/livepatch/livepatch-shadow-mod.c
>>>>> @@ -118,6 +118,10 @@ noinline struct dummy *dummy_alloc(void)
>>>>>
>>>>> /* Oops, forgot to save leak! */
>>>>> leak = kzalloc(sizeof(int), GFP_KERNEL);
>>>>> + if (!leak) {
>>>>> + kfree(d);
>>>>> + return NULL;
>>>>> + }
>>>>>
>>>>> pr_info("%s: dummy @ %p, expires @ %lx\n",
>>>>> __func__, d, d->jiffies_expire);
>>>>>
>>>>
>>>> Hi Nicholas,
>>>>
>>>> Thanks for finding and fixing these up... can we either squash these two
>>>> patches into a single commit or give them unique subject lines? Code
>>>> looks good (including Petr's suggested fix) otherwise.
>>>>
>>> yup - makes sense to pop it into a single patch - I assumed that this
>>> would not be acceptable - so I actually split it up :)
>>> I´ll send a V3 then.
>>
>> I don't know if there is a hard rule, but I always thought that unique
>> subject lines were desired to avoid grep/search confusion.
>>
> the duplicated subjectline was my mistake
>
>> As far as one or two commits, I'd prefer a single commit since these are
>> so small. Personal preference, you could just say that you're fixing
>> samples/livepatch as a whole.
>>
>>>
>>> BTW: wanted to fix up the sparse warnings but I think thats not going
>>> to be that simple as the functions/structs sparse complains about
>>> are actually being shared:
>>
>> Ok, these are welcome too, separate commit...
>>
>>> CHECK samples/livepatch/livepatch-shadow-fix1.c
>>> samples/livepatch/livepatch-shadow-fix1.c:74:14: warning: symbol 'livepatch_fix1_dummy
>>> alloc' was not declared. Should it be static?
>>> samples/livepatch/livepatch-shadow-fix1.c:116:6: warning: symbol 'livepatch_fix1_dummy
>>> free' was not declared. Should it be static?
>>>
>>> CHECK samples/livepatch/livepatch-shadow-mod.c
>>> samples/livepatch/livepatch-shadow-mod.c:99:1: warning: symbol 'dummy_list' was not declared. Should it be static?
>>> samples/livepatch/livepatch-shadow-mod.c:100:1: warning: symbol 'dummy_list_mutex' was not declared. Should it be static?
>>> samples/livepatch/livepatch-shadow-mod.c:107:23: warning: symbol 'dummy_alloc' was not declared. Should it be static?
>>> samples/livepatch/livepatch-shadow-mod.c:132:15: warning: symbol 'dummy_free' was not declared. Should it be static?
>>> samples/livepatch/livepatch-shadow-mod.c:140:15: warning: symbol 'dummy_check' was not declared. Should it be static?
>>>
>>> so to clean that appropriate declarations should probably
>>> go into a .h file. Technically its maybe not important as this
>>> is not production code - it would though be nice if sample
>>> code is sparse/smatch/cocci clean.
>>>
>>> would it be acceptable to clean this up with an additional
>>> livepatch-shadow-mod.h ?
>>
>> I'm not a C language expert, but as I understand it: static functions
>> are only a namespacing game for the compiler. So I think it is safe to
>> pass around and call function pointers to static functions between
>> compilation units. At least I see this throughout the kernel, so that
>> is my assumption :)
>>
> I´m not into the details of livepatch but if I declare e.g. dummy_check
> static as proposed by sparse and then check the relocs I no longer see
> it:
>
> Without the changes sparse proposes dummy_check is visible
> hofrat@debian:~/linux-next/samples/livepatch# readelf --relocs livepatch-shadow-mod.ko | grep dummy_check
> 000000000193 002f00000002 R_X86_64_PC32 0000000000000110 dummy_check - 4
>
> When I then try to load livepatch-shadow-fix1.ko which does not have
> dummy_check in its klp_func array its ok but livepatch-shadow-fix2.ko
> wich has an entry will fail to load. So while this may work with other modules
> I think in the live-patch case its not that simple due to the inner workings
> of resolving symbols via klp_object and klp_func array.
>
> So I´ll leave that sparse cleanup to someone who understand the inner
> workinsgs of livepatch - before I make a mess of it....
>
> thx!
> hofrat
>

Ahh, I understand the question now. Yeah, by making those routines local
static, the compiler applied optimizations that renamed the symbols:

noinline static
% readelf --syms samples/livepatch/livepatch-shadow-mod.o | grep dummy_
5: 0000000000000000 20 FUNC LOCAL DEFAULT 1 dummy_check.isra.0
7: 0000000000000020 52 FUNC LOCAL DEFAULT 1 dummy_free.constprop.1
12: 00000000000000c0 32 OBJECT LOCAL DEFAULT 3 dummy_list_mutex
13: 00000000000000e0 16 OBJECT LOCAL DEFAULT 3 dummy_list
15: 0000000000000160 115 FUNC LOCAL DEFAULT 1 dummy_alloc


I can avoid that optimization (and successfully load all the modules)
by using either:

__attribute__((optimize("O0"))) noinline static
% readelf --syms samples/livepatch/livepatch-shadow-mod.o | grep dummy_
6: 0000000000000000 6016 FUNC LOCAL DEFAULT 1 dummy_alloc
11: 00000000000000c0 32 OBJECT LOCAL DEFAULT 3 dummy_list_mutex
12: 00000000000000e0 16 OBJECT LOCAL DEFAULT 3 dummy_list
14: 0000000000001810 73 FUNC LOCAL DEFAULT 1 dummy_free
16: 0000000000001860 108 FUNC LOCAL DEFAULT 1 dummy_check

or:

__noclone noinline static
% readelf --syms samples/livepatch/livepatch-shadow-mod.o | grep dummy_
5: 0000000000000000 22 FUNC LOCAL DEFAULT 1 dummy_check
7: 0000000000000020 51 FUNC LOCAL DEFAULT 1 dummy_free
12: 00000000000000c0 32 OBJECT LOCAL DEFAULT 3 dummy_list_mutex
13: 00000000000000e0 16 OBJECT LOCAL DEFAULT 3 dummy_list
15: 0000000000000160 115 FUNC LOCAL DEFAULT 1 dummy_alloc

but I'm not sure if either is the definitive way to avoid such
optimization. Anyone know for sure?

-- Joe

2018-12-13 20:51:18

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: [PATCH 2/2 V2] livepatch: handle kzalloc failure properly

On Thu, Dec 13, 2018 at 03:39:20PM -0500, Joe Lawrence wrote:
> Ahh, I understand the question now. Yeah, by making those routines local
> static, the compiler applied optimizations that renamed the symbols:
>
> noinline static
> % readelf --syms samples/livepatch/livepatch-shadow-mod.o | grep dummy_
> 5: 0000000000000000 20 FUNC LOCAL DEFAULT 1 dummy_check.isra.0
> 7: 0000000000000020 52 FUNC LOCAL DEFAULT 1 dummy_free.constprop.1
> 12: 00000000000000c0 32 OBJECT LOCAL DEFAULT 3 dummy_list_mutex
> 13: 00000000000000e0 16 OBJECT LOCAL DEFAULT 3 dummy_list
> 15: 0000000000000160 115 FUNC LOCAL DEFAULT 1 dummy_alloc
>
>
> I can avoid that optimization (and successfully load all the modules)
> by using either:
>
> __attribute__((optimize("O0"))) noinline static
> % readelf --syms samples/livepatch/livepatch-shadow-mod.o | grep dummy_
> 6: 0000000000000000 6016 FUNC LOCAL DEFAULT 1 dummy_alloc
> 11: 00000000000000c0 32 OBJECT LOCAL DEFAULT 3 dummy_list_mutex
> 12: 00000000000000e0 16 OBJECT LOCAL DEFAULT 3 dummy_list
> 14: 0000000000001810 73 FUNC LOCAL DEFAULT 1 dummy_free
> 16: 0000000000001860 108 FUNC LOCAL DEFAULT 1 dummy_check
>
> or:
>
> __noclone noinline static
> % readelf --syms samples/livepatch/livepatch-shadow-mod.o | grep dummy_
> 5: 0000000000000000 22 FUNC LOCAL DEFAULT 1 dummy_check
> 7: 0000000000000020 51 FUNC LOCAL DEFAULT 1 dummy_free
> 12: 00000000000000c0 32 OBJECT LOCAL DEFAULT 3 dummy_list_mutex
> 13: 00000000000000e0 16 OBJECT LOCAL DEFAULT 3 dummy_list
> 15: 0000000000000160 115 FUNC LOCAL DEFAULT 1 dummy_alloc
>
> but I'm not sure if either is the definitive way to avoid such
> optimization. Anyone know for sure?

Yeah, for now I think "static __noclone" is the way to go. Soon we'll
have a GCC flag which disables such optimizations for all functions.

And the dummy_list* variables can just be "static".

--
Josh