Commit Graph

83 Commits

Author SHA1 Message Date
Josh Poimboeuf
ecf6173869 kmod/core: validate dynrela destination address
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.
2014-05-30 09:24:38 -05:00
Seth Jennings
2225bd83cc Merge pull request #180 from ryanmiao/print_funcs
export funcs via sysfs
2014-05-27 23:24:49 -05:00
Josh Poimboeuf
625fcdfb72 kmod/core: ensure page is RO before changing its permissions
Make sure we leave the page's execution permissions in the same state we
found them.
2014-05-27 21:58:15 -05:00
Josh Poimboeuf
ab941fb90a kmod/core: make loc variable a u64
So less casting is needed.
2014-05-27 21:49:45 -05:00
Josh Poimboeuf
80c1e8ac83 kmod/core: move dynamic relocation writes to new function
Unclutter kpatch_register a little bit.
2014-05-27 21:47:50 -05:00
Josh Poimboeuf
0ebbed244e create-diff-object: percpu support
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.
2014-05-27 12:47:42 -05:00
Jincheng Miao
827a143caf kmod/patch: export patched functions information via sysfs
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>
2014-05-27 21:56:56 +08:00
Seth Jennings
a5d986ee96 review fixups
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-23 23:41:28 -05:00
Seth Jennings
505e948af0 symbol location verification support
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>
2014-05-23 16:39:56 -05:00
Seth Jennings
170c8b1ba1 fix review comments
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-20 12:44:31 -05:00
Seth Jennings
21fc274448 dynrelas support, obsoleting link-vmlinux-syms
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
2014-05-20 12:44:31 -05:00
Seth Jennings
fd8176faf8 rename .patches section to .kpatch.patches
Adding .kpatch to the section name more clearly documents that these
are kpatch related sections.

Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-20 12:44:30 -05:00
Seth Jennings
797b7af234 cleanup: remove unneeded patches variable
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-20 12:44:30 -05:00
Josh Poimboeuf
5e25365244 Revert #186 (add dynamic symbol linking support)
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.
2014-05-15 17:34:16 -05:00
Seth Jennings
e1177e3a03 fix review comments
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-15 13:42:27 -05:00
Seth Jennings
880e271841 dynrelas support, obsoleting link-vmlinux-syms
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>
2014-05-15 13:29:15 -05:00
Seth Jennings
2de5f6cbfb rename .patches section to .kpatch.patches
Adding .kpatch to the section name more clearly documents that these
are kpatch related sections.

Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-15 13:28:24 -05:00
Seth Jennings
108cd9f95e cleanup: remove unneeded patches variable
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-05-14 14:04:54 -05:00
Josh Poimboeuf
a6694fffff kmod: install core module to "extra" subdir
To be more consistent with other out-of-tree modules, install the core
module to /usr[/local]/lib/modules/`uname -r`/extra/kpatch/kpatch.ko.
2014-05-13 15:10:40 -05:00
Josh Poimboeuf
5ea376a47a Merge pull request #181 from spartacus06/interface-refactor
refactor core <-> patch interface
2014-05-12 15:43:26 -05:00
Seth Jennings
e5f17c6b9a fix incompatible pointer type warning
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>
2014-05-12 15:20:09 -05:00
Seth Jennings
681a6e80b9 refactor core <-> patch interface
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>
2014-05-12 14:58:29 -05:00
Jincheng Miao
171cd567ce Fix kpatch.ko build on Ubuntu Saucy.
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>
2014-05-07 17:48:02 +08:00
Josh Poimboeuf
ab112cce2d kmod/core: minor style fix
For compatibility with checkpatch
2014-05-05 13:40:42 -05:00
Josh Poimboeuf
6ee8803978 kmod/core: kpatch_unregister return error if !kpmod->enabled
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.
2014-05-02 23:02:29 -05:00
Josh Poimboeuf
4bde6c3bbf kmod/core: fix kpatch_num_registered decrement
Oops, kpatch_unregister doesn't decrement kpatch_num_registered whenever
it's > 1.
2014-05-02 22:55:32 -05:00
Josh Poimboeuf
de40ff3e54 kmod/core: check for needed kernel config options
Yes, this is ugly.  There's a much cleaner way to do this for an in-tree
module, but this is the only way I know how to do it here.
2014-05-02 16:11:55 -05:00
Josh Poimboeuf
65810a47d0 kpatch replace
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.
2014-05-02 15:35:00 -05:00
Josh Poimboeuf
411fd570f2 kmod/core: update a few comments
- update the file description comment to be a little more accurate and
  concise
- s/trampoline/ftrace handler/
2014-05-01 12:36:28 -05:00
Josh Poimboeuf
b5de5a8b25 kmod/core: checkpatch and sparse fixes
- 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
2014-05-01 12:31:33 -05:00
Josh Poimboeuf
968845f1bd kmod/core: make WARN messages more informative 2014-04-30 13:42:22 -05:00
Josh Poimboeuf
ac22230761 kmod/core: make func->op an enum 2014-04-30 13:26:29 -05:00
Josh Poimboeuf
2f34cf9a89 kmod/core: NMI synchronization improvements
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>").
2014-04-29 23:36:53 -05:00
Josh Poimboeuf
87d852afa2 kmod/core: fail more gracefully in kpatch_unregister
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.
2014-04-29 23:36:53 -05:00
Josh Poimboeuf
0858e8b054 add include linux/module.h to kpatch.h
Needed for the module and kobject structs.
2014-04-28 13:24:04 -05:00
Josh Poimboeuf
b7a2862f90 safe kpatch unload
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".
2014-04-25 23:05:26 -05:00
Jincheng Miao
6c2d6444b1 Adding preempt_mask.h to core.c
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>
2014-04-25 12:08:04 +08:00
Josh Poimboeuf
fe6ace4fc7 kmod/core: error handling review fixes
Some fixes from the code review for better readability.
2014-04-24 14:22:51 -05:00
Josh Poimboeuf
f3f39c0587 fix activeness safety check when unpatching
When unpatching, the activeness safety logic should check for the new
function on the stack, not the old one.

Fixes #64.
2014-04-23 14:37:35 -05:00
Josh Poimboeuf
48cc3a409e kmod/core: move a couple of functions
Move kpatch_get_*_func a little higher in the file where they will be
needed for the next commit.
2014-04-23 14:37:35 -05:00
Josh Poimboeuf
2984b53d21 kmod: add new kpatch_module struct
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).
2014-04-23 14:36:15 -05:00
Josh Poimboeuf
ff28767295 kmod: error handling cleanup
Cleanup the error handling a little bit and make the flow a little
clearer.
2014-04-23 14:36:15 -05:00
Masami Hiramatsu
42e0779c0c kmod/core: Support live patching on NMI handlers
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>
2014-04-23 10:58:45 +09:00
Masami Hiramatsu
79ca5dbfa7 kmod/core: Handle registering error and unroll it
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>
2014-04-23 10:58:45 +09:00
Josh Poimboeuf
991b25b067 kmod/core: require fentry
Only compile the core module if the compiler supports -mfentry.
2014-04-15 14:40:03 -05:00
Josh Poimboeuf
e6cad4f0b1 kmod/core: use pr_err instead of printk 2014-04-15 14:21:19 -05:00
Josh Poimboeuf
56645d346d kmod/core: taint kernel with TAINT_USER
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.
2014-04-15 13:34:01 -05:00
Josh Poimboeuf
3b489e7d29 support CONFIG_MODVERSIONS=y
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.
2014-03-27 16:36:43 -07:00
Josh Poimboeuf
d4ab5fab2e always rebuild core module
If the kernel updates, make won't detect that the core module needs
rebuilding.  So always rebuild it.
2014-03-26 21:28:37 -07:00
Seth Jennings
5932f0d083 add uninstall target
Make it easy to clean up an install

Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-03-20 11:29:25 -05:00