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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
.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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
"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>
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>
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>
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>
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>
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>
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>
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>
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.htmlFixes#854.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
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>
Use named variables instead of cmdline argument indexes so that it is
easier to read create-diff-object.c.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Artem Savkov <asavkov@redhat.com>
ppc64le lacked kpatch_line_macro_change_only() implementation. Add one
based on x86_64 version and available unit tests.
Fixes: #843
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Update the `__LINE__` macro detection heuristics based on recent kernel
changes:
- __warn_printk(), used in the WARN macros, which put the line number in
%edx
- __might_fault(), used in the usercopy macros
- lockdep_rcu_suspicious(), used in the RCU_LOCKDEP_WARN macro
- printk(), used in the ASSERT_RTNL macro
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
With #755, we started using dynrelas for function pointers. However,
this behavior only makes sense for function pointers to existing
functions. For function pointers to *new* functions, just use a normal
rela.
The 'function-ptr-new' unit test is from the following patch:
https://github.com/dynup/kpatch/files/1927198/new-static-callback.patch.txtFixes#834.
Fixes: 495e619750 ("kpatch-build, x86: do not use the patched functions as callbacks directly")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Because $PLUGIN variable is a part of $TARGETS we are trying to install
gcc-plugins twice which is treated as an error by install command:
/usr/bin/install create-diff-object create-klp-module create-kpatch-module gcc-plugins/ppc64le-plugin.so kpatch-gcc gcc-plugins/ppc64le-plugin.so /usr/local/libexec/kpatch
/usr/bin/install: will not overwrite just-created '/usr/local/libexec/kpatch/ppc64le-plugin.so' with 'gcc-plugins/ppc64le-plugin.so'
Signed-off-by: Artem Savkov <asavkov@redhat.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>
If a patch failed a first time, kpatch-build is using the previous
cache directory on subsequent builds. The UBUNTU_KERNEL=1 variable is
not set in this case. Therefore, utsrelease.h is not updated correctly
and the appropriate structures are not used. Just check if distro is
Ubuntu and we didn't request our own specific directory.
Signed-off-by: Vincent Bernat <vincent@bernat.im>
Because of signedness difference kpatch_check_relocations() would trigger
an error on any negative addend.
Fix by casting Elf_Data->d_size from size_t to int.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Check that none of the relocations are out-of-range of their
corresponding sections before writing the output elf.
Fixes: #618
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Heavy lifting of reading .toc rela entries for rela symbols
referring to .toc + offset, can be simplified using toc_rela() in
rela_equal() and remove the #ifdery guarding PowerPC code.
This patch also trims the commentary related to PowerPC.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
On ppc64le, the static local variable correlation doesn't take into
account the .toc rela indirection for data references, meaning that it's
basically broken in many cases.
Fix it by making the code .toc-aware.
Fixes#793.
Reported-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Upstream 4.15 kernels provide support for pre and post (un)patch
callbacks, inspired by the kpatch load hooks. Add support for them
in the livepatch-patch-hook.
At the same time, convert the kpatch hooks to use the same API.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Cleanup some of the new bash script code to appease 'make check':
- kpatch: Use integer comparison for $MAX_LOAD_ATTEMPTS
- kpatch-build: Quote ${TEMPDIR} variable
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
kpatch_include_symbol() is confusing. Refactor it:
- Remove the "inclusion tree" debug messages. I never use them, and
they just help make the code more confusing and the debug output more
cluttered.
- Split it up into two functions: kpatch_include_symbol() and
kpatch_include_section(), so that kpatch_include_section() can be used
elsewhere.
- Call kpatch_include_section() from kpatch_include_standard_elements().
This covertly fixes#702, by also including the .rela.rodata section.
- Add a bunch of comments to clarify some of the trickier points.
Fixes#702.
Fixes#807.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
It was observed by Evgenii Shatokhin in PR#755, that when the RCU
callback was called on the patched function, from unloaded livepatch
module triggered a kernel crash.
This patch implements the approach on PowerPC outlined in PR#755.
With -mcmodel=large, like any other data, function pointers are also
loaded relative to the current TOC base and are populated as
relocation entries in .toc section. Every function passing a function
pointer as the argument need to load the function address through
.toc section + offset. Convert such .toc + offset relocation into
a dynamic rela, which resolves to original function address, during
module load.
Also move the comment related to nested function check, into
may_need_dynrela().
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
Cc: Joe Lawrence <jdl1291@gmail.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
A kernel crash happened in __do_softirq() in very rare cases when the
binary patch created from mainline commit be82485fbcbb
("netlink: fix an use-after-free issue for nlk groups") was unloaded.
Investigation has shown that the kernel tried to execute an RCU
callback, deferred_put_nlk_sk(), defined in the patch module after the
module had been unloaded.
The callback was set by the patched variant of netlink_release() and
the address of the patched deferred_put_nlk_sk() was used, rather than
the address of the original function.
Similar problems occur with workqueue functions as well.
As suggested in
https://github.com/dynup/kpatch/pull/755#issuecomment-344135224,
create-diff-object was modified so that the addresses of the original
functions were used in such situations, at least for x86 systems. A
similar fix for PowerPC was added as well.
Changes in v4:
* '#ifdef __x86_64__' was removed. It is not actually needed right now
because the constants for relocation types are different on different
architectures.
Changes in v3:
* Minor refactoring and a comment explaining what this all is about.
Quite lengthy, but the dynrela-related code is really far from obvious.
Changes in v2:
* Handle the nested functions the same way as before, because they are
unlikely to be used as asynchronous callbacks. Example: cmp() in
bch_cache_show() from drivers/md/bcache/sysfs.c in the kernel 4.4.
As the nested functions are local to the functions they are defined in,
the compiler names them in a similar way to static locals: <name>.<number>.
Currently, we filter out all functions with '.' in their names. If there
are any asynchronous callbacks in the kernel that have a dot in their
names too, they could be handled in the future patches. It is unclear
though, if the callbacks with such names can appear in the kernel.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
Don't die outright when encountering an 'undefined reference' error,
instead write those down and check if needed symbols are provided by the
resulting module or core kpatch module.
Fixes#783.
v2:
- make undefined_references and new_symbols unique before comparing
- remove leftover $KMOD_PATH from new_symbols readelf
Signed-off-by: Artem Savkov <asavkov@redhat.com>
for-next branch of kbuild repo contains a "kbuild: rename built-in.o to
built-in.a" which renames all built-in.o instances. Filter on both .o
and .a in kpatch-gcc/kpatch-build to be prepared for this change.
Fixes#800.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
With kernel commit b1fca27d384 ("kernel debug: support resetting
WARN*_ONCE") the *_ONCE warnings are placed .data.once section.
Including .data.once section is valid, so add an check in
kpatch_verify_patchability() while checking for included invalid
sections.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Symbols with R_PPC64_REL24 relocation type are functions and it's
currently assumed that all functions are replaced with their respective
section symbols.
There are function whose reference are not straight forward section
symbol but section + offset. These function replacement should be
handled more like bundled sections. Remove the check, which imposes
the inital assumption.
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
.toc section entries are mostly place holder for relocation entries,
specified in .rela.toc section. Sometimes, .toc section may have
constants as entries. These constants are not reference to any symbols,
but plain instructions mostly due to some arthimetics in the functions
referring them.
They are referred by the functions like normal .toc entries, these
entries can not be resolved to any symbols. This patch creates a list
of constants if available for .toc sections and compares them in
rela_equal() to ensure their is no mismatch in the generated constants
for original and patched .o files.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
GCC 7.2.1 complains about the usage of the PPC64_LOCAL_ENTRY_OFFSET
macro:
create-diff-object.c: In function ‘is_gcc6_localentry_bundled_sym’:
create-diff-object.c:119:83: error: ‘<<’ in boolean context, did you mean ‘<’ ? [-Werror=int-in-bool-context]
(((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
create-diff-object.c:140:10: note: in expansion of macro ‘PPC64_LOCAL_ENTRY_OFFSET’
return (PPC64_LOCAL_ENTRY_OFFSET(sym->sym.st_other) &&
^~~~~~~~~~~~~~~~~~~~~~~~
Fix it by explicitly treating the macro as an integer instead of a bool.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
On ppc64le, building drivers/media/i2c/cx25840/cx25840.ko with GCC 4.85,
the plugin triggers the following errors:
{standard input}: Assembler messages:
{standard input}:1078: Error: operand out of range (0x0000000000008fd4 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:1288: Error: operand out of range (0x000000000000874c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:3844: Error: operand out of range (0x00000000000080e8 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:4028: Error: operand out of range (0x00000000000082b4 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:4031: Error: operand out of range (0x00000000000080b4 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:6661: Error: operand out of range (0x000000000000841c is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:6664: Error: operand out of range (0x0000000000008214 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:6845: Error: operand out of range (0x00000000000089dc is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:6848: Error: operand out of range (0x00000000000087d4 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:7587: Error: operand out of range (0x0000000000008930 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:7590: Error: operand out of range (0x0000000000008728 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
{standard input}:14592: Error: operand out of range (0xffffffffffff79b8 is not between 0xffffffffffff8000 and 0x0000000000007ffc)
make[1]: *** [drivers/media/i2c/cx25840/cx25840-core.o] Error 1
The problem is that the plugin nops were inserted too late. GCC laid
out the code with knowledge about the distance between branches, but
then the plugin came along after that and increased the branch distances
by inserting the nops.
Fix it by inserting the nops as early as possible. The 'vregs' pass is
where the insn codes get initialized, so run the plugin immediately
afterwards.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Sometimes git doesn't see that the patches have been reverted, if that
happens during ./scripts/setlocalversion call the resulting patch module
is built with a wrong vermagic because the tree is still considered
dirty.
Fix by moving git update-index call into remove_patches function so that
it is called every time the patches are reverted, not only on cleanup.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Found in the scope of https://github.com/dynup/kpatch/pull/755 but not
related to the main problem discussed there.
kpatch_create_patches_sections() and kpatch_create_intermediate_sections()
used 'hint' in error messages.
However, the string 'hint' refers to is owned by 'kelf_base' and is
freed before kpatch_create_*_sections() are called. As a result, if
these functions try to output errors and print 'hint',
create-diff-object will crash.
As suggested in the mentioned PR, 'hint' is actually no longer needed at
that stage, so I have removed it from kpatch_create_*_sections().
By specifying -d, --debug multiple times, the following additional
debug modes can be enabled:
-d -d: Writes everything that is written to the logfile also to
stdout.
-d -d -d: Same as '-d -d' plus sets 'xtrace' in kpatch-build.
-d -d -d -d: Same as '-d -d -d' plus sets 'xtrace' in kpatch-gcc.
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
Add a logger funcition that can be used to log to both stdout and the
logfile or only to the logfile. This is needed for subsequent patches
where we introduce an alternate debug mode.
Since we're piping to a logger now, we need to set 'pipefail' otherwise
the return status of such a pipeline is always 0 (the exit status of the
logger) and we won't catch any errors.
From the bash manpage:
The return status of a pipeline is the exit status of the last command,
unless the pipefail option is enabled
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
This is in response to an upstream discussion for the following patch:
https://lkml.kernel.org/r/1508217523-18885-1-git-send-email-kamalesh@linux.vnet.ibm.com
This should hopefully make it a lot easier for the ppc64le kernel module
code to support klp relocations.
The gcc-common.h and gcc-generate-rtl-pass.h header files are copied
from the upstream Linux source tree.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
When searching for 'Linux version ...' in vmlinux, stop after the first
match so that we don't keep reading a potentially huge file.
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
The current checks never fail, because the first grep in the pipeline
doesn't write anything to stdout.
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
This can be used for building a kpatch module for a non-running
kernel. Note that the correct kernel and debug packages still need
to be installed.
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
When creating .kpatch.relocations, there's no reason to convert the
relocation destinations to symbols. In fact, it's actively harmful
because it makes it harder for create-klp-module to deal with the GCC 6+
8-byte localentry gap.
This also fixes a regression which was introduced in 5888f316e6, which
broke ppc64le relocations.
Fixes#754.
Fixes: 5888f316e6 ("create-klp-module: support unbundled symbols")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
kpatch_relocation's 'dest' addend and 'offset' fields are redundant. In
fact, the 'offset' field isn't always accurate because it doesn't have a
relocation, so its value doesn't adjust when multiple .o files are
combined. Just use the 'dest' addend instead.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
kpatch_replace_sections_syms() assumes that all bundled symbols start at
section offset zero. With ppc64le and GCC 6+, that assumption is no
longer accurate. When replacing a rela symbol section with its
corresponding symbol, adjust the addend as necessary.
Also, with this fix in place, the workaround in
create_klp_relasecs_and_syms() can be removed.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
On ppc64le, adding a printk to total_mapping_size() caused it to change
from non-localentry to localentry, presumably because it was no longer a
leaf function. With GCC 6, a localentry function is offset by 8 in the
section, so different st_values are ok.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
The STT_FUNC and SHN_UNDEF checks aren't needed because they're already
implied by the localentry check.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
is_localentry_sym() isn't quite the right name, because it also checks
for the 8-byte gap introduced by GCC 6, and also checks that the
function is otherwise at the beginning of the section.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Replace stray spaces with tabs, except in the usage output where tabs
don't make much sense.
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
This was introduced in commit 5352d8b01a ('build objects in separate
directory to fix caching') but is no longer necessary.
Fixes: 2e99d6b7a4 ('kpatch-build: build the kernel in ~/.kpatch/src again')
Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
Fix the version checks for when we enable CONFIG_LIVEPATCH on RHEL. It
will be based on the latest upstream code.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
The paravirt_patch_site struct has 12 bytes of data and 4 bytes of
padding, for a total of 16 bytes. However, when laying out the structs
in the .parainstructions section, the vmlinux script only aligns before
each struct's data, not after. So the last entry doesn't have the
4-byte padding, which breaks kpatch_regenerate_special_section()'s
assumption of a 16-byte struct, resulting in a memcpy past the end of
the section.
Fixes#747.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Replace find * with find ./* to prevent treating files with dashes as
options. The leading ./ is later used in comparisons and thus must be
removed before that.
Found by shellcheck.
gcc --version varies too much for sane comparisons with vmlinux's
.comment section. Therefore compile a test file and compare its .comment
section.
Also fix gcc 4.8 check which used a lexicographically comparison which
will break for gcc versions >= 10. Instead check for the required
compiler options.
Closes#565.
- Replace grep | wc -l with grep -c.
- Use find -print0 and xargs -0 to handle non-alphanumeric filenames
(shouldn't be an issue for us but it's good practice).
- Replace expr with $(( )).
Found by shellcheck.
The double quotes are confusing as they don't quote $UBUNTU_ABI and thus
have no real effect. As $UBUNTU_ABI is a number simply remove them and
put $UBUNTU_ABI into the surrounding quotes.
Found by shellcheck.
- Replace echo $(cmd) with just cmd.
- Replace $@ inside quotes with $*.
- Always die if cd fails.
- Ensure rm -rf "$TEMPDIR"/* never expands to rm -rf /*.
Found by shellcheck.
Without proper quoting kpatch fails if the argument contains spaces, the
other scripts might be affected as well.
Not all new quotes are strictly necessary but they were added for
consistency with the existing code and to prevent copy & paste errors in
the future.
There's one conversion which is not straight-forward:
- grepname=$grepname\\\.o
+ grepname="$grepname\.o"
There are different quoting rules with and without the double quotes.
Valgrind complains about an uninitialized variable in
create-klp-module.c:
==4412== Conditional jump or move depends on uninitialised value(s)
==4412== at 0x402846: main (create-klp-module.c:497)
This warning refers to main()'s struct arguments stack variable,
precisely its .no_klp_arch member. Initialize the entire structure to
zero to avoid complaint.
Signed-off-by: Joe Lawrence <joe.lawrence@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>
The create_klp_relasecs_and_syms() function assumes that all dest
symbols are bundled, i.e. each symbol is located at offset 0 in its own
section.
However that may not always be the case. Unbundled symbols can occur,
for example, when combining two .o files which have the same bundled
symbol. They will be combined into the same section and will no longer
be considered "bundled".
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
The create_dynamic_rela_sections() function assumes that all dest
symbols are bundled, i.e. each symbol is located at offset 0 in its own
section.
However that may not always be the case. Unbundled symbols can occur,
for example, when combining two .o files which have the same bundled
symbol. They will be combined into the same section and will no longer
be considered "bundled".
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Use kpatch-<modname>.ko or livepatch-<modname>.ko depending on the type
of module we're building.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
It can be convenient to build a patchset into a single kpatch module, so
teach kpatch-build to accept a list of .patch files on the commandline.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Add commandline option to specify the kpatch module name, else derive it
from the .patch filename.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
When there is a ".." in the source object path, kpatch-gcc can't handle
it correctly. kpatch-gcc is called for objects which were recompiled
and writes the changed objects to "changed_objs". But if the path of the
input obj is something like:
arch/x86/kvm/../../../virt/kvm/.tmp_kvm_main.o
then it will fall into the "*.*.o" branch of the kpatch-gcc case
statement and kpatch-build will report "ERROR: no changed objects
found."
Use Joe's suggestion to revert d526805619 ("kpatch-gcc: update
ignorelist to avoid foo/.lib_exports.o files") and instead add a
"*/.lib_exports.o" pattern.
Fixes#735.
[ cleaned up changelog - jpoimboe@redhat.com ]
Cc: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: chen xiaoguang <xiaoggchen@tencent.com>
Normally, kpatch doesn't complain if you remove or rename a function.
This is a feature, because sometimes you have to rename a function in
order to patch it, if for example it doesn't have an fentry call. In
the object code, it's treated as a new function. You could get the same
result by copying/pasting the original function and giving the copy a
new name. But renaming it makes it much easier to review the patch.
In RHEL 7.4, I tried to rename l2cap_config_rsp() to
l2cap_config_rsp_kpatch(), but it failed with:
ERROR: l2cap_core.o: reference to static local variable CSWTCH.347 in l2cap_config_rsp was removed
This particular error is an easy fix, because the CSWTCH.* symbols are
read-only and are created by GCC. So they shouldn't be correlated
anyway.
In the future, we will need a more general fix to allow the removal of
functions which use *any* static local variables. Either automatically,
or by adding a manual annotation. This can be handled when we rewrite
the static local variable handling in #545.
Instead of always using the maximum number of CPUs available, allow
user to tune the number of make jobs using the command line argument
('-j', '--jobs').
If an .LCx symbol gets renamed or changes sections, or if its section
gets renamed, kpatch-build will get confused.
They aren't *real* symbols, just string constants. So no need to
correlate and compare them.
Fixes#714.
Fixes#727.
This removes duplicate code which is already handled by make internally
and also respects CPPFLAGS.
LDFLAGS are general linker flags, LDLIBS should be used for the
libraries itself. Therefore switch to LDLIBS which is put after the
object files in the command line (which is not true for LDFLAGS).
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>
Add support for ppc64le specific special sections:
- __ftr_fixup
- __mmu_ftr_fixup
- __fw_ftr_fixup
- __lwsync_fixup
This patch also add #ifdef guards for architecture specific
special sections.
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>
Move special section data checks to helper function
find_special_section_data(). Special section data will differ
between architectures and all architecture specific and common
checks can be handled better within a helper function.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
gcc -mprofile-kernel support is required on ppc64le for livepatch
to work. Check should be performed on the gcc, instead of relying
on the verion number.
This check is already performed during the kernel build by:
<linux-sources>/arch/poweprc/tools/gcc-check-mprofile-kernel.sh
Bail out, during the kernel build. Incase the gcc lacks the support
for -mprofile-kernel, instead of duplicating the check in kpatch-buid.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
kpatch-build/insn provides x86 instruction analysis, disable
the analyzer support when build on powerpc.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
If you give kpatch-build a bad argument for the '-s' option, it shows
the following error:
$ kpatch-build/kpatch-build -s foo
ERROR: source dir not found.
The supplied 'foo' argument isn't printed as intended.
Also fix some other options which have a similar issue.
With #650, we found that using -ffunction-sections and -fdata-sections
sometimes causes GCC to output the local symbols in a different order in
the symbol table. So don't assume they're in the same order, and
instead search all the locals.
This requires two passes: once going through the lookup table symbols
and once going through the .o symbols. This is needed to make sure
there aren't any extra symbols in one of the files.
I also reorganized the code a bit to simplify it.
When compiling with -O2, it fails with:
gcc -MMD -MP -O2 -I../kmod/patch -Iinsn -Wall -g -Werror -c -o lookup.o lookup.c
lookup.c: In function ‘lookup_open’:
lookup.c:132:21: error: ‘file_sym’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
table->local_syms = file_sym;
~~~~~~~~~~~~~~~~~~^~~~~~~~~~
lookup.c:83:30: note: ‘file_sym’ was declared here
struct object_symbol *sym, *file_sym;
^~~~~~~~
lookup.c:129:27: error: ‘child_sym’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (in_file && !child_sym->name) {
~~~~~~~~~^~~~~~
lookup.c:85:27: note: ‘child_sym’ was declared here
struct sym_compare_type *child_sym;
^~~~~~~~~
cc1: all warnings being treated as errors
Makefile:17: recipe for target 'lookup.o' failed
make[1]: *** [lookup.o] Error 1
make[1]: Leaving directory '/home/jpoimboe/git/kpatch/kpatch-build'
Makefile:14: recipe for target 'build-kpatch-build' failed
make: *** [build-kpatch-build] Error 2
As far as I can tell, these are false positive warnings. When in_file
is 1, file_sym and child_sym are properly initialized. But silence the
warnings anyway so Gentoo users can build with -O2.
Fixes: #675
On Debian/Ubuntu, the `vmlinux` from `-dbg` package has a version number
appended to it. For example:
`/usr/lib/debug/boot/vmlinux-3.13.0-117-generic`. Make it work
nonetheless.
On Ubuntu Trusty, HWE kernels don't come with a linux-source
package. Use dget to retrieve the source package instead. This is not
the case anymore with Xenial as the linux-source package is also
provided for the HWE kernels. For Debian, backports always come with the
linux-source package.
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
Joe saw the following errors when loading Linux commit 128394eff343
("sg_write()/bsg_write() is not fit to be called under KERNEL_DS"):
Skipped dynrela for copy_user_generic_unrolled (0xffffffffa0475942 <- 0xffffffff813211e0): the instruction has been changed already.
Skipped dynrela for copy_user_generic_unrolled (0xffffffffa0475a57 <- 0xffffffff813211e0): the instruction has been changed already.
That is known issue #580, but it can be avoided by leaving
'copy_user_generic_unrolled' as a normal relocation instead of
converting it to a dynrela, because it's an exported symbol.
Also remove the manual check for '__fentry__' because it's covered by
the exported symbol check.
Also remove a duplicate comment about unexported global object symbols
being in another .o in the patch object.
Fixes#695.
Upstream kernel commit 7f2084fa55e6 ("[kbuild] handle exports in lib-y
objects reliably") (v4.9+) added temporary dummy .lib_exports.o objects
to the kernel build. As these ephemeral files don't contain any code,
update the kpatch-gcc glob pattern to ignore them.
(glob pattern suggested by flaming-toast)
Fixes#686.
Strip kpatch_ignore_func_* and __UNIQUE_ID_kpatch_ignore_section_*
symbols to prevent the inclusion of .kpatch.ignore.functions and
.kpatch.ignore.sections. Mark the symbols as SAME, otherwise they are
considered NEW and are recursively included. This includes the
corresponding ignore sections and rela sections and may also create new,
unnecessary dynrelas.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
A couple of minor cleanups:
- move the `if (locals)` check to find_local_syms()
- remove the explicit initialization of `local_syms`, the entire struct
was already previously cleared to zero.
When wiping out the ~/.kpatch cache before replacing it with a new
kernel source, there's no need to keep anything around. Just wipe it
all out and start over.
Also, when building with the -s option, it doesn't need to touch
~/.kpatch/version or ~/.kpatch/src, so it can just skip the cleaning.
That keeps the previous cache around for the next incantation of
kpatch-build without '-s'.
Once upon a time, kpatch-build did the kernel build in three passes.
The extra pass was done without '-ffunction-sections -fdata-sections',
so it could produce the original vmlinux file.
At that time, there was no ~/.kpatch/obj directory. The kernel was
built directly in ~/.kpatch/src. Because the same directory was used
for both the original kernel build and the '-ffunction-sections
-fdata-sections' build, the entire tree had to be rebuilt twice for
every kpatch-build incantation, making it very slow.
That situation was improved with the following commit:
5352d8b01a ("build objects in separate directory to fix caching")
That built the regular and special binaries in ~/.kpatch/obj and
~/.kpatch/obj2, respectively.
Since then we've simplified things so that it only does two build
passes: original and patched, both with '-ffunction-sections
-fdata-sections', and ~/.kpatch/obj2 was removed. However,
~/.kpatch/obj still remained. That's because we never had a reason to
change it, until now.
Recent commit aa2907df29 ("support dup file+symbol")
triggers a new warning:
create-diff-object: ERROR: dynamic_debug.o: find_local_syms: 124: find_local_syms for dynamic_debug.c: found_none
This was actually a preexisting issue which that commit helped uncover.
The root issue is that dynamic_debug.c has some creative uses of the
`__FILE__` macro. When building the kernel objects outside the source
tree, the macro results in a absolute path like:
/home/jpoimboe/.kpatch/src/lib/dynamic_debug.c
But when building inside the source tree it's a relative path:
lib/dynamic_debug.c
The Fedora kernel is built in-tree, and I would imagine most other
distros are also built that way. So the way kpatch builds can result in
a slightly different 'original' object than the distro version, thanks
to the __FILE__ macro.
In this case, the order of the symbol table changed slightly between
vmlinux and the 'orig' object. Presumably, the difference in string
lengths was enough to convince the compiler to shuffle things around a
bit.
So considering that bug, and the possibility of other mismatches, go
back to building the kernel in the source tree.
For some reason, the backticks on this line confuse my editor's syntax
highlighter! Make vim happy by using the other form of command
substition.
Also convert the function definition syntax to comply with the
kpatch-build coding guidelines ;-)
A few symbols are discarded in the kernel linking phase, which means
they won't be in the lookup table. Skip their comparison.
This fixes a bunch of warnings seen when building a patch which triggers
a tree-wide rebuild:
create-diff-object: ERROR: aes_glue.o: find_local_syms: 112: find_local_syms for aes_glue.c: found_none
create-diff-object: ERROR: aesni-intel_glue.o: find_local_syms: 112: find_local_syms for aesni-intel_glue.c: found_none
create-diff-object: ERROR: init.o: find_local_syms: 112: find_local_syms for init.c: found_none
create-diff-object: ERROR: iosf_mbi.o: find_local_syms: 112: find_local_syms for iosf_mbi.c: found_none
create-diff-object: ERROR: setup.o: find_local_syms: 112: find_local_syms for setup.c: found_none
...
After this patch, there's still one warning remaining:
create-diff-object: ERROR: dynamic_debug.o: find_local_syms: 133: find_local_syms for dynamic_debug.c: found_none
That one has a completely different cause, which I'll fix in another
pull request (coming soon).
Fixes: #676
Normal correlated symbols are marked the SAME initially but static local
variables are correlated in a separate function. Also mark these the
SAME.
This fixes an issue where patching a function which called printk_once
(which uses a static local variable) would fail to build because the
static local variable was considered new and thus introduced a new data
member into .data..read_mostly which is not allowed to change.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Rename a couple of the variables in find_local_syms() to better reflect
their purpose. The passed in 'locals' are from the childobj (e.g.
foo.o) rather than the parent (e.g. vmlinux).
When CONFIG_DEBUG_ATOMIC_SLEEP is enabled, might_sleep calls will add
the line number to the instruction stream. Detect and ignore any such
changes.
Fixes: #657.
CONFIG_PARAVIRT is not required for building kpatch patch modules. The
sizeof paravirt_patch_site struct was only needed to create
.parainstructions sections as part of create-diff-object. As long as
the original objects were built without such sections then
this kernel option (and struct handling) can be considered optional.
The CONFIG_DEBUG_INFO_SPLIT kernel .config option places debug
information into separate .dwo files. As no known distribution is
currently shipping .dwo in their debuginfo packages, leave it as
unsupported for now.
When building a kernel with CONFIG_DEBUG_INFO_REDUCED, it was observed
that subsequent readelf -wi output may not always display structure size
information first. The affects the kpatch-build awk script that needs
to consider readelf output like the following:
<1><26393>: Abbrev Number: 12 (DW_TAG_structure_type)
<26394> DW_AT_name : (indirect string, offset: 0x914f): alt_instr
<26398> DW_AT_declaration : 12
...
<1><169d1b>: Abbrev Number: 13 (DW_TAG_structure_type)
<169d1c> DW_AT_name : (indirect string, offset: 0x914f): alt_instr
<169d20> DW_AT_byte_size : 13
Therefore the awk state machine should reset if it doesn't encounter
"DW_AT_byte_size" after given structure name match.
Fixes: #668.
Support for gawk '\s' (whitespace) GNU Regexp Operator was added
somewhere between gawk 3 and 4 (RHEL6 and RHEL7). Use the [[:space:]]
bracket expression to support older releases of gawk.
We use kelf_base->symbols to find a unique matching FILE+locals combination
when we call lookup_open(). If we can't find one matching or we find more
than one matching, we error out.
If we find a unique one, we setup table->local_syms in lookup_open(),
so later lookup_local_symbol() could do its lookup based on table->local_syms.
Fixes#604.
Suggested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
Introduce a second phase in the kpatch-build process that creates kpatch
modules or livepatch modules that use the new klp rela sections depending on
the kernel version being worked on. This change uses the two new programs to
either create a patch module that uses dynrelas (create-kpatch-module) or a
patch module that uses klp rela and arch sections + klp symbols marked with the
correct Elf flags (create-klp-module).
For klp patch modules, the --unique flag for ld is needed to prevent
.parainstructions and .altinstructions sections from different objects
from being merged, as arch_klp_init_object_loaded() applies these sections
per-object.
Add new program create-kpatch-module, that, given an intermediate object
outputted by create-diff-object, outputs an object (.o) that contains the
.kpatch.dynrelas section required by kpatch.
Add a new program, create-klp-module, that, given a built module (.ko),
will create a patch module with klp rela sections, klp arch sections, and
klp symbols.
In addition to .kpatch.relocations and .kpatch.symbols, have
create-diff-object create an .kpatch.arch section. This section can be used
to create .klp.arch. sections that are required for klp modules built for
versions >= 4.9. Each entry in the .kpatch.arch section represents an
arch-specific section (.altinstructions or .parainstructions) and contains
a pointer to the arch-specific section itself (see kpatch_arch struct
member 'sec') and a pointer to the objname string (see kpatch_arch struct
member 'objname'). This is enough information to be able to build
.klp.arch. sections in a later phase of kpatch-build.
Instead of creating dynrela sections, have create-diff-object create
intermediate sections .kpatch.relocations and .kpatch.symbols which can
then be used to build (depending on kernel version) either dynrela sections
or klp rela/klp arch sections + klp symbols in a later phase of kpatch-build.
Have lookup_open() also parse Module.symvers and add the resulting symbols
and their objnames to the lookup table. This code was essentially
cherry-picked from Josh Poimboeuf's lookup code found here:
8cdca59c88
That patch was modified to fix a bug in obj_read() (calling elf_end()
without strdup'ing the symbol name strings, which was causing null
dereferences) and to fix up the module name after reading it from
Module.symvers (replacing '-' with '_' and stripping the path prefixes).
Also, add lookup_exported_symbol_objname(), which looks up the objname of
an exported symbol by making use of the objname information obtained from
Module.symvers.
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.
commit eb55adc52d ("use livepatch 4.5 features in Ubuntu Xenial
kernel") will trigger following build failure, while building stock
kernel on Ubuntu:
make[2]: Entering directory '/root/.kpatch/obj'
CC [M] /root/.kpatch/tmp/patch/patch-hook.o
In file included from
/root/.kpatch/tmp/patch/livepatch-patch-hook.c:28:0,
from /root/.kpatch/tmp/patch/patch-hook.c:21:
/root/.kpatch/tmp/patch/livepatch-patch-hook.c: In functionpatch_ini:
/root/linux-4.8.15/include/generated/utsrelease.h:2:32: error: too many
decimal points in number
#define UTS_UBUNTU_RELEASE_ABI 4.8.15
^
/root/.kpatch/tmp/patch/livepatch-patch-hook.c:252:7: note: in expansion
of macro UTS_UBUNTU_RELEASE_ABI
UTS_UBUNTU_RELEASE_ABI >= 7 ) \
^
Stock kernel version string might differ from the ubuntu kernel
versioning format. This patch sets UBUNTU_KERNEL flag, when kpatch
module is being build for ubuntu distro kernel and check for this
flag before echoing UTS_UBUNTU_RELEASE_ABI tag.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Cc: Chris J Arges <christopherarges@gmail.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Fixes sparse complaints:
create-diff-object.c:2302:24: warning: Using plain integer as NULL pointer
create-diff-object.c:2303:11: warning: Using plain integer as NULL pointer
create-diff-object.c:2334:59: warning: Using plain integer as NULL pointer
create-diff-object.c:2347:43: warning: Using plain integer as NULL pointer
When passing '-d' to kpatch-build, it prints out some useful information
and keeps the related files around in ~/.kpatch/tmp. However, it also
passes '-d' to create-diff-object, which spits out way too much
information, drowning out all the other useful messages printed by
kpatch-build.
In my experience, the create-diff-object debug info is overkill for
debugging most issues, so disable it. The flag can still be used when
running create-diff-object manually.
GCC with KASAN instrumentation creates section ".rodata" with some static strings (i.e. some of them go to ".rodata.str1.1" for release build).
This change makes possible to build patch and check if it fixes issue found with KASAN, such as CVE-2016-9555.
The UTS_UBUNTU_RELEASE_ABI symbol is in utsrelease.h as installed by
linux-headers-`uname -r`. However when building a module with kpatch-build
utsrelease.h gets regenerated and doesn't include the ABI variable. This
patch just adds the additional define based on the input ARCHVERSION.
Give a slightly better error message for the dup file+symbol issue.
It's still cryptic but it's good enough to at least give us kpatch
developers a better idea about what went wrong. This would have helped
diagnose issue #633 much more quickly.
On RHEL 7 based kernels, copy_user_64.o misuses the .fixup section by
placing a normal function in it. That confuses create-diff-object.
Work around it by just skipping the file altogether, which is fine to do
because it's an assembly file which should never change anyway.
Fixes#625.
For newer kernels, some new objects have been added to the 'head-y'
build target. These objects aren't directly traceable to vmlinux so
they have to be added manually.
Fixes#626.
When building the patched version of the kernel, vmlinux has to be
linked with the '--warn-unresolved-symbols' linker flag. Otherwise the
link will fail if the patch uses kpatch-specific symbols like
kpatch_shadow_alloc() and friends.
As of upstream Linux commit b36fad65d61f ("kbuild: Initialize exported
variables"), LDFLAGS_vmlinux= no longer works from the command line,
resulting in '--warn-unresolved-symbols' no longer getting set.
Instead we can use kpatch-gcc to pass the flag to the linker.
Fixes#627.
When pruning entries from the fixup table, update the offsets in
.rela__ex_table otherwise the relas might point to the wrong fixup entry
or even out of the .fixup section.
Fixes#615.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
If $SRCDIR was a git repo, we leave the repo with a dirty index even after
reversing the patch during cleanup. This gets picked up by
scripts/setlocalversion and consequently subsequent kpatch-builds using the
same $SRCDIR end up with a '+' sign appended to the version string. Fix
this by properly refreshing the index during cleanup.
Source RPMs for recent Fedora kernels have a '.git' subdirectory, which
causes '+' to be appended to the module version magic, causing the
module to fail to load:
kpatch_readdir: version magic '4.8.6-201.fc24.x86_64+ SMP mod_unload ' should be '4.8.6-201.fc24.x86_64 SMP mod_unload '
Add a switch to kpatch-build that provides an opt-out to the cleanup
portion of the script. This can be handy when debugging $TEMPDIR or
$RPMTOPDIR contents, as well as inspecting the patched source code
itself.
The user's environment might have TEMPDIR exported. If so, then kpatch-build
dies with a bogus "invalid ancestor" error. If you turn those bogus errors into
warnings, then the script goes on to incorrectly put into the generated .ko file
every single function that was compiled in the *original* kernel build, thereby
producing an immense .ko file with more than 64k sections that the linux kernel
cannot load. This fix makes sure that TEMPDIR is unexported on the build of the
original kernel. Actually, this fix uses a separate KPATCH_GCC_TEMPDIR variable,
so that if the kernel build is interrupted, the cleanup function in the kpatch-kbuild
script will still have TEMPDIR set correctly.
Signed-off-by: Martin Carroll <martin.carroll@alcatel-lucent.com>
This fixes the detection of WARN_ON_ONCE, WARN_ONCE, and WARN_TAINT_ONCE
on Linux 4.6 and newer.
The signature for those macros changed with upstream Linux commit
dfbf2897d004 ("bug: set warn variable before calling WARN()").
Fixes#602.
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.
Including the .altinstr_replacement section by itself and without
.altinstructions doesn't make sense, as it only serves as a memory area to
hold replacement instructions to be copied over when alternatives are
applied. Don't include .altinstr_replacement unconditionally and only
include it when .altinstructions is also marked as included.
While the officially supported distributions all have
CONFIG_DEBUG_KERNEL enabled, this is not true for some other
distributions.
This option is necessary when kpatch-build retrieves the
SPECIAL_VARS using readelf command.
Signed-off-by: Quey-Liang Kao <s101062801@m101.nthu.edu.tw>
kpatch-build currently requires Module.symvers for the Kpatch core
module unconditionally and fails if it is not found. This does not allow
using kpatch-build to prepare livepatch-based patches.
This patch fixes the problem.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
Process the patch name correctly that only concern the fuffix with
.patch or .diff. Otherwise if the patch name is not end with .patch
or .diff but has it as substring, the fuffix will be removed
unreasonably.
Signed-off-by: Li Bin <huawei.libin@huawei.com>
Support patching objects that have duplicated function names. This feature was
introduced upstream in Linux v4.5.
This patch appends the symbol position to the symbol structure when
lookup_local_symbol is called. This pos variable is then used when creating the
funcs and dynrelas sections. Finally, incorporate sympos into the livepatch
patch hook only if the kernel version is greater than v4.5. In other cases the
older format is used.
Fixes: #493
Signed-off-by: Chris J Arges <chris.j.arges@canonical.com>
The uncorrelation logic is incomplete. For bundled symbols, in addition
to uncorrelating the sections, it should also uncorrelate the section
symbols and any rela sections.
Similarly the correlation logic needs to correlate section symbols. (It
already correlates rela sections.)
If a kernel SRPM is used to get the kernel sources, the target kernel
version is determined from the name of the SRPM.
One cannot obtain the target kernel version this way if the source tree
is used instead of an SRPM, so let us extract that information from
vmlinux.
Signed-off-by: Evgenii Shatokhin <eshatokhin@odin.com>
This fix is an addition to 9fedd0d283 "kpatch-build: fix
gcc_version_check".
On some systems, the GCC version stored in vmlinux may have the
following format:
(GNU) 4.8.3 20140911 (Red Hat 4.8.3-9)
while GCC returns
(GCC) 4.8.3 20140911 (Red Hat 4.8.3-9)
As a result, binary patches cannot be built, although the compiler is
the same.
gcc_version_check() now takes this into account.
Signed-off-by: Evgenii Shatokhin <eshatokhin@odin.com>
Deal with a special case where gcc needs a pointer to the address at the end of
a data section.
This is usually used with a compare instruction to determine when to end a
loop. The code doesn't actually dereference the pointer so this is "normal"
and we just replace the section reference with a reference to the last symbol
in the section.
Note that this only catches the issue when it happens at the end of a section.
It can also happen in the middle of a section. In that case, the wrong symbol
will be associated with the reference. But that's ok because:
1) This situation only occurs when gcc is trying to get the address of the
symbol, not the contents of its data; and
2) Because kpatch doesn't allow data sections to change, &(var1+sizeof(var1))
will always be the same as &var2.
Fixes: #553
Refine the static local variable handling again. This builds on a
previous patch by Zhou Chengming.
This fixes the following bugs reported by Zhou:
1. xxx.123 ---> xxx.123 (previous correlation by coincidence)
xxx.256 ---> xxx.256 (previous correlation by coincidence)
But real xxx.123 ---> xxx.256
In this case, the code doesn't work. Because when find patched_sym for
xxx.123, the xxx.256 in patched_object hasn't been de-correlated.
2. old-object | new-object
func1 | func1
xxx.123 | xxx.123 (inline)
func2 | func2
xxx.256 | xxx.256
xxx.123 | xxx.123 (inline)
When find patched_sym for xxx.123, first find xxx.123 in func1 of new-object,
But then find xxx.256 in func2 of new-object.
So I think should not iterate the base-sections, when find one, just go out to next symbol.
Both of these problems can be fixed by splitting the code up into
multiple passes:
1. uncorrelate all static locals
2. correlate all static locals
3. ensure each static local is referenced by all the same sections in
both objects
4. print warning on any new static locals
Fixes: #545