Make sure we don't set HAVE_SIMPLE_ENABLE on rhel8 before rhel8.2
Fixes: b913b4b ("livepatch-patch-hook: skip klp_(un)register_patch() for RHEL-7.8+ kernels")
Fixes: #1031
Signed-off-by: Artem Savkov <asavkov@redhat.com>
RHEL-7.8 backported upstream kernel commit 958ef1e39d24 ("livepatch:
Simplify API by removing registration step"), so add it to the kernels
using the simple registration API.
Signed-off-by: Joe Lawrence <joe.lawrence@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_verify_activeness_safety() calls kpatch_backtrace_address_verify()
for each address in the call traces of the processes.
Among other things, kpatch_backtrace_address_verify() searches the whole
set of functions for the ones being replaced (func->op == KPATCH_OP_UNPATCH).
This is a waste of time when the patch is loaded or unloaded rather than
replaced. Let us do the searching only if patch replacement is in
progress.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
If atomic replacement is used for the old-style patches (the patches
that depend on kpatch.ko), the kernel might crash if the new patch
changes a smaller set of functions than the patch being replaced.
kpatch_apply_patch() does check if the functions from the patch to be
replaced are currently running. However, the functions are removed from
'kpatch_func_hash' in kpatch_register() only after stop_machine() and
kpatch_apply_patch() have finished:
ret = stop_machine(kpatch_apply_patch, kpmod, NULL);
/*
* For the replace case, remove any obsolete funcs from the hash and
* the ftrace filter, and disable the owning patch module so that it
* can be removed.
*/
if (!ret && replace) {
struct kpatch_module *kpmod2, *safe;
hash_for_each_rcu(kpatch_func_hash, i, func, node) {
if (func->op != KPATCH_OP_UNPATCH)
continue;
if (func->force)
force = 1;
hash_del_rcu(&func->node);
WARN_ON(kpatch_ftrace_remove_func(func->old_addr));
}
<...>
As a result, the kernel may end up with an inconsistent set of patched
functions. Some of the functions from the replaced patch could
still be running, while some would be already reverted to the original
ones.
I observed kernel crashes in such situations when I was trying to
replace a patch with a new one without a faulty fix.
Let us remove the replaced patched functions from 'kpatch_func_hash'
in kpatch_apply_patch() to avoid such issues.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
Make kpatch_apply_patch() aware of whether the patch should replace other
patches.
This will be used by subsequent fixes.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
In v5.1, upstream kernel commit 958ef1e39d24 ("livepatch: Simplify API
by removing registration step") removed klp_(un)register_patch(). We
only need to call klp_enable_patch() now.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
reason: after the function klp_unregister_patch, the lpatch must
be freed, otherwise, it would cause memory leak.
Signed-off-by: chenzefeng <chenzefeng2@huawei.com>
While adding proper linker script option my previous patch left the
linker script in the list of source files (on pre-4.20 kernels) for
ld somehow breaking kpatch callback sections. For this to work
properly kpatch.lds needs to be added to 'extra-y' instead of objs. And
for kbuild to process this option properly we need to call make without
the .ko target, i.e. let kbuild decide what to build.
Fixes: 17a97b4 ("kmod/patch: fix patch linking with 4.20")
Signed-off-by: Artem Savkov <asavkov@redhat.com>
4.20 includes commit 69ea912fda74 "kbuild: remove unneeded link_multi_deps"
which changes kbuild so that only '.o' files are given to ld as targets
for linking, leaving out our linker script. Even before this commit we
were still doing this wrong and were succeeding just because ld is smart
enough to detect the script, it even throws a warning:
ld: warning: kpatch.lds contains output sections; did you forget -T?
The right thing to do is to add the script to ldflags either through
kbuilds 'ldflags-y' or by adding it to LDFLAGS/KPATCH_LDFLAGS directly.
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>
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>
Preprocessor doesn't stop unwinding macroses in #if clauses if one of
the conditions is false resulting in the following error when trying to
build on non-rhel system:
patch/livepatch-patch-hook.c:53:48: error: missing binary operator before token "("
RHEL_RELEASE_CODE <= RHEL_RELEASE_VERSION(7, 5))
Fix by using 2 levels of #ifs instead of &&. The same way HAVE_CALLBACKS
does.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Since commit 926e4e0c7d ("kmod: add support
for in-kernel livepatch hooks") livepatch-patch-hook.c unconditionally
creates callbacks. This causes build error for kernels older than 4.15:
make -C /home/rppt/git/linux M=/home/rppt/.kpatch/tmp/patch livepatch-proc-vmalloc-live.ko
make[1]: Entering directory '/home/rppt/git/linux'
CC [M] /home/rppt/.kpatch/tmp/patch/patch-hook.o
In file included from /home/rppt/.kpatch/tmp/patch/patch-hook.c:21:0:
/home/rppt/.kpatch/tmp/patch/livepatch-patch-hook.c:82:23: error: field ‘callbacks’ has incomplete type
struct klp_callbacks callbacks;
^
/home/rppt/.kpatch/tmp/patch/livepatch-patch-hook.c: In function ‘patch_init’:
/home/rppt/.kpatch/tmp/patch/livepatch-patch-hook.c:395:10: error: ‘struct klp_object’ has no member named ‘callbacks’
lobject->callbacks = object->callbacks;
^
scripts/Makefile.build:302: recipe for target '/home/rppt/.kpatch/tmp/patch/patch-hook.o' failed
make[2]: *** [/home/rppt/.kpatch/tmp/patch/patch-hook.o] Error 1
Makefile:1687: recipe for target 'livepatch-proc-vmalloc-live.ko' failed
make[1]: *** [livepatch-proc-vmalloc-live.ko] Error 2
make[1]: Leaving directory '/home/rppt/git/linux'
Makefile:20: recipe for target 'livepatch-proc-vmalloc-live.ko' failed
make: *** [livepatch-proc-vmalloc-live.ko] Error 2
Introduce HAVE_CALLBACKS to allow conditional compilation of the callbacks
addition.
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
The module notifier currently only handles newly loaded modules in the
MODULE_STATE_COMING state. If target modules need to be unloaded, the
any kpatch module that patches it must first be disabled, releasing
module references held against the target module. When the kpatch
modules are disabled, the target module is unpatched and the kpatch
core's data structures updated accordingly.
If a loading module happens to fail its init routine (missing hardware
for example), that module will not complete loading. The kpatch core
doesn't properly account for this "phantom" target module, so when the
kpatch patch module is removed, it spews out an ugly warning when
attempting to remove a non-existing ftrace filter on the target module.
Register an additional module notifier (first in the list) to handle the
MODULE_STATE_GOING case. This handler needs to do the inverse of the
MODULE_STATE_COMING handler.
Fixes#699.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Fixes sparse warnings:
kmod/core/core.c:142:20: warning: symbol 'trace' was not declared. Should it be static?
livepatch-patch-hook.c:73:18: warning: symbol 'lpatch' was not declared. Should it be static?
Signed-off-by: Joe Lawrence <joe.lawrence@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>
Effective Kernel v4.16, the immediate flag is removed by upstream
kernel commit d0807da78e11 ("livepatch: Remove immediate feature").
Add an upper bound kernel version check for inclusion of the
immediate flag.
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
A cosmetic fix.
If KPATCH_BUILD ending with 'build/' is passed to 'make', KERNELRELEASE
will become 'build' and the error message will look like:
"<...> doesn't exist. Try installing the kernel-devel-build RPM or
linux-headers-build DEB."
Let us fix that.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.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>
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>
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>
Starting with kernel 4.11, CONFIG_DEBUG_SET_MODULE_RONX has been
replaced with CONFIG_ARCH_HAS_SET_MEMORY. This fixes the following
error:
kpatch: write to 0xffffffffc0d7650e failed for symbol copy_mnt_ns
Fixes#721.
When the core module loops through an object's list of dynrelas, it
determines whether or not the target location of the dynrela is in a
read-only region of the patch module. If it is, the readonly flag is set to
1 and it calls set_memory_{rw,ro} before and after the probe_kernel_write()
operation. This flag gets set once, and never gets reset for subsequent
iterations. Therefore, if a target happens to be in a RW section of the
patch module, and readonly = 1 had been set before, we may unintentionally
set a normally RW page to RO. Fix this by setting the readonly flag with
each iteration of the loop.
Fixes#681.
Restructure kpatch's sysfs interface and mirror the sysfs tree after
livepatch's sysfs layout. With the current sysfs layout, we cannot
distinguish which object a function belongs to, and we cannot tell which
modules/objects are patched. Therefore, restructure the kpatch sysfs tree
such that module/object information is available. With the new layout, each
patched object has its own directory, with each function being a
subdirectory of its object.
Implement this by embedding a kobject struct within the kpatch_module,
kpatch_func, and kpatch_object structs and supplying their ktypes and
kobject release methods.
Before:
/sys/kernel/kpatch
└── patches
└── <patch_module>
├── checksum
├── enabled
└── functions
├── <function> # from <object1>
│ ├── new_addr
│ └── old_addr
├── <function> # from <object2>
│ ├── new_addr
│ └── old_addr
└─── <function> # from <object3>
├── new_addr
└── old_addr
After:
/sys/kernel/kpatch
└── <patch_module>
├── <object1>
│ └── <function,sympos>
│ ├── new_addr
│ └── old_addr
├── <object2>
│ └── <function,sympos>
│ ├── new_addr
│ └── old_addr
├── checksum
├── enabled
└── <object3>
└── <function,sympos>
├── new_addr
└── old_addr
Upstream 2992ef29ae01 "livepatch/module: make TAINT_LIVEPATCH module-specific"
added a TAINT_LIVEPATCH flag to the module-specific taint flags. This
commit is v4.9+ and the modules taint field is an unsigned int.
Upstream 7fd8329ba502 "taint/module: Clean up global and module taint
flags handling" modified the modules taint field to be an unsigned long.
This commit is v4.10+.
Adjust the module tainting code in kpatch_register() to consider v4.9
kernels as well as v4.10 (and any distro-specific behavior).
Fixes: #666.
The dump_trace interface was deprecated in v4.9: instead of adding yet
another kernel-specific code block to kpatch's stack safety checks, use
save_stack_trace_tsk. It's relatively simple (no callbacks like
dump_trace), arch-independent, and its interface is stable across kernel
releases.
Fixes: #623.
Previous commit "kmod: let kernel apply TAINT_LIVEPATCH" modified the
kpatch patch module to set the "livepatch" module info. This breaks
module loading for kernel config CONFIG_LIVEPATCH=n
kpatch_kmalloc: module is marked as livepatch module, but livepatch support is disabled
kpatch modules can still use TAINT_LIVEPATCH as a per-module taint flag,
but only if it is set after the module loads.
Fixes: 660.
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.
Upstream commit 2992ef29ae01 ("livepatch/module: make TAINT_LIVEPATCH
module-specific") v4.9+ modified the kernel to add the TAINT_LIVEPATCH
flag on module load. To support this feature, add the "livepatch"
module info in the {k,live}patch modules and drop the add_taint() in the
core module.
Fixes smatch warning:
kmod/core/core.c:64:1: warning: symbol 'kpmod_list' was not declared. Should it be static?
Fixes sparse warnings:
kmod/core/core.c:680 kpatch_write_relocations() warn: inconsistent indenting
kmod/core/core.c:750 kpatch_write_relocations() warn: inconsistent indenting
The error paths in kpatch_shadow_alloc do not free an allocated
kpatch_shadow structure (and it's not added to the kpatch_shadow_hash).
Handle the kfree in the various error return paths.
Fixes the smatch warning:
kmod/core/shadow.c:97 kpatch_shadow_alloc() warn: possible memory leak of 'shadow'
Some features were backported into the 4.4 kernel which change the fields
of the livepatch structures. Ensure we can work with either v4.5 or greater,
or Ubuntu 4.4.0-7 or greater.
If an activeness safety check fails for kernels newer than 4.6, the
error is silently ignored because the newer version of
kpatch_backtrace_address_verify() doesn't set args.ret on error.
It would be an easy fix to just set args->ret on error, but I think a
better approach is just to combine the two versions of the function into
a single function with the use of a little macro trickery.
Backport the symbol lookup and checking code from upstream livepatch
code that relies on a symbol position enumeration rather than a fixed
memory address.
Fixes#617.
ftrace only allows a single user of this flag to register for a given
function. This prevents kpatch conflicts with kprobes handlers which
also might want to change regs->ip for a function.
We should have done this a few years ago. Better late than never...
When building against a different kernel from the one that is currently
running, install the kernel module to a directory based on the version
of the target kernel rather than the currently running kernel.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Upstream commit 568b329a "perf: generalize perf_callchain" modified the
return type (void -> int) of the address member of struct stacktrace_ops.
Use the void function if the kernel version is < 4.6 or return an int
otherwise.