Commit Graph

976 Commits

Author SHA1 Message Date
Julien Thierry
e9600c5513 kpatch-build: Check exported symbol version changes
The CRCs of exported symbols Module.symvers can differ between the
original build and the patched build.

In such a case, it is probably wise to rework the patch to avoid such
modifications.

Warn when a symbol changes version in the exported symbol list.

Fixes issue #1084

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-08-17 12:38:32 +01:00
Julien Thierry
b4c2753684 kpatch-build: Create module symbol version file once
When patching an OOT module, the symbol version file is obtained by
combining the file from the module build and the Module.symvers file
provided with kernel headers. This is done for each modified .o in the
OOT build.

Create the final Module.symvers file once for the whole OOT module.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-08-12 10:47:35 +01:00
Yannick Cote
677e5c29c4
Merge pull request #1128 from joe-lawrence/modpost-cmd-file
kpatch-build: avoid modpost .output.o.cmd complaints
2020-07-23 08:44:16 -04:00
Joe Lawrence
6531a7e075 kpatch-build: avoid modpost .output.o.cmd complaints
The modpost step complains about one of our generated files, output.o
and that it can't find a corresponding .cmd file for it (full path names
stripped):

	WARNING: could not find .output.o.cmd for output.o

This was turned into an error in v5.8:

	.output.o.cmd: No such file or directory

Avoid this by creating an empty .cmd file so that modpost acknowledges
that the file exists, but doesn't parse anything out of it.

Fixes #1125
Reported-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> (for v5.8+)
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2020-07-21 09:52:48 -04:00
Kamalesh Babulal
ea647e50ae kpatch-build/Makefile: Fail build on unsupported architectures
Fail the kpatch build, while attempted to build on unsupported
architecture. The build will eventually fail but with the error that
doesn't hint the user clearly about the support status of kpatch, on the
architecture.  This patch forces the build error with the message about
the unsupported status, avoiding confusion to the user.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-07-20 18:37:00 +05:30
Artem Savkov
17ec03ef95 Keep build.log on --skip-cleanup
Before kpatch-build would only keep build.log with --debug option
specified, but it also makes sense to keep it if --skip-cleanup is
specified.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2020-07-01 10:03:51 +02:00
Yannick Cote
a6e8fd84cc
Merge pull request #1115 from kamalesh-babulal/tristate-lookup-fix
lookup: Add __UNIQUE_ID_ to maybe_discarded_sym list
2020-06-26 12:09:10 -04:00
Artem Savkov
32e2f502f5
Merge pull request #1116 from kamalesh-babulal/jump-labels-log-improv
create-diff-object: improve jump label warnings
2020-06-26 10:41:31 +02:00
Joe Lawrence
e0221f489e
Merge pull request #1117 from jpoimboe/rela-equal
Ignore changes to .altinstr_aux
2020-06-25 10:34:41 -04:00
Josh Poimboeuf
ed849a9b3e create-diff-object: Ignore changes to .altinstr_aux
On x86, .altinstr_aux is used to store temporary code which allows
static_cpu_has() to work before apply_alternatives() has run.  This code
is completely inert for modules, because apply_alternatives() runs
during module init, before the module is fully formed.  Any changed
references to it (i.e. changed addend) can be ignored.  As long as
they're both references to .altinstr_aux, they can be considered equal,
even if the addends differ.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-06-23 22:27:52 -05:00
Josh Poimboeuf
abd2ff81c7 create-diff-object: change rela_equal() to return bool
Change rela_equal's return value to bool to make its return semantics
more clear.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-06-23 22:20:33 -05:00
Kamalesh Babulal
514acc32e9 create-diff-object: improve jump label warnings
Improve logging of Jump label warnings with a new line between warnings.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-06-23 20:02:35 +05:30
Kamalesh Babulal
b381a0cc0b lookup: Add __UNIQUE_ID_ to maybe_discarded_sym list
Linux kernel tristate config options allows selected feature, either to
be built-in to the kernel or to be built as a kernel module. When built
as a kernel module, it's expected that the module, will be built with
module information such as author, license, description and others.

For each of the modinfo, a corresponding __UNIQUE_ID_ symbol is
generated.  Their lookup succeeds in the case of module but fails when
selected to built-in to the kernel, the reason being that the kernel
discards these __UNIQUE_ID_ symbols during linking. Add __UNIQUE_ID_
symbols to maybe_discarded_sym list, to avoid failure in case of
table->object is vmlinux.

i.e.:
 # cat .config|grep IOSCHED_BFQ (can be compiled as module too)
 CONFIG_IOSCHED_BFQ=y

 # readelf -sW ./block/bfq-iosched.o|grep UNIQUE
   219: 0000000000000000    54 OBJECT  LOCAL  DEFAULT  267 __UNIQUE_ID_description223
   220: 0000000000000036    16 OBJECT  LOCAL  DEFAULT  267 __UNIQUE_ID_license222
   221: 0000000000000046    19 OBJECT  LOCAL  DEFAULT  267 __UNIQUE_ID_file221
   222: 0000000000000059    25 OBJECT  LOCAL  DEFAULT  267 __UNIQUE_ID_author220
   223: 0000000000000072    22 OBJECT  LOCAL  DEFAULT  267 __UNIQUE_ID_alias219

the line below before the kpatch error, is a debug printf to find the failing lookup symbol:
Failed lookup for __UNIQUE_ID_description223
/root/kpatch/kpatch-build/create-diff-object: ERROR: bfq-iosched.o: find_local_syms: 180: couldn't find matching bfq-iosched.c local symbols in ./vmlinux symbol table

with the patch, it successfully builds with both y/m config options:
...
bfq-iosched.o: changed function: bfq_idle_slice_timer
Patched objects: vmlinux
Building patch module:
livepatch-0001-block-bfq-fix-use-after-free-in-b.ko
SUCCESS

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-06-18 12:40:57 +05:30
Kamalesh Babulal
67aa131137 gcc-plugin: GCC 10 - update local/non local insn names
Kernel livepatching modules build on GCC 10, with patched functions
referring to local function would fail to load with the error:
 module_64: livepatch_ext4_cond_resched: Expected nop after call, got 7fe5fb78 at ext4_setup_system_zone+0x460/0xc90 [livepatch_ext4_cond_resched]

for more details on the error, refer to discussion at:
 https://lkml.kernel.org/r/1508217523-18885-1-git-send-email-kamalesh@linux.vnet.ibm.com

the reason was that the gcc-plugin would skip the pass on error, failing
to convert the local calls into global, i.e on ppc64le every global call
is followed by a nop instruction, that gets replaced by the kernel to
restore
the TOC/r2 value of the callee, while parsing the relocations and would
skip the TOC restoration for local functions, where the TOC remains the
same across sibling functions.

GCC 10 commit 07c48b61a082("[RS6000] Put call cookie back in AIX/ELFv2
call patterns") merged a couple of call codes definition, breaking the
plugin.  Change the plugin codes to match the GCC 10 codes.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-06-12 13:27:06 +05:30
Kamalesh Babulal
92c42039bf gcc-plugin: abort building klp module on error
Abort building the klp module, if the code for local and non-local calls
are not found instead of skipping the pass and building module, which
might result in un-loadable module with the kernel error:

module_64: livepatch_ext4_cond_resched: Expected nop after call, got 7fe5fb78 at ext4_setup_system_zone+0x460/0xc90 [livepatch_ext4_cond_resched]

gcc would not allow me to use "can't" in the error message and throw
build error:

gcc-plugins/ppc64le-plugin.c:49:17: error: contraction ‘can't’ in format; use ‘cannot’ instead [-Werror=format-diag]

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-06-12 13:26:50 +05:30
Kamalesh Babulal
fde1a75b7f gcc-plugin: Fix build failure with GCC 10
Building on Fedora 32 with GCC 10.1.1, triggers build failures:

In file included from gcc-plugins/ppc64le-plugin.c:1:
gcc-plugins/gcc-common.h:37:10: fatal error: params.h: No such file or directory
   37 | #include "params.h"
      |          ^~~~~~~~~~
compilation terminated.

In file included from gcc-plugins/ppc64le-plugin.c:1:
gcc-plugins/gcc-common.h:841:13: error: redefinition of ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const ggoto*]’
  841 | inline bool is_a_helper<const ggoto *>::test(const_gimple gs)
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-plugins/gcc-common.h:124,
                 from gcc-plugins/ppc64le-plugin.c:1:
/usr/lib/gcc/ppc64le-redhat-linux/10/plugin/include/gimple.h:1037:1:
note: ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const ggoto*]’ previously declared here
 1037 | is_a_helper <const ggoto *>::test (const gimple *gs)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-plugins/ppc64le-plugin.c:1:
gcc-plugins/gcc-common.h:848:13: error: redefinition of ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const greturn*]’
  848 | inline bool is_a_helper<const greturn *>::test(const_gimple gs)
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-plugins/gcc-common.h:124,
                 from gcc-plugins/ppc64le-plugin.c:1:
/usr/lib/gcc/ppc64le-redhat-linux/10/plugin/include/gimple.h:1489:1:
note: ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const greturn*]’ previously declared here
 1489 | is_a_helper <const greturn *>::test (const gimple *gs)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

as per kernel commit c7527373fe28 ("gcc-common.h: Update for GCC 10")
 "params.h header file has been dropped from GCC 10 and is_a_helper()
  macro is now defined in gimple.h"

this patch fix them by guarding the both param.h header file and
is_a_helper() with #ifdef checking for gcc version < 10000.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-06-09 20:34:27 +05:30
Joe Lawrence
5331463768
Merge pull request #1102 from joe-lawrence/jp-ppc-mcount
create-diff-object: Add ppc64le mcount support
2020-05-18 09:20:40 -04:00
Josh Poimboeuf
b958ed601c create-diff-object: Add ppc64le mcount support
Add the __mcount_loc section on ppc64le.  It has pointers to all the
mcount calls.  This will enable the ftrace hook to be used for patched
functions.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> (rebased)
2020-05-18 08:35:33 -04:00
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
Julien Thierry
c1caee1468 create-diff-object: Ignore kpatch_ignored functions/sections missing ftrace hook
Some theoretically unchanged functions can have undesired changes if the
compiler decides to perform inlining in a different way (e.g. because of
newly added references). In such a case, it can be useful to discard
changes to functions that don't actually need modification.

Sadly, this currently doesn't work for functions missing the ftrace hook
(e.g. notrace code) as presence of the hook is checked before
identifying elements to ignore.

Look for functions/sections to ignore earlier.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-04-23 08:22:50 +01:00
Josh Poimboeuf
1991ff0018 create-diff-object: add support for .klp.arch removal
Starting with Linux 5.8, vmlinux-specific KLP relas are applied early,
before all the special section initializations are done.

This means that jump labels can now be supported for cases where the
corresponding static keys live in the core kernel (vmlinux).

It also means that paravirt patching and alternatives can also now be
supported without the need for the .klp.arch sections.

This simplifies things greatly for newer kernels.  We just have to make
sure that module-specific KLP relas aren't created for special sections.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-14 12:44:04 -05:00
Josh Poimboeuf
3982b329bc kpatch-build: drop support for old non-.klp.arch kernels
There were a few kernels (4.7 and 4.8) which didn't have support for
.klp.arch sections, but for which we still tried to use
CONFIG_LIVEPATCH.  Those are inherently buggy, so just drop
CONFIG_LIVEPATCH support for them altogether.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-14 12:44:04 -05:00
Josh Poimboeuf
e80562a8cb kpatch-build: add kpatch.ko deprecation warning
kpatch.ko has been quietly deprecated for a while, because there are
some known issues, including special section initialization ordering
issues.  Starting with Linux 5.7, it will be completely broken because
kallsyms_lookup_name() will no longer be exported.

Add a warning to make its deprecation status more obvious.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-14 12:44:04 -05:00
Josh Poimboeuf
d97de8d554 kpatch-build: readability cleanups
Do some kpatch-build script cleanups to improve readability.  This
is only a cleanup and shouldn't affect any functionality.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-14 12:44:04 -05:00
Josh Poimboeuf
4e0db559c1 lookup: fix Module.symvers reading for newer kernels
With Linux commit 5190044c2965 ("modpost: move the namespace field in
Module.symvers last"), the format of Module.symvers has changed yet
again.

Use a completely different approach for figuring out the format.  If a
column has "vmlinux", assume that's the "Module" column.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-14 12:44:00 -05:00
Yannick Cote
1cc52bf19b
Merge pull request #1088 from euspectre/show-all-jump-labels
create-diff-object: show all jump labels before reporting failure
2020-04-14 09:09:48 -04:00
Evgenii Shatokhin
89e8574027 create-diff-object: show all jump labels before reporting failure
We have recently encountered a situation when a patched function
had more than one jump label (static branches with the same static key
used to turn on/off some debugging feature). As it is often the case
with jump labels, their locations were far from obvious in the source
code, hidden in the chains of inline functions.

create-diff-object, however, exits after it has reported one jump label.
This is inconvenient, because, after one updates the patch to avoid
that jump label, the next build of the binary patch reveals another
one and fails again, and so on. It can be very time-consuming.

Let us report all jump labels first.

Before this commit the messages looked like this:

  kpatch-build/create-diff-object: ERROR: dev.o:
  kpatch_regenerate_special_section: 2084:
  Found a jump label at ploop_req_state_process()+0x220, using key css_stacks_on.
  Jump labels aren't currently supported.  Use static_key_enabled() instead.

After:

  dev.o: Found a jump label at ploop_req_state_process+0x220, key: css_stacks_on.
  dev.o: Found a jump label at ploop_ioctl+0x2708, key: css_stacks_on.
  kpatch-build/create-diff-object: ERROR: dev.o:
  kpatch_regenerate_special_section: 2123:
  Found 2 jump label(s) in the patched code.
  Jump labels aren't currently supported. Use static_key_enabled() instead.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2020-04-10 19:26:06 +03:00
Josh Poimboeuf
0a3e6c5f42 create-diff-object: refactor dynrela conversion
The dynrela (aka .klp.rela) conversion logic is notoriously complex and
fragile.  Simplify it and improve the comments.

This is mainly a cosmetic change.  In theory it shouldn't change
functionality or break anything.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
d2089a4d72 create-diff-object: rename lookup 'result' -> 'symbol'
Improve readability by renaming the lookup "result" variables to
"symbol".

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
ae9f1c17b1 lookup: add duplicate symbol checks
Add checks for duplicate symbols, and refactor the logic slightly.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
3064cf3c60 lookup: add 'objname' to lookup table and lookup results
This will be needed for the upcoming dynrela refactoring.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
7e1f2b0e07 lookup: convert lookup functions to return bool
IMO, the code is easier to follow if these functions return bool.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
6cc03f9599 lookup: rename 'pos' to 'sympos'
To more accurately describe its purpose.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
cd121422d9 lookup: rename 'value' -> 'addr'
Rename 'value' to 'addr' to more accurately describe it.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
5fad6599a4 lookup: remove unused testing code
This testing code is no longer used.  Remove it.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
e4d37dad5d lookup: Skip .dynsym table in symtab_read()
On powerpc, "readelf -s" of vmlinux shows both .dynsym and .symtab.
.dynsym is just a subset of .symtab, so skip it to avoid duplicates.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
7e48138185 lookup: Simplify first loop in symtab_read()
symtab_read() is quite fragile because it relies on the fact that the
first and second loops have the exact same conditions.

Instead just change the first loop to count all the lines in the file,
to get an upper bound for allocation.  It's ok to over-allocate
slightly.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Josh Poimboeuf
74c9c99931 create-diff-object: reduce indentation in kpatch_create_patches_sections()
Reverse the if condition and use a 'continue' statement to reduce
indentation and improve readability.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-04-06 15:18:58 -05:00
Julien Thierry
b548ba153f kpatch-build: Look for local static variables in child functions
A symbol in the original object might get split in several sub-functions
in the patched object, which can themselves be bundled (and use a
separate rela section). References to local static variables from the
original function, might have been moved in one of the sub-functions
in the patched object.

Look for references to local static variables in the rela section
of child symbols in the patched object.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-03-30 14:14:17 +01:00
Julien Thierry
42128ff78c kpatch-build: Include .part. symbols as child function
Consider symbols containing .part. in their names as sub-function
of the symbols they are derived from (if such symbol still exists in the
object file).

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-03-30 14:14:17 +01:00
Julien Thierry
b502e5b1cc kpatch-build: Allow function to have multiple child functions
A symbol associated to a function can be split into multiple
sub-functions. Currently, kpatch only supports one child per function.

Extend this to support an arbitrary number of sub-function per function.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-03-30 14:14:17 +01:00
Julien Thierry
af1fe267c5 create-diff-object: Avoid unnecessary parent symbol inclusion
When a child symbol has changed, the parent symbol is only needed
in the output object if the child symbol is unpatchable on its own.
This is the case when the child symbol does not have its own profiling
call.

Only include unchanged parent symbols if their child has changed and
the child does not have a function profiling call.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-03-30 14:14:17 +01:00
Julien Thierry
fbfc8f9bec create-diff-object: Handle ppc64le toc with only constants
When a ppcle64 ".toc" section contains only constants, the compiler
might not (won't?) create a corresponding ".rela.toc" section.

In such cases, create-diff-object crashes, assuming ".rela.toc" exists
whenever .toc exists. Simply report that no rela are available when
looking up possible relocations in .toc.

Fixes #1078.
Signed-off-by: Julien Thierry <jthierry@redhat.com>
2020-02-28 03:50:44 -05:00
Josh Poimboeuf
687e2caabc create-diff-object: Don't strip callback section symbols
Internal CI is reporting a SIGSEGV in create-diff-object when it
processes macro-callbacks.patch, starting with 19baa5b7c7
("create-diff-object: process debug sections last").

The problem is that, after changing the order between callback and debug
section inclusion, kpatch_include_debug_sections() now tries to include
the callback section symbols.  But kpatch_include_callback_elements()
inadvertently un-includes the callback section symbols (e.g.,
".kpatch.callbacks.pre_patch") when it un-includes the callback struct
symbols (e.g., "kpatch_pre_patch_data").

So after kpatch_elf_teardown(kelf_patched), the callback section symbols
get freed even though there are DWARF .debug_info relocations which
reference them.  Then kpatch_check_relocations() goes off into the weeds
when it accesses one of the freed symbols.

Fix it by refining the callback un-include logic so that it *only*
strips the struct object symbols.

Fixes: 19baa5b7c7 ("create-diff-object: process debug sections last")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2020-02-18 10:16:39 -06:00
Josh Poimboeuf
648be4c380
Merge pull request #1053 from julien-thierry/stricter-static-twin
kpatch-build: Make local static twining stricter
2020-02-17 15:15:52 -06:00
Josh Poimboeuf
1b7871507a
Merge pull request #1055 from jpoimboe/process-debug-sections-last
create-diff-object: process debug sections last
2020-02-17 14:50:39 -06:00
Kamalesh Babulal
37e950a653 create-kpatch-module: Fix -Wconversion warnings
Fix warnings reported by -Wconversion,-Wno-sign-conversion CFLAGS.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-02-11 19:25:10 +05:30
Kamalesh Babulal
ea9e708df0 create-klp-module: Fix -Wconversion warnings
Fix warnings reported by -Wconversion,-Wno-sign-conversion flags.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-02-11 19:25:04 +05:30
Kamalesh Babulal
f67c2ebce0 kpatch-elf: Fix -Wconversion warnings
Fix warnings reported by -Wconversion,-Wno-sign-conversion flags.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-02-11 19:24:57 +05:30
Kamalesh Babulal
5f68db22e5 create-diff-object: Fix -Wconversion warnings
Fix warnings reported by -Wconversion,-Wno-sign-conversion flags.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-02-10 09:07:21 +05:30
Kamalesh Babulal
a0c608de70 kpatch-build/Makefile: Skip build insn/plugin with -Wconversion
Skip building insn/* on x86 and gcc-plugin on Power with -Wconversion,
-Wno-sign-converion flags.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-01-23 12:59:38 +05:30
Kamalesh Babulal
4e4a8d99da kpatch-build: add -Wconversion/-Wno-sign-conversion CFLAGS
Add -Wconversion and -Wno-sign-conversion to CFLAGS.  The first flag
should catch any implicit conversions like the one seen with #1065 and
the second flag suppress the warnings between signed and unsigned
integers.

Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2020-01-23 12:59:31 +05:30
Evgenii Shatokhin
f5f5479614 create-diff-object: fix relocations used for ZERO_PAGE(0)
On x86_64, GCC generates the following instruction to compute
'empty_zero_page - __START_KERNEL_map' (__phys_addr_nodebug(), used in
the implementation of ZERO_PAGE()):

    48 ba 00 00 00 00 00 00 00 00   movabs $0x0,%rdx
          R_X86_64_64  empty_zero_page+0x80000000

__START_KERNEL_map is 0xffffffff80000000.

However, the relocation addend becomes wrong in the patch module:

    48 ba 00 00 00 00 00 00 00 00   movabs $0x0,%rdx
          R_X86_64_64  empty_zero_page-0x80000000

Note the sign of the addend.

As a result, ZERO_PAGE(0) returns a wrong value in any function touched
by the patch, which may lead to memory corruption and difficult-to-debug
kernel crashes.

The cause is that 'struct rela' uses 'int' for the addend, which is not
enough to store such values. r_addend from Elf64_Rela is int64_t
(Elf64_Sxword) for that.

Let us use 'long' instead of 'int' for the addend in 'struct rela'.

v2:
* Moved 'addend' field after 'offset' in struct rela to facilitate
  structure packing (suggested by Kamalesh Babulal).

Fixes https://github.com/dynup/kpatch/issues/1064.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2020-01-20 11:41:01 +03:00
Zhipeng Xie
61c55d9e52 kpatch-build: replace all '-' to '_' in KOBJFILE_NAME
When patching kernel module dm-persistent-data, I found
that the KOBJFILE_NAME is incorrectly replaced to
dm_persistent-data while the module name in kernel is
dm_persistent_data.

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2019-12-30 17:48:14 +08:00
Julien Thierry
68530e4c2b kpatch-build: Make local static twining stricter
The current code to find the twin of a local static variable allows two
variables of the same name to be wrongly matched with the other's twin.

While there isn't a magic formula to avoid this, make stricter
requirements for twining static local from the original object with
a symbol from the patched object. This reduces the risk of erroneous
matches.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-11-22 09:53:16 +00:00
Josh Poimboeuf
19baa5b7c7 create-diff-object: process debug sections last
Process the debug sections only after all the other inclusion logic has
finished, since it makes decisions based on what else has already been
included.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-11-01 15:26:07 -05:00
Julien Thierry
852bad5e8d create-diff-object: Use new helpers for static local correlation
Simplify static local variable correlation and renaming code by using
the newly introduced helpers for section and symbol correlation.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-10-29 15:29:51 +00:00
Julien Thierry
e49e3a59c2 create-diff-object: Rename elements getting correlated
Change 935f199875 ('create-diff-object: simplify mangled function
correlation') simplified the way symbols are correlated and got rid of
symbol section renaming.

As a result a symbol/section can now have a CHANGED status, being
correlated to an element that doesn't have the exact same name. This
will cause lookups to the original object fail when creating the new
patch object.

So lets bring back the symbol/section renaming, but only once they
have actually been correlated.

Fixes: 935f199875 ('create-diff-object: simplify mangled function
correlation')
Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-10-29 15:27:51 +00:00
Julien Thierry
49a9adaf74 create-diff-object: Correlate objects related to a section at once
Elements from the original object and the patched object can be
correlated using their mangled names. In case an elements (section or
symbol) could be matched with more than one object through mangling,
make sure all elements related to a section are correlated with the
corresponding elements of the twin section.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-10-29 15:27:51 +00:00
Julien Thierry
770f529225 kpatch-elf: Ensure stale references are not used
When freeing a kpatch_elf, another object might have symbols and
sections twined with elements that are getting freed.

Clear the twin references, so if they are used after the object they
reference is freed, the program will crash.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-10-29 10:48:02 +00:00
Josh Poimboeuf
e0bd024c18
Merge pull request #1052 from sm00th/symvers
Make symvers reading code more flexible.
2019-10-28 15:46:53 -05:00
Artem Savkov
3a1a73f08c Make symvers reading code more flexible.
Kernel commit cb9b55d21fe0 modpost: add support for symbol namespaces
adds a new namespace column to Module.symvers file which can be blank.
fscanf is no longer a viable solution to parse that. Switch to the way
scripts/mod/modpost.c handles this and try to support both versions with
and without namespace column.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-10-25 14:17:11 +02:00
Julien Thierry
a02842fb69 kpatch-elf: Free sections in elf teardown
Currently, only rela section get freed. This seems like a simple
scope mistake.

Free all sections regardless of their nature in kpatch_elf_teardown()

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-10-15 16:02:11 +01:00
Josh Poimboeuf
935f199875 create-diff-object: simplify mangled function correlation
The RHEL powerpc kernel is compiled with -O3, which triggers some
"interesting" new optimizations.  One of them, which seems to be
relatively common, is the replacing of a function with two separate
"constprop" functions.

Previously we only ever saw a single constprop clone, so we just renamed
the patched version of the function to match the original version.  Now
that we can have two such clones, that no longer makes sense.

Instead of renaming functions, just improve the correlation logic such
that they can be correlated despite having slightly different symbol
names.  The first clone in the original object is correlated with the
first clone in the patched object; the second clone is correlated with
the second clone; and so on.

This assumes that the order of the symbols and sections doesn't change,
which seems to be a reasonable assumption based on past experience with
the compiler.  Otherwise it will just unnecessarily mark the cloned
constprop functions as changed, which is annoying but harmless, and
noticeable by a human anyway.

Fixes #935.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-10-03 09:38:29 -05:00
Josh Poimboeuf
683289206b
Merge pull request #1038 from wwheart/master
kpatch-build: fix two parent matches error
2019-09-27 14:43:25 -05:00
Josh Poimboeuf
c175d8697c
Merge pull request #1039 from julien-thierry/misc-cleanups
Misc cleanups
2019-09-27 14:29:53 -05:00
chenzefeng
e9755413ed kpatch-build: use whole word filename matching in find_parent_obj()
Building a kpatch for a module with this Makefile:

The Makefile is as follow:
	obj-m += m_hello.o
	m_hello-y = hello.o
	default:
        	$(MAKE) -C /lib/modules/4.4.21-69-default/build M=$(shell pwd) modules
	clean:
        	$(MAKE) -C /lib/modules/4.4.21-69-default/build M=$(shell pwd) clean

results in kpatch-build "ERROR: two parent matches for hello.o".

The problem is that find_parent_obj() looks for filenames like so:

	% grep -l hello.o ./.*.cmd | grep -Fv hello.o
	.m_hello.ko.cmd
	.m_hello.o.cmd

where .m_hello.ko.cmd is the parant for m_hello.o, and .m_hello.o.cmd is the
parant for hello.o, but because the "hello.o" is a substring of "m_hello.o",
it will cause "m_hello.o" to be matched for the "hello.o" as well.

Fix this by using grep's -w|--word-regexp option to force it to match
whole words instead of substrings.

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-09-27 09:36:39 +08:00
Josh Poimboeuf
0b000cb87d
Merge pull request #1037 from jpoimboe/ppc64le-remove-unsupported-check
Revert "create-diff-object: Check for *_fixup sections changes"
2019-09-17 11:37:05 -05:00
Julien Thierry
878bac379f create-diff-object: Simplify relocation processing
If the symbol associated with a relocation does not have a section set,
nothing is done for that relocation.

Skip iterating through all the symbols of the ELF file in such a case.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-09-17 15:42:01 +01:00
Julien Thierry
bd4fae25f9 create-diff-object: Add const to unmodified rela_insn arguments
rela_insn() only retrieves information about an instruction and does not
modify sections or relocations.

Add const to make this explicit.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-09-17 15:42:01 +01:00
Julien Thierry
50476c94cc create-diff-object: Check ELF headers earlier
There is no point inspecting through the symbols of the ELF files
(original and patched) when the ELF headers do not meet requirements.

Check ELF headers as soon as the files are mapped.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
2019-09-17 15:42:01 +01:00
Josh Poimboeuf
2499eb2bdc Revert "create-diff-object: Check for *_fixup sections changes"
We are seeing the following error on a real world patch:

  unsupported reference to special section __barrier_nospec_fixup

The kpatch commit bb444c2168 ("create-diff-object: Check for *_fixup
sections changes") created this error because we were trying to be
future proof.  However, that may have been overly paranoid, as it
doesn't seem likely that those fixup sections will need relocations
anytime soon, because the replacement instructions are manually
generated in code.  And anyway that "future proof" commit breaks the
present.

Also we decided at LPC that we are going to remove .klp.arch sections
anyway, so once that happens we will be fully future-proof anyway.

This reverts commit bb444c2168.

Fixes #974.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-09-16 09:22:54 -05:00
Artem Savkov
aabdf9c9c9 Fix parent matches for kernels newer than 5.3
Somewhere starting with 5.3 (probably with 9f69a496f100 "kbuild: split
out *.mod out of {single,multi}-used-m rules", but that is not
confirmed) .mod and correcponding .mod.cmd files started showing up
during module builds throwing off kpatch-build's find_parent_obj() func.

Filter out any files ending with .mod.cmd as they are definitely not the
parent.

Signed-off-by: Artem Savkov <artem.savkov@gmail.com>
2019-09-16 14:18:32 +02:00
Joe Lawrence
0507ea2bb7
Merge pull request #1030 from joe-lawrence/verify-patch-files
kpatch-build: sanity check patched filenames
2019-09-03 10:19:08 -04:00
Pawel Wieczorkiewicz
ed5091b16f kpatch-build: Check if /etc/os-release exists
Not every distro out there supports /etc/os-release file.
This file is useful for obtaining given distro defaults, but not
essential for the script to work (when all parameters are passed
on a command line).

To avoid warnings or unwanted errors, make sourcing of this file
conditional.

Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
2019-08-27 14:52:05 +00:00
Joe Lawrence
e4525ce311 kpatch-build: sanity check patched filenames
Run the input patch(es) through lsdiff and then verify that no obviously
unsupported files are directly modified (e.g. assembly .S files).

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2019-08-22 11:44:02 -04:00
Josh Poimboeuf
e187de3fe4 kpatch-build: update core file error message
Recent distros don't require you to set 'ulimit -c unlimited'.  Instead
they place core files in a distro-specific location.  Update the SIGSEGV
error message accordingly.

Fixes: #1025

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-08-20 16:18:59 -05:00
Joe Lawrence
a23c82d9e6
Merge pull request #1026 from jpoimboe/ppc-replace-sections-syms-callbacks-fix
create-diff-object: Don't strip callback symbols
2019-08-19 10:50:36 -04:00
Josh Poimboeuf
2975775768 create-diff-object: allow dynamic debug static keys
While static keys (jump labels) are currently broken in livepatch, a
broken dynamic debug static key is harmless since it just disables
dynamically enabled debug printks in the patched code.

Fixes: #1021

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-08-15 16:01:55 -05:00
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
Josh Poimboeuf
14cc8a013d create-diff-object: add is_callback_section() helper
This simplifies the code a bit.  Also this helper will be needed for
subsequent patches.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-08-15 14:08:29 -05:00
Josh Poimboeuf
5665d06853 create-diff-object: fix kpatch_replace_sections_syms() comment
The existing comment is wrong.  It confusingly conflates the function's
offset, which is 8 bytes from the beginning of the section, with the
function's localentry offset which is 8 bytes from the beginning of the
function.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-08-15 14:02:09 -05:00
Artem Savkov
f1263a4292 create-diff-object: section size check in rela_insn()
Without this check we are risking returning uninitialized insn var.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:11:43 +02:00
Artem Savkov
7129bb48c9 create-diff-object: free hint variable on failure
Make sure we are freeing previously allocated "hint" variable on error
before exiting.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:11:43 +02:00
Artem Savkov
054915e957 create-diff-object: remove unneeded var initialization in kpatch_regenerate_special_section()
group_size variable is assigned right after we enter for loop without
ever being read so there is no need to initialize it to 0 beforehand.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:11:43 +02:00
Artem Savkov
1722f14221 create-diff-object: make sure sym->sec is not null in kpatch_replace_sections_syms()
Check that sym->sec is not null before dereferencing it.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:11:29 +02:00
Artem Savkov
9049abd0f5 create-diff-object: remove unused variables
"funcs" in kpatch_create_patches_sections() and "entries" in
kpatch_create_kpatch_arch_section() were only used by sizeof, replaced
those with corresponding types.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
9c1aa2d492 lookup: exit on error in make_modname()
Actually exit on strdup error instead of just printing a warning message
in make_modname().

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
79728dddaf kpatch-elf: add a couple mission section checks
There were 2 insances where return value of find_section_by_name wasn't
checked before dereference.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
04c0831705 create-kpatch-module: check symtab in main()
Make sure symtab section was found before dereferencing it.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
5cd9833b0d create-klp-module: check symtab in main()
Make sure symtab section was found before dereferencing it.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
bba18e3612 create-klp-module: remove unused variable in create_klp_arch_sections()
Only user of "entries" variable was sizeof and the value was never
actually used. Use struct name directly instead.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
38efb307c2 create-diff-object: check symtab in main()
Make sure symtab section was found before dereferencing it.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
dba95bae62 create-diff-object: check mallor retval in kpatch_create_mcount_sections()
newdata variable is allocated through malloc call and requires a NULL
check.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
deb7719280 create-diff-object: check ORC_STRUCT_SIZE correctness in kpatch_regenerate_orc_sections()
Since ORC_STRUCT_SIZE is used for division in
kpatch_regenerate_orc_sections() we need to make sure that it is
properly set.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
f0d071def7 create-diff-object: check fixupsec in fixup_group_size()
Make sure fixup section was found before dereferencing it.

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Artem Savkov
f367438b19 create-diff-object: null checks in rela_equal()
Make sure rela_toc(1|2) are not null before dereferencing them in
rela_equal().

Found by covscan, see issue #984 for full log.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2019-08-05 12:10:47 +02:00
Stefan Strogin
14b094484e
kpatch-build: check if gcc supports -gz=none
The flag -gz[=type] was added in GCC 5. To support older GCC versions
check if the flag is supported before adding it to KCFLAGS.

Fixes: #1012

Signed-off-by: Stefan Strogin <steils@gentoo.org>
2019-07-31 11:16:16 +03:00
Stefan Strogin
fe6e3f51bf
create-diff-object: disable DWARF compression explicitly
On some systems the linker produces compressed debug sections by
default. It is not supported by create-diff-object for now.

Fixes: #877

Signed-off-by: Stefan Strogin <steils@gentoo.org>
2019-07-29 13:20:20 +03:00
Josh Poimboeuf
e8f7f2dfe8 create-diff-object/ppc64le: Fix replace_sections_syms() for bundled symbols
With the following patch:

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index b60c9c7498dd..39a39ca89230 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1594,6 +1594,8 @@ static void xs_tcp_state_change(struct sock *sk)
 	struct rpc_xprt *xprt;
 	struct sock_xprt *transport;

+	asm("nop");
+
 	read_lock_bh(&sk->sk_callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;

I saw the following panic on a RHEL8 kernel:

  Unable to handle kernel paging request for data at address 0xcc0080040
  Faulting instruction address: 0xc000000000b1515c
  Oops: Kernel access of bad area, sig: 7 [#1]
  LE SMP NR_CPUS=2048 NUMA PowerNV
  Modules linked in: rpcsec_gss_krb5 nfsv4 dns_resolver nfs fscache nfsd auth_rpcgss nfs_acl lockd grace kpatch_4_18_0_118_1_1(OEK) i2c_dev sunrpc ofpart powernv_flash at24 sg xts ipmi_powernv ipmi_devintf ipmi_msghandler uio_pdrv_genirq uio mtd vmx_crypto ibmpowernv opal_prd xfs libcrc32c sd_mod ast i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm ahci libahci libata tg3 drm_panel_orientation_quirks dm_mirror dm_region_hash dm_log dm_mod
  CPU: 15 PID: 7814 Comm: kworker/u260:0 Kdump: loaded Tainted: G           OE K  --------- -  - 4.18.0-118.el8.ppc64le #1
  Workqueue: xprtiod xs_tcp_setup_socket [sunrpc]
  NIP:  c000000000b1515c LR: c000000000ad9968 CTR: c000000000b15140
  REGS: c000001fab6ff6b0 TRAP: 0300   Tainted: G           OE K  --------- -  -  (4.18.0-118.el8.ppc64le)
  MSR:  9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE>  CR: 44002222  XER: 20040000
  CFAR: c000000000078c7c DAR: 0000000cc0080040 DSISR: 00080000 IRQMASK: 0
  GPR00: c000000000ad9968 c000001fab6ff930 c000000001662800 0000000cc0080000
  GPR04: c00800000f5cfaa4 c000001f998fd0a8 c000001ff67e8080 c0000000016f46f0
  GPR08: c000001fb4918f80 0000000000000000 0000000cc0080040 c0000000011b8980
  GPR12: 0000000000002000 c000001ffffee200 c00000000017c458 c000001fe8a23a40
  GPR16: c00000000150e480 c000001fd6e90090 0000000000000000 0000000000000000
  GPR20: c00000000150e498 fffffffffffffef7 0000000000000402 0000000000000000
  GPR24: c000001fd6e90380 0000000000000000 c00800000f5cfaa4 0000000000000000
  GPR28: 00000000000004c4 c000001f998fd0a8 c00800000f5cfaa4 0000000cc0080000
  NIP [c000000000b1515c] dst_release+0x2c/0x110
  LR [c000000000ad9968] skb_release_head_state+0x178/0x190
  Call Trace:
  [c000001fab6ff930] [c000000000b15140] dst_release+0x10/0x110 (unreliable)
  [c000001fab6ff9a0] [c000000000ad9968] skb_release_head_state+0x178/0x190
  [c000001fab6ff9d0] [c000000000adb058] __kfree_skb+0x28/0x120
  [c000001fab6ffa00] [c000000000be8d64] tcp_rcv_state_process+0xc24/0x1180
  [c000001fab6ffa90] [c000000000cd5478] tcp_v6_do_rcv+0x1a8/0x5e0
  [c000001fab6ffae0] [c000000000ad1724] __release_sock+0xc4/0x1a0
  [c000001fab6ffb40] [c000000000ad1850] release_sock+0x50/0xe0
  [c000001fab6ffb70] [c000000000c20018] inet_stream_connect+0x68/0x90
  [c000001fab6ffbb0] [c000000000ac0f50] kernel_connect+0x30/0x50
  [c000001fab6ffbd0] [c00800000f55dc34] xs_tcp_setup_socket+0xbc/0x650 [sunrpc]
  [c000001fab6ffc70] [c000000000172014] process_one_work+0x2f4/0x5c0
  [c000001fab6ffd10] [c000000000172adc] worker_thread+0xcc/0x760
  [c000001fab6ffdc0] [c00000000017c5fc] kthread+0x1ac/0x1c0
  [c000001fab6ffe30] [c00000000000b75c] ret_from_kernel_thread+0x5c/0x80
  Instruction dump:
  60000000 3c4c00b5 3842d6d0 7c0802a6 4b563b61 fbe1fff8 f821ff91 7c7f1b79
  4182003c fbc10060 7c0004ac 395f0040 <7d205028> 3129ffff 7d20512d 40c2fff4

The problem is that the function has a GCC switch jump table, and the
.toc had the wrong offset for the jump table.

This is the switch jump table code from xs_tcp_state_changed():

  70:   12 00 3d 89     lbz     r9,18(r29)
  74:   0b 00 89 2b     cmplwi  cr7,r9,11
  78:   f8 02 9d 41     bgt     cr7,370 <xs_tcp_state_change+0x368>
  7c:   00 00 42 3d     addis   r10,r2,0
                        7c: R_PPC64_TOC16_HA    .toc+0x188
  80:   00 00 4a e9     ld      r10,0(r10)
                        80: R_PPC64_TOC16_LO_DS .toc+0x188
  84:   64 17 29 79     rldicr  r9,r9,2,61
  88:   aa 4a 2a 7d     lwax    r9,r10,r9
  8c:   14 52 29 7d     add     r9,r9,r10
  90:   a6 03 29 7d     mtctr   r9
  94:   20 04 80 4e     bctr
  98:   d8 02 00 00     .long 0x2d8
  9c:   38 00 00 00     .long 0x38
  a0:   d8 02 00 00     .long 0x2d8
  a4:   d8 02 00 00     .long 0x2d8
  a8:   68 02 00 00     .long 0x268
  ac:   d8 02 00 00     .long 0x2d8
  b0:   d8 02 00 00     .long 0x2d8
  b4:   c8 01 00 00     .long 0x1c8
  b8:   38 01 00 00     .long 0x138
  bc:   88 01 00 00     .long 0x188
  c0:   d8 02 00 00     .long 0x2d8
  c4:   68 01 00 00     .long 0x168

The switch jump table address is at offset 0x98.  The code reads this
offset from .toc+0x188:

Relocation section '.rela.toc' at offset 0x75320 contains 134 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000188  0000003f00000026 R_PPC64_ADDR64         0000000000000000 .text.xs_tcp_state_change + 98

After create-diff-object runs, the .toc entry now looks like this:

0000000000000188  0000000200000026 R_PPC64_ADDR64         0000000000000008 xs_tcp_state_change + 98

Notice the offset is the same, but it's now referring to the function
symbol instead of the text symbol.  That's done by
kpatch_replace_sections_syms().

On x86, that's not a problem, because the function symbol is at offset 0
in the .text.function section.  So the section symbol and the function
symbol are at the same location.

But on ppc64le, with -ffunction-sections, GCC 6+ somehow thinks it's a
good idea to associate the function symbol with the localentry point,
which is at an 8-byte offset from its corresponding section:

   Num:    Value          Size Type    Bind   Vis      Ndx Name
     2: 0000000000000008  1228 FUNC    LOCAL  DEFAULT    3 xs_tcp_state_change  [<localentry>: 8]

Notice the "Value" is 8 instead of 0.

That causes the .toc entry's jump table address to be wrongly offset by
8 bytes.

The fix is to adjust the rela addend accordingly in
kpatch_replace_sections_syms().

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-23 18:11:25 -05:00
Josh Poimboeuf
8b952bd771 create-diff-object/ppc64le: Don't allow sibling calls
With the following patch:

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index e008aefc3a9d..7c70e369390d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2228,6 +2228,8 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
 	struct socket *sock = transport->sock;
 	int skst = transport->inet ? transport->inet->sk_state : TCP_CLOSE;

+	asm("nop");
+
 	if (sock == NULL)
 		return;
 	switch (skst) {

We saw the following panic on a RHEL7.6 kernel:

  Unable to handle kernel paging request for data at address 0xd00000000577f390
  Faulting instruction address: 0xd000000002e918f4
  Oops: Kernel access of bad area, sig: 11 [#1]
  SMP NR_CPUS=2048 NUMA pSeries
  Modules linked in: kpatch_3_10_0_957_1_3_1_1(OEK) nfsd nfs_acl rpcsec_gss_krb5 auth_rpcgss nfsv4 dns_resolver nfs lockd grace fscache sunrpc virtio_balloon ip_tables xfs libcrc32c virtio_net virtio_console virtio_blk virtio_pci virtio_ring virtio dm_mirror dm_region_hash dm_log dm_mod
  CPU: 9 PID: 5961 Comm: kworker/9:1H Kdump: loaded Tainted: G           OE K------------   3.10.0-957.1.3.el7.ppc64le #1
  Workqueue: xprtiod xprt_autoclose [sunrpc]
  task: c00000000300c3c0 ti: c0000003f1814000 task.ti: c0000003f1814000
  NIP: d000000002e918f4 LR: d000000002e57394 CTR: c00000000089d100
  REGS: c0000003f1817980 TRAP: 0300   Tainted: G           OE K------------    (3.10.0-957.1.3.el7.ppc64le)
  MSR: 8000000100009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 240f2084  XER: 20000000
  CFAR: 000000010bb5270c DAR: d00000000577f390 DSISR: 40000000 SOFTE: 1
  GPR00: c00000000000b054 c0000003f1817c00 d00000000579add8 c000000214f0f4d0
  GPR04: c0000003fd618200 c0000003fd618200 0000000000000001 0000000000000dc2
  GPR08: 0000000000000dc3 0000000000000000 0000000000000000 d00000000577f370
  GPR12: c0000003f1814000 c000000007b85100 c00000000012fd88 c0000003f711bb40
  GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
  GPR20: 0000000000000001 c0000000013510b0 0000000000000001 fffffffffffffef7
  GPR24: 0000000000000000 0000000000000000 0000000000000000 c000000001b60600
  GPR28: c000000214f0f000 c000000214f0f4d0 c000000214f0f408 c000000214f0f448
  NIP [d000000002e918f4] __rpc_create_common.part.6+0x640/0x533c [sunrpc]
  LR [d000000002e57394] xprt_autoclose+0x74/0xe0 [sunrpc]
  Call Trace:
  [c0000003f1817c00] [c00000000000b054] livepatch_handler+0x30/0x80 (unreliable)
  [c0000003f1817c40] [c00000000012333c] process_one_work+0x1dc/0x680
  [c0000003f1817ce0] [c000000000123980] worker_thread+0x1a0/0x520
  [c0000003f1817d80] [c00000000012fe74] kthread+0xf4/0x100
  [c0000003f1817e30] [c00000000000a628] ret_from_kernel_thread+0x5c/0xb4
  Instruction dump:
  396b4570 f8410018 e98b0020 7d8903a6 4e800420 00000000 73747562 000f49c0
  c0000000 3d62fffe 396b4598 f8410018 <e98b0020> 7d8903a6 4e800420 00000000
  ---[ end trace 98e026b8fa880db7 ]---

The original version of xs_tcp_shutdown() has the following sequence:

  0xd000000003cfda44 <xs_tcp_shutdown+148>:       addi    r1,r1,64
  0xd000000003cfda48 <xs_tcp_shutdown+152>:       ld      r0,16(r1)
  0xd000000003cfda4c <xs_tcp_shutdown+156>:       ld      r29,-24(r1)
  0xd000000003cfda50 <xs_tcp_shutdown+160>:       ld      r30,-16(r1)
  0xd000000003cfda54 <xs_tcp_shutdown+164>:       ld      r31,-8(r1)
  0xd000000003cfda58 <xs_tcp_shutdown+168>:       mtlr    r0
  0xd000000003cfda5c <xs_tcp_shutdown+172>:       b       0xd000000003cfd768

That is, it restores the stack to the caller's stack frame and then does
a sibling call to the localentry point of xs_reset_transport()).  So
when xs_reset_transport() returns, it will return straight to
xs_tcp_shutdown()'s caller (xprt_autoclose).

The patched version of the function has this instead (dumped from a
vmcore):

  0xd000000003df0834 <xs_tcp_shutdown+148>:       addi    r1,r1,64
  0xd000000003df0838 <xs_tcp_shutdown+152>:       ld      r0,16(r1)
  0xd000000003df083c <xs_tcp_shutdown+156>:       ld      r29,-24(r1)
  0xd000000003df0840 <xs_tcp_shutdown+160>:       ld      r30,-16(r1)
  0xd000000003df0844 <xs_tcp_shutdown+164>:       ld      r31,-8(r1)
  0xd000000003df0848 <xs_tcp_shutdown+168>:       mtlr    r0
  0xd000000003df084c <xs_tcp_shutdown+172>:       b       0xd000000003df0ad0

After restoring the stack, instead of branching directly to
xs_reset_transport(), it (rightfully) branches to a toc stub.  A stub is
needed because the function it's branching to is in another module
(branching from the patch module to the sunrpc module).

The stub is:

  0xd000000003df0ad0 <xs_tcp_shutdown+816>:       addis   r11,r2,-1
  0xd000000003df0ad4 <xs_tcp_shutdown+820>:       addi    r11,r11,26328
  0xd000000003df0ad8 <xs_tcp_shutdown+824>:       std     r2,24(r1)
  0xd000000003df0adc <xs_tcp_shutdown+828>:       ld      r12,32(r11)
  0xd000000003df0ae0 <xs_tcp_shutdown+832>:       mtctr   r12
  0xd000000003df0ae4 <xs_tcp_shutdown+836>:       bctr

And the "std r2,24(r1)" corrupts the caller's stack.

This stub makes sense for a normal call, because the stack would be
owned by the caller of the stub, so it's ok to write r2 to it.  But
because this is a sibling call, the stack has been restored and r2 gets
incorrectly saved to the original caller's stack (i.e., xprt_autoclose's
stack).

So xprt_autoclose() -- which is in the sunrpc module -- gets the
livepatch module's toc pointer written to its stack.  It panics on when
it tries to use that vlue on its very next call.

Fix it by disallowing sibling calls from patched functions on ppc64le.

In theory we could instead a) generate a custom stub, or b) modify the
kernel livepatch_handler code to save/restore the stack r2 value, but
this is easier for now.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-23 11:11:23 -05:00
Josh Poimboeuf
33d174669b
Merge pull request #1005 from joe-lawrence/ppc64le-new_symbols
kpatch-build: remove localentry info from ppc64le new_symbols file
2019-07-23 08:14:24 -05:00
Joe Lawrence
3ff1af2151 kpatch-build: remove localentry info from ppc64le new_symbols file
Apply a sed filter to remove "[<localentry>: 8] " info from
readelf --wide --symbols output.  This ensures consistent column
data for the awk script creating the new_symbols file.

Fixes #994
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2019-07-22 22:55:10 -04:00
Josh Poimboeuf
62e09ed3e3 kpatch-build: Use rpmbuild --nodeps
The list of prerequsite RPMs which are needed to build the kernel RPM is
constantly growing.  But at least some of those RPMs aren't strictly
necessary for building the kernel, at least for kpatch-build's purposes.
Requiring them all to be installed is a bit overkill, and sometimes
causes kpatch-build to fail when it doesn't need to.

If the build does fail, we can always check the kpatch.log file and
update the dependencies listed in the README as needed.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-22 16:23:52 -05:00
Josh Poimboeuf
4f4870dd05 create-diff-object: Don't allow jump labels
Create an error if a patched function uses a jump label.  We need this
until upstream livepatch supports them with a .klp.arch section.

Fixes #946.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-17 09:03:17 -05:00
Josh Poimboeuf
7b367a4ef5 create-diff-object: Support dynamic debug on newer kernels
After Linux commit 47cdd64be483 ("dynamic_debug: refactor
dynamic_pr_debug and friends"), the name of the static local variable
used for dynamic printks is no longer "descriptor".

Make the is_special_static() check broader such that it doesn't care
about the variable name, and just whitelists any variable in the
__verbose section.

Fixes #990.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-15 18:20:21 -05:00
Josh Poimboeuf
b5745d7ea6 Add support for R_X86_64_PLT32
Starting with binutils 2.31, the Linux kernel may have R_X86_64_PLT32
relocations. Make sure we support them. This should be as simple as
treating R_X86_64_PLT32 exactly like R_X86_64_PC32 everywhere. For more
details see upstream commit torvalds/linux@b21ebf2.

This also fixes the following issue seen on Fedora 29:

```
$ kpatch-build/kpatch-build -t vmlinux ./test/integration/fedora-27/convert-global-local.patch
Using cache at /home/jpoimboe/.kpatch/src
Testing patch file(s)
Reading special section data
Building original source
Building patched source
Extracting new and modified ELF sections
ERROR: slub.o: 1 function(s) can not be patched
slub.o: function __kmalloc has no fentry/mcount call, unable to patch
/home/jpoimboe/git/kpatch/kpatch-build/create-diff-object: unreconcilable difference
ERROR: 1 error(s) encountered. Check /home/jpoimboe/.kpatch/build.log for more details.
```

Fixes #975.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-05 11:45:50 -05:00
Kamalesh Babulal
bb444c2168 create-diff-object: Check for *_fixup sections changes
Currently we do not support changes to functions referring to any of the
*_fixup sections on ppc64le. This patch introduces check for such
changes during the patchability check, where we abort building the
patch module.

This patch implements the phase 1 fix of 3 phases discussed at
https://github.com/dynup/kpatch/issues/974:
"
Phase 1 fix:

For kernel versions which don't have livepatch-specific powerpc code
(currently all kernel versions), kpatch-build needs to assert an error
if it detects that one of the following sections refers to a patched
function: __ftr_fixup, __mmu_ftr_fixup, __fw_ftr_fixup.
"

Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2019-06-25 14:46:55 +05:30
Kamalesh Babulal
09a5686277 create-diff-object: Add support for __spec_barrier_fixup
Add support for __spec_barrier_fixup (barrier nospec fixup) special
section on ppc64le.

Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2019-06-19 13:24:25 +05:30
Kamalesh Babulal
a2fb8719b7 create-diff-object: Fix lwsync group size
Fix the size of special group __lwsync_fixup on ppc64le.

Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2019-06-19 13:24:22 +05:30
Joe Lawrence
ff78bad23b kpatch-build: remove localentry data from ppc64le symtab
commit f8213c87f6 ("lookup: Fix format string for symtab_read() on
PPC64LE") fixed the symbol table lookup when readelf adds ppc64le
"[<localentry>: 8]" info for functions like so:

  23: 0000000000000008    96 FUNC    LOCAL  DEFAULT [<localentry>: 8]    4 cmdline_proc_show

however, it seems that readelf 2.30-57.el8 displays this in a slightly
different format:

  24493: c000000000587970    96 FUNC    LOCAL  DEFAULT    2 cmdline_proc_show    [<localentry>: 8]

Instead of adding more cases to kpatch-build's lookup.c scanf format,
let's just delete this information from the symtab file with a quick and
dirty sed regex.  This allows us to handle both observed cases (and
perhaps others) while removing the arch-specific scanf formatting in
lookup.c

Fixes: f8213c87f6 ("lookup: Fix format string for symtab_read() on PPC64LE")
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2019-06-12 10:56:06 -04:00
Joe Lawrence
288568653a
Merge pull request #970 from wwheart/master
kpatch-elf: fix Segmentation fault when d_type not set properly
2019-06-10 11:17:19 -04:00
Kamalesh Babulal
f8213c87f6 lookup: Fix format string for symtab_read() on PPC64LE
commit 767d9669bd ("kpatch-build: use readelf instead of eu-readelf")
replaced eu-readelf with readelf for constructing symbol table.  The
format of symbol table entries differs a little on Power when the symbol
is a function with binding type LOCAL.  For example, consider:

23: 0000000000000008    96 FUNC    LOCAL  DEFAULT [<localentry>: 8]    4 cmdline_proc_show

An extra column preceding index of the symbol denoting symbol value to
be local entry point offset of the function is printed, with the
current sscanf format string in lookup::symtab_read the values will
mismatch ending with in accurate lookup table getting constructed. This
patch fixes it by introducing an Power specific format string for
function symbols with bind type LOCAL.

Fixes: 767d9669 ("kpatch-build: use readelf instead of eu-readelf")
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2019-06-04 12:22:02 +05:30
chenzefeng
23c232d3c1 kpatch-elf: fix Segmentation fault when d_type not set properly
kpatch-elf::create_section_pair would create new rela section, and the
relasec->data->d_type is not set, which is a random value, and it will
use in kpatch-elf::kpatch_write_output_elf
	data->d_type = sec->data->d_type;
which would cause Segmentation fault in kpatch_write_output_elf::elf_update.

Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
0  0x00007ffff7bcd8d2 in __elf64_updatefile at elf64_updatefile.c
1  0x00007ffff7bc9bed in write_file at elf_update.c
2  0x00007ffff7bc9f16 in elf_update at elf_update.c
3  0x000000000040ca3d in kpatch_write_output_elf at kpatch-elf.c
4  0x0000000000409a92 in main at create-diff-object.c

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-06-03 11:29:59 +08:00
Joe Lawrence
0cdc2a3757
Merge pull request #965 from joe-lawrence/altinstr_replacement
kpatch-build: ensure that .altinstr_replacement section is included
2019-05-31 13:51:27 -04:00
chenzefeng
767d9669bd kpatch-build: use readelf instead of eu-readelf
readelf is more standard, using readelf insteaded we should solve there
issues:

First, using "readelf -s", the symbol name would truncated by 25 chars,
to solve this issue, add option "--wide".

Second, the size may be mixed of decimal and hex, we get the size by "%s",
and use strtoul(size, NULL, 0) to convert the size.

Third, the symbol type is SHN_UNDE, the Ndx display "UND", so changed to
compare with "UND".

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-05-28 20:36:45 +08:00
Joe Lawrence
13b0014671 kpatch-build: ensure that .altinstr_replacement section is included
.altinstr_replacement section may have relocation symbols which need to
be included, therefore we should call kpatch_include_symbol() to ensure
that its section is included as well.

The special section processing should also occur before
kpatch_print_changes() to provide accurate logging info.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2019-05-17 10:31:04 -04:00
Joe Lawrence
92b9c7d73b
Merge pull request #961 from kamalesh-babulal/shell_check
kpatch, kpatch-build: Use -n instead of ! -z
2019-05-15 10:23:38 -04:00
Joe Lawrence
d40ecd6835
Merge pull request #960 from wwheart/master
kpatch-elf: fix the unexpected elf class
2019-05-15 10:22:41 -04:00
Joe Lawrence
66dfd9ab5b
Merge pull request #958 from kirawrath/master
Making kpatch-build compatible with custom gcc names
2019-05-15 10:21:38 -04:00
chenzefeng
3bfc85732d kpatch-elf: fix the unexpected elf classes
kpatch-elf::kpatch_write_output_elf will call the gelf_getclass()
to acquire the output elf's class. But the input parameter kelf->elf
is NULL, the gelf_getclass(kelf->elf) will return ELFCLASSNONE, not
the value we expect ELFCLASS32 or ELFCLASS64.

the gelf_getclass function code:
int
gelf_getclass (Elf *elf)
{
  return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class;
}

the gelf_newehdr fuction code:
void *
gelf_newehdr (Elf *elf, int class)
{
  return (class == ELFCLASS32
          ? (void *) INTUSE(elf32_newehdr) (elf)
          : (void *) INTUSE(elf64_newehdr) (elf));
}

Luckily, when we create a patch for x86_64 or powerpc64, if we pass the
ELFCLASSNONE for the function gelf_newehdr, it will return elf64_newehdr,
so don't cause the fault. But it's better to use the gelf_getclass(elf)
instead of gelf_getclass(kelf->elf).

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-05-15 14:10:47 +08:00
Kamalesh Babulal
13e03de0d4 kpatch, kpatch-build: Use -n instead of ! -z
make check using shellcheck version 0.6.0 suggests following
improvements:
In kpatch/kpatch line 160:
        if [[ ! -z "$checksum" ]] && [[ -e "$SYSFS/${modname}/checksum"]] ; then
              ^-- SC2236: Use -n instead of ! -z.

In kpatch-build/kpatch-build line 953:
[[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
   ^-- SC2236: Use -n instead of ! -z.

'-n' and '! -z' are used interchangeably across the scripts, let's use
'-n' consistently to check a non-empty string instead of using negation.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2019-05-12 21:26:45 +05:30
chenzefeng
b6e19c7795 create-diff-object: fix the condition for the sections changed
The create-diff-object.c create intermediate ".kpatch.relocations"
sections instead of ".kpatch.dynrelas" sections, and add a new
section ".rela.kpatch.symbols", so we should update the conditions
in function kpatch_create_intermediate_sections for these changed.

Fixes: 87643703a7 ("create-diff-object: create .kpatch.relocations and .kpatch.symbols sections")

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-05-10 08:58:36 +08:00
Bruno Loreto
4c40c3ff4b Making kpatch-build compatible with custom gcc names
After changing the gcc name in a linux tree to gcc72, kpatch-build failed to
produce hotpatches with the error message "ERROR: no changed objects found."

This is due to a wrapper script called kpatch-gcc, called while kpatch-build
builds the kernel, which checks if the compiler name matches exactly gcc,
failing the check when comparing to gcc72, and thus not producing the expected
file changed_objs containing the list of changed objects.

This commit fixes this issue by loosening the check on the gcc name.

Signed-off-by: Bruno Loreto <loretob@amazon.com>
Reviewed-by: Bjoern Doebel <doebel@amazon.com>
Reviewed-by: Amit Shah <aams@amazon.com>
Reviewed-by: Pawel Wieczorkiewicz <wipawel@amazon.com>
2019-05-09 19:15:11 +02:00
chenzefeng
eb4f5833e0 kpatch-build: find_parent_obj should search subdirs
The kpatch-build :: find_parent_obj() function's "deep find" may
failed to find objects if they are not located in current directory:

	ERROR: invalid ancestor xxx/xxx.o for xxx/xxx.o.

This is reproducable when building an out-of-tree module of the
following structure:

	wwheart@linux41:~/helloworld 0 > tree -a
	.
	├── buffer_overflow1.ko
	├── .buffer_overflow1.ko.cmd
	├── buffer_overflow1.mod.c
	├── buffer_overflow1.mod.o
	├── .buffer_overflow1.mod.o.cmd
	├── buffer_overflow1.o
	├── .buffer_overflow1.o.cmd
	├── hello.c
	├── hello.o
	├── .hello.o.cmd
	├── Makefile
	├── modules.order
	├── Module.symvers
	├── test.patch
	├── .tmp_versions
	│   └── buffer_overflow1.mod
	└── xxx
	    ├── xxx.c
	    ├── xxx.h
	    ├── xxx.o
	    └── .xxx.o.cmd

	wwheart@linux41:~/helloworld 0 > cat test.patch
	diff --git a/xxx/xxx.c b/xxx/xxx.c
	index aab3c67..d81ad00 100644
	--- a/xxx/xxx.c
	+++ b/xxx/xxx.c
	@@ -1,6 +1,7 @@
	#include <linux/kernel.h>
	void czf_test(void)
	{
	+       printk("livepatch test\n");
		printk("xxx\n");
	}

	wwheart@linux41:~/helloworld 0 > cat Makefile
	obj-m += buffer_overflow1.o
	buffer_overflow1-y += hello.o xxx/xxx.o

Modify the deep find to traverse sub-directories in order to search
the entire tree instead of only the current directory.

Fixes: 8c2792af6c ("kpatch-build: deep find performance improvement")

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-05-07 15:41:18 +08:00
chenzefeng
7513db3c63 fix memleak in the create-klp-module.c
reason: The strdup() function returns a pointer to a new string
	which is a duplicate of the string s.  Memory for the
	new string is obtained with malloc, and can be freed
	with free.

	here, fix memleak by removing the strdup.

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-04-26 11:37:19 +08:00
Kamalesh Babulal
08a353bdcc lookup: Fix memleak in symtab_read()
Fix memory leak in symtab_read(), by removing the duplicate strdup()
of obj_syms.name.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2019-04-23 12:03:17 +05:30
chenzefeng
8e3ffbc8f6 create-diff-objject: fix memleak of the struct lookup_table
reason: Firstly, in the function lookup_open use the malloc to
	allocate some memory, but call the function lookup_close
	to free the memory.
	Secondly, table->obj_sym->name, table->exp_sym->name and
	table->exp_sym->objname used the strdup, so them should
	free also.
	Thirdly, adjust the order of make_nodname, if not, it
	will cause an exception when free(exp_sym->objname) in
	lookup_close.

Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-04-18 10:15:29 +08:00
chenzefeng
206db25c27 kpatch-build: fix memleak in function kpatch_write_output_elf
Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
2019-04-12 17:09:10 +08:00
Joe Lawrence
05b18e6d0a
Merge pull request #942 from joe-lawrence/oot-fixes
Out of tree module fixes
2019-03-25 15:57:13 -04:00
Josh Poimboeuf
09ee03f3df Revert "create-diff-object: add jump label support"
This reverts commit 87c64519fc.

The jump label support doesn't work with upstream livepatch.  Joe
Lawrence found the following ordering issue:

load_module

  apply_relocations

    /* Livepatch relocation sections are applied by livepatch */
    if (info->sechdrs[i].sh_flags & SHF_RELA_LIVEPATCH)
            continue;

  post_relocation
    module_finalize
      jump_label_apply_nops        << crash

  ...

  do_init_module
    do_one_initcall(mod->init)
      __init patch_init [kpatch-patch]
        klp_register_patch
          klp_init_patch
            klp_init_object
              klp_init_object_loaded
                klp_write_object_relocations

So jump_label_apply_nops() is called *before*
klp_write_object_relocations() has had a chance to write the klp
relocations (.klp.rela.kvm_intel.__jump_table, for example).

We need to resolve this upstream first.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-02-19 16:10:54 -06:00
Joe Lawrence
b4e6085b6d
Merge pull request #928 from haoren3696/master
kpatch-build: include secsym in kpatch_mark_ignored_sections
2019-02-19 13:24:42 -05:00
Joe Lawrence
fd9806b152 kpatch-gcc: use relative path when filtering objects to ignore
When building out-of-tree modules, gcc may be passed full source
pathnames (like /home/user/testmod/testmod.c).  Adjust the filepath
filtering in kpatch-gcc to match against files relative to the
KPATCH_GCC_SRCDIR / kpatch-build SRCDIR prefix.

Fixes: #941
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2019-02-15 10:10:24 -05:00
Josh Poimboeuf
87c64519fc create-diff-object: add jump label support
Add support for jump labels, also known as static jumps, static keys,
static branches, and jump tables.  Luckily,
kpatch_process_special_sections() is already generic enough to make this
an easy fix.

Fixes: #931

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-02-08 13:45:38 -06:00
Josh Poimboeuf
d8a44076f8 create-diff-object: cleanup special section array
Clean up the special section array a bit, to make it a little more
readable.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-01-29 13:04:09 -06:00
Balbir singh
3998784d71 Fix NULL pointer deref in main due to base_locals
For fun I tried to create a livepatch of upstream patch
ad211f3e94b314a910d4af03178a0b52a7d1ee0a for my kernel. This
caused kpatch-build to fail with a NULL pointer derefence because
base_locals was NULL (returned via kpatch_elf_locals(), which
can return a NULL pointer). This patch fixes the SIGSEGV
via a NULL check. The end result is a live patch is created
and loaded.

Signed-off-by: Balbir singh <bsingharora@gmail.com>
2019-01-17 19:53:46 +11:00
Zhipeng Xie
517e26a6cb kpatch-build: include secsym in kpatch_mark_ignored_sections
kpatch_mark_ignored_sections include .rodata.str1.1 section but does
not include its section symbol, causing its section symbol can not be
included any more in kpatch_include_standard_elements. After the
section symbol is freed in kpatch_elf_teardown, we got a segmentation
fault in kpatch_create_intermediate_sections.

Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
2018-11-23 10:50:21 +08:00
Joe Lawrence
f06f65666a
Merge pull request #925 from rudis/master
kpatch-build: abort on unsupported options GCC_PLUGIN_LATENT_ENTROPY,…
2018-11-14 11:15:16 -05:00
Paul Dagnelie
51a8fad34f Add support for building out-of-tree modules 2018-11-09 08:22:39 -08:00
Simon Ruderich
2441cdd7ba kpatch-build: abort on unsupported options GCC_PLUGIN_LATENT_ENTROPY, GCC_PLUGIN_RANDSTRUCT
Both generate randomly modified object files on each build. This breaks
comparing original and patched object file. See also #924.

Signed-off-by: Simon Ruderich <simon@ruderich.org>
2018-10-27 08:23:24 +02:00
Simon Ruderich
3cd2e1efd0 kpatch-build/kpatch-build: use command -v instead of which
Prevents the following shellcheck warning:

    In kpatch-build/kpatch-build line 583:
    which yumdownloader &>/dev/null || die "yumdownloader (yum-utils or dnf-utils) not installed"
    ^-- SC2230: which is non-standard. Use builtin 'command -v' instead.

Signed-off-by: Simon Ruderich <simon@ruderich.org>
2018-10-21 08:45:57 +02:00
Joe Lawrence
019c1fb3eb
Merge pull request #919 from jpoimboe/__FUNCTION__-special-static
create-diff-object: add __FUNCTION__ variables to the special static …
2018-10-18 09:46:03 -04:00
Joe Lawrence
3ac8b2e038
Merge pull request #917 from sm00th/addressable
Add "__addressable_" to maybe_discarded_sym().
2018-10-18 09:43:39 -04:00
Josh Poimboeuf
72103a178c create-diff-object: add __FUNCTION__ variables to the special static list
As discovered in #918, the `__FUNCTION__` static local variable is
similar to the `__func__` variable, in that it refers to the current
function name.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-10-17 21:08:30 -05:00
Artem Savkov
f959edecdb Move lookup_open() call to a later stage
Sometimes due to config-dependency issues or other reasons whole
object-files would get optimized out from final vmlinux/module, in cases
like this create-diff-object would fail during symbol lookup table
creation in lookup_open(). Because lookup_open() call is situated before
we established that objectfile has changed this triggers not only on
real problems, but also during mass-rebulds caused by changes to
header-files. While it usually indicates a real issue with config this
should not prevent kpatch from building.

Move lookup_open() call so that it is called only for changed
object-files.

Fixes #910

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-10-17 10:23:40 +02:00
Artem Savkov
c46191028e strdup symbol names from kelf_base
strdup symbol names in kpatch_elf_locals and when noting down hint
instead of just copying pointers so that they are still usable after
we teardown/free kelf_base.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-10-17 10:21:44 +02:00
Artem Savkov
722d27f6bd Add "__addressable_" to maybe_discarded_sym().
Starting with 1b1eeca7e4c1 "init: allow initcall tables to be emitted using
relative references" [1] __init functions are generating an "__addressable_"
symbol in a ".discarded.addressable" section so it does not show up in final
vmlinux triggering find_local_syms failures. Add "_addressable_" to the list
in maybe_discarded_sym().

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1b1eeca7e4c19fa76d409d4c7b338dba21f2df45

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-10-16 17:26:38 +02:00
Artem Savkov
f5679c9780 symtab_read: support entries with blank names
symtab_read() would previously skip entries with blank names resulting
in some of important entries being skipped. For instance vmlinux file
has an STT_FILE entry at the end with a blank name that contains global
offset table. Because it was skipped all of the global entries from this
table were considered a part of previous processed file resulting in
create-diff-object failing in find_local_syms().

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-09-20 16:06:29 +02:00
Artem Savkov
f7cfe25e8a symtab_read(): fix SECTION detection in symtab_read
symtab_read has been checking a wrong field for "SECTION". Switch the
field from "bind" to "type".

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-09-12 16:31:58 +02:00
Evgenii Shatokhin
0215587ad1 kpatch-build: ppc64le - fix a typo in find_special_section_data_ppc64le
Nothing critical, but find_special_section_data_ppc64le() could run
longer than needed: the exit condition was not met after all the values
had been found.

Fixes: 77f8fd09 "kpatch-build: ppc64le - Add special section support"
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2018-09-11 13:21:14 +03:00
Joe Lawrence
3a45a6ebb3
Merge pull request #900 from kamalesh-babulal/data_rel
create-diff-object.c: Extend is_bundleable()
2018-08-07 09:28:48 -04:00
Kamalesh Babulal
5b690b28bf create-diff-object.c: Extend is_bundleable()
GCC puts the constant variable requiring relocation into .data.rel. or
.data.rel.ro depending upon the bind type of the symbol. Extend
is_bundledable() to check these .data sections too.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2018-08-06 14:09:43 +05:30
Joe Lawrence
bc268c60e1 kpatch-build: update for RHEL / CentOS 8
- Future releases of RHEL / CentOS will provide the yumdownloader
  program with the 'dnf-utils' package (not 'yum-utils').  Instead of
  looking to see that the package is installed, just look for the
  program itself.

- RHEL / CentOS 8 kernel release names (as returned by 'uname -r') may
  not match the SRPM buildroot release subdirectory name.  Relax the
  wildcard when moving this directory to $SRCDIR.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-07-31 16:26:59 -04:00
Artem Savkov
19c4b52105 create-diff-object: -mcount-record support
4.18 adds -mcount-record to KBUILD_FLAGS when supported by the compiler.
This results in most of kpatch_create_mcount_sections()'s work being
already done, so we can at least skip the last part of it that updates
the first instruction in patched functions.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-26 16:51:24 +02:00
Lennert Buytenhek
932e0377bd kpatch-build: Ubuntu signed/unsigned kernel image package fix
In Ubuntu 18.04 LTS (but not in 16.04 LTS), the "linux" source package
no longer builds the "linux-image-*" binary kernel image packages
directly, but instead, it produces the "linux-image-unsigned-*" binary
packages, and the "linux-signed" source package then produces the
(signed) "linux-image-*" binary packages from the unsigned binaries.

This means that querying the target kernel's linux-image-* package for
its source package will yield a source package that is just a wrapper,
and does not actually contain the kernel source code.

Deal with this by removing the "-signed" substring from the kernel
source package name if it is present.  This makes kpatch-build work
on Ubuntu 18.04.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
2018-07-25 14:59:56 +03:00
Joe Lawrence
b974770197
Merge pull request #881 from sm00th/gcc8-opts
gcc8 fixes
2018-07-18 08:56:54 -04:00
Josh Poimboeuf
0655ca50b8 kpatch-build: fix clean_cache
Commit d86c1113cc ("kpatch-build: less aggressive clean_cache()")
broke clean_cache().  Instead of expanding the wildcard, it tries to
delete a file named '*'.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-07-17 15:43:43 -05:00
Artem Savkov
61839832ed create-diff-object: propagate ignore.functions to children
Add child symbols to .kpatch.ignore.functions in case their parents are
added to the list.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-13 09:39:26 +02:00
Artem Savkov
2ac1387701 create-diff-object: add .text.hot to the list of bundleable functions
According to gcc8's man pages gcc can put functions into .text.unlikely
or .text.hot subfunctions during optimization. Add ".text.hot" to the
list of bundleable functions in is_bundleable().

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-13 09:39:26 +02:00
Artem Savkov
35cc6ff016 create-diff-object: allow changing subsections
gcc8 can place functions to .text.unlikely and .text.hot subsections
during optimizations. Allow symbols to change subsections instead of
failing.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-13 09:39:21 +02:00
Artem Savkov
246c6e2ae7 create-diff-object: propagate child symbol changes
Propagate child symbol changes to it's parent.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-13 09:38:15 +02:00
Artem Savkov
73a278c2b6 create-diff-object: child symbol skips
Skip profiling calls checks for child symbols and don't include them in
output or .kpatch.funcs.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-11 09:57:54 +02:00
Artem Savkov
bd2589530c create-diff-object: add symbol relations
Add a function that would detect parent/child symbol relations. So far
it only supports .cold.* symbols as children.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-07-11 09:57:31 +02:00
Kamalesh Babulal
09fdb0772d create-diff-object: Relax sh_addralign check for .text sections
.text section addralign value might change between original and
patched .o files, for a loop() such as:

for (i = 0; i < sections_per_block; i++) {
	remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE);
	base += MIN_MEMORY_BLOCK_SIZE;
}

On ppc64le, which translate to:

  f0:   78 1b 7b 7c     mr      r27,r3
  f4:   6c 00 9d 40     ble     cr7,160 <pseries_remove_memblock+0x158>
  f8:   ff ff 9c 3b     addi    r28,r28,-1
  fc:   38 00 a1 fb     std     r29,56(r1)
 100:   00 01 bf 3f     addis   r29,r31,256
 104:   08 c2 9c 7b     rldic   r28,r28,24,8
 108:   14 ea 9c 7f     add     r28,r28,r29
 10c:   14 00 00 48     b       120 <pseries_remove_memblock+0x118>
 110:   00 00 00 60     nop
 114:   00 00 00 60     nop
 118:   00 00 00 60     nop
 11c:   00 00 00 60     nop
 120:   78 fb e4 7f     mr      r4,r31

.LVL174:
        rldic 28,28,24,8         #, tmp198, tmp196,
        add 28,28,29     # _45, tmp198, base
        .p2align 5,,31

Patch removing such loop, changes the section alignment boundary. Given
that alignment changes to .text section are not fatal, relax the check
for text sections.

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2018-07-04 08:41:00 +05:30
Joe Lawrence
4d1ee7f80a kpatch-build: fix RHEL-ALT kernel version detection
kpatch-build detects RHEL-ALT kernel support by looking for a ".el7a."
substring in the kernel release string.  Look for that substring in the
unchanged $ARCHVERSION instead of $KVER, which may not have the
trailing '.' character that our regex expects.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-06-20 10:37:05 -04:00
Joe Lawrence
bc28b576ed kpatch-build: drop architecture spec from source rpm request
Source RPMs don't have an architecture associated with them, so to avoid
confusion, drop that part of the kernel release string when calling
yumdownloader.

Fixes #887.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-06-20 10:15:49 -04:00
Joe Lawrence
7dc6e5f215
Merge pull request #886 from sm00th/safe_cleancache
kpatch-build: less aggressive clean_cache()
2018-06-19 09:30:07 -04:00
Joe Lawrence
d3ed66a103
Merge pull request #885 from rudis/shellcheck
kpatch-build: fix shellcheck warnings
2018-06-19 09:29:47 -04:00
Joe Lawrence
d0ced9760d
Merge pull request #884 from rudis/master
create-diff-object: prevent "'toc_data1' may be used uninitialized" warning
2018-06-19 09:29:24 -04:00
Joe Lawrence
123e7d5603
Merge pull request #883 from sm00th/awkfix
kpatch-build: fix find_special_section_data with blank AWK_OPTIONS
2018-06-19 09:29:02 -04:00
Joe Lawrence
89257f937e
Merge pull request #882 from joe-lawrence/kpatch-build-misc
kpatch-build misc fixups
2018-06-19 09:28:20 -04:00
Artem Savkov
d86c1113cc kpatch-build: less aggressive clean_cache()
Some of the provisioned machines I sometimes use don't have enough
diskspace for a full kpatch-patch build in home partition. I usually
solve this by symlinking .kpatch(and .ccache) dirs to a different
partition, however this only works with -s option because of
clean_cache().

clean_cache() currently removes .kpatch directory completely, recreating
it from scratch, change it to only remove the contents of the directory
instead.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-06-18 18:15:05 +02:00
Simon Ruderich
0acc62e1ce create-diff-object: prevent "'toc_data1' may be used uninitialized" warning
Building with GCC 7.3.0 on Debian sid fails with the following error:

    gcc -g -O2 -fdebug-prefix-map=/build/kpatch-0.6.0=. -fstack-protector-strong -Wformat -Werror=format-security -MMD -MP -I../kmod/patch -Iinsn -Wall -Wsign-compare -g -Werror -Wdate-time -D_FORTIFY_SOURCE=2  -c -c
    create-diff-object.c: In function 'kpatch_compare_correlated_rela_section':
    create-diff-object.c:316:20: error: 'toc_data1' may be used uninitialized in this function [-Werror=maybe-uninitialized]
    return toc_data1 == toc_data2;
           ~~~~~~~~~~^~~~~~~~~~~~
    create-diff-object.c:256:16: note: 'toc_data1' was declared here
    unsigned long toc_data1, toc_data2;
                  ^~~~~~~~~
    cc1: all warnings being treated as errors

This is a false positive as the code only compares those two values
after initializing them. But lets keep GCC happy.

Signed-off-by: Simon Ruderich <simon@ruderich.org>
2018-06-18 09:13:18 +02:00
Simon Ruderich
865a9e2c71 kpatch-build: fix shellcheck warnings
shellcheck 0.4.7 reported the following errors:

    [  "$1" = "$(echo -e "$1\n$2" | sort -rV | head -n1)" ]
                            ^-- SC1117: Backslash is literal in "\n". Prefer explicit escaping: "\\n".

    grepname="$grepname\.o"
                       ^-- SC1117: Backslash is literal in "\.". Prefer explicit escaping: "\\.".

    grep "undefined reference" "$LOGFILE" | sed -r "s/^.*\`(.*)'$/\1/" \
                                                                  ^-- SC1117: Backslash is literal in "\1". Prefer explicit escaping: "\\1".

Signed-off-by: Simon Ruderich <simon@ruderich.org>
2018-06-16 21:01:07 +02:00
Artem Savkov
fda7c87a70 kpatch-build: fix find_special_section_data with blank AWK_OPTIONS
If $AWK_OPTIONS are blank gawk would treat "" as a blank script
resulting in none of the special struct being detected.

Fixes: 1330dcc "create-diff-object: add ORC section support"
Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-06-15 14:19:11 +02:00
Joe Lawrence
1f4551a49e kpatch-build: add exit status enum
Convert magic exit status values into a common enum for clarity.

Suggested-by: Artem Savkov <asavkov@redhat.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-06-15 07:11:48 -04:00
Joe Lawrence
9f7c76b9c1 kpatch-build: add lib/ files to kpatch-gcc skip-list
None of the lib/* file are built with fentry calls, so we can't patch
them.  Add these files to the list that kpatch-gcc skips.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-06-13 13:53:19 -04:00
Joe Lawrence
dc6530f11c kpatch-build: clarify symbol-not-found msg find_local_syms()
Add a little more context ("in the vmlinux symbol table") to the
symbol-not-found message in find_local_syms().

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-06-13 13:53:19 -04:00
Joe Lawrence
391c9875ee kpatch-build: change FILE symbol not found to warning
Change the "FILE symbol not found in base. Stripped?" (fatal) error
message into a warning.  These crop up whenever a change is made to an
assembly file.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-06-13 13:52:34 -04:00
Joe Lawrence
63582367f4
Merge pull request #879 from jpoimboe/orc
create-diff-object: add ORC section support
2018-06-12 11:04:46 -04:00
Josh Poimboeuf
1330dcc43d create-diff-object: add ORC section support
Finally add support for processing the ORC unwinder sections.

The ORC unwinder sections are more special than the other special
sections, so they need their own dedicated function to process them,
though the code is similar to kpatch_regenerate_special_sections().

BTW, upstream livepatch still doesn't support the ORC unwinder.  That
change will be coming soon (probably Linux 4.19).

Fixes #785.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-06-11 17:41:54 -05:00
Balbir singh
8ef31a0e92 trivial: __powerpc__ should be __powerpc64__
Since the codeset supports just the 64 bit variant, lets move
to __powerpc64__ and use it. I checked the ABI doc as well
and the kernel/gcc.

Signed-off-by: Balbir singh <bsingharora@gmail.com>
2018-06-07 17:33:06 +10:00
Joe Lawrence
a8133b1dc3
Merge pull request #873 from jpoimboe/detect-truncated-Module.symvers
kpatch-build: detect truncated Module.symvers
2018-06-04 16:07:42 -04:00
Joe Lawrence
014a7dd48d
Merge pull request #871 from jpoimboe/symtab-fix
lookup: don't add undefined symbols to the lookup table
2018-06-04 13:59:07 -04:00
Josh Poimboeuf
f32363e634 kpatch-build: don't do "make mrproper" on every build
As discussed in #848, there is no known reason to do "make mrproper" on
every build.  It seems to be an artifact from previous iterations (we
used to use 'O=' to build the kernel in a separate object tree.

It has many downsides:

- massive performance degradation
- breaks the '-t' option
- prevents the user from manually saving/restoring ~/.kpatch

Only do it where it's really needed, which is after first extracting the
source from an RPM.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-06-02 16:08:38 -05:00
Josh Poimboeuf
30c37847e1 kpatch-build: detect truncated Module.symvers
"make mrproper" combined with the '-t' flag is dangerous, as it results
in the Module.symvers file getting truncated, which causes
create-diff-object to create some funky dynrelas.  Detect this condition
in kpatch-build and error out.

We will hopefully also be removing "make mrproper" soon, which will make
'-t' even more useful.

Fixes #589.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-06-02 16:04:30 -05:00
Josh Poimboeuf
a310e9e82e kpatch-build: get Fedora .config from configs dir
In recent versions of Fedora, when building from a source RPM,
kpatch-build fails because it can't find the .config file.  Get the file
from the canonical location: the configs subdirectory.

This also works with older versions of Fedora and RHEL, and ensures we
always have the right config file for the arch we're building for.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-06-02 15:22:39 -05:00
Josh Poimboeuf
1ad9cefbcf lookup: don't add undefined symbols to the lookup table
Before we were adding the undefined symbols to the lookup table, but we
were skipping them by setting the sym.skip flag.

With 3aa5abb807 ("kpatch-build: use symbol table instead of kobject"),
the skip flag was removed but the undefined symbol check was removed
with it.

The skip flag can remain gone.  Instead of adding undefined symbols to
the table and skipping them when iterating the table, just don't add
them to start with.

Also make the sscanf conditional lines identical, to ease maintenance.

Fixes #869.

Fixes: 3aa5abb807 ("kpatch-build: use symbol table instead of kobject")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-06-02 13:37:37 -05:00
Josh Poimboeuf
d04f5723bc kpatch-build: RHEL kernel-alt support
Deal with a few RHEL kernel-alt quirks for ppc64le:

- The RPM and spec names are "kernel-alt".

- 7.6 ALT is based on 4.14 but it doesn't have the 'immediate' flag.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-06-01 22:15:52 -05:00
Josh Poimboeuf
a7c413d4e9
Merge pull request #856 from sm00th/unlikely-cold
create-diff-object: ignore .cold.* suffixes in is_bundleable()
2018-05-31 09:25:28 -05:00
Joe Lawrence
27accf46ee
Merge pull request #857 from joe-lawrence/local-symbols
create-klp-module: group .kpatch.symbols with like-scope
2018-05-30 14:16:40 -04:00
Joe Lawrence
ace1e2cbf6
Merge pull request #849 from sm00th/cdo-symtab
create-diff-object symtab
2018-05-30 14:15:43 -04:00
Joe Lawrence
a879d1f3ea
Merge pull request #859 from jpoimboe/ppc-TOC
create-diff-object: don't convert .TOC. references to dynrelas
2018-05-30 14:09:02 -04:00
Artem Savkov
019c029830 Add .cold. to mangled functions check
gcc8 introduces ".cold." optimization symbols that have arbitrary
trainling numbers in their names just like ".isra." and others.
Add ".cold." to a condition in kpatch_rename_mangled_functions()

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-05-30 19:20:18 +02:00
Kamalesh Babulal
3ba9a145e9 gcc-plugin: Include additional header for GCC 8
plugin compilation fails on GCC 8:

In file included from gcc-plugins/gcc-common.h:100,
                 from gcc-plugins/ppc64le-plugin.c:1:
/usr/lib/gcc/powerpc64le-linux-gnu/8/plugin/include/attribs.h: In function ‘tree_node* canonicalize_attr_name(tree)’:
/usr/lib/gcc/powerpc64le-linux-gnu/8/plugin/include/attribs.h:118:11: error: ‘get_identifier_with_length’ was not declared in this scope
    return get_identifier_with_length (s + 2, l - 4);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-linux-gnu/8/plugin/include/attribs.h:118:11: note: suggested alternative: ‘get_attr_min_length’
    return get_identifier_with_length (s + 2, l - 4);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~
           get_attr_min_length
Makefile:34: recipe for target 'gcc-plugins/ppc64le-plugin.so' failed

get_identifier_with_length() is defined under stringpool.h, include this
header file for GCC 8, before including attribs.h

Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
2018-05-30 19:39:48 +05:30
Josh Poimboeuf
7023c239b1 create-diff-object: don't convert .TOC. references to dynrelas
When I made a patch to the nfsd module on a ppc64le system with a RHEL 7
based kernel, livepatch prevented the target module from loading with:

  livepatch: symbol '.TOC.' not found in symbol table

References to this symbol are treated specially by the kernel module
loader, so references to it should never be converted to dynrelas.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-05-30 08:59:54 -05:00
Artem Savkov
8927b57509 create-diff-object: ignore .cold.* suffixes in is_bundleable()
While building a gcc-consprop patch from integration tests gcc8 would place a
__timekeeping_inject_sleeptime.constprop.18.cold.27 symbol into
.text.unlikely.__timekeeping_inject_sleeptime.constprop.18 section. Because
section name doesn't have the '.cold.27' suffix this symbol fails
is_bundleable() check while still being bundleable and later exits early in
kpatch_rename_mangled_functions() without renaming the corresponding patched
function. All of this results in a create-diff-object errror:

  ERROR: timekeeping.o: symbol changed sections: __timekeeping_inject_sleeptime.constprop.18.cold.27
  /home/asavkov/dev/kpatch/kpatch-build/create-diff-object: unreconcilable difference

Fix by ignoring .cold.* name suffix in is_bundleable() for.text.unlikely
sections.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-05-30 10:15:10 +02:00
Joe Lawrence
de10550fae create-klp-module: group .kpatch.symbols with like-scope
From Oracle's Linker and Libraries Guide [1]:

"The symbols in a symbol table are written in the following order ...
The global symbols immediately follow the local symbols in the symbol
table. The first global symbol is identified by the symbol table sh_info
value. Local and global symbols are always kept separate in this manner,
and cannot be mixed together."

[1] https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter6-79797/index.html

Fixes #854.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-05-29 15:30:39 -04:00
Josh Poimboeuf
3d04265899 create-klp-module: Properly align merged .parainstructions sections
When a patch is composed of multiple .o files which have
.parainstructions sections, loading the patch causes a panic:

  general protection fault: 0000 [#1] SMP
  Modules linked in: livepatch_4_9_88_1_20180518_1(OK+) livepatch_4_9_88_1_20180510_1(OK) ...
  CPU: 1 PID: 17257 Comm: insmod Tainted: G           O  K 4.9.0-6-amd64 #1 Debian 4.9.88-1
  Hardware name: HP ProLiant MicroServer Gen8, BIOS J06 11/02/2015
  task: ffff9ff3411a4480 task.stack: ffffac8f8271c000
  RIP: 0010:[<ffffffff8ae2e1d0>]  [<ffffffff8ae2e1d0>] apply_paravirt+0xc0/0x140
  RSP: 0018:ffffac8f8271f9a0  EFLAGS: 00010216
  RAX: 00010749ffffffff RBX: ffffffffc0940658 RCX: 0000000000000085
  RDX: 00000000bfebfbff RSI: ffffac8f8271f9a2 RDI: 0000000000000246
  RBP: ffffac8f8271f9a2 R08: 0000000000000085 R09: ffffffff8ae5acb0
  R10: 0000000000000001 R11: ffff9ff3544b4400 R12: ffffffffc0940660
  R13: 0000000000000000 R14: ffff9ff3544b49c0 R15: ffff9ff3b43f0800
  FS:  00007f04c1cea700(0000) GS:ffff9ff3ca640000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 0000560cfd63e460 CR3: 00000001455c6000 CR4: 0000000000160670
  Stack:
   401f0ff889486973 6172007172006b00 746c00650031312e 007265746e655f69
   74006e6f69007870 ffffac8f006e6f69 00ffac8f8271fa28 ffffffff8b13ae86
   ffffac8f8271fa68 ffffffffc09471ec ffffffff8b7da9eb 0000000affffffff
  Call Trace:
   [<ffffffff8b13ae86>] ? vsscanf+0x4c6/0x800
   [<ffffffff8b13b20e>] ? sscanf+0x4e/0x70
   [<ffffffff8ae52be5>] ? arch_klp_init_object_loaded+0x105/0x130
   [<ffffffff8b13b0be>] ? vsscanf+0x6fe/0x800
   [<ffffffff8b13b20e>] ? sscanf+0x4e/0x70
   [<ffffffff8aee29e8>] ? klp_init_object_loaded+0xf8/0x210
   [<ffffffff8aee2d85>] ? klp_register_patch+0x285/0x390
   [<ffffffffc09491fa>] ? patch_init+0x1fa/0x1000 [livepatch_4_9_88_1_20180518_1]
   [<ffffffffc0949000>] ? 0xffffffffc0949000
   [<ffffffff8ae0218e>] ? do_one_initcall+0x4e/0x180
   [<ffffffff8afc87dd>] ? __vunmap+0x6d/0xc0
   [<ffffffff8afc87dd>] ? __vunmap+0x6d/0xc0
   [<ffffffff8af7eaa1>] ? do_init_module+0x5b/0x1ed
   [<ffffffff8af025a6>] ? load_module+0x2596/0x2ab0
   [<ffffffff8aefed50>] ? __symbol_put+0x60/0x60
   [<ffffffff8af02d06>] ? SYSC_finit_module+0xc6/0xf0
   [<ffffffff8ae03b7d>] ? do_syscall_64+0x8d/0xf0
   [<ffffffff8b41244e>] ? entry_SYSCALL_64_after_swapgs+0x58/0xc6
  Code: 8d 7c 05 00 e8 62 f7 ff ff 0f b6 53 f9 48 8b 7b f0 48 89 ee e8 f2 f8 ff ff 49 39 dc 76 57 44 0f b6 43 09 41 80 f8 ff 75 84 0f 0b <48> 8b 10 48 8d 7d 08 48 83 e7 f8 48 89 55 00 89 ca 48 8b 74 10
  RIP  [<ffffffff8ae2e1d0>] apply_paravirt+0xc0/0x140
   RSP <ffffac8f8271f9a0>
  ---[ end trace 128c0fa6efe85d9e ]---

The panic is caused by a corrupt .klp.arch.vmlinux..parainstructions
section:

Relocation section [208] '.rela.klp.arch.vmlinux..parainstructions' for section [207] '.klp.arch.vmlinux..parainstructions' at offset 0x29dc78 contains 10 entries:
  Offset              Type            Value               Addend Name
  000000000000000000  X86_64_64       000000000000000000    +750 __get_user_pages
  0x0000000000000010  X86_64_64       000000000000000000    +823 __get_user_pages
  0x0000000000000020  X86_64_64       000000000000000000    +890 __get_user_pages
  0x0000000000000030  X86_64_64       000000000000000000    +941 __get_user_pages
  0x0000000000000040  X86_64_64       000000000000000000   +1631 __get_user_pages
  0x0000000000000050  X86_64_64       000000000000000000   +1671 __get_user_pages
  0x000000000000005c  X86_64_64       000000000000000000   +1245 handle_userfault
  0x000000000000006c  X86_64_64       000000000000000000   +1340 handle_userfault
  0x000000000000007c  X86_64_64       000000000000000000   +1417 handle_userfault
  0x000000000000008c  X86_64_64       000000000000000000   +1717 handle_userfault

The entries are supposed to be 16 bytes each, but notice they become
misaligned starting with the 'handle_userfault' entry.

This happens because the kernel linking process lies about the
.parainstructions section size, underreporting it by four bytes.  So
when two .parainstructions sections are merged together, it results in a
corrupted .klp.arch.vmlinux..parainstructions section.

Fix it by properly aligning the section before merging it with another
one.

Fixes #852.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-05-18 16:11:41 -05:00
Artem Savkov
3aa5abb807 kpatch-build: use symbol table instead of kobject
create-diff-object doesn't really need the full kernel object file as
input. All it requires is a symbol table. Switch to using "eu-readelf -s"'s
output instead of object files. This will enable us to cover more cases
in unit tests.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-05-18 09:24:40 +02:00