kpatch/kpatch-build
Josh Poimboeuf b13aca7cde create-diff-object: Don't strip callback symbols
We saw the following panic on ppc64le when loading the macro-callbacks
integration test:

  livepatch: enabling patch 'kpatch_macro_callbacks'
  Oops: Exception in kernel mode, sig: 4 [#1]
  LE SMP NR_CPUS=2048 NUMA pSeries
  Modules linked in: kpatch_macro_callbacks(OEK+) rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache sunrpc sg pseries_rng xts vmx_crypto xfs libcrc32c sd_mod ibmvscsi scsi_transport_srp ibmveth dm_mirror dm_region_hash dm_log dm_mod [last unloaded: kpatch_gcc_static_local_var_6]
  CPU: 2 PID: 17445 Comm: insmod Kdump: loaded Tainted: G           OE K  --------- -  - 4.18.0-128.el8.ppc64le #1
  NIP:  d00000000bb708e0 LR: c0000000001fd610 CTR: d00000000bb708e0
  REGS: c00000040e98f640 TRAP: 0700   Tainted: G           OE K  --------- -  -  (4.18.0-128.el8.ppc64le)
  MSR:  800000000288b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE>  CR: 28008228  XER: 20040003
  CFAR: c0000000001fd60c IRQMASK: 0
  GPR00: c0000000001fd5c0 c00000040e98f8c0 c000000001662a00 c000000733525400
  GPR04: 0000000000000800 0000000000000800 c0000000015e2c00 c0000007335254a8
  GPR08: 0000000000000001 d00000000bb708e0 c0000007eeb68400 0000000000000000
  GPR12: d00000000bb708e0 c000000007fad600 0000000000000001 aaaaaaaaaaaaaaab
  GPR16: 000000000000ff20 000000000000fff1 000000000000fff2 d00000000bb90000
  GPR20: 00000000000000a9 c00000040e98fc00 c000000000d8a728 c00000040e98fc00
  GPR24: d00000000bb73f88 00000000006080c0 d00000000bb73a38 c000000733525400
  GPR28: 0000000000000001 c000000733525400 ffffffffffffffed c0000007eeb60900
  NIP [d00000000bb708e0] callback_info.isra.0+0x7c/0x66c [kpatch_macro_callbacks]
  LR [c0000000001fd610] __klp_enable_patch+0x130/0x230
  Call Trace:
  [c00000040e98f8c0] [c0000000001fd5c0] __klp_enable_patch+0xe0/0x230 (unreliable)
  [c00000040e98f940] [c0000000001fd7d8] klp_enable_patch+0xc8/0x100
  [c00000040e98f980] [d00000000bb7079c] patch_init+0x460/0x4cc [kpatch_macro_callbacks]
  [c00000040e98fa20] [c000000000010108] do_one_initcall+0x58/0x248
  [c00000040e98fae0] [c00000000023b860] do_init_module+0x80/0x330
  [c00000040e98fb70] [c0000000002416a4] load_module+0x3994/0x3d00
  [c00000040e98fd30] [c000000000241cf4] sys_finit_module+0xc4/0x130
  [c00000040e98fe30] [c00000000000b388] system_call+0x5c/0x70
  Instruction dump:
  7cea482a 48000235 e8410018 48000014 3c620000 e8638160 48000221 e8410018
  38210060 e8010010 7c0803a6 4e800020 <0000ae18> 00000000 3c4c0001 3842ae18

The problem was introduced by a recent fix:

  e8f7f2dfe8 ("create-diff-object/ppc64le: Fix replace_sections_syms() for bundled symbols")

We didn't notice the fact that there's a hack in
kpatch_include_callback_elements() which reverts the work of
kpatch_replace_sections_syms() for callback function symbols.

The problem is that that revert is only partial, causing the callback
pointers to point to the .TOC data which is located 8 bytes before the
start of the function code.  This happens because
kpatch_include_callback_elements() makes the same assumption that
kpatch_replace_sections_syms() had previously made: that bundled symbols
are always located at the start of their corresponding sections.

kpatch_include_callback_elements() mysteriously strips references to the
callback function symbols, replacing them with section symbols.  In this
case it replaced a 'pre_patch_callback' function reference with a
'.text.unlikely.pre_patch_callback' section reference.  But it didn't
adjust the rela->addend accordingly.

Joe discovered the reasoning for why kpatch_include_callback_elements()
removes function symbol references in the commit log for 7dfad2fb76
("fix dynrela corruption in load/unload hooks"):

  In the case of the hook functions, we strip the FUNC symbol to prevent
  it from being added to the kpatch.funcs section as a patched function.

But that justification doesn't really make sense, at least not with the
current code.  Callbacks aren't added to .kpatch.funcs anyway.  They're
classifed as NEW.  Only CHANGED functions are added to .kpatch.funcs.

So remove that hack, fixing this bug in the process.

This does have a side effect of showing the callback functions as new
functions, because their symbols are now included.

Before:

  aio.o: found callback: post_unpatch_callback
  aio.o: found callback: pre_patch_callback
  aio.o: found callback: pre_unpatch_callback
  aio.o: new function: callback_info.isra.0

After:

  aio.o: found callback: post_unpatch_callback
  aio.o: found callback: pre_patch_callback
  aio.o: found callback: pre_unpatch_callback
  aio.o: new function: callback_info.isra.0
  aio.o: new function: pre_patch_callback
  aio.o: new function: post_patch_callback
  aio.o: new function: pre_unpatch_callback
  aio.o: new function: post_unpatch_callback

But anyway they _are_ new functions, so the new output seems more
correct to me.

Fixes: e8f7f2dfe8 ("create-diff-object/ppc64le: Fix replace_sections_syms() for bundled symbols")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-08-15 15:08:31 -05:00
..
gcc-plugins gcc-plugin: Include additional header for GCC 8 2018-05-30 19:39:48 +05:30
insn insn: get it to compile in create-diff-object 2014-05-30 15:19:57 -05:00
create-diff-object.c create-diff-object: Don't strip callback symbols 2019-08-15 15:08:31 -05:00
create-klp-module.c create-klp-module: check symtab in main() 2019-08-05 12:10:47 +02:00
create-kpatch-module.c create-kpatch-module: check symtab in main() 2019-08-05 12:10:47 +02:00
kpatch-build kpatch-build: check if gcc supports -gz=none 2019-07-31 11:16:16 +03:00
kpatch-elf.c kpatch-elf: add a couple mission section checks 2019-08-05 12:10:47 +02:00
kpatch-elf.h create-diff-object: add symbol relations 2018-07-11 09:57:31 +02:00
kpatch-gcc Making kpatch-build compatible with custom gcc names 2019-05-09 19:15:11 +02:00
kpatch-intermediate.h create-klp-module: get rid of redundant kpatch_relocation.offset field 2017-11-09 19:16:14 -06:00
kpatch.h kpatch-build: add exit status enum 2018-06-15 07:11:48 -04:00
list.h new .fixup group size algorithm 2014-09-15 14:54:57 -05:00
log.h kpatch-build: add exit status enum 2018-06-15 07:11:48 -04:00
lookup.c lookup: exit on error in make_modname() 2019-08-05 12:10:47 +02:00
lookup.h kpatch-build: use symbol table instead of kobject 2018-05-18 09:24:40 +02:00
Makefile ppc64le: fix gcc-plugin installation 2018-04-19 10:16:37 +02:00