Commit Graph

136 Commits

Author SHA1 Message Date
Josh Poimboeuf
a4dec316f3 kmod/core: fix dynrela writes for kernel 4.11+
Starting with kernel 4.11, CONFIG_DEBUG_SET_MODULE_RONX has been
replaced with CONFIG_ARCH_HAS_SET_MEMORY.  This fixes the following
error:

  kpatch: write to 0xffffffffc0d7650e failed for symbol copy_mnt_ns

Fixes #721.
2017-07-17 09:48:24 -05:00
Jessica Yu
a095b4ed41 kmod/core: ensure the readonly flag is reset correctly
When the core module loops through an object's list of dynrelas, it
determines whether or not the target location of the dynrela is in a
read-only region of the patch module. If it is, the readonly flag is set to
1 and it calls set_memory_{rw,ro} before and after the probe_kernel_write()
operation. This flag gets set once, and never gets reset for subsequent
iterations. Therefore, if a target happens to be in a RW section of the
patch module, and readonly = 1 had been set before, we may unintentionally
set a normally RW page to RO. Fix this by setting the readonly flag with
each iteration of the loop.

Fixes #681.
2017-03-03 11:41:30 -08:00
Jessica Yu
0bb5c106ef kmod: restructure kpatch sysfs tree
Restructure kpatch's sysfs interface and mirror the sysfs tree after
livepatch's sysfs layout. With the current sysfs layout, we cannot
distinguish which object a function belongs to, and we cannot tell which
modules/objects are patched. Therefore, restructure the kpatch sysfs tree
such that module/object information is available. With the new layout, each
patched object has its own directory, with each function being a
subdirectory of its object.

Implement this by embedding a kobject struct within the kpatch_module,
kpatch_func, and kpatch_object structs and supplying their ktypes and
kobject release methods.

Before:
/sys/kernel/kpatch
└── patches
    └── <patch_module>
        ├── checksum
        ├── enabled
        └── functions
            ├── <function>    # from <object1>
            │    ├── new_addr
            │    └── old_addr
            ├── <function>    # from <object2>
            │    ├── new_addr
            │    └── old_addr
            └─── <function>   # from <object3>
                 ├── new_addr
                 └── old_addr

After:
/sys/kernel/kpatch
└── <patch_module>
    ├── <object1>
    │   └── <function,sympos>
    │       ├── new_addr
    │       └── old_addr
    ├── <object2>
    │   └── <function,sympos>
    │       ├── new_addr
    │       └── old_addr
    ├── checksum
    ├── enabled
    └── <object3>
        └── <function,sympos>
            ├── new_addr
            └── old_addr
2017-02-27 20:07:16 -08:00
Joe Lawrence
d62a9aa996 kmod/core: fix module taint for 4.9 kernel
Upstream 2992ef29ae01 "livepatch/module: make TAINT_LIVEPATCH module-specific"
added a TAINT_LIVEPATCH flag to the module-specific taint flags.  This
commit is v4.9+ and the modules taint field is an unsigned int.

Upstream 7fd8329ba502 "taint/module: Clean up global and module taint
flags handling" modified the modules taint field to be an unsigned long.
This commit is v4.10+.

Adjust the module tainting code in kpatch_register() to consider v4.9
kernels as well as v4.10 (and any distro-specific behavior).

Fixes: #666.
2017-02-02 13:40:25 -05:00
Jessica Yu
8e1aef2893 Merge pull request #659 from joe-lawrence/4.9-unwinder
RFC - 4.9 unwinder
2017-01-30 09:57:04 -08:00
Joe Lawrence
586feb40fe kmod/core: use save_stack_trace_tsk
The dump_trace interface was deprecated in v4.9: instead of adding yet
another kernel-specific code block to kpatch's stack safety checks, use
save_stack_trace_tsk.  It's relatively simple (no callbacks like
dump_trace), arch-independent, and its interface is stable across kernel
releases.

Fixes: #623.
2017-01-25 11:59:37 -05:00
Joe Lawrence
13fd6f2563 kmod: fix kpatch patch module load if CONFIG_LIVEPATCH=n
Previous commit "kmod: let kernel apply TAINT_LIVEPATCH" modified the
kpatch patch module to set the "livepatch" module info.  This breaks
module loading for kernel config CONFIG_LIVEPATCH=n

  kpatch_kmalloc: module is marked as livepatch module, but livepatch support is disabled

kpatch modules can still use TAINT_LIVEPATCH as a per-module taint flag,
but only if it is set after the module loads.

Fixes: 660.
2017-01-24 15:38:51 -05:00
Joe Lawrence
e7937196b7 kmod: let kernel apply TAINT_LIVEPATCH
Upstream commit 2992ef29ae01 ("livepatch/module: make TAINT_LIVEPATCH
module-specific") v4.9+ modified the kernel to add the TAINT_LIVEPATCH
flag on module load.  To support this feature, add the "livepatch"
module info in the {k,live}patch modules and drop the add_taint() in the
core module.
2017-01-12 16:05:53 -05:00
Joe Lawrence
501a63ad6d smatch,sparse: trivial code cleanups
Fixes smatch warning:
  kmod/core/core.c:64:1: warning: symbol 'kpmod_list' was not declared.  Should it be static?

Fixes sparse warnings:
  kmod/core/core.c:680 kpatch_write_relocations() warn: inconsistent indenting
  kmod/core/core.c:750 kpatch_write_relocations() warn: inconsistent indenting
2016-12-16 14:26:45 -05:00
Joe Lawrence
5a6ddaad8d smatch: fix kpatch_shadow_alloc cleanup
The error paths in kpatch_shadow_alloc do not free an allocated
kpatch_shadow structure (and it's not added to the kpatch_shadow_hash).
Handle the kfree in the various error return paths.

Fixes the smatch warning:

  kmod/core/shadow.c:97 kpatch_shadow_alloc() warn: possible memory leak of 'shadow'
2016-12-16 14:26:11 -05:00
Jessica Yu
e9fc979712 Merge pull request #637 from arges/636
kpatch and patch module builds fail on Ubuntu 16.04 #636
2016-12-16 10:55:45 -08:00
Chris J Arges
eb55adc52d use livepatch 4.5 features in Ubuntu Xenial kernel
Some features were backported into the 4.4 kernel which change the fields
of the livepatch structures. Ensure we can work with either v4.5 or greater,
or Ubuntu 4.4.0-7 or greater.
2016-12-16 07:05:53 -06:00
Josh Poimboeuf
8927b02197 kmod/core: fix activeness safety checks for kernels >= 4.6
If an activeness safety check fails for kernels newer than 4.6, the
error is silently ignored because the newer version of
kpatch_backtrace_address_verify() doesn't set args.ret on error.

It would be an easy fix to just set args->ret on error, but I think a
better approach is just to combine the two versions of the function into
a single function with the use of a little macro trickery.
2016-12-14 10:40:45 -06:00
Joe Lawrence
a6133bba08 Add CONFIG_RANDOMIZE_BASE KASLR support
Backport the symbol lookup and checking code from upstream livepatch
code that relies on a symbol position enumeration rather than a fixed
memory address.

Fixes #617.
2016-11-29 13:55:34 -05:00
Josh Poimboeuf
3c7300c341 kmod/core: use FTRACE_OPS_FL_IPMODIFY flag
ftrace only allows a single user of this flag to register for a given
function.  This prevents kpatch conflicts with kprobes handlers which
also might want to change regs->ip for a function.

We should have done this a few years ago.  Better late than never...
2016-08-19 12:09:30 -05:00
Jessica Yu
684171acc7 kmod/core: fix stacktrace_ops 'address' function prototype for 4.6
Upstream commit 568b329a "perf: generalize perf_callchain" modified the
return type (void -> int) of the address member of struct stacktrace_ops.
Use the void function if the kernel version is < 4.6 or return an int
otherwise.
2016-04-27 14:40:28 -07:00
Josh Poimboeuf
c56c411b2a kmod/core: TAINT_USER -> TAINT_LIVEPATCH
Ok, technically it's not livepatch.  But it's close enough, and more
accurate than TAINT_USER.
2016-04-14 16:28:49 -05:00
Evgenii Shatokhin
8dac9d0871 kmod/core: Skip relocations of already altered instructions
When a patch module is loaded, the kernel facilities like alternatives
and paravirt may alter some of its instructions. This happens before
Kpatch core module is notified and tries to apply dynrelas to it. If an
instruction to apply a dynrela to has already been changed by these
facilities, an incorrect instruction might be written as a result.

The core module now detects such conditions and does not apply dynrela
to the changed instructions.

Suggested by Josh Poimboeuf in the discussion of
https://github.com/dynup/kpatch/issues/580.

Changes in v.2:
* Used pr_notice to give more emphasis to the messages.
* Added an explanation message.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2016-04-11 15:11:35 +03:00
Jessica Yu
85a055665e kmod: core: use new module core_layout struct
Commit 7523e4dc5057 upstream ("module: use a structure to encapsulate
layout") uses a new field to access module memory. Account for this change
and ensure backwards compatibility with kernel versions < 4.5
2016-02-17 13:13:46 -08:00
Chris J Arges
3c8f5f7bfa Makefile: determine kernel release in Makefile
Don't assume we are building for the current kernel. In addition print out
a proper package necessary for building the module.

Signed-off-by: Chris J Arges <chris.j.arges@canonical.com>
2016-02-10 09:46:38 -06:00
Josh Poimboeuf
a683f7da21 kmod/core: fix crash with !CONFIG_DEBUG_SET_MODULE_RONX
When loading a patch module on a kernel with
!CONFIG_DEBUG_SET_MODULE_RONX, the following crash occurs:

  loading core module: /root/src/kpatch/kpatch/../kmod/core/kpatch.ko
  loading patch module: kpatch-meminfo-string.ko
  BUG: unable to handle kernel paging request at ffffffffa0010cc0
  IP: [<ffffffff8125ecb0>] do_init_module+0x84/0x1af
  PGD 13d3067 PUD 13d4063 PMD 1e1ee067 PTE 1e1a0161
  Oops: 0003 [#1]
  Modules linked in: kpatch_meminfo_string(O+) kpatch(O)
  CPU: 0 PID: 149 Comm: insmod Tainted: G           O  K 4.1.0+ #1
  task: ffff88001e17b810 ti: ffff88001e1cc000 task.ti: ffff88001e1cc000
  RIP: 0010:[<ffffffff8125ecb0>]  [<ffffffff8125ecb0>] do_init_module+0x84/0x1af
  RSP: 0018:ffff88001e1cfda8  EFLAGS: 00010246
  RAX: 0000000000000000 RBX: ffffffffa0010cc0 RCX: 0000000080a02001
  RDX: 0000000000000024 RSI: 0000000000000000 RDI: ffffffff813fabe0
  RBP: 0000000000000000 R08: 0000000000000000 R09: 00000000d0000000
  R10: ffffffffa000e000 R11: 0000000000000001 R12: ffff88001eb58638
  R13: ffffffffa0010d10 R14: 0000000000000001 R15: 0000000000000000
  FS:  00007f0ae00aa700(0000) GS:ffffffff813e1000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
  CR2: ffffffffa0010cc0 CR3: 000000001e181000 CR4: 00000000000006b0
  Stack:
   ffff88001e1cfed8 0000000000000001 ffffffffa0010cc0 ffffffff81058aac
   ffff88001e207680 00000000810a462f ffffc90000096890 0000000000000e00
   ffffffff00000016 ffffffff8126cd40 ffff88001eaa6a08 ffff88001e1cfe48
  Call Trace:
   [<ffffffff81058aac>] ? load_module+0x18ad/0x18e9
   [<ffffffff81056290>] ? copy_module_from_fd+0x86/0xdf
   [<ffffffff81058c1e>] ? SyS_finit_module+0x56/0x61
   [<ffffffff81261854>] ? system_call_fastpath+0x12/0x6a
  Code: f8 00 00 00 74 23 49 c7 c0 80 ca 26 81 48 8d 53 18 89 c1 4c 89 c6 48 c7 c7 6d ef 36 81 31 c0 e8 16 fb ff ff e8 18 06 00 00 31 f6 <c7> 03 00 00 00 00 48 89 da 48 c7 c7 c0 c9 3f 81 e8 7e b3 dd ff
  RIP  [<ffffffff8125ecb0>] do_init_module+0x84/0x1af
   RSP <ffff88001e1cfda8>
  CR2: ffffffffa0010cc0

With !CONFIG_DEBUG_SET_MODULE_RONX, module text and rodata pages are
writable, and the debug_align() macro allows the module struct to share
a page with executable text.  When klp_write_module_reloc() calls
set_memory_ro() on the page, it effectively turns the module struct into
a read-only structure, resulting in a page fault when load_module() does
"mod->state = MODULE_STATE_LIVE".

Fixes: #497
2015-11-03 14:44:00 -06:00
Josh Poimboeuf
b2de4ba059 kmod/core: call unexported set_memory_[ro|rw]
In recent kernels, set_memory_ro() and set_memory_rw() are no longer
exported.  Call them anyway :-)

Fixes #496.
2015-10-26 08:23:54 -05:00
Li Bin
495948242e kpatch-build: fix shadow_get function
The shadow_get function does't consider the case that
'shadow is inpace', and after the shadow->data be set to the data,
it will not be the pointer. This patch fix it.

Signed-off-by: Li Bin <huawei.libin@huawei.com>
2015-10-12 17:15:00 +08:00
Jan Stancek
6e67e57a42 wait for outstanding shadow variables free requests in kpatch_exit
Unload of kpatch module (and kpatch_shadow_hash table) before
all shadow variables free requests are processed can lead to
kernel crash.

Add rcu_barrier() to kpatch_exit() to wait for all outstanding
RCU callbacks to complete.

Signed-off-by: Jan Stancek <jstancek@redhat.com>
2014-11-21 17:19:51 +01:00
Seth Jennings
bb6edd16f9 Merge pull request #452 from jpoimboe/module-call-external
allow patched modules to call external functions
2014-10-07 00:04:43 -05:00
Josh Poimboeuf
f5de932b8d allow patched modules to call external functions
When patching a kernel module, if we can't find a needed dynrela symbol,
we currently assume it's exported.  However, it's also possible that
it's provided by another .o in the patch module.  Add support for that.

Fixes #445.
2014-10-06 23:16:13 -05:00
Josh Poimboeuf
b6ef92bf6c fix error path typo 2014-10-06 22:38:06 -05:00
Josh Poimboeuf
4d01e89c3a fix object unlink error handling
Fix the object unlink error handling so that each function cleans up
after itself properly.

Also use find_symbol() instead of __symbol_get() to make cleanup easier.
When patching a module we don't need a reference to each symbol, since
we already have done a try_module_get() on the module.

Fixes #392.
2014-10-03 21:18:47 -05:00
Seth Jennings
c21cc1292f Merge pull request #398 from flaming-toast/patch-reenable
re-enable forced patch modules
2014-09-09 12:05:30 -05:00
Jessica Yu
0c9a54645c re-enable patch modules with checksum matching
In order to safely re-enable patch modules, add a special
.kpatch.checksum section containing an md5sum of a patch module's
contents. The contents of this section are exported to sysfs via
patch_init and double checked when kpatch load finds that a module of
the same name is already loaded.
2014-09-09 07:52:16 -04:00
Seth Jennings
eb75f0aaae Store small shadow fields in-place
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-09-08 16:00:20 -05:00
Josh Poimboeuf
4dee89269c add support for shadow variables
This adds support for shadow variables, which allow you to add new
"shadow" fields to existing data structures.

To allow patches to call the shadow functions in the core module, I had
to add a funky hack to use --warn-unresolved-symbols when linking, which
allows the patched vmlinux to link with the missing symbols.  I also
added greps to the log file to ensure that only unresolved symbols to
kpatch_shadow_* are allowed.  We can remove this hack once the core
module gets moved into the kernel tree.

Fixes #314.
2014-09-08 13:36:37 -05:00
Jessica Yu
6a69f5f91a consolidate variables func->old_offset and func->old_addr to just old_addr
To reduce redundancy, remove/change the old_offset fields in the
kpatch_func and kpatch_patch_func structs to just old_addr. Since
old_offset is being used as a placeholder for old_addr, might as well
consolidate it to just one variable.
2014-08-15 23:42:26 -07:00
Gaetan Trellu
52ad9452ba kmod/core/Makefile: update the Makefile for Debian Like 2014-07-28 10:50:03 -04:00
Josh Poimboeuf
8a008e8645 kmod/core: module old_addr fix
When patching a module, I ran into a "can't set ftrace filter at
address" error.  The root cause was due to the fact that
mod->module_core + old_offset is apparently not a reliable way to
determine the function's address.

Instead, just get the address from kallsyms like we do for module
dynrelas.
2014-07-18 10:09:52 -05:00
Josh Poimboeuf
96d3d241f5 kmod/core: checkpatch style fixes 2014-07-14 15:53:41 -05:00
Seth Jennings
f5189d815f Merge pull request #305 from jpoimboe/force-prevent-rmmod
prevent rmmod of forced modules
2014-07-09 22:57:30 -05:00
Josh Poimboeuf
e1890e627a prevent rmmod of forced modules
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.
2014-07-09 22:16:29 -05:00
Josh Poimboeuf
dfc759227a kmod/core: check force flag in replace case
When unpatching a function due to "kpatch replace", check the force flag
before doing the activeness safety check.
2014-07-09 15:06:57 -05:00
Seth Jennings
2e93c5e1e3 support forced patching
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>
2014-07-02 14:06:33 -05:00
Josh Poimboeuf
df679e3192 Merge pull request #278 from spartacus06/user-hook-support-v2
add user-defined load/unload hook support
2014-07-01 13:09:33 -05:00
Seth Jennings
d4e4d14dbe fixup review comments
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-07-01 12:22:16 -05:00
Seth Jennings
1ebae501ba Merge pull request #283 from jpoimboe/mcount
create-diff-object: create __mcount_loc section
2014-07-01 11:10:59 -05:00
Josh Poimboeuf
d2201980e6 kmod/core: ftrace function_graph tracer compatibility
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.
2014-07-01 10:16:38 -05:00
Josh Poimboeuf
2dbae9ae42 kmod/core: fix ftrace unregister order
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.
2014-07-01 08:52:59 -05:00
Gaetan Trellu
4a00442e1d core.c: add check to be sure that the kernel run with CONFIG_KALLSYMS_ALL option 2014-06-30 18:13:44 -04:00
Seth Jennings
4835e3edc3 add user-defined load/unload hook support
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.
2014-06-30 13:37:26 -05:00
Josh Poimboeuf
b6541ab85b kmod/core: use pr_err instead of printk 2014-06-29 21:59:38 -05:00
Seth Jennings
b3665a03d3 Merge pull request #266 from jstancek/safety_check_stacktrace
kmod/core: be more verbose when activness safety check fails
2014-06-27 09:01:31 -05:00
Jan Stancek
0617ae1b2c kmod/core: be more verbose when activness safety check fails
Print some basic info and stack trace for task when activness
safety check fails.

Signed-off-by: Jan Stancek <jstancek@redhat.com>
2014-06-27 09:32:34 +02:00