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 <hofrat@xxxxxxxxx> >>>>> --- >>>>> >>>>> Problem was located with an experimental coccinelle script >>>>> >>>>> V2: returning NULL is ok but not without cleanup - thanks to >>>>> Petr Mladek <pmladek@xxxxxxxx> 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