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.
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.
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
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.
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.
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>
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.
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.
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.)
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
Rewrite the static local variable correlation logic. The algorithm now
traverses all the static locals in the original object rather than the
patched object, ensuring that each symbol in the original object has a
twin. It adds a new restriction that static local variables can't be
removed.
This adds support for the following:
- Multiple static locals with the same name in the same function
- Two separate static locals which happen to have the same numbered
suffix
- Static locals which are referenced by data sections
- CSWTCH and other static locals which are sometimes unused due to
sharing of their data sections
Fixes: #514
It turns out this is a more general issue which exists for more than
just CSWTCH symbols. The new static local handling code will handle it.
This reverts commit fd0c1bbe9c.
create-diff-object now checks if the original functions have fentry calls.
If an original function to be affected by the patch does not have the
fentry call, it cannot be patched. Error is reported in that case.
kpatch_create_mcount_sections() now also takes into account if a changed
or a new function has fentry call. If it does, mcount record is
generated for it as before. If a changed or a new function has no fentry
call, it is not an error in this case.
All this fixes the following issues.
1. If an original function has no fentry call (e.g. a "notrace" function)
but the patched function has it, the original function can not be
patched, but it would only be detected when applying the patch.
2. kpatch_create_mcount_sections() crashed if a patched function had no
relocation at all.
I observed such crashes when experimenting with a modified version of
the patch "tcp_cubic: better follow cubic curve after idle period" in
CentOS 7 x64.
Besides that, for a function with the first instruction starting with
0x0f, it would be incorrectly detemined that the function had fentry call.
The first bytes of the function would be overwritten in that case.
3. create-diff-object output an error if a new (an added) function had
no fentry call. This restriction is not necessary.
v2:
* Moved the check for fentry calls after the call to
kpatch_compare_correlated_elements() and before info about the original
ELF file is destroyed. The original symbols are now checked there (via
sym->twin) rather than the patched ones.
* Removed an excessive error check.
Signed-off-by: Evgenii Shatokhin <eshatokhin@odin.com>
Hard-coding the special section group sizes is unreliable. Instead,
determine them dynamically by finding the related struct definitions in
the DWARF metadata.
Fixes#517.
Fixes#523.
kpatch_verify_patchability can detect the change of .bss or .data or
.init section, but it must be processed before verify num_changed.
Otherwise, for example, if only .init section changed, it will fail
with 'no changed functions were found', but not 'unsupported section
change(s)'.
With this patch,
for .init section: .init section will not a bundled section, so if
the section changed, not sync the function status, kpatch_verify_patchability
will give 'changed section <secname> not selected for inclusion' and
'unsupported section change(s)' error.
for .bss/.data section: kpatch_verify_patchability will ensure not
including .data or .bss section, otherwise it will give 'data section
<secname> selected for inclusion' and 'unsupported section change(s)'
error.
Signed-off-by: Li Bin <huawei.libin@huawei.com>
If a static variable is a pointer, it has rela section.
Example:
static int *p = &a;
changed to:
static int *p = &b;
so its rela section has changed.
Then this change of data should be found and report error.
But if we don't correlate its rela section, we won't
find this change.
Signed-off-by: Zhou ChengMing <zhouchengming1@outlook.com>
The current WARN detection logic catches the majority of cases, but
there are still a lot of outliers which it doesn't catch (thanks, gcc).
I looked at a much larger sample of WARN calls and came up with a more
generic algorithm.
The _rs variable is used for printk ratelimiting, similar to __warned,
which makes it a logical candidate to be "special": don't correlate it,
yet don't mark a function as changed just because it references it.