Commit Graph

459 Commits

Author SHA1 Message Date
Sumanth Korikkar
85344cf524 support ubsan for kpatch
ubsan generates .data..Lubsan_data* sections as follows:

1. int main(int argc, char **argv) {
        int arr[100];
        arr[101] = 1;
        printf("arr[101] = %d", arr[101]);
        return 0;
}

2. 1a:   50 10 b0 ac          st      %r1,172(%r11)
      int arr[100];
      arr[101] = 1;
1e:   a7 39 00 65             lghi    %r3,101
22:   c0 20 00 00 00 00       larl    %r2,22 <main+0x22>
            24: R_390_PC32DBL       .data..Lubsan_data1+0x2
28:   c0 e5 00 00 00 00       brasl   %r14,28 <main+0x28>
            2a: R_390_PLT32DBL      __ubsan_handle_out_of_bounds+0x2

3. 0000000000000000 <.data..Lubsan_data1>:
0: R_390_64     .rodata              <=== source_location.location->file_name
8: 00 00 00 04  .long   0x00000004   <=== source_location.location->line
c: 00 00 00 05  .long   0x00000005   <=== source_location.location->column

10: R_390_64    .data..Lubsan_type0   <== source_location->array_type
18: R_390_64    .data..Lubsan_type1   <=== source_location->index_type

4. Avoid correlating the *.data.Lubsan* sections. This means
   included function points to new *.data.Lubsan* sections.

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
2023-03-02 17:31:09 +01:00
Josh Poimboeuf
48854d5633 create-diff-object: rename "dynrela" -> "klp_reloc"
The term "dynrela" was invented before klp relocations ever existed.
They're basically the same thing: special livepatch-specific relocations
which get applied when the patched object gets loaded or patched.
They're necessary due to a) the need to access unexported symbols; and
b) late module patching.

The different names are confusing.  Consolidate them by replacing
"dynrela" with "klp_reloc" (code) or "klp relocation" (English).

Note there's still some antiquated code in the kpatch core module and in
the pre-4.7 klp patch template which still use the "dynrela" naming.
That code is mostly dead anyway so I've just left it alone.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-12-01 14:00:09 -08:00
Josh Poimboeuf
92c178b6a3 create-diff-object: use errx() instead of err()
Otherwise on recent distros it appends the errno to the error message,
like:

  create-diff-object: ERROR: x86.o: kpatch_regenerate_special_section: 2633: Found 1 unsupported static call(s) in the patched code. Use KPATCH_STATIC_CALL() instead.: Success

which is not what we want in most cases.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-11-30 12:58:31 -08:00
Josh Poimboeuf
f83218ad12 create-diff-object: detect unsupported static calls
Similar to jump labels, static calls aren't supported when the static
call key was originally defined in a module rather than in vmlinux.
Detect those cases and either remove them (in the case of tracepoints)
or error out.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-11-30 12:58:31 -08:00
Josh Poimboeuf
56bd8c4d0d create-diff-object: refactor jump label filtering
Convert the hard-coded should_keep_jump_label() to a proper callback,
since static calls will need a similar filter.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-11-30 12:58:31 -08:00
Josh Poimboeuf
87ad96760a create-diff-object: fix s390 special_section initializer spacing
Align the s390 special_section initializers to improve readability and
for consistency with the rest.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-11-30 12:58:31 -08:00
Josh Poimboeuf
901445a54f create-diff-object: fix __UNIQUE_ID() variable correlation
kpatch_mangled_strcmp() only ignores the digits after the period, but in
the case of __UNIQUE_ID(), the symbol names have random digits before
the period due to the use of `__COUNTER__`.  Make sure such symbols are
properly correlated.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-11-21 19:46:18 -08:00
Joe Lawrence
6507700d02
Merge pull request #1305 from joe-lawrence/llvm-from-swine
Collection of small llvm fixes
2022-10-04 10:06:23 -04:00
Pete Swain
85781b7ea7 create-diff-object: ignore .llvm.* sections
Clang FDO adds a new, ignorable ELF section, .llvm.call-graph-profile

Generalize to ignore all .llvm.*

Signed-off-by: Pete Swain <swine@google.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [subject line]
2022-09-27 15:56:06 -04:00
Pete Swain
3704057244 create-diff-object: ignore clang's .llvm_addrsig sections
Signed-off-by: Pete Swain <swine@google.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [subject line]
2022-09-27 15:56:06 -04:00
Longjun Luo
d46fea98ef kpatch-build: strengthen conditions for changed sections
If two sections want to be the same, they need to satisfy
two conditions:

1) the result of memcmp is zero, which means they
have the same content.

2) they have the same relocation entries.

In one specific situation, two sections have the same content.
But one section has relocation entries while the other one has
no relocation entries. For example, in X86, consider the
following code:

original code
```
__noreturn noinline int kpatch_func(void)
{
	while(1) {};
}
```

patched code
```
__noreturn notrace noinline int kpatch_func(void)
{
	asm(".byte 0xe8, 0x00, 0x00, 0x00, 0x00");
	while(1){};
}
```

Since the original code has a fentry call, these two functions have
the same compile result. But obviously, they are different functions.
Currently, kpatch would not find their differences since the patched
code has no relocation entries.

For the situation that one section has relocation entries while the
other one doesn't have, it should be set to be changed directly.

Cooperated-by: Zongwu Li <lizongwu@huawei.com>
Signed-off-by: Longjun Luo <luolongjuna@gmail.com>
2022-09-23 23:52:53 +08:00
Longjun Luo
9fac261ed0 kpatch-build: rela section could disappear after patched
After patched, rela information for some sections could
disappear. For example, a function like the following:

"
notrace noinline static int version_proc_show(struct seq_file *m,
    void *v)
{
    return 0;
}
"

Apart from common rela entries, trace and return thunk mechanism
will generate rela information. Use `notrace` to remove the
effect of trace. Make CONFIG_RETHUNK=n can remove the effect of
return thunk.

Discovered-by: Zongwu Li <lizongwu@huawei.com>
Signed-off-by: Longjun Luo <luolongjuna@gmail.com>
2022-09-21 10:10:41 +08:00
Nicolas Lorin
8cc0fedefb kpatch-build: use err.h instead of error.h for musl support 2022-08-05 08:52:03 +02:00
Jonathan Dobson
33368a88cd create-diff-object: add support for .return_sites section (x86) 2022-07-16 15:46:54 -06:00
Joe Lawrence
dc7e5cb03d
Merge pull request #1203 from sumanthkorikkar/s390x-kpatch-support
S390x kpatch support
2022-06-29 09:55:53 -04:00
Josh Poimboeuf
a1171b112e create-diff-object: Create missing section symbol
Recent toolchains only create a section symbol if it's needed, i.e. if
there's a reference to it.  If there's a missing section symbol in
kpatch_create_intermediate_sections(), create one instead of erroring
out.

Fixes #1272.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-06-07 20:31:10 -07:00
Sumanth Korikkar
b0330ab18e kpatch/s390: Add additional bundled symbols.
1. static const struct inet_sock fake_sk = {
	/* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */
	.sk.sk_bound_dev_if = 1,
	.pinet6 = (struct ipv6_pinfo *) &fake_pinfo,
};

gcc can place fake_sk in .data.rel.ro.local:
ndx 38, data 0x3ffb3280a58, size 960, name .data.rel.ro.local.fake_sk.1
ndx 39, data 0x3ffb32be5e8, size 24, name .rela.data.rel.ro.local.fake_sk.1

2. static LIST_HEAD(patch_objects);

gcc can place patch_objects relocation in .data.rel.local:
sym 56, type 1, bind 0, ndx 34, name patch_objects -> .data.rel.local

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
2022-05-20 15:50:29 +02:00
Sumanth Korikkar
f0d00a9290 kpatch/s390: Add initial support for kpatch
* Add s390 specific checks
* Identify patchable functions.
* Dont mark expolines as dynrelas. These expolines are always included
  in final kernel module. This ensures that expoline functions and the
  kernel itself are not too far apart and avoids out of range
  relocation. However, this isnt a problem for other functions, as these
  relocations are performed via R_390_PLT32DBL using gcc option
  -mno-pic-data-is-text-relative.
* s390 maintains expoline tables to locate the expoline thunks. If
  needed,  the module loader could later replace these expoline thunks
  with normal indirect branch. Each element in the expoline table is of 4
  bytes. If there is a changed function in rela.s390_return*, then mark
  that specific rela symbol as included. This is already performed in the
  processing of special sections. Hence include it.

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
2022-05-20 15:50:29 +02:00
Josh Poimboeuf
52863dace0 create-diff-object: fix endianness in kpatch_no_sibling_calls_ppc64le()
Otherwise it fails the unit tests on an s390 host.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-17 19:28:56 -07:00
Josh Poimboeuf
017015a725 create-diff-object: make kpatch_check_relocations() more precise
Use rela_target_offset() to make the relocation bounds checking more
precise.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-17 19:28:56 -07:00
Josh Poimboeuf
86d5208b46 create-diff-object: error on symbol conversion failure
If a section reference can't be converted to a symbol reference, error
out to try to prevent unexpected behavior later on.

There are a few sections for which a symbol is optional: .rodata and
string literal sections.  Don't warn about those.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-17 19:27:25 -07:00
Josh Poimboeuf
325bccd89d create-diff-object: skip conversion for sections which never have symbols
These sections don't have symbols.  Don't even try to replace references
to them with symbols.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:02:07 -07:00
Josh Poimboeuf
8508abd3b1 create-diff-object: allow converstion of empty symbols
Empty (zero-length) symbols are possible, allow
kpatch_replace_sections_syms() to work on them.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:02:07 -07:00
Josh Poimboeuf
8d5a628bde create-diff-object: add extra check for symbol conversion edge case
This issue was only seen in in a text section.  Explicitly check for
that.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:02:07 -07:00
Josh Poimboeuf
01427d50a1 create-diff-object: move addend math to a new function
Split out the addend offset math into a separate function so it can be
used elsewhere.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:02:04 -07:00
Josh Poimboeuf
bec6488af6 create-diff-object: add rela_insn() error check
Error out if the insn can't be found.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:26 -07:00
Josh Poimboeuf
6b1895a6b7 create-diff-object: convert rela_insn() to take normal 'sec'
rela_insn() only cares about the base section.  Convert it to take a
non-rela section as its argument instead of a relasec.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:26 -07:00
Josh Poimboeuf
bf212f7750 create-diff-object: error on unsupported rela in symbol conversion
Error out if an unsupported rela is encountered.  This is more robust
than just ignoring it.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:26 -07:00
Josh Poimboeuf
3f8e1062cc create-diff-object: support R_X86_64_NONE in kpatch_replace_sections_syms()
Add support for R_X86_64_NONE.  With an upstream kernel, it's quite
rare, only used for a few jump labels.  With older kernels it was used
for fentry hooks.  Either way, it should be treated like a PC-relative
relocation.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:26 -07:00
Josh Poimboeuf
79f45d1b0a create-diff-object: fix kpatch_replace_sections_syms() for non-text
It doesn't make sense to disassemble a data section.  That just happened
to work by accident.  PC-relative offsets only need adjusting when
associated with an instruction.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:26 -07:00
Josh Poimboeuf
61e46094b5 create-diff-object: convert function return types to 'bool'
Several functions have a boolean semantic, but don't actually return
bool, which is confusing.  Fix that.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:26 -07:00
Josh Poimboeuf
c24d135f40 create-diff-object: rename "sec" -> "relasec" for rela sections
Several functions expect to take a ".rela" section as an argument.  Make
such cases more clear by renaming "sec" -> "relasec".

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-05-11 17:00:25 -07:00
Josh Poimboeuf
ef8b270e4d
Merge pull request #1258 from jpoimboe/seg-fault
Fix seg fault caused by missing .LCx symbol
2022-04-07 09:31:52 -05:00
Josh Poimboeuf
c2e73c2cbc create-diff-object: ensure debug sections don't use dynrelas
Debug sections are intended to refer to the patch module only.  And in
fact, any debug section references to non-included symbols are stripped
in kpatch_include_debug_sections().  So there's no need for
need_dynrela() to even think about it.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-06 13:26:09 -07:00
Josh Poimboeuf
305ff8a5d8 create-diff-object: include .LCx string literal symbols
A seg fault was reported:

  Program received signal SIGSEGV, Segmentation fault.
  0x00007ffff7f18c8e in __strcmp_avx2 () from /lib64/libc.so.6
  Missing separate debuginfos, use: dnf debuginfo-install elfutils-libelf-0.186-1.fc34.x86_64 zlib-1.2.11-26.fc34.x86_64
  (gdb) bt
  #0  0x00007ffff7f18c8e in __strcmp_avx2 () from /lib64/libc.so.6
  #1  0x000000000040a0f7 in kpatch_is_core_module_symbol (name=0x0) at create-diff-object.c:3060
  #2  0x000000000040a267 in need_dynrela (kelf=0x4669a0, table=0x92af30, sec=0x6d6b20, rela=0x8c7fd0) at create-diff-object.c:3117
  #3  0x000000000040a4cc in kpatch_create_intermediate_sections (kelf=0x4669a0, table=0x92af30, objname=0x7fffffffcfc6 "vmlinux", pmod_name=0x7fffffffd020 "livepatch_a") at create-diff-object.c:3281
  #4  0x000000000040c7c5 in main (argc=8, argv=0x7fffffffca48) at create-diff-object.c:3931

It happened because 'rela->sym->name' was NULL, and
kpatch_is_core_module_symbol() tried to dereference it.

Here's the corresponding relocation:

  Relocation section [455] '.rela.debug_loclists' for section [454] '.debug_loclists' at offset 0xd0478 contains 2432 entries:
    Offset              Type            Value               Addend Name
    ...
    0x000000000000aad6  X86_64_64       000000000000000000     +32 .LC55
    ...

That '.LC55' symbol lives in the following section:

  [104] .rodata.btf_show_end_aggr_type.str1.8 PROGBITS     0000000000000000 00003ef0 00000021  1 AMS    0   0  8

The problem is that the symbol wasn't included in the output file
(though its corresponding section was).  So it got zeroed by
kpatch_elf_teardown(), which was designed to trigger seg faults to help
find bugs like this.

The string literal sections which hold the '.LCx' string symbols are
already being included.  Include their symbols as well.

Fixes #1257.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-06 13:26:09 -07:00
Josh Poimboeuf
b700732f5d create-diff-object: add "_printk" to the __LINE__ detection
The __LINE__ detection code looks for "printk", which on newer kernels
has been renamed to "_printk".  Fix the check for newer kernels.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-05 12:14:22 -07:00
Josh Poimboeuf
79fd60b28d create-diff-object: check arg2 and arg3 on all arches for line detection
For x86, we already check arg2 and arg3 for `__LINE__` immediate load
detection.  For parity, do the same thing for the other two arches.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-05 12:14:09 -07:00
Josh Poimboeuf
e6b1664d0e create-diff-object.c: add s390 support for __LINE__ detection
Technically we don't support s390 yet, but it's coming soon and there's
no harm in merging this one early.  In fact this came in handy for
testing my endian fixes with #1203.

Note it doesn't actually do anything since 'kelf->arch' can't actually
get set to 'S390' yet.  But it should work nicely with #1203 as it
evolves.

This is based on the patch from C. Erastus Toe in #1243, though there
may still be a few outstanding issues to look at in that PR, based on
some of the code review comments.

Originally-by: C. Erastus Toe <ctoe@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-04 21:13:49 -07:00
Josh Poimboeuf
a6920b9381 create-diff-object: fix endian issues in insn_is_load_immediate()
With s390 support coming, we'll soon have to worry about endianness
issues when doing cross-compiles and cross-arch unit tests.  Make
insn_is_load_immediate() endian-agnostic.

Suggested-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-04 21:13:49 -07:00
Josh Poimboeuf
1152e58244 create-diff-object: support __LINE__ detection for btrfs macros
These btrfs macros use the `__LINE__` macro.  Add proper support for
them in kpatch_line_macro_change_only().

   5:   ba 34 09 00 00          mov    $0x934,%edx
   a:   48 c7 c6 00 00 00 00    mov    $0x0,%rsi
                        d: R_X86_64_32S .rodata.__func__.5
  11:   4c 89 ef                mov    %r13,%rdi
  14:   e8 00 00 00 00          callq  19 <push_node_left.cold+0x19>
                        15: R_X86_64_PLT32      __btrfs_abort_transaction-0x4

Fixes #1253.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2022-04-04 21:12:58 -07:00
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