With the inclusion of the debug sections, the debug output is so verbose
that it becomes less useful.
This commit reduces the verbosity by skipping rela listings of debug
sections.
It includes a new helper function, is_debug_section(), to consolidate
the logic for detecting debug sections.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
When patching module A, if one of the new function's relas reference a
symbol in module B, we currently just leave it as a normal rela. But if
module B hasn't been loaded yet, the patch module will fail to load due
to the rela's reference to an undefined symbol.
The fix is to convert these relas to dynrelas, which can be resolved
later in the module notifier when A is loaded.
Also added support for the R_X86_64_NONE relocation type, needed for
dynrelas which reference __fentry__.
This commit adds basic debuginfo support. It is "basic" in as much as
it does not try to parse the DWARF data to figure out which parts
pertain to the changed code. It simply includes all .debug_ and
.rela.debug_ section and strips out any rela entries that reference
unchanged symbols. This corrupts the debuginfo for unchanged symbols
but since they are not going to be included anyway, there should be no
way to reference that information.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The recent module patching code has exposed some problems with our data
structures. We currently patch the funcs and dynrelas individually,
which is kind of scary now that different objects can be patched at
different times. Instead it's cleaner and safer to group them by
patched object.
This patch implements per-object patching and relocations by refactoring
the interfaces:
- Completely separate the create-diff-object <-> patch module interface
from the patch module <-> core module interface. create-diff-object
will include "kpatch-patch.h" but not "kpatch.h". Thus,
create-diff-object has no knowledge about the core module's
interfaces, and the core module has no knowledge about the patch
module's special sections.
- Newly added kpatch-patch.h defines the format of the patch module
special sections. It's used by create-diff-object to create the
special sections and used by the patch module to read them.
- kpatch.h still defines the core module interfaces. Each kpatch_module
has a list of kpatch_objects for each module object to be patched.
Each kpatch_object has a list of kpatch_funcs and a list of
kpatch_dynrelas. The patch module creates these lists when populating
kpatch_module.
This way of structuring the data allows us to patch funcs and dynrelas
on a per patched object basis, which will allow us to catch more error
scenarios and make the code easier to manage going forward. It also
allows the use of much more common code between kpatch_register() and
kpatch_module_notify().
This allows a patch module to contain patched functions for modules
which haven't been loaded yet. If/when the module is loaded later, it
will be patched from the module notifier function.
kpatch load fails on Ubuntu with:
kpatch: unable to find module 'vmlinux_3'
The root cause is that the vmlinux file on Ubuntu is named
vmlinux-3.13.0-24-generic instead of just vmlinux.
Let's just call it "vmlinux" in the objname field.
With test/integration/data-read-mostly.patch, create-diff-object
includes the __verbose section but not the .rela__verbose section, which
is a bug, resulting in the following printk during the integration
tests:
[13740.801920] dynamic debug error adding module: (null)
If a non-bundled section is included, its rela section should also be
included. Also add support for converting those relas to dynrelas.
When renaming a foo.isra.1 function, there might also be a foo_bar
function which would be falsely matched with the current strchr logic.
Instead of matching the "foo" prefix, match "foo.isra".
This commit adds module patching support to create-diff-object by:
1) generalizing the vmlinux CLI parameter
2) adding the kernel object name to each patch and dynrela
3) adding slightly different logic for vmlinux/module in the dynrela
creation
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Rather than keep the logic in sync between the counting and processing
code in kpatch_create_dynamic_rela_sections() just do a "dumb" count
establishing an upper bound and allocating the buffer, then determine
the actual size (i.e. number of dynrelas) in the processing section.
No functional change intended.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Make old addresses relative to the start address of the relocatable
kernel or module.
This commit has no functional effect; it just prepares the code for
future acceptance of the module patching support.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The current approach of trying to include the tracepoint-related
sections doesn't work at all. The new tracepoints don't show up in
"perf list".
And also, with one patch (issue #219) I've seen a panic in
jump_label_del_module(). I suspect it's because the kernel is confused
by dynamic relocations' changing of the jump table after it was
registered with the jump table code.
I think the best approach for now is to just always exclude these
sections. It should be harmless, with the only consequence being that
tracepoints and jump labels can't be enabled in patched functions (which
is already the case with the current code anyway).
Fixes#221.
For a rela with type X86_64_PC32, the addend of the needed symbol is
relative to the address of the instruction _after_ the one which is the
target of the relocation.
When a changed function needs relocations for special data sections like
.data..percpu or .data..read_mostly, it's possible for those sections to
get included. We try to avoid that situation by converting section
references to data symbol references in kpatch_replace_sections_syms(),
but the conversion success rate isn't 100%, and we could be forgetting
about some other sections, so ensure that it never happens in
kpatch_verify_patchability().
Abstract out the common functionality for dealing with special sections
into a new kpatch_process_special_sections() function.
The base sections are partitioned into "groups". Only those groups
whose relas reference a changed function are kept. The only difference
in the logic for handling each special section is determining the size
of a given group. Each section has its own group_size() callback for
this. It's a callback instead of an integer because one of the
soon-to-be-supported special sections requires that its group sizes be
dynamically determined.
For a local non-included function or object which is needed by an
included function, its symbol table entry will still refer to a local
section index. Instead it should be changed to SHN_UNDEF.
The -fdata-sections gcc flag doesn't work with objects in the
.data..percpu section. Any function which uses a percpu variable
references this section, causing the section to get incorrectly included
in the patch module.
Manually convert these section references to object symbol references so
that the needed symbol can be found in vmlinux.
Also, the core module symbol verification code will fail when looking up
a percpu variable, because sprint_symbol doesn't think a percpu address
is a valid kernel address. So rewrite the symbol verification code to
use kallsyms_on_each_symbol() instead. It's not ideal performance-wise:
it seems to cost about 1ms per symbol lookup. I think that's acceptable
for now. In the future we may want to try to get a better upstream
kallsyms interface.
Both unpatched and patched objects may contain FILE
symbol with empty name. This is unexpected for
create-diff-object and could correlate 2 symbols
with same (empty) name but different types:
sym 00, type 0, bind 0, ndx 00, name (SAME)
...
sym 425, type 4, bind 0, ndx 65521, name (SAME)
...
signal.o: changed function: do_rt_tgsigqueueinfo
signal.o: changed function: do_rt_sigqueueinfo
signal.o: changed function: get_signal_to_deliver
signal.o: signal.o: changed section .rela__jump_table not selected for inclusion
signal.o: 1 unsupported section change(s)
/root/kpatch/kpatch-build/create-diff-object: unreconcilable difference
Introduce condition to match symbols also by type.
Signed-off-by: Jan Stancek <jstancek@redhat.com>
The inventory based testing for create-diff-object was introduced at a
time when create-diff-object only needed the two object files to operate.
Now, it requires vmlinux as well. This makes the inventory testing (a
unit testing framework for create-diff-object) obsolete and difficult to
update in it's current form.
This commit removes the inventory test framework.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit introduces functionality to verify the location of symbols
used in both the patch and dynrelas sections. It adds significant
protection from mismatches between the base and running kernels.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Right now the matching criteria for the NULL sym is type LOCAL and shndx
UNDEF. Unfortunately, that would also match any new LOCAL symbol
added to the symbol table with uninit'd sym.* fields i.e. the upcoming
__kpatch_strings and .kpatch.strings symbols.
Change the matching criteria to be symbols that have a zero-length name;
a property unique to the NULL sym.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
kpatch_migrate_included_symbols() is called from
kpatch_reorder_symbols() now, not kpatch_migrate_included_elements().
The difference is the kpatch_reorder_symbols() is operating on the
output kpatch_elf structure, and thus all symbols are by definition
included.
Remove the check and rename the function since it is redundant.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This fixes the weird ld errors we've been seeing lately.
According to the "ELF-64 Object File Format" spec, the symtab sh_info
field should contain "Index of first non-local symbol (i.e., number of
local symbols)".
Right now, reindexing of the included sections and symbols is done
when they migrate to the output kpatch_elf structure. However, due
to recently added features, the section and symbol list is not
final at this point, leading to constant tracking of the indexes for
addition sections and symbols added after this point. Additionally,
symbols have to be in a particular order, adding to the complexity.
This commit delays the reindexing and symbol reordering until the
section and symbol lists are finalized, removing the need to
track indexes and placeholders in the symbol list.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Because create-diff-object is a one-shot program (not a long lived
process) we haven't really bothered with cleaning up and freeing any
allocated memory. However, freeing data when it passes out of the
logical scope does have debugging benefits.
This commit adds two new functions for tearing down and freeing the
primary struct kpatch_elf data structures. The idea is the if a stale
pointer still references the old data structure that has passed out of
the logical scope, an issue will be more immediately apparent (i.e. NULL
references).
Signed-off-by: Seth Jennings <sjenning@redhat.com>
We rebuild the rela section data buffer in kpatch_create_rela_section()
just to rebuild it again later in kpatch_rebuild_rela_section_data()
before writing the output ELF file.
This commit removes the redundant rebuild while retaining the update
for the section header data.
Signed-off-by: Seth Jennings <sjenning@redhat.com>