Commit Graph

141 Commits

Author SHA1 Message Date
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
Jessica Yu
8464c25d95 kpatch-patch-hook: fix incorrect old_offsets for loadable modules
Fix incorrect old_offsets for loadable modules during sysfs
initialization in patch_init.

sysfs will be initialized on patch module init regardless of whether
or not the module is loaded. func_old_addr_show() will read from func->old_addr,
which is initially set to 0; it'll be eventually filled in by the core module.
2014-08-15 23:42:22 -07:00
Josh Poimboeuf
a8a037271d macros: add KPATCH_PRINTK macro
Use this instead of calling printk to avoid unwanted compiler
optimizations which cause kpatch-build errors.

The printk function is annotated with the __cold attribute, which tells
gcc that the function is unlikely to be called.  A side effect of this
is that code paths containing calls to printk might also be marked cold,
leading to other functions called in those code paths getting moved into
.text.unlikely or being uninlined.

This macro places printk in its own code path so as not to make the
surrounding code path cold.

I have a related integration test to add, but right now it's broken
because we don't yet properly support the __verbose special section.
That'll be another PR.

Fixes #296.
2014-07-31 23:11:20 -05:00
Josh Poimboeuf
4e0ec591e3 macros: document more implications of KPATCH_FORCE_UNSAFE 2014-07-31 13:54:15 -05:00
Josh Poimboeuf
ec77b26c76 kpatch: change core module path again
On RHEL I'm seeing issues with putting the core module in the "extra"
path.  On the next depmod run, it gets added to modules.dep, and on a
subsequent kpatch install I see the following errors:

    /usr/lib/dracut/modules.d/50drm/module-setup.sh: line 26: /lib/modules/3.10.0-123.4.4.el7.x86_64//weak-updates/kpatch/kpatch.ko: No such file or directory
    /usr/lib/dracut/modules.d/90kernel-modules/module-setup.sh: line 14: /lib/modules/3.10.0-123.4.4.el7.x86_64//weak-updates/kpatch/kpatch.ko: No such file or directory
    modinfo: ERROR: Module /lib/modules/3.10.0-123.4.4.el7.x86_64/weak-updates/kpatch/kpatch.ko not found.

Until the core module gets merged into Linux, I think we can put it in
/usr/lib/kpatch, which is also where the patch modules are going to be
delivered in the RHEL RPM.

Making sure the other options still work with the kpatch utility for
now, so as to keep backwards compatibility between a newer kpatch
utility and older core modules.  We can break this compatibility for
kpatch 0.2.0.
2014-07-28 20:30:20 -05:00
Josh Poimboeuf
c260364882 Revert "add KPATCH_WARN_*_LINE macros"
This reverts commit 57b51d0bdc.

Probably no longer needed now that we have KPATCH_IGNORE_FUNCTION and
KPATCH_IGNORE_SECTION.
2014-07-28 15:04:25 -05:00
Josh Poimboeuf
b68dec7d22 Merge pull request #332 from spartacus06/ignore-sections
add KPATCH_IGNORE_SECTION support (plus fixups)
2014-07-28 15:03:40 -05:00
Seth Jennings
8ac20f5475 add KPATCH_IGNORE_SECTION support
This macro is for ignoring sections that may change as a side effect of
another change or might be a non-bundlable section; that is one that
does not honor -ffunction-section and create a one-to-one relation from
function symbol to section.

Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-07-28 11:10:32 -05:00
Gaetan Trellu
52ad9452ba kmod/core/Makefile: update the Makefile for Debian Like 2014-07-28 10:50:03 -04:00
Seth Jennings
85da92132f s/funcs/functions/g
Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-07-28 09:29:46 -05:00
Seth Jennings
84618404e0 add support for manually ignore functions
This commit adds the KPATCH_IGNORE_FUNC() macro for ignoring functions
that may change as a side effect of a change in another function.  The
WARN class of macros, for example, embed the line number in an
instruction, which will cause the function to be detected as changed
when, in fact, there has been no functional change.

Signed-off-by: Seth Jennings <sjenning@redhat.com>
2014-07-23 09:00:16 -05: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
a12715c2e2 Merge pull request #303 from jpoimboe/warn-macros
add KPATCH_WARN_*_LINE macros
2014-07-14 09:51:30 -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
Josh Poimboeuf
57b51d0bdc add KPATCH_WARN_*_LINE macros
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.
2014-07-09 10:39:07 -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
Josh Poimboeuf
c36e90e188 kmod/core: fix relocation writes across page boundaries
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.
2014-06-26 16:37:05 -05:00
Seth Jennings
e8d2ab565b kmod: patch: cleanup error paths
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>
2014-06-24 12:50:26 -05:00
Josh Poimboeuf
731e39aea9 kmod: fix uninstall path 2014-06-20 09:07:23 -05:00
Josh Poimboeuf
27c80f5439 kmod/core: don't print "patching module 'vmlinux'" 2014-06-19 22:19:06 -05:00
Josh Poimboeuf
625b98488d kmod/core: fix unloaded module 'vmlinux' error
Fix the following error:

  [  344.564905] kpatch: delaying patch of unloaded module 'vmlinux'
2014-06-19 10:39:14 -05:00
Josh Poimboeuf
9d016add40 fix review comments 2014-06-18 12:23:38 -05:00
Josh Poimboeuf
6b45c5dbd0 remove unused kpatch_dynrela.objname field 2014-06-18 11:17:55 -05:00
Josh Poimboeuf
34cc258a31 fix undefined symbols for future loaded modules
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__.
2014-06-18 11:17:11 -05:00
Josh Poimboeuf
827c91bae6 fix review comments
- get rid of unneeded vmlinux variable
- create patch_make_funcs_list() and patch_make_dynrelas_list()
2014-06-17 12:17:58 -05:00
Josh Poimboeuf
84c34ff584 implement per-object patching/relocations
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().
2014-06-17 10:03:08 -05:00
Josh Poimboeuf
844af68115 kmod/core: support for patching of future loaded modules
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.
2014-06-13 12:49:43 -05:00
Josh Poimboeuf
052806fe43 kmod/core: fix replace race condition
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.
2014-06-13 12:49:43 -05:00
Josh Poimboeuf
2ec9a0481d kmod/core: create global kpmod_list
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.
2014-06-13 11:57:15 -05:00
Josh Poimboeuf
063e9a62f5 kmod/core: get rid of kpatch_internal
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.
2014-06-13 11:57:15 -05:00
Josh Poimboeuf
b58e77ae9c kmod/core: move kpatch_write_relocations call
Write the relocations _after_ calling kpatch_calculate_old_addr() so
that we'll have a reference to the affected modules.
2014-06-13 11:57:15 -05:00
Josh Poimboeuf
c61fb88a23 kmod/core: add ftrace helper functions
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.
2014-06-13 11:57:14 -05:00
Josh Poimboeuf
dfc2641de2 kmod/core: use single quotes
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!
2014-06-13 11:56:17 -05:00
Josh Poimboeuf
3ad35bd4f4 kmod/core: protect find_module with module_mutex 2014-06-13 11:56:17 -05:00
Josh Poimboeuf
6d951dc996 kmod/core: fix error path for kpatch_verify_symbol_match failure
If kpatch_verify_symbol_match() fails, set the num_funcs variable so
that the ftrace rollback only removes the filter for the affected
functions.
2014-06-13 11:56:17 -05:00
Josh Poimboeuf
579ee5f499 kmod/core: fix kpatch_put_modules call in error path
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.
2014-06-13 11:56:16 -05:00
Josh Poimboeuf
31bd3a1538 kmod/core: fix kpatch_put_modules call order
kpatch_put_modules() should be called _after_ removing the ftrace
filters.
2014-06-13 11:55:16 -05:00