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.
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 integration test suite was intermittently giving the following
error:
[192685.907072] kpatch: write to 0xffffffffa082bffe failed for symbol call_netdevice_notifiers_info
The error was caused by a write across a page boundary without first
making the second page read/write.
Right now, if there is a failure in patch_make_dynrelas_list(),
patch_free_objects() is called twice; once in the error section of
patch_make_dynrelas_list() and again in the err_objects section of
patch_init().
This fixes this and cleans up the error handling a bit.
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__.
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.
In the replace case, stop calling module_put on a patch module before
we're potentially done with it.
This will also be needed for future module patching if we want to
properly replace a patch module which only patches a future loaded
module (that's a mouthful).
Fixes#165.
Create a list of registered patch modules, which will be used in the
module notifier to patch future loaded modules. It will also be used to
fix the kpatch replace race condition where it calls module_put too
early.
The kpatch_internal struct is a good idea, in that it documents which
parts of kpatch_module shouldn't be used by the patch module. But it
creates extra code and will require more extra code if we want to keep a
list of kpmods, which is needed to create a module notifier for module
patching of future loaded modules.
Embedding the private data directly in the public struct allows the code
to be simpler: no extra kmallocs/kfrees, no need to store pointers
between the public and private structs. I think the simpler code is
worth the tradeoff (exposing implementation detail). Kernel code
usually doesn't bother with hiding a internal struct data from other
kernel code anyway. For example, see ftrace_ops or struct kprobe.
The private fields are documented with a "private" comment.
Move all the ftrace filtering and registering logic into a couple of new
helper functions. Change kpatch_num_registered to kpatch_num_patched,
which now tracks the number of patched functions rather than the number
of patch modules.
This simplifies the code a bit and will also prevent a future loaded
module scenario where ftrace_ops can be registered with an empty filter,
resulting in _all_ kernel functions getting registered with ftrace.
Use single quotes when printing the name of a patch module, rather than
double quotes. This is more consistent with other printk messages, and
looks better too!
If kpatch_ftrace_add_func fails, num_funcs will be one less than what it
needs to be for kpatch_put_modules to work properly. Instead give it
the full array size, and it can figure out which modules to put based on
whether func->mod is nonzero.
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>
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>
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.
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.
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>
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>
This adds dynamic linking support for the patch modules. It is the
first step toward supporting patching module code and relocatable
kernels.
Rela entries that reference non-included local and non-exported global
symbols are converted to "dynrelas". These dynrelas are relocations
that are done by the core module, not the kernel module linker. This
allows the core module to apply offsets to the base addresses found
in the base vmlinux or module.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Conflicts:
kpatch-build/kpatch-build
We merged PR #186 a little too hastily. It seg faults with the new
parainstructions-section.patch in the integration test suite. Reverting
it for now until we get it figured out.
This reverts commit e1177e3a03.
This reverts commit 880e271841.
This reverts commit 2de5f6cbfb.
This reverts commit 38b7ac74ad.
This reverts commit 108cd9f95e.
This adds dynamic linking support for the patch modules. It is the
first step toward supporting patching module code and relocatable
kernels.
Rela entries that reference non-included local and non-exported global
symbols are converted to "dynrelas". These dynrelas are relocations
that are done by the core module, not the kernel module linker. This
allows the core module to apply offsets to the base addresses found
in the base vmlinux or module.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Fixes the following warning:
kpatch-patch-hook.c:71:2: warning: initialization from incompatible pointer type [enabled by default]
__ATTR(enabled, 0644, patch_enabled_show, patch_enabled_store);
^
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Make kpatch_funs truly internal by:
Defining it in core.c
Adding a struct kpatch_internal, declared in kpatch.h and defined in
core.c, that contains per patch module internal data.
Adding an "internal" field to struct kpatch_modules.
Allocating internal and funcs data in core.c, not in the patch module,
since the patch module has no knowledge of kpatch_func anymore.
Adding a "patch" field to kpatch_func that points directly to the
kpatch_patch provided by the module (rather than a field-by-field copy)
Signed-off-by: Seth Jennings <sjenning@redhat.com>
The error likes:
make -C /lib/modules/3.11.0-12-generic/build M=/home/ryan/kpatch/kmod/core kpatch.ko
make[3]: Entering directory `/usr/src/linux-headers-3.11.0-12-generic'
CC [M] /home/ryan/kpatch/kmod/core/core.o
/home/ryan/kpatch/kmod/core/core.c:42:32: fatal error: linux/preempt_mask.h: No such file or directory
#include <linux/preempt_mask.h>
I feel sorry to introduce this problem from my laster commit 6c2d6444.
Some old kernel doesn't have header file preempt_mask.h, and the safe
way is using hardirq.h to find in_nmi().
Signed-off-by: Jincheng Miao <jincheng.miao@gmail.com>
It's probably cleaner to just return -EINVAL if the kpmod isn't enabled,
instead of warning and continuing, which would be dangerous.
I think the reason I had it WARN before is because this condition
shouldn't be possible given the source for the patch module. But the
core module can't necessarily assume that it's our trustworthy patch
module code on the other side.
Allow the user to atomically replace all existing modules with a new
"kpatch replace" command. This provides a safe way to do atomic
upgrades for cumulative patch module updates.
- checkpatch doesn't like the FSF address since it's subject to change
- checkpatch doesn't like strings split by line
- whitespace fix
- sparse suggested to change some variables and functions to static
This is an attempt to both simplify and improve the correctness of the
NMI synchronization code.
There's a race in kpatch_ftrace_handler() between the kpatch_get_func()
and kpatch_finish_status() calls which could result in func being NULL.
The retry was supposed to fix this. However, this race would still be a
problem in the repatching case (if the function had already been
previously patched), in which case func would not be NULL, but could
instead point to the previously patched version of the function. In
this case it wouldn't retry and it would be possible for the previous
version of the function to run.
The fix is to use a memory barrier between accesses of the func hash and
the status variable, and then just call kpatch_get_func() *after*
accessing the status variable. For OP_PATCH, if status is SUCCESS, then
func is guaranteed to point to the new function. If status is FAILURE,
func might point to the new function, in which case we can use
get_prev_func to get the previous version of the function.
I also made some pretty big changes to try to simplify the design so
that there are less moving parts and so that it's hopefully easier to
understand. I moved the OP field into the kpatch_func struct. This
allows us to merge the two global state variables (status + op) into a
single global state variable (state), which helps make the code quite a
bit simpler. I turned it into a proper state machine and documented the
meaning of each state in the comments.
Moving the OP field to the kpatch_func struct also paves the way for an
upcoming pull request which will allow patch modules to be atomically
replaced ("kpatch load --replace <module>").
In kpatch_unregister(), if kpatch_remove_patch succeeds but one of the
subsequent ftrace unregistering calls fails, it returns an error and
fails to module_put() the patch module, even though the patch has been
removed. This causes the patch module to get stuck in a weird place
where its patch has been unregistered but the patch module can't ever be
removed.
These errors aren't serious and wouldn't cause any real problems if they
did somehow fail, so instead just WARN if they fail.
Currently the patch module calls kpatch_unregister in the patch module
exit path. If the activeness safety check fails in kpatch_unregister,
it's too late for the patch module to stop exiting, so all it can do is
panic.
Prevent this scenario by requiring the user to disable the patch module
via sysfs before allowing the module to be unloaded. The sysfs write
will fail if the activeness safety check fails. An rmmod will fail if
the patch is still enabled.
Also add support for this new unloading model in "kpatch unload".
When compiling core.c, it may report error like:
"error: implicit declaration of function ‘in_nmi’"
Adding header file in_nmi defined could avoid this.
Signed-off-by: Jincheng Miao <jincheng.miao@gmail.com>
Put funcs, num_funcs, and mod in their own struct called kpatch_module.
This allows us to keep patch module specific variables in one place (and
we'll have more of these variables soon).
Support live patching on NMI handlers. This adds checks for
possible inconsistency of live patching on NMI handlers.
The inconsistency problem means that any concurrent execution
of old function and new function, which can lead unexpected results.
Current kpatch checks possible inconsistency problem with
stop_machine, which can cover only threads and normal interrupts.
However, beacuse NMI can not stop with it, stop_machine is not
enough for live patching on NMI handlers or sub-functions which are
invoked in the NMI context.
To check for possible inconsistency of live patching on those
functions, add an atomic flag to count patching target functions
invoked in NMI context while updating kpatch hash table. If the
flag is set by the target functions in NMI, we can not ensure
there is no concurrent execution on it.
This fixes the issue #65.
Changes from v5:
- Fix to add a NULL check in kpatch_get_committed_func().
Changes from v4:
- Change kpatch_operation to atomic_t.
- Use smp_rmb/wmb barriers between kpatch_operation and kpatch_status.
- Check in_nmi() first and if true, access kpatch_operation.
Changes from v3:
- Fix kpatch_apply/remove_patch to return 0 if succeeded.
Changes from v2:
- Clean up kpatch_get_committed_func as same style of kpatch_get_func.
- Rename opr to op in kpatch_ftrace_handler.
- Consolidate in_nmi() and kpatch_operation check into one condition.
- Fix UNPATCH/PATCH mistype in kpatch_register.
Changes from v1:
- Rename inconsistent_flag to kpatch_status.
- Introduce new enums and helper functions for kpatch_status.
- Use hash_del_rcu instead of hlist_del_rcu.
- Rename get_committed_func to kpatch_get_committed_func.
- Use ACCESS_ONCE for kpatch_operation to prevent compiler optimization.
- Fix to remove (!func || func->updating) condition from NMI check.
- Add more precise comments.
- Fix setting order of kpatch_status and kpatch_operation.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Handle registering error to unroll the ftrace filter.
This also introduces get_kpatch_func() and
kpatch_remove_funcs_from_filter() for holding up
redundant loops.
Changes from v2:
- Rebased on the latest kpatch.
Changes from v1:
- Rename get_kpatch_func to kpatch_get_func.
- Fix function definition style issue.
- Do not jump to a label in "if" block.
- Rollback the ftrace user counter if we hit an error.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
For now, taint with TAINT_USER when loading a patch module so that the
user can always detect when a kpatch module has been previously loaded.
Eventually we will want a dedicated TAINT_KPATCH flag in the kernel.
When CONFIG_MODVERSIONS is enabled, loading of the patch module fails
with "no symbol version for kpatch_register". When building the patch
module, we need to point it to the core module's Module.symvers file.
This also works when CONFIG_MODVERSIONS is disabled, since
Module.symvers is created regardless.
When multiple patch modules patch the same function, there's no need to
patch all the intermediate functions. Just hook them all into the
original function and use the ftrace handler to find the newest one.
Also use a mutex in the register/unregister functions to protect changes
to kpatch_num_registered, kpatch_func_hash and calls to the ftrace
functions by other register/unregister invocations.
Use a mutex in the register/unregister functions to protect changes to
kpatch_num_registered, kpatch_func_hash and calls to the ftrace
functions by other register/unregister invocations.
There's no need to zero out the kpatch funcs array. The addr fields are
initialized by the patch module, the mod field is intialized by the core
module, and the node struct doesn't need to be initialized because its
fields are overwritten by hash_add.
My apologies for the size of this commit. I combined these two features
(updating API and using a hash table) into a single commit because their
implementations are tightly coupled and I didn't want to have to add
support for the old kpatch_funcs array with the new API just for the
sake of splitting up the commit :-)
- Update the core module API to get a more clear separation between core
module and patch module. This is cleaner and will help our case for
getting the core module merged upstream into the kernel.
- Convert the old kpatch_funcs array into a hash table. This is so much
nicer performance-wise and everything-else-wise than that ugly old
array.
- Do the incremental patching in stop machine. This ensures that the
funcs hash is up to date and we don't miss anything.
- Disable preemption in the ftrace handler when accessing the func hash.
That way we don't get conflicts with the stop_machine handler updating
the hash.
Print the loading/unloading messages after they have successfully
completed. Using the KERN_NOTICE log level which corresponds to a
"normal but significant condition."
Preemption shouldn't cause a problem with determining activeness safety.
Even if a thread is preempted, it'll be on the backtrace.
We may need to disable preemption when reading the kpatch_funcs array,
but I'm removing that comment for now because the kpatch_funcs array
will soon be replaced by a much better data structure, and we'll deal
with proper synchronization then.
Long ago, the kpatch_trampoline required being written in assembler, but
that's no longer needed now that it integrates nicely with ftrace.
Move it to a C function and rename it kpatch_ftrace_handler.
Build and install the kpatch core module with make and make install,
rather than building it every time with kpatch build.
The only downside to this approach is that the user has to make and make
install kpatch every time they get a new kernel. But this is only
temporary, until the kpatch module is delivered in an RPM.
- setup the makefiles to support "make" and "make install", which builds
the kpatch-build tools and installs everything in /usr/local.
- update kpatch-build to support new paths
- add "kpatch build" wrapper around kpatch-build
This changes the way the trampoline code works, thanks to a suggestion
by Steve Rostedt. Before, the trampoline was mucking with the stack
pointer and other registers, and jumping to the new function directly.
With this change, all it does is set regs->ip to the address of the new
function and return back to ftrace. When ftrace returns, it will return
to the beginning of the new function.
- fix real issue with 0's in the middle of a merged section (wrong
alignment)
- show patch util output in case it asks a question so it doesn't
silently fail
- fix issue with relocation of local objects (because they become global
objects)
- allow changes to .rela.initcall*. they should be instead caught by
the relocation comparison code.
- fix issue in compare symbols when the symbol section index has changed
but the sections themselves are the same
- in compare_symbols, when a new STT_SECTION symbol is added, ignore it.
it will be caught instead by the section comparison code
- fix issue in kpatch-gcc script that was causing gcc command lines
containing quotes to fail
The end-to-end patching works. From object analysis to generation to
runtime patching. It's still missing the scripting piece that will only
take a patch and kernel source dir as input.