In commit [1], kpatch added support for function padding,
and CONFIG_CFI_CLANG, which hardcoded a value of 16 for
the prefix size.
In some cases, the padding around __cfi prefixed functions can
vary. For example, in Photon OS 5.0, the __cfi prefix
size is modified in a patch for the gcc RAP plugin [2].
Since we have read the prefix size anyways, we can use it
instead of hardcoding.
Ref:
1. 3e54c63b17
2. https://github.com/vmware/photon/blob/5.0/SPECS/linux/secure/gcc-rap-plugin-with-kcfi.patch
Signed-off-by: Brennan Lamoreaux <brennan.lamoreaux@broadcom.com>
The __mcount_loc section contains the addresses of patchable ftrace
sites which is used by the ftrace infrastructure in the kernel to create
a list of tracable functions and to know where to patch to enable
tracing of them. On some kernel configurations, section is called
__patchable_function_entries and is generated by the compiler. Either of
__mcount_loc or __patchable_function_entries is recognised by the kernel
but for these configurations, use __patchable_function_entries as it is
what is expected.
The x86_64 arch is special (of course). Unlike other arches (ppc64le
and aarch64) a x86_64 kernel built with -fpatchable-function-entry will
generate nops AND create rela__patchable_function_entries for functions even
marked as notrace. For this arch, always create __mount_loc sections and
rely on __fentry__ relocations to indicate ftrace call sites.
Note: this patch is a refactoring of original code by Pete Swain
<swine@google.com> for aarch64. At the same time, this version squashes
several follow up commits from him and zimao <zimao@microsoft.com>. The
intent is minimize the eventual changeset for aarch64 support now that
other arches are making use of __patchable_function_entries sections.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Kernel v6.2+ commit bea75b33895f ("x86/Kconfig: Introduce function
padding") added 16 bytes of NOP padding in front of each function.
For objects built with --function-sections, this means that function
symbols no longer sit at the beginning of their respective ELF sections,
but 16 bytes offset.
In the same release, kernel v6.2+ commit 9f2899fe36a6 ("objtool: Add
option to generate prefix symbols") adds ELF function symbols with
prefix "__pfx_" to indicate the start of a function, inclusive of
NOP-padding.
For example:
$ objdump -Dr -j.text.cmdline_proc_show fs/proc/cmdline.o
...
Disassembly of section .text.cmdline_proc_show:
0000000000000000 <__pfx_cmdline_proc_show>:
0: 90 nop
1: 90 nop
2: 90 nop
3: 90 nop
4: 90 nop
5: 90 nop
6: 90 nop
7: 90 nop
8: 90 nop
9: 90 nop
a: 90 nop
b: 90 nop
c: 90 nop
d: 90 nop
e: 90 nop
f: 90 nop
0000000000000010 <cmdline_proc_show>:
10: e8 00 00 00 00 callq 15 <cmdline_proc_show+0x5>
11: R_X86_64_PLT32 __fentry__-0x4
15: 55 push %rbp
16: 48 8b 35 00 00 00 00 mov 0x0(%rip),%rsi # 1d <cmdline_proc_show+0xd>
19: R_X86_64_PC32 saved_command_line-0x4
1d: 48 89 fd mov %rdi,%rbp
20: e8 00 00 00 00 callq 25 <cmdline_proc_show+0x15>
21: R_X86_64_PLT32 seq_puts-0x4
25: 48 89 ef mov %rbp,%rdi
28: be 0a 00 00 00 mov $0xa,%esi
2d: e8 00 00 00 00 callq 32 <cmdline_proc_show+0x22>
2e: R_X86_64_PLT32 seq_putc-0x4
32: 31 c0 xor %eax,%eax
34: 5d pop %rbp
35: e9 00 00 00 00 jmpq 3a <cmdline_proc_show+0x2a>
36: R_X86_64_PLT32 __x86_return_thunk-0x4
Kpatch-build needs to gracefully handle NOP-padding when it is present.
At the same time, it should include "__pfx_<function>" symbols when
their respective functions change, but not treat prefix such functions
as first-class functions.
This also adds support for CONFIG_CFI_CLANG, which also creates prefixed
symbols with the name "__cfi_<function>".
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Kernel v6.2+ commit de3d098dd1fc ("powerpc/64: Add module check for ELF
ABI version") now verifies the ELF header e_flags for its ABI value and
refuse to load modules with complaint, "Invalid module architecture in
ELF header: 21"
Like other ELF header details, copy the flags from the reference ELF
input file to the new ELF file to avoid module load errors.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
While gcc puts strings in .strtab and .shstrtab sections,
llvm toolchain just uses .strtab.
Adapt kpatch to handle both styles.
Signed-off-by: Pete Swain <swine@google.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [small changes]
* 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>
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>
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>
Symbol indexes over 64k don't fit into st_shndx and are stored in
extended symbol table. Make sure we properly handle these cases. It is
not normally useful during kpatch builds but will come up if we start
diffing linked objects.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
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]
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
- convert section/symbol indexes and rela->offset to unsigned int as I
couldn't find any way for them to become negative.
- cast a number of rela->addend comparisons to int (assuming an 64bit
system this should be enough)
- a number of simple for-loop counter conversions to the type it
compares against
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Valgrind complains about uninitialized bytes passed to pwrite64(buf)
from kpatch_write_output_elf()'s call to elf_update():
==32378== Syscall param pwrite64(buf) points to uninitialised byte(s)
==32378== at 0x5141A03: __pwrite_nocancel (in /usr/lib64/libc-2.23.so)
==32378== by 0x4E46846: ??? (in /usr/lib64/libelf-0.168.so)
==32378== by 0x4E42B88: elf_update (in /usr/lib64/libelf-0.168.so)
==32378== by 0x40C57A: kpatch_write_output_elf (kpatch-elf.c:895)
==32378== by 0x40926F: main (create-diff-object.c:2851)
==32378== Address 0x28d52300 is 0 bytes inside a block of size 56 alloc'd
==32378== at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
==32378== by 0x40B86A: create_section_pair (kpatch-elf.c:707)
==32378== by 0x406CAE: kpatch_create_patches_sections (create-diff-object.c:2109)
==32378== by 0x4090C5: main (create-diff-object.c:2815)
These are fields which we don't need to populate (like a
funcs[index].new_addr value that will be filled by relocation). The
easiest way to appease valgrind and not clutter the code is to just
zero-out this entire buffer on allocation.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
kpatch-elf.c is used by binaries other than create-diff-object, but
create-diff-object is the only one that cares about "bundling". Move
the bundling to create-diff-object.
Fixes#700.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
With gcc-6 the function prologue is changeg by
moving the toc base resolution func - 0x8 bytes:
.globl my_func
.type my_func, @function
.quad .TOC.-my_func
my_func:
.reloc ., R_PPC64_ENTRY ; optional
ld r2,-8(r12)
add r2,r2,r12
.localentry my_func, .-my_func
Add support for function prologue, along with gcc-5.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
This patch adds support for livepatch hook based module
creation for PPC64le. It introduces PPC64le architecture
bits:
- Add relocation type of R_PPC64_ADDR64 while parsing powerpc ELF.
- Introduce .toc sections mainpulation.
- Skip kpatch specific details for livepatch hook.
Also remove the definition of rela_insn() for powerpc. The only
call site is been guarded by #ifdef x86.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
symbol->has_fentry_call is x86 specfic. Rename it to more
generic name, representing the general idea of calling
profiling function at function entry.
This patch converts all instance of symbol->has_fentry_call
to symbol->has_func_profiling and also renames functions:
kpatch_check_fentry_calls() -> kpatch_check_func_profiling_calls()
kpatch_find_fentry_calls() -> kpatch_find_func_profiling_calls()
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
SUSE-based kernels have a DWARF unwinder, so they build with the gcc
'-fasynchronous-unwind-tables' flag, which adds .eh_frame and
.eh_frame_hdr sections. Treat those sections like the other debug
sections.
Fixes: #703
If there exist multiple sections with the same name (which can happen when
using the --unique option with ld, which will be used to keep multiple
(per-object) .parainstructions and .altinstructions sections separate),
find_section_by_name() will only return the first section name match, which
leads to incorrect base section assignments for rela sections. Fix this by
using the sh_info field of the rela section to find its base section
instead, which contains the index of the section to which the relocation
applies.
Make sure sym->sec is not NULL before checking for its rela section
(sym->sec->rela). This fixes a case where an object may have STT_FUNC
symbols whose the sections (sym->sec) were not selected for inclusion (or
are located in another object) and hence these symbols do not have sym->sec
set. This corner case only recently popped up after reusing kpatch_elf_open()
on objects that have been outputted by create-diff-object (and these
objects only contain the necessary sections needed for the patch module).
This will also automatically exclude livepatch symbols from the check,
because they do not have sections associated with them (i.e., sym->sec is
NULL). We do not have to check for fentry calls for klp (SHN_LIVEPATCH)
symbols, because [1] they do not have sections associated with them, [2]
they are not the target functions to be patched, and [3] they are
technically just placeholder symbols for symbol resolution in livepatch.
Move functions kpatch_reindex_elements() and kpatch_rebuild_rela_section_data()
from create-diff-object.c to kpatch-elf.c. These functions will be used
to rebuild kpatch elf data in create-klp-module and create-kpatch-module,
i.e. during the second "phase" of kpatch-build.
Since is_bundleable() is only called once by kpatch_create_symbol_list(),
and no other kpatch-build tool will need to call this function, we can
simply make it static and local to kpatch-elf.c
Introduce a common kpatch elf api by moving all functions and struct
declarations related to manipulating kpatch_elf objects from
create-diff-object to kpatch-elf.{h,c}. Move logging macros to a separate
file log.h, and have kpatch-elf.h include it. These changes will generalize
the kpatch-elf and logging api and make it available to other kpatch-build
tools.