Commit Graph

149 Commits

Author SHA1 Message Date
Joe Lawrence
15067fcd64 kmod/core: apply dynrela addend for R_X86_64_64
User stettberger noticed that the kpatch support module does not
apply the addend for R_X86_64_64 in kpatch_write_relocations().

The AMD64 ABI draft doc [1], Table 4.10: Relocation Types lists that
relocation type as:

  Name         Value  Field   Calculation
  R_X86_64_64  1      word64  S + A

where:

  S : Represents the value of the symbol whose index resides in the
      relocation entry.

  A : Represents the addend used to compute the value of the relocatable
      field.

[1] http://refspecs.linuxfoundation.org/elf/x86_64-abi-0.99.pdf

Fixes: #1093
Reported-by: Christian Dietrich <stettberger@dokucode.de>
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2020-05-01 09:01:50 -04:00
Josh Poimboeuf
c9fa73bb9a
Merge pull request #986 from euspectre/old-replace-fix
Patch replacement fixes for the old KPatch core
2019-08-15 16:05:13 -05:00
Josh Poimboeuf
b5745d7ea6 Add support for R_X86_64_PLT32
Starting with binutils 2.31, the Linux kernel may have R_X86_64_PLT32
relocations. Make sure we support them. This should be as simple as
treating R_X86_64_PLT32 exactly like R_X86_64_PC32 everywhere. For more
details see upstream commit torvalds/linux@b21ebf2.

This also fixes the following issue seen on Fedora 29:

```
$ kpatch-build/kpatch-build -t vmlinux ./test/integration/fedora-27/convert-global-local.patch
Using cache at /home/jpoimboe/.kpatch/src
Testing patch file(s)
Reading special section data
Building original source
Building patched source
Extracting new and modified ELF sections
ERROR: slub.o: 1 function(s) can not be patched
slub.o: function __kmalloc has no fentry/mcount call, unable to patch
/home/jpoimboe/git/kpatch/kpatch-build/create-diff-object: unreconcilable difference
ERROR: 1 error(s) encountered. Check /home/jpoimboe/.kpatch/build.log for more details.
```

Fixes #975.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2019-07-05 11:45:50 -05:00
Evgenii Shatokhin
f447c6f40e kmod/core: Check all patched functions only if replacement is in progress
kpatch_verify_activeness_safety() calls kpatch_backtrace_address_verify()
for each address in the call traces of the processes.

Among other things, kpatch_backtrace_address_verify() searches the whole
set of functions for the ones being replaced (func->op == KPATCH_OP_UNPATCH).
This is a waste of time when the patch is loaded or unloaded rather than
replaced. Let us do the searching only if patch replacement is in
progress.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2019-07-02 17:51:28 +03:00
Evgenii Shatokhin
3bd131612d kmod/core: Safely remove the replaced functions
If atomic replacement is used for the old-style patches (the patches
that depend on kpatch.ko), the kernel might crash if the new patch
changes a smaller set of functions than the patch being replaced.

kpatch_apply_patch() does check if the functions from the patch to be
replaced are currently running. However, the functions are removed from
'kpatch_func_hash' in kpatch_register() only after stop_machine() and
kpatch_apply_patch() have finished:

	ret = stop_machine(kpatch_apply_patch, kpmod, NULL);

	/*
	 * For the replace case, remove any obsolete funcs from the hash and
	 * the ftrace filter, and disable the owning patch module so that it
	 * can be removed.
	 */
	if (!ret && replace) {
		struct kpatch_module *kpmod2, *safe;

		hash_for_each_rcu(kpatch_func_hash, i, func, node) {
			if (func->op != KPATCH_OP_UNPATCH)
				continue;
			if (func->force)
				force = 1;
			hash_del_rcu(&func->node);
			WARN_ON(kpatch_ftrace_remove_func(func->old_addr));
		}
	<...>

As a result, the kernel may end up with an inconsistent set of patched
functions. Some of the functions from the replaced patch could
still be running, while some would be already reverted to the original
ones.

I observed kernel crashes in such situations when I was trying to
replace a patch with a new one without a faulty fix.

Let us remove the replaced patched functions from 'kpatch_func_hash'
in kpatch_apply_patch() to avoid such issues.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2019-07-02 17:40:49 +03:00
Evgenii Shatokhin
6881c07f6c kmod/core: pass 'replace' flag to kpatch_apply_patch()
Make kpatch_apply_patch() aware of whether the patch should replace other
patches.

This will be used by subsequent fixes.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2019-07-02 17:33:58 +03:00
Artem Savkov
da3eed612d kmod/core: fix compilation with CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
Kernel commit 7290d5809571 "module: use relative references for
__ksymtab entries" changed kernel_symbol structure on some
architectures. Adjust kmod/core/core.c accordingly.

Signed-off-by: Artem Savkov <asavkov@redhat.com>
2018-11-14 12:33:23 +01:00
Josh Poimboeuf
4f6a96f94a kmod/core: add check for CONFIG_STACKTRACE
As discovered in #837.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
2018-04-19 17:27:38 -05:00
Joe Lawrence
fdf36400fb kmod/core: account for failing modules in notifier
The module notifier currently only handles newly loaded modules in the
MODULE_STATE_COMING state.  If target modules need to be unloaded, the
any kpatch module that patches it must first be disabled, releasing
module references held against the target module.  When the kpatch
modules are disabled, the target module is unpatched and the kpatch
core's data structures updated accordingly.

If a loading module happens to fail its init routine (missing hardware
for example), that module will not complete loading.  The kpatch core
doesn't properly account for this "phantom" target module, so when the
kpatch patch module is removed, it spews out an ugly warning when
attempting to remove a non-existing ftrace filter on the target module.

Register an additional module notifier (first in the list) to handle the
MODULE_STATE_GOING case.  This handler needs to do the inverse of the
MODULE_STATE_COMING handler.

Fixes #699.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-04-10 11:46:36 -04:00
Joe Lawrence
55650e16af
Merge pull request #780 from joe-lawrence/livepatch-hooks
kmod: add support for in-kernel livepatch hooks
2018-04-02 14:49:07 -04:00
Joe Lawrence
4d5febd4a8 sparse: quiet latest trivial complaints
Fixes sparse warnings:

  kmod/core/core.c:142:20: warning: symbol 'trace' was not declared. Should it be static?

  livepatch-patch-hook.c:73:18: warning: symbol 'lpatch' was not declared. Should it be static?

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-03-23 16:20:45 -04:00
Joe Lawrence
926e4e0c7d kmod: add support for in-kernel livepatch hooks
Upstream 4.15 kernels provide support for pre and post (un)patch
callbacks, inspired by the kpatch load hooks.  Add support for them
in the livepatch-patch-hook.

At the same time, convert the kpatch hooks to use the same API.

Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
2018-03-23 10:32:14 -04:00
Evgenii Shatokhin
03c41d05e3 kmod/core: fix definition of KERNELRELEASE
A cosmetic fix.

If KPATCH_BUILD ending with 'build/' is passed to 'make', KERNELRELEASE
will become 'build' and the error message will look like:

"<...> doesn't exist. Try installing the kernel-devel-build RPM or
linux-headers-build DEB."

Let us fix that.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
2018-02-19 13:13:03 +03:00
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