A simple kernel module for testing basic kernel module patching.
Just run doit.sh from test/testmod.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit adds support for patching modules. If a patch or dynrela is
determined to be for a kernel module, the old_offset/src is not used and
the symbol location is looked up using kallsyms. The module being
patched is also references to keep if from disappearing from underneath
us.
This commit introduces early and limited support. The kernel module to
be patched must already be loaded or the patch module will not apply.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
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.
We need a disassembler library to help with converting data section
relocation references to their corresponding symbols. Unfortunately,
the only library I could find that's widely available in enterprise
Linux distros was libopcodes, which is part of binutils. But its
interface is far too clunky for our needs.
The best alternative I can find is to just copy the kernel's
disassembler library code from arch/x86/lib.
Ensure that dynrela destination addresses are within the patch module's
memory.
Also, use the module address ranges to check whether set_memory_rw() is
needed.
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>
Combine all the patch modules into a single kpatch-COMBINED.ko for a
much quicker test which still gives 95% or so of the coverage compared
to the full test suite. Use "make quick" for use this new option.
This feature is implemented as:
```
[root@localhost kpatch]# insmod ./kpatch-meminfo.ko
[root@localhost kpatch]# ls /sys/kernel/kpatch/patches/kpatch_meminfo/functions/meminfo_proc_show/
new_addr old_addr
[root@localhost kpatch]# cat /sys/kernel/kpatch/patches/kpatch_meminfo/functions/meminfo_proc_show/new_addr
0xffffffffa05211e0
[root@localhost kpatch]# cat /sys/kernel/kpatch/patches/kpatch_meminfo/functions/meminfo_proc_show/old_addr
0xffffffff8125d0e0
```
The patch module init function will allocate and init kpatch_func_obj with
customized kobj_type func_ktype. The attribute new_addr and old_addr of
kpatch_func_obj is attached to this func_ktype, so that these files could
be created by kobject_add automatically.
Signed-off-by: Jincheng Miao <jincheng.miao@gmail.com>