kpatch/kpatch-build
Evgenii Shatokhin 9bb75659e2 kpatch-build: Detect R_X86_64_64 dynrelas with large addends
Or, to be exact, with addend values which cannot be represented by
a signed int variable.

This only applies to the old KPatch core.

Commit 15067fcd "kmod/core: apply dynrela addend for R_X86_64_64" fixed
calculation of the values for R_X86_64_64 dynrelas. This revealed
another issue, similar to https://github.com/dynup/kpatch/issues/1064.

Dynrelas are stored as 'struct kpatch_patch_dynrela' instances in the
patch module but both the patch module and kpatch.ko use
'struct kpatch_dynrela' to work with the dynrelas. 'addend' has type
'long' in kpatch_patch_dynrela but 'int' in kpatch_dynrela, so this
value can be truncated when read.

R_X86_64_64 dynrela can be created, for example, if a patch for vmlinux
refers to something like '(unsigned long)&idt_table+0x80000000' (a global
variable which is not exported, with some addend).
The addend == +0x80000000, however, effectively becomes 0xffffffff80000000
(== -0x80000000) due to this bug.

Unfortunately, 'struct kpatch_dynrela' is a part of the ABI between
kpatch.ko and patch modules. Plain changing 'int addend' into 'long addend'
there could be problematic. The patch module built using the new
'struct kpatch_dynrela' will either fail to load if kpatch.ko is using the old
'struct kpatch_dynrela' or cause crashes or data corruptions. Unloading
and reloading patch modules and kpatch.ko is not always an option
either.

Luckily, R_X86_64_64 dynrelas seem to be quite rare in the production
patch modules and R_X86_64_64 dynrelas with large addends are expected
to be even more rare.

So, instead of fixing the truncation of addends right away, I propose to
detect it, for now, when building a patch. If one never hits such conditions,
it is not worth it to fix the issue. If R_X86_64_64 dynrelas with large
addends do happen and cannot be avoided, we can try to figure out how to
fix this properly, without breaking too much.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2020-05-05 23:21:16 +03: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: Ignore kpatch_ignored functions/sections missing ftrace hook 2020-04-23 08:22:50 +01:00
create-klp-module.c lookup: rename 'pos' to 'sympos' 2020-04-06 15:18:58 -05:00
create-kpatch-module.c kpatch-build: Detect R_X86_64_64 dynrelas with large addends 2020-05-05 23:21:16 +03:00
kpatch-build create-diff-object: add support for .klp.arch removal 2020-04-14 12:44:04 -05:00
kpatch-elf.c kpatch-build: Allow function to have multiple child functions 2020-03-30 14:14:17 +01:00
kpatch-elf.h kpatch-build: Allow function to have multiple child functions 2020-03-30 14:14:17 +01:00
kpatch-gcc Making kpatch-build compatible with custom gcc names 2019-05-09 19:15:11 +02:00
kpatch-intermediate.h lookup: rename 'pos' to 'sympos' 2020-04-06 15:18:58 -05: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: fix Module.symvers reading for newer kernels 2020-04-14 12:44:00 -05:00
lookup.h create-diff-object: refactor dynrela conversion 2020-04-06 15:18:58 -05:00
Makefile kpatch-build/Makefile: Skip build insn/plugin with -Wconversion 2020-01-23 12:59:38 +05:30