Commit Graph

419 Commits

Author SHA1 Message Date
Josh Poimboeuf
af672577b3 create-diff-object: use toc_rela() in kpatch_line_macro_change_only()
For ppc64le, if a rela goes through the .toc, it requires an extra level
of indirection.  Use toc_rela() here to ensure it gets the rela we care
about.  This will be needed for the upcoming patch which checks for
`__func__`.

For non-ppc64le arches, and for ppc64le relas which don't go through the
.toc, toc_rela() is a no-op which just returns the rela.  So this is
harmless for non-.toc cases.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-01 16:47:57 -07:00
Josh Poimboeuf
81296117f4 create-diff-object: unify kpatch_line_macro_change_only()
The arch-specific versions of kpatch_line_macro_change_only() are mostly
duplicate code.  Unify them into a single implementation.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-01 16:47:54 -07:00
Josh Poimboeuf
4ba6f1fbc9 create-diff-object: include __dyndbg section when referenced by jump table
If the only reference to the `__dyndbg` section is through a jump table
entry, the section doesn't get included and the jump table relocations
end up with a dangling reference to an UNDEF section symbol.

Make sure jump table referenced dynamic debug symbols get their sections
included.

Fixes #1253.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-03-31 21:37:28 -07:00
Bill Wendling
4c0e4898d9 create-diff-object: detect architecture from input ELF file
libelf can read and write various architecture ELF files that may
differ from the host system.  Instead of using preprocessor directives
to build architecture-specific code as per the current host, detect the
intended target architecture from the input ELF files.

Based-on: https://github.com/dynup/kpatch/pull/1179
Signed-off-by: Bill Wendling <morbo@google.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [small tweaks]
2022-02-02 17:36:19 -05:00
Joe Lawrence
394a907a37 create-diff-object: move kpatch_find_func_profiling_calls definition
The last part of kpatch_elf_open() calls kpatch_find_func_profiling_calls() to
find and set sym->has_func_profiling.  However, only create-diff-object.c
requires sym->has_func_profiling, so remove the call from
kpatch_elf_open() and let the lone user, create-diff-object, provide and
call it as needed.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2022-01-21 16:12:28 -05:00
Markus Boehme
c4286ee2cb create-diff-object: add support for .retpoline_sites section
Commit 134ab5bd1883 ("objtool,x86: Replace alternatives with .retpoline_sites")
in the kernel starts keeping track of retpoline thunk call sites in a
dedicated section rather than via the alternatives mechanism.

The .retpoline_sites section needs to have its entries and relocations
for changed symbols included in the patch ELF when building for kernel
5.16+ with CONFIG_RETPOLINE=y.

Signed-off-by: Markus Boehme <markubo@amazon.com>
2022-01-17 21:54:58 +01:00
David Vernet
9ee9f7a3ec kpatch-build: Add missing allocation failure checks
In kpatch-build, there are a number of places where a dynamic allocation
is performed, but the allocation is not checked for a failure. The
common pattern in kpatch-build is to check whether the returned pointer
is NULL, and if so, invoke the ERROR() macro to print a message and
abort the program.

kpatch_create_mcount_sections(), CORRELATE_ELEMENT(), and
create_klp_arch_sections() all had dynamic allocations without failure
checks. This diff adjusts those callsites to properly check for a failed
allocation, and ERROR() accordingly.

Signed-off-by: David Vernet <void@manifault.com>
2022-01-14 07:32:54 -08:00
Joe Lawrence
6c4c8c0a2d create-diff-object: update for __already_done
Upstream v5.14+ kernel change a358f40600b3 ("once: implement
DO_ONCE_LITE for non-fast-path "do once" functionality") consolidated a
bunch of do-once macros into a common macro:

  #define DO_ONCE_LITE_IF(condition, func, ...)				\
  	({								\
  		static bool __section(".data.once") __already_done;	\
  		...

which replaced static local variable __warned with __already_done.

Update any __warned static local checks to also look for the new
__already_done variable as well.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2021-12-08 11:05:31 -05:00
Joe Lawrence
4f51ee7fa3 create-diff-object: support ppc64le relative jump labels
RHEL-9 integration tests revealed that the kernel now makes use of
R_PPC64_REL64 relocations in the jump table, but need_dynrela() contains
code to specifically skip any R_PPC64_REL64 type when determining if a
relocation should be turned into dynrela.

Kamalesh Babulal explains:

  I tried digging a little deeper and the upstream Kernel commit
  b0b3b2c78ec (powerpc: Switch to relative jump labels) in v5.13,
  introduced the change of generating relocation entries of type
  R_PPC64_REL64, instead of absolute relocation type R_PPC64_ADDR64:

  Relocation section '.rela__jump_table' at offset 0x1a87d8 contains 303 entries:
      Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
  ...
  00000000000003c8  000007910000002c R_PPC64_REL64          0000000000000000 __tracepoint_netif_receive_skb + 8
  ...

Relax the existing check in need_dynrela() for .rela__jump_table
R_PPC64_REL64 relocations in case we need dynrelas for them.

Fixes: #1212
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2021-09-28 12:49:23 -04:00
Joe Lawrence
ef0ce9715a create-diff-object: fix use after free in kpatch-check-relocations()
Building data-read-mostly.patch on rhel-9.0-beta for ppc64le leads to a
segmentation fault:

    Program received signal SIGSEGV, Segmentation fault.
    kpatch_check_relocations (kelf=0x10040490) at create-diff-object.c:2571
    2571                                    sdata = rela->sym->sec->data;
    (gdb) bt
    (gdb) p rela->sym->sec->data
    Cannot access memory at address 0x160000007e

Valgrind narrows the problem down to invalid reads through rela->sym in
kpatch-check-relocations().

The culprits are kpatch_create_intermediate_sections(), which marks
symbols referenced by rela sections that are now dynrelas to be
stripped, and kpatch_strip_unneeded_syms(), which removes and frees
them.

The problem with the symbol stripping is that multiple relas may
reference the same ELF symbol.  If any remaining relocation references a
shared symbol, we must keep it.

Replace the symbol->strip boolean with an enumeration:

  SYMBOL_DEFAULT - initial value, symbol usage unknown
  SYMBOL_USED    - symbol is definitely used by a rela
  SYMBOL_STRIP   - symbol was only referenced by dynrela(s)

Allow transitions from SYMBOL_DEFAULT to SYMBOL_* and SYMBOL_STRIP to
SYMBOL_USED, but _not_ SYMBOL_USED to SYMBOL_*.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2021-09-14 22:54:09 -04:00
Artem Savkov
99542e864e create-diff-object: rename arguments in most correlate/compare functions
While theoretically most of these functions can work both ways right now
all calls follow the same pattern: first argument is orig element and
second is patched element. Rename the arguments so that these functions
are used in the same fashion going forward. This allows us to cut some
corners such as removing the elseif statement in kpatch_correlate_symbol().

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-08-17 09:37:44 +02:00
Artem Savkov
22e16619e0 create-diff-object: base->orig renames
Rename "base" to "orig" when referencing object files and their contents
to be consistent with temporary directory structure.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-08-17 09:37:44 +02:00
Artem Savkov
720768767d Switch to per-file lookup table pointers.
So far create-diff-object worked only with objectfiles built from a
single source file. To support object-files built from multiple sources
such as linked vmlinux.o, we call locals_match() for each of STT_FILE
symbols and store the pointer to the beginning of appropriate symbol
block in lookup table in each symbol.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-08-17 09:37:44 +02:00
Artem Savkov
db442d1405 Make lookup_symbol() accept struct symbol as an argument
At the moment lookup_symbol() takes symbol name as an argument which
might not be enough in some cases (e.g. for objectfiles built from
multiple source files). Make it accept full symbol structure.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-08-17 09:37:44 +02:00
Josh Poimboeuf
56471ffc7c kpatch-build: Support CONFIG_PRINTK_INDEX, part 2
For each printk() call site, CONFIG_PRINTK_INDEX makes a static local
struct named `_entry`, and then adds a pointer to it in the
`.printk_index` section.

When regenerating the `.printk_index` section for the patch module, we
only need to include those entries which are referenced by included
functions.  Luckily this is a common pattern already used by several
other "special" sections.  Add `.printk_index` to the special section
handling logic.

Fixes: #1206

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-08-11 08:47:04 -07:00
Josh Poimboeuf
6cf50a6fca create-diff-object: Support CONFIG_PRINTK_INDEX, part 1
CONFIG_PRINTK_INDEX creates a static local struct variable named
`_entry` for every call site to printk().  The initializer for that
struct assigns the `__LINE__` macro to one of its fields.

Similarly to the WARN macro's usage [1] of `__LINE__`, it causes
problems because it results in the line number getting directly embedded
in the struct.  If a line is added or removed higher up in the source
file, the `_entry` struct changes accordingly due to a change in the
printk() call site line number.

`_entry` is similar to other "special" static locals, in that we don't
need to correlate the patched version with the original version.  We can
instead just ignore any changes to it.

Any substantial (non-line-number) change to the `_entry` struct would be
a second-order (dependent) effect of a first-order code change, which
would be detected using other means.  In that case the patched version
of `_entry` will be included, due to being referenced by the changed
function.

Fixes: #1206

[1] See kpatch_line_macro_change_only()

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-08-11 08:46:32 -07:00
Josh Poimboeuf
ea0470baa7 create-diff-object: change kpatch_line_macro_change_only() return type to bool
Make kpatch_line_macro_change_only()'s usage more clear by changing its
return type to bool.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-08-10 13:56:58 -07:00
Artem Savkov
5622e3cc3d Make sure section symbols exist
Binutils recently became much more aggressive about removing unused
section symbols. Since we can not rely on those being available anymore
add additional checks before using them.

Fixes: #1193

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-07-13 17:40:58 +02:00
Bill Wendling
ba3defa060 create-diff-object: Check that the section has a secsym
A STT_SECTION symbol is not needed if if it is not used as a relocation
target. Therefore, a section, in this case a debug section, may not have
a secsym associated with it.

Signed-off-by: Bill Wendling <morbo@google.com>
2021-06-03 01:50:16 -07:00
Josh Poimboeuf
81f9ca4833 create-diff-object: Fix out-of-range relocation check
Improve the relocation check for the case where the referenced symbol
isn't at the beginning of the section.

Note that the check still isn't perfect, as many relocations have a
negative addend.  But it's still a lot better than nothing.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-04-13 14:04:54 -05:00
Josh Poimboeuf
fa5a95cafd create-diff-object: Fix out-of-range relocation error message
Showing sec+addend isn't valid, show sym+addend instead.

Before:

  create-diff-object: ERROR: sys.o: kpatch_check_relocations: 2550: out-of-range relocation .rodata.__kpatch_do_sys_uname.str1.1+139 in .rela.text.__kpatch_do_sys_uname

After:

  create-diff-object: ERROR: sys.o: kpatch_check_relocations: 2550: out-of-range relocation .LC7+139 in .rela.text.__kpatch_do_sys_uname

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-04-13 13:58:59 -05:00
Josh Poimboeuf
7be75549ba kpatch-build: add support for static calls
Add the new .static_call_sites special section.

Fixes #1165.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2021-03-24 10:37:44 -05:00
Artem Savkov
1b5a17f934 create-build-diff: support for .cold functions with no id suffix
create-build-diff expects .cold functions to be suffixed by an id, which
is not always the case. Drop the trailing '.' when searching for cold
functions.

Fixes: #1160

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-03-04 15:55:58 +01:00
Artem Savkov
6c83b642a4 create-diff-object: make digit tail optional in kpatch_mengled_strcmp
Make kpatch_mangled_strcmp treat two strings as the same in case when
one has a digit tail and the other one doesn't.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-02-19 12:41:12 +01:00
Artem Savkov
b6e1d071ff create-diff-object: consider '.L' symbols not static local
Make kpatch_is_normal_static_local() treat all symbols prefixed by '.L'
as not static locals.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-02-19 12:41:12 +01:00
Artem Savkov
fddc6242c6 create-diff-object: support both gcc and clang style of static variables
gcc-generated static variables always have a numbered suffix, while
clang-generated static variables are always prepended with a function
name. Change is_special_static() so that it detects both cases.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2021-02-19 12:41:09 +01:00
WANG Chao
aea2cb96d6 create-diff-object: fix __dyndbg section inclusion
__verbose has renamed to __dyndbg since Linux 5.9, commit e5ebffe18e5a
("dyndbg: rename __verbose section to __dyndbg")

Signed-off-by: WANG Chao <chao.wang@ucloud.cn>
2020-10-27 15:25:36 +08:00
Joe Lawrence
ef420050e3 kpatch-elf: pass new ELF output file mode to kpatch_write_output_elf()
Currently all the callers of kpatch_write_output_elf() are creating
.o object files or .ko kernel modules.  Neither of these filetypes are
executable on their own, so enhance kpatch_write_output_elf() to accept
file creation mode and update its callers to pass 0664 to match
the expected permissions.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2020-09-25 09:30:13 -04:00
Joe Lawrence
25f12681fa create-diff-object: cleanup maybe-uninitialized compiler complaints
User disaster123 reports the following build errors:

  create-diff-object.c: In function 'kpatch_process_special_sections':
  create-diff-object.c:2215:41: error: 'key' may be used uninitialized in this function [-Werror=maybe-uninitialized]
         code->sym->name, code->addend, key->sym->name);
                                           ^~
  create-diff-object.c:2138:22: note: 'key' was declared here
    struct rela *code, *key, *rela;
                        ^~~
  In file included from kpatch-elf.h:26,
                   from create-diff-object.c:53:
  log.h:20:3: error: 'code' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     printf(format, ##__VA_ARGS__); \
     ^~~~~~
  create-diff-object.c:2138:15: note: 'code' was declared here
    struct rela *code, *key, *rela;
                 ^~~~
  cc1: all warnings being treated as errors

These are reproducible when building with 9.3.1 and 8.3.1 when building
with optimization level > 2 ( CFLAGS=-O2 make ).  Fix them by
initializing the reported variables to NULL and verifying that they are
infact non-NULL after processing the __jump_table.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2020-09-09 14:28:44 -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
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
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
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
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
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
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