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.