Currently all the callers of kpatch_write_output_elf() are creating
.o object files or .ko kernel modules. Neither of these filetypes are
executable on their own, so enhance kpatch_write_output_elf() to accept
file creation mode and update its callers to pass 0664 to match
the expected permissions.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Interesting changes since v0.9.1:
- Integration test support for rhel-{7.8,7.9,8.1,8.2}, centos-8
- Better support for gcc child functions
- Batch jump label errors to report all instances
- Dynrela code cleanup
- Remove .klp.arch and add support for jump labels in v5.8+ kernels
- Mark ignored sections earlier to support functions missing ftrace hook
- Minor README.md improvements
- Add ppc64le mcount support to patched functions
- Show additional stalled process information in kpatch script
- Increased shellcheck coverage and fixes
- ppc64le plugin fixes for gcc v10
- Ignore __UNIQUE_ID_ symbol from tristate config objects
- Don't clear dmesg during integration tests
- Detect and report MODVERSIONS symbol version CRC changes
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
User disaster123 reports the following build errors:
create-diff-object.c: In function 'kpatch_process_special_sections':
create-diff-object.c:2215:41: error: 'key' may be used uninitialized in this function [-Werror=maybe-uninitialized]
code->sym->name, code->addend, key->sym->name);
^~
create-diff-object.c:2138:22: note: 'key' was declared here
struct rela *code, *key, *rela;
^~~
In file included from kpatch-elf.h:26,
from create-diff-object.c:53:
log.h:20:3: error: 'code' may be used uninitialized in this function [-Werror=maybe-uninitialized]
printf(format, ##__VA_ARGS__); \
^~~~~~
create-diff-object.c:2138:15: note: 'code' was declared here
struct rela *code, *key, *rela;
^~~~
cc1: all warnings being treated as errors
These are reproducible when building with 9.3.1 and 8.3.1 when building
with optimization level > 2 ( CFLAGS=-O2 make ). Fix them by
initializing the reported variables to NULL and verifying that they are
infact non-NULL after processing the __jump_table.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Rebased against kernel-3.10.0-1160.el7.
data-read-mostly.patch.disabled remains disabled as we hit several build
errors like:
"Found a jump label at __netif_receive_skb_core()+0x50, using key
netstamp_needed. Jump labels aren't supported with this kernel. Use
static_key_enabled() instead."
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Explain MODVERSIONS in enough detail for a kpatch author:
- What is it
- How does a kpatch interact with it
- How does kpatch-build report problems
- How to fix / avoid CRC mismatches
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Signed-off-by: Julien Thierry <jthierry@redhat.com>
Add a RHEL reproducer that causes a kpatch-build to fail when the final
module references a symbol with a different CRC than the original
kernel.
Signed-off-by: Julien Thierry <jthierry@redhat.com>
If the final module has a reference in its symbol table to a kernel
symbol and the symbol version differs from the kernel symbol version,
the module will be unloadable.
Have kpatch-build emit a clear error and die in such a case instead
of providing an unusable module.
Signed-off-by: Julien Thierry <jthierry@redhat.com>
The CRCs of exported symbols Module.symvers can differ between the
original build and the patched build.
In such a case, it is probably wise to rework the patch to avoid such
modifications.
Warn when a symbol changes version in the exported symbol list.
Fixes issue #1084
Signed-off-by: Julien Thierry <jthierry@redhat.com>
When patching an OOT module, the symbol version file is obtained by
combining the file from the module build and the Module.symvers file
provided with kernel headers. This is done for each modified .o in the
OOT build.
Create the final Module.symvers file once for the whole OOT module.
Signed-off-by: Julien Thierry <jthierry@redhat.com>
we remove the pre_patch_callback/post_unpatch_callback from the
stop_machine context. If a schedule/sleep happend in callbacks while the
process to be scheuded later will send IPI, because all interrupts
are disabled, the machine will trap into a deadlock in such situation.
So we remove the pre_patch_callback and post_unpatch_callback from
the stop_machine to avoid such situation. On the other hand, to avoid
the race between the patched code and post-patch/pre-unpatch callbacks when
run in parallel, we didn't remove the post_patch_callback and
pre_unpatch_callback from stop_machine.
The kpatch-test script clears the kernel log buffer to distinguish
between old and new dmesg entries. Wiping out the old buffer may
surprise some users, but isn't too hard to avoid:
- save the last dmesg line
- run the tests
- filter out old dmesg lines until after finding the saved entry
- if no saved entry is found, the buffer most likely overflowed
- inform the user to increase the log size
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Defer clearing the kernel buffer until we're ready to start the tests,
otherwise we increase the likelihood of catching stray errors while
we're building the modules and preparing the tests.
Fixes#1133 ("kpatch-test should ignore older kernel log messages")
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Issue #1124 ("Jump label issues are triggered from an unrelated
function") was caused by a minor __LINE__ change in a pr_warn statement.
Reference it here in the author guide for future reference.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
The modpost step complains about one of our generated files, output.o
and that it can't find a corresponding .cmd file for it (full path names
stripped):
WARNING: could not find .output.o.cmd for output.o
This was turned into an error in v5.8:
.output.o.cmd: No such file or directory
Avoid this by creating an empty .cmd file so that modpost acknowledges
that the file exists, but doesn't parse anything out of it.
Fixes#1125
Reported-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> (for v5.8+)
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Fail the kpatch build, while attempted to build on unsupported
architecture. The build will eventually fail but with the error that
doesn't hint the user clearly about the support status of kpatch, on the
architecture. This patch forces the build error with the message about
the unsupported status, avoiding confusion to the user.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
The commands used to build the livepatches and to load or unload them
are currently hard-coded in kpatch-test.
This patch adds 2 options to kpatch-test to make it easier to use custom
kpatch and kpatch-build commands:
* --system-kpatch-tools - if set, 'sudo kpatch' will be used to
load/unload the patches; 'kpatch-build' - to build them.
To use custom tools here, the user can adjust $PATH.
If the option is not set, kpatch-test will assume it is in kpatch source
tree, same as before this commit, and will use the tools from there.
* --kpatch-build-opts="..." - additional options to pass to
kpatch-build.
Example:
./kpatch-test \
--system-kpatch-tools \
--kpatch-build-opts="-s ./linux-src -c ./config -v ./vmlinux" \
-d my_kpatch_tests/test/integration/v01
In this case, kpatch and kpatch-build installed in the system will be used,
and kpatch-build will look for the kernel source tree, configuration
file and vmlinux binary in the current directory.
Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
Before kpatch-build would only keep build.log with --debug option
specified, but it also makes sense to keep it if --skip-cleanup is
specified.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
RHELs older than 7.7 are missing 5279631271b3 "module: fix ddebug_remove_module()"
which leads to a crash if dynamic debug is used with livepatching.
Disable recent dynamic debug addition on those distros.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
On x86, .altinstr_aux is used to store temporary code which allows
static_cpu_has() to work before apply_alternatives() has run. This code
is completely inert for modules, because apply_alternatives() runs
during module init, before the module is fully formed. Any changed
references to it (i.e. changed addend) can be ignored. As long as
they're both references to .altinstr_aux, they can be considered equal,
even if the addends differ.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Linux kernel tristate config options allows selected feature, either to
be built-in to the kernel or to be built as a kernel module. When built
as a kernel module, it's expected that the module, will be built with
module information such as author, license, description and others.
For each of the modinfo, a corresponding __UNIQUE_ID_ symbol is
generated. Their lookup succeeds in the case of module but fails when
selected to built-in to the kernel, the reason being that the kernel
discards these __UNIQUE_ID_ symbols during linking. Add __UNIQUE_ID_
symbols to maybe_discarded_sym list, to avoid failure in case of
table->object is vmlinux.
i.e.:
# cat .config|grep IOSCHED_BFQ (can be compiled as module too)
CONFIG_IOSCHED_BFQ=y
# readelf -sW ./block/bfq-iosched.o|grep UNIQUE
219: 0000000000000000 54 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_description223
220: 0000000000000036 16 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_license222
221: 0000000000000046 19 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_file221
222: 0000000000000059 25 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_author220
223: 0000000000000072 22 OBJECT LOCAL DEFAULT 267 __UNIQUE_ID_alias219
the line below before the kpatch error, is a debug printf to find the failing lookup symbol:
Failed lookup for __UNIQUE_ID_description223
/root/kpatch/kpatch-build/create-diff-object: ERROR: bfq-iosched.o: find_local_syms: 180: couldn't find matching bfq-iosched.c local symbols in ./vmlinux symbol table
with the patch, it successfully builds with both y/m config options:
...
bfq-iosched.o: changed function: bfq_idle_slice_timer
Patched objects: vmlinux
Building patch module:
livepatch-0001-block-bfq-fix-use-after-free-in-b.ko
SUCCESS
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Kernel livepatching modules build on GCC 10, with patched functions
referring to local function would fail to load with the error:
module_64: livepatch_ext4_cond_resched: Expected nop after call, got 7fe5fb78 at ext4_setup_system_zone+0x460/0xc90 [livepatch_ext4_cond_resched]
for more details on the error, refer to discussion at:
https://lkml.kernel.org/r/1508217523-18885-1-git-send-email-kamalesh@linux.vnet.ibm.com
the reason was that the gcc-plugin would skip the pass on error, failing
to convert the local calls into global, i.e on ppc64le every global call
is followed by a nop instruction, that gets replaced by the kernel to
restore
the TOC/r2 value of the callee, while parsing the relocations and would
skip the TOC restoration for local functions, where the TOC remains the
same across sibling functions.
GCC 10 commit 07c48b61a082("[RS6000] Put call cookie back in AIX/ELFv2
call patterns") merged a couple of call codes definition, breaking the
plugin. Change the plugin codes to match the GCC 10 codes.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Abort building the klp module, if the code for local and non-local calls
are not found instead of skipping the pass and building module, which
might result in un-loadable module with the kernel error:
module_64: livepatch_ext4_cond_resched: Expected nop after call, got 7fe5fb78 at ext4_setup_system_zone+0x460/0xc90 [livepatch_ext4_cond_resched]
gcc would not allow me to use "can't" in the error message and throw
build error:
gcc-plugins/ppc64le-plugin.c:49:17: error: contraction ‘can't’ in format; use ‘cannot’ instead [-Werror=format-diag]
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Building on Fedora 32 with GCC 10.1.1, triggers build failures:
In file included from gcc-plugins/ppc64le-plugin.c:1:
gcc-plugins/gcc-common.h:37:10: fatal error: params.h: No such file or directory
37 | #include "params.h"
| ^~~~~~~~~~
compilation terminated.
In file included from gcc-plugins/ppc64le-plugin.c:1:
gcc-plugins/gcc-common.h:841:13: error: redefinition of ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const ggoto*]’
841 | inline bool is_a_helper<const ggoto *>::test(const_gimple gs)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-plugins/gcc-common.h:124,
from gcc-plugins/ppc64le-plugin.c:1:
/usr/lib/gcc/ppc64le-redhat-linux/10/plugin/include/gimple.h:1037:1:
note: ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const ggoto*]’ previously declared here
1037 | is_a_helper <const ggoto *>::test (const gimple *gs)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-plugins/ppc64le-plugin.c:1:
gcc-plugins/gcc-common.h:848:13: error: redefinition of ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const greturn*]’
848 | inline bool is_a_helper<const greturn *>::test(const_gimple gs)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from gcc-plugins/gcc-common.h:124,
from gcc-plugins/ppc64le-plugin.c:1:
/usr/lib/gcc/ppc64le-redhat-linux/10/plugin/include/gimple.h:1489:1:
note: ‘static bool is_a_helper<T>::test(U*) [with U = const gimple; T = const greturn*]’ previously declared here
1489 | is_a_helper <const greturn *>::test (const gimple *gs)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
as per kernel commit c7527373fe28 ("gcc-common.h: Update for GCC 10")
"params.h header file has been dropped from GCC 10 and is_a_helper()
macro is now defined in gimple.h"
this patch fix them by guarding the both param.h header file and
is_a_helper() with #ifdef checking for gcc version < 10000.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Fixing the remaining warnings suggesting to quote the output subshell
invocation would hinder readability. Also the results of dirname and
"type -p" used in the subshell should return spaceless strings in kpatch
usecases.
Ignore the warnings for now.
Signed-off-by: Julien Thierry <jthierry@redhat.com>