While theoretically most of these functions can work both ways right now
all calls follow the same pattern: first argument is orig element and
second is patched element. Rename the arguments so that these functions
are used in the same fashion going forward. This allows us to cut some
corners such as removing the elseif statement in kpatch_correlate_symbol().
Signed-off-by: Artem Savkov <asavkov@redhat.com>
Rename "base" to "orig" when referencing object files and their contents
to be consistent with temporary directory structure.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
So far create-diff-object worked only with objectfiles built from a
single source file. To support object-files built from multiple sources
such as linked vmlinux.o, we call locals_match() for each of STT_FILE
symbols and store the pointer to the beginning of appropriate symbol
block in lookup table in each symbol.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
At the moment lookup_symbol() takes symbol name as an argument which
might not be enough in some cases (e.g. for objectfiles built from
multiple source files). Make it accept full symbol structure.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
gcc-static-local-var-4.patch is disabled on this distribution, disable
the test as well as it will always fail during 'slow' integration test
runs.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
For each printk() call site, CONFIG_PRINTK_INDEX makes a static local
struct named `_entry`, and then adds a pointer to it in the
`.printk_index` section.
When regenerating the `.printk_index` section for the patch module, we
only need to include those entries which are referenced by included
functions. Luckily this is a common pattern already used by several
other "special" sections. Add `.printk_index` to the special section
handling logic.
Fixes: #1206
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
CONFIG_PRINTK_INDEX creates a static local struct variable named
`_entry` for every call site to printk(). The initializer for that
struct assigns the `__LINE__` macro to one of its fields.
Similarly to the WARN macro's usage [1] of `__LINE__`, it causes
problems because it results in the line number getting directly embedded
in the struct. If a line is added or removed higher up in the source
file, the `_entry` struct changes accordingly due to a change in the
printk() call site line number.
`_entry` is similar to other "special" static locals, in that we don't
need to correlate the patched version with the original version. We can
instead just ignore any changes to it.
Any substantial (non-line-number) change to the `_entry` struct would be
a second-order (dependent) effect of a first-order code change, which
would be detected using other means. In that case the patched version
of `_entry` will be included, due to being referenced by the changed
function.
Fixes: #1206
[1] See kpatch_line_macro_change_only()
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Update the test/integration/Makefile to pass a KPATCH_BUILD_OPTS
variable to kpatch-test. This allows the user better control over the
kpatch build process, for example, building non-atomic replace .ko files
on kernels that do support atomic-replace:
% make integration KPATCH_BUILD_OPTS="--non-replace"
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
In PR #1205, Kamalesh reports:
... I see that the -mcmodel=large flag is being passed twice with
KBUILD_CFLAGS_MODULE set:
gcc -Wp,-MMD,/root/.kpatch/tmp/patch/.livepatch-meminfo.mod.o.d ............ -mcmodel=medium .... -I/root/kpatch/kmod/patch -mcmodel=large -fplugin=/root/kpatch/kpatch-build/gcc-plugins/ppc64le-plugin.so ... -DMODULE -mno-save-toc-indirect -mcmodel=large -mcmodel=large -DKBUILD_BASENAME='"livepatch_meminfo.mod"' -DKBUILD_MODNAME='"livepatch_meminfo"' -D__KBUILD_MODNAME=kmod_livepatch_meminfo -c -o /root/.kpatch/tmp/patch/livepatch-meminfo.mod.o /root/.kpatch/tmp/patch/livepatch-meminfo.mod.c.
I loaded the module built without the KBUILD_CFLAGS_MODULE +=
-mcmodel=large flag and seems to okay. I guess, we can remove the arch
specific flag from the Makefile.
Suggested-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
The kmod/patch/Makefile defines KBUILD_CFLAGS_MODULE, but it seems that
kbuild doesn't honor it as environment variable. This is noticed when
attempting to use the kpatch-build --non-replace option: the flag is
added to KBUILD_CFLAGS_MODULE, yet the kernel module build ignores it.
At the same time, the kernel docs suggest passing CFLAGS_MODULE [1], not
KBUILD_CFLAGS_MODULE, from the commandline. Setup KPATCH_MAKE to pass
these options through that variable.
[1] https://www.kernel.org/doc/Documentation/kbuild/makefiles.txt
Fixes: c14e6e9118 ("kpatch-build: Add PPC64le livepatch support")
Fixes: 17dcebf077 ("kpatch-build: enable klp with replace option by default")
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Binutils recently became much more aggressive about removing unused
section symbols. Since we can not rely on those being available anymore
add additional checks before using them.
Fixes: #1193
Signed-off-by: Artem Savkov <asavkov@redhat.com>
There are some Red Hat kernel NVR combinations like
"kernel-5.13.0-0.rc4.33.el9.x86_64" that don't work well with our srpm
localversion strategy and end up botching the utsrelease.h file... which
allows for kpatch builds, but the module loader rightly rejects the
vermagic mismatch.
An ordinary rpmbuild sets up the kernel Makefile with:
# make sure EXTRAVERSION says what we want it to say
# Trim the release if this is a CI build, since KERNELVERSION is limited to 64 characters
ShortRel=$(perl -e "print \"%{release}\" =~ s/\.pr\.[0-9A-Fa-f]{32}//r")
perl -p -i -e "s/^EXTRAVERSION.*/EXTRAVERSION = -${ShortRel}.%{_target_cpu}${Variant:++${Variant}}/" Makefile
The simplest fix is just adding the version string to the kernel
Makefile EXTRAVERSION as rpmbuild would do (minus the perl voodoo).
Fixes: #1196
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
With klp->replace, when a patch is replaced, it is no longer an active
patch, but the module is still loaded with a refcount of 0. If the user
tries to load the patch again, insmod will fail with EEXIT. To avoid
such errors, run a proactive rmmod before loading the module. This is a
no-op if the module is not loaded or is actually in use.
Also, update module_ref_count() to only succeed with refcnt > 1.
Signed-off-by: Song Liu <song@kernel.org>
Fixes#1187
checking if kpatch_register or klp_enable_patch exists in /proc/kallsyms
might not be reliable when module loading or unloading occurs at the same time.
The kernel implementation about /proc/kallsyms is not guranteed to be consistent.
Signed-off-by: xiejingfeng <xiejingfeng@linux.alibaba.com>
A STT_SECTION symbol is not needed if if it is not used as a relocation
target. Therefore, a section, in this case a debug section, may not have
a secsym associated with it.
Signed-off-by: Bill Wendling <morbo@google.com>
Add documentation about kpatch-build enables livepatch "replace" flag by
default, and provides -R|--non-replace option to disable the flag.
Signed-off-by: Song Liu <song@kernel.org>
Since 5.1 kernel, klp_patch supports a "replace" option, which does atomic
replace of cumulative patches. Enable building such patch by default. If
replace behavior is not desired, the user can use -R|--non-replace option
to disable it.
Signed-off-by: Song Liu <song@kernel.org>
Interesting changes since v0.9.2:
- Initial support for clang compiler
- Add support for rhel-8.4
- rhel-8.4: workaround pahole and extended ELF sections
- rhel-8.4: drop klp.arch support
- Kpatch command waits for module to fully unload
- Kpatch command informs user when signal subcommand is unnecessary
- kpatch-build skips ppc64le vdso files
Signed-off-by: Yannick Cote <ycote@redhat.com>
Rebased to kernel-4.18.0-304.el8.
Note: since RHEL-8.4 dropped klp.arch support, we can now re-enable
those tests that reference static keys defined in vmlinux.
Also, adjust for adjust for ppc64le inlining:
Building gcc-static-local-var-4.patch on ppc64le results in test
failure, as the kpatch .ko now contains a 'free_ioctx' symbol (the test
expects to NOT see one).
From the build log:
aio.o: changed function: free_ioctx
aio.o: new function: put_aio_ring_file << now un-inlined?
aio.o: changed function: aio_free_ring
aio.o: changed function: ioctx_alloc
aio.o: changed function: aio_prep_rw
aio.o: changed function: aio_read_events
aio.o: new function: kpatch_aio_foo << expected new function
and a source code change to free_ioctx():
% diff -upr \
<(objdump -D -j .text.free_ioctx ~/.kpatch/tmp/orig/fs/aio.o) \
<(objdump -D -j .text.free_ioctx ~/.kpatch/tmp/patched/fs/aio.o)
--- /dev/fd/63 2020-10-26 14:28:18.086236019 -0400
+++ /dev/fd/62 2020-10-26 14:28:18.086236019 -0400
@@ -1,5 +1,5 @@
-/root/.kpatch/tmp/orig/fs/aio.o: file format elf64-powerpcle
+/root/.kpatch/tmp/patched/fs/aio.o: file format elf64-powerpcle
Disassembly of section .text.free_ioctx:
@@ -53,7 +53,7 @@ Disassembly of section .text.free_ioctx:
b0: 00 00 82 3c addis r4,r2,0
b4: 00 00 84 e8 ld r4,0(r4)
b8: 78 fb e6 7f mr r6,r31
- bc: e0 00 63 38 addi r3,r3,224
+ bc: 38 00 63 38 addi r3,r3,56
c0: 01 00 00 48 bl c0 <free_ioctx+0xb8>
c4: 00 00 00 60 nop
c8: 70 ff ff 4b b 38 <free_ioctx+0x30>
Marking put_aio_ring_file() as __always_inline keeps the r3 / 224
offset value, leaving free_ioctx() unchanged. Since it's no longer
included in the resulting .ko, gcc-static-local-var-4.test will pass
once again.
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
Improve the relocation check for the case where the referenced symbol
isn't at the beginning of the section.
Note that the check still isn't perfect, as many relocations have a
negative addend. But it's still a lot better than nothing.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Add unit tests through github actions. This is exactly the same as our
travis tests but using github actions instead.
Signed-off-by: Artem Savkov <asavkov@redhat.com>
During review of PR #1163, Josh reported:
When trying this out, I think I found that kernel_is_rhel() is broken
for z-stream kernels. It expects a "." after the el8, like ".el8.",
but [rhel-8] z-stream kernels have the minor version appended to the
major version like ".el8_3".
Tweak the regex pattern in kernel_is_rhel() to account for such z-stream
kernel versions. At the same time, add .el9 to the regex in preparation
of rhel-9.
Reported-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>