I found a bad bug:
- Module A is loaded, and registers function foo() with
KPATCH_FORCE_UNSAFE.
- Module A is unloaded. The new version of foo() is on the backtrace of
a task, but the core module ignores it because of the force flag, so
the unloading succeeds.
- The task returns to the new version of foo() which no longer exists.
- BOOM.
The only way I can think of to prevent this scenario is to prevent
forced modules from being unloaded (but still allow them to be
disabled).
An annoying side effect of this approach is that forced modules stay
loaded and in memory forever. And that after "kpatch unload" of a
forced module, you can't ever load it again because the previous
instance of it is still loaded (but permanently disabled).
This is ugly but I can't really think of a better way to handle it. If
necessary we could create a workqueue and periodically check to see if
we can safely call module_put() so that the module could be eventually
removed.
WARN macros are problematic because they embed the line number in an
instruction. As a result, when a function is changed higher in a file,
the line numbers for any WARN calls below that function in the file can
result in unnecessarily changed functions.
These macros allow a patch author to hard code the line numbers in WARN
macros to prevent functions from otherwise changing and getting pulled
into a patch module unnecessarily.
When running kpatch-build with -d, I was getting a seg fault. It was
faulting in kpatch_dump_kelf() when trying to print sec->secsym->name
for the .smp_locks section. It turns out that the section was included
but its section symbol wasn't included, so sec->secsym pointed to freed
memory.
This fixes the following issue for a patch which changes a module:
kpatch_create_mcount_sections: 1968: bad first rela in .rela.text.e_show
The first rela is "bad" because the real first rela was converted to a
dynrela and then removed from the rela list.
This is a temporary fix. The more permanent fix should be to allow
lookups in vmlinux for patched modules so we don't create any
unnecessary dynrelas.
Some functions in the kernel are always on the stack of some thread
in the system. Attempts to patch these function will currently always
fail the activeness safety check.
However, through human inspection, it can be determined that, for a
particular function, consistency is maintained even if the old and new
versions of the function run concurrently.
This commit introduces a KPATCH_FORCE_UNSAFE() macro to define patched
functions that such be exempted from the activeness safety check.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Steven Rostedt recommended to return "regs->ip + MCOUNT_INSN_SIZE",
which is what the function_graph tracer expects. This fixes
function_graph tracing for a patched function.
This change also means that the function tracer will only show the
patched function once (corresponding to a trace of the original
function) rather than twice. This is probably more in line with what a
user would expect.
Currently, when removing a patch module, the ftrace buffer gets flooded
with traces. This happens because we're clearing the ftrace ops filter
before unregistering the ops, which creates a small window where all
functions are being traced.
We should be doing the unregistering in the reverse order in which we
registered, meaning ops should be unregistered and _then_ the filter
should be cleared.
For ftrace to be able to trace a patched function, it requires that the
__mcount_loc section contains a pointer to the function, and that the
first instruction of the function is "callq __fentry__".
Normally that work is done by the recordmcount script, but it ignores
functions that aren't in a few standard sections (.text and a few
others).
This commit enables the ability to create user-defined hooks as part of
the normal code patch that can do preparatory work for the application
of the patch. This work could include, but is not limited to, changing
data structure semantics.
The user may define a new function as part of the patch and mark it as a
load-time or unload-time hook with the kpatch_load_hook() and
kpatch_unload_hook() macros. These macros are in an include file that
gets copied into the source tree at include/linux/kpatch-hooks.h at
patch build time. The signature for both hooks is "int kpatch_unload_hook(void)".
For now, the return code is ignored. The hooks may not fail. They also
run in stop_machine() context and may not sleep. These hooks, more or
less, must follow all the rules of interrupt context code.
The printks in the integration tests aren't very useful and annoyingly
fill up the dmesg buffer. Remove them by making them contingent on
unlikely conditions.