Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching

Pull live patching infrastructure from Jiri Kosina:
"Let me provide a bit of history first, before describing what is in
this pile.

Originally, there was kSplice as a standalone project that implemented
stop_machine()-based patching for the linux kernel. This project got
later acquired, and the current owner is providing live patching as a
proprietary service, without any intentions to have their
implementation merged.

Then, due to rising user/customer demand, both Red Hat and SUSE
started working on their own implementation (not knowing about each
other), and announced first versions roughly at the same time [1] [2].

The principle difference between the two solutions is how they are
making sure that the patching is performed in a consistent way when it
comes to different execution threads with respect to the semantic
nature of the change that is being introduced.

In a nutshell, kPatch is issuing stop_machine(), then looking at
stacks of all existing processess, and if it decides that the system
is in a state that can be patched safely, it proceeds insterting code
redirection machinery to the patched functions.

On the other hand, kGraft provides a per-thread consistency during one
single pass of a process through the kernel and performs a lazy
contignuous migration of threads from "unpatched" universe to the
"patched" one at safe checkpoints.

If interested in a more detailed discussion about the consistency
models and its possible combinations, please see the thread that
evolved around [3].

It pretty quickly became obvious to the interested parties that it's
absolutely impractical in this case to have several isolated solutions
for one task to co-exist in the kernel. During a dedicated Live
Kernel Patching track at LPC in Dusseldorf, all the interested parties
sat together and came up with a joint aproach that would work for both
distro vendors. Steven Rostedt took notes [4] from this meeting.

And the foundation for that aproach is what's present in this pull
request.

It provides a basic infrastructure for function "live patching" (i.e.
code redirection), including API for kernel modules containing the
actual patches, and API/ABI for userspace to be able to operate on the
patches (look up what patches are applied, enable/disable them, etc).

It's relatively simple and minimalistic, as it's making use of
existing kernel infrastructure (namely ftrace) as much as possible.
It's also self-contained, in a sense that it doesn't hook itself in
any other kernel subsystem (it doesn't even touch any other code).
It's now implemented for x86 only as a reference architecture, but
support for powerpc, s390 and arm is already in the works (adding
arch-specific support basically boils down to teaching ftrace about
regs-saving).

Once this common infrastructure gets merged, both Red Hat and SUSE
have agreed to immediately start porting their current solutions on
top of this, abandoning their out-of-tree code. The plan basically is
that each patch will be marked by flag(s) that would indicate which
consistency model it is willing to use (again, the details have been
sketched out already in the thread at [3]).

Before this happens, the current codebase can be used to patch a large
group of secruity/stability problems the patches for which are not too
complex (in a sense that they don't introduce non-trivial change of
function's return value semantics, they don't change layout of data
structures, etc) -- this corresponds to LEAVE_FUNCTION &&
SWITCH_FUNCTION semantics described at [3].

This tree has been in linux-next since December.

[1] https://lkml.org/lkml/2014/4/30/477
[2] https://lkml.org/lkml/2014/7/14/857
[3] https://lkml.org/lkml/2014/11/7/354
[4] http://linuxplumbersconf.org/2014/wp-content/uploads/2014/10/LPC2014_LivePatching.txt

[ The core code is introduced by the three commits authored by Seth
Jennings, which got a lot of changes incorporated during numerous
respins and reviews of the initial implementation. All the followup
commits have materialized only after public tree has been created,
so they were not folded into initial three commits so that the
public tree doesn't get rebased ]"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching:
livepatch: add missing newline to error message
livepatch: rename config to CONFIG_LIVEPATCH
livepatch: fix uninitialized return value
livepatch: support for repatching a function
livepatch: enforce patch stacking semantics
livepatch: change ARCH_HAVE_LIVE_PATCHING to HAVE_LIVE_PATCHING
livepatch: fix deferred module patching order
livepatch: handle ancient compilers with more grace
livepatch: kconfig: use bool instead of boolean
livepatch: samples: fix usage example comments
livepatch: MAINTAINERS: add git tree location
livepatch: use FTRACE_OPS_FL_IPMODIFY
livepatch: move x86 specific ftrace handler code to arch/x86
livepatch: samples: add sample live patching module
livepatch: kernel: add support for live patching
livepatch: kernel: add TAINT_LIVEPATCH

+1475 -1
+44
Documentation/ABI/testing/sysfs-kernel-livepatch
··· 1 + What: /sys/kernel/livepatch 2 + Date: Nov 2014 3 + KernelVersion: 3.19.0 4 + Contact: live-patching@vger.kernel.org 5 + Description: 6 + Interface for kernel live patching 7 + 8 + The /sys/kernel/livepatch directory contains subdirectories for 9 + each loaded live patch module. 10 + 11 + What: /sys/kernel/livepatch/<patch> 12 + Date: Nov 2014 13 + KernelVersion: 3.19.0 14 + Contact: live-patching@vger.kernel.org 15 + Description: 16 + The patch directory contains subdirectories for each kernel 17 + object (vmlinux or a module) in which it patched functions. 18 + 19 + What: /sys/kernel/livepatch/<patch>/enabled 20 + Date: Nov 2014 21 + KernelVersion: 3.19.0 22 + Contact: live-patching@vger.kernel.org 23 + Description: 24 + A writable attribute that indicates whether the patched 25 + code is currently applied. Writing 0 will disable the patch 26 + while writing 1 will re-enable the patch. 27 + 28 + What: /sys/kernel/livepatch/<patch>/<object> 29 + Date: Nov 2014 30 + KernelVersion: 3.19.0 31 + Contact: live-patching@vger.kernel.org 32 + Description: 33 + The object directory contains subdirectories for each function 34 + that is patched within the object. 35 + 36 + What: /sys/kernel/livepatch/<patch>/<object>/<function> 37 + Date: Nov 2014 38 + KernelVersion: 3.19.0 39 + Contact: live-patching@vger.kernel.org 40 + Description: 41 + The function directory contains attributes regarding the 42 + properties and state of the patched function. 43 + 44 + There are currently no such attributes.
+2
Documentation/oops-tracing.txt
··· 270 270 271 271 15: 'L' if a soft lockup has previously occurred on the system. 272 272 273 + 16: 'K' if the kernel has been live patched. 274 + 273 275 The primary reason for the 'Tainted: ' string is to tell kernel 274 276 debuggers if this is a clean kernel or if anything unusual has 275 277 occurred. Tainting is permanent: even if an offending module is
+1
Documentation/sysctl/kernel.txt
··· 843 843 8192 - An unsigned module has been loaded in a kernel supporting module 844 844 signature. 845 845 16384 - A soft lockup has previously occurred on the system. 846 + 32768 - The kernel has been live patched. 846 847 847 848 ============================================================== 848 849
+15
MAINTAINERS
··· 5853 5853 F: drivers/misc/lis3lv02d/ 5854 5854 F: drivers/platform/x86/hp_accel.c 5855 5855 5856 + LIVE PATCHING 5857 + M: Josh Poimboeuf <jpoimboe@redhat.com> 5858 + M: Seth Jennings <sjenning@redhat.com> 5859 + M: Jiri Kosina <jkosina@suse.cz> 5860 + M: Vojtech Pavlik <vojtech@suse.cz> 5861 + S: Maintained 5862 + F: kernel/livepatch/ 5863 + F: include/linux/livepatch.h 5864 + F: arch/x86/include/asm/livepatch.h 5865 + F: arch/x86/kernel/livepatch.c 5866 + F: Documentation/ABI/testing/sysfs-kernel-livepatch 5867 + F: samples/livepatch/ 5868 + L: live-patching@vger.kernel.org 5869 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching.git 5870 + 5856 5871 LLC (802.2) 5857 5872 M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> 5858 5873 S: Maintained
+3
arch/x86/Kconfig
··· 17 17 depends on 64BIT 18 18 select X86_DEV_DMA_OPS 19 19 select ARCH_USE_CMPXCHG_LOCKREF 20 + select HAVE_LIVEPATCH 20 21 21 22 ### Arch settings 22 23 config X86 ··· 2028 2027 2029 2028 This is used to work around broken boot loaders. This should 2030 2029 be set to 'N' under normal conditions. 2030 + 2031 + source "kernel/livepatch/Kconfig" 2031 2032 2032 2033 endmenu 2033 2034
+46
arch/x86/include/asm/livepatch.h
··· 1 + /* 2 + * livepatch.h - x86-specific Kernel Live Patching Core 3 + * 4 + * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 5 + * Copyright (C) 2014 SUSE 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License 9 + * as published by the Free Software Foundation; either version 2 10 + * of the License, or (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #ifndef _ASM_X86_LIVEPATCH_H 22 + #define _ASM_X86_LIVEPATCH_H 23 + 24 + #include <linux/module.h> 25 + #include <linux/ftrace.h> 26 + 27 + #ifdef CONFIG_LIVEPATCH 28 + static inline int klp_check_compiler_support(void) 29 + { 30 + #ifndef CC_USING_FENTRY 31 + return 1; 32 + #endif 33 + return 0; 34 + } 35 + extern int klp_write_module_reloc(struct module *mod, unsigned long type, 36 + unsigned long loc, unsigned long value); 37 + 38 + static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) 39 + { 40 + regs->ip = ip; 41 + } 42 + #else 43 + #error Live patching support is disabled; check CONFIG_LIVEPATCH 44 + #endif 45 + 46 + #endif /* _ASM_X86_LIVEPATCH_H */
+1
arch/x86/kernel/Makefile
··· 63 63 obj-y += apic/ 64 64 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o 65 65 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 66 + obj-$(CONFIG_LIVEPATCH) += livepatch.o 66 67 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 67 68 obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 68 69 obj-$(CONFIG_X86_TSC) += trace_clock.o
+90
arch/x86/kernel/livepatch.c
··· 1 + /* 2 + * livepatch.c - x86-specific Kernel Live Patching Core 3 + * 4 + * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 5 + * Copyright (C) 2014 SUSE 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License 9 + * as published by the Free Software Foundation; either version 2 10 + * of the License, or (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/uaccess.h> 23 + #include <asm/cacheflush.h> 24 + #include <asm/page_types.h> 25 + #include <asm/elf.h> 26 + #include <asm/livepatch.h> 27 + 28 + /** 29 + * klp_write_module_reloc() - write a relocation in a module 30 + * @mod: module in which the section to be modified is found 31 + * @type: ELF relocation type (see asm/elf.h) 32 + * @loc: address that the relocation should be written to 33 + * @value: relocation value (sym address + addend) 34 + * 35 + * This function writes a relocation to the specified location for 36 + * a particular module. 37 + */ 38 + int klp_write_module_reloc(struct module *mod, unsigned long type, 39 + unsigned long loc, unsigned long value) 40 + { 41 + int ret, numpages, size = 4; 42 + bool readonly; 43 + unsigned long val; 44 + unsigned long core = (unsigned long)mod->module_core; 45 + unsigned long core_ro_size = mod->core_ro_size; 46 + unsigned long core_size = mod->core_size; 47 + 48 + switch (type) { 49 + case R_X86_64_NONE: 50 + return 0; 51 + case R_X86_64_64: 52 + val = value; 53 + size = 8; 54 + break; 55 + case R_X86_64_32: 56 + val = (u32)value; 57 + break; 58 + case R_X86_64_32S: 59 + val = (s32)value; 60 + break; 61 + case R_X86_64_PC32: 62 + val = (u32)(value - loc); 63 + break; 64 + default: 65 + /* unsupported relocation type */ 66 + return -EINVAL; 67 + } 68 + 69 + if (loc < core || loc >= core + core_size) 70 + /* loc does not point to any symbol inside the module */ 71 + return -EINVAL; 72 + 73 + if (loc < core + core_ro_size) 74 + readonly = true; 75 + else 76 + readonly = false; 77 + 78 + /* determine if the relocation spans a page boundary */ 79 + numpages = ((loc & PAGE_MASK) == ((loc + size) & PAGE_MASK)) ? 1 : 2; 80 + 81 + if (readonly) 82 + set_memory_rw(loc & PAGE_MASK, numpages); 83 + 84 + ret = probe_kernel_write((void *)loc, &val, size); 85 + 86 + if (readonly) 87 + set_memory_ro(loc & PAGE_MASK, numpages); 88 + 89 + return ret; 90 + }
+1
include/linux/kernel.h
··· 471 471 #define TAINT_OOT_MODULE 12 472 472 #define TAINT_UNSIGNED_MODULE 13 473 473 #define TAINT_SOFTLOCKUP 14 474 + #define TAINT_LIVEPATCH 15 474 475 475 476 extern const char hex_asc[]; 476 477 #define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
+133
include/linux/livepatch.h
··· 1 + /* 2 + * livepatch.h - Kernel Live Patching Core 3 + * 4 + * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 5 + * Copyright (C) 2014 SUSE 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License 9 + * as published by the Free Software Foundation; either version 2 10 + * of the License, or (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #ifndef _LINUX_LIVEPATCH_H_ 22 + #define _LINUX_LIVEPATCH_H_ 23 + 24 + #include <linux/module.h> 25 + #include <linux/ftrace.h> 26 + 27 + #if IS_ENABLED(CONFIG_LIVEPATCH) 28 + 29 + #include <asm/livepatch.h> 30 + 31 + enum klp_state { 32 + KLP_DISABLED, 33 + KLP_ENABLED 34 + }; 35 + 36 + /** 37 + * struct klp_func - function structure for live patching 38 + * @old_name: name of the function to be patched 39 + * @new_func: pointer to the patched function code 40 + * @old_addr: a hint conveying at what address the old function 41 + * can be found (optional, vmlinux patches only) 42 + * @kobj: kobject for sysfs resources 43 + * @state: tracks function-level patch application state 44 + * @stack_node: list node for klp_ops func_stack list 45 + */ 46 + struct klp_func { 47 + /* external */ 48 + const char *old_name; 49 + void *new_func; 50 + /* 51 + * The old_addr field is optional and can be used to resolve 52 + * duplicate symbol names in the vmlinux object. If this 53 + * information is not present, the symbol is located by name 54 + * with kallsyms. If the name is not unique and old_addr is 55 + * not provided, the patch application fails as there is no 56 + * way to resolve the ambiguity. 57 + */ 58 + unsigned long old_addr; 59 + 60 + /* internal */ 61 + struct kobject kobj; 62 + enum klp_state state; 63 + struct list_head stack_node; 64 + }; 65 + 66 + /** 67 + * struct klp_reloc - relocation structure for live patching 68 + * @loc: address where the relocation will be written 69 + * @val: address of the referenced symbol (optional, 70 + * vmlinux patches only) 71 + * @type: ELF relocation type 72 + * @name: name of the referenced symbol (for lookup/verification) 73 + * @addend: offset from the referenced symbol 74 + * @external: symbol is either exported or within the live patch module itself 75 + */ 76 + struct klp_reloc { 77 + unsigned long loc; 78 + unsigned long val; 79 + unsigned long type; 80 + const char *name; 81 + int addend; 82 + int external; 83 + }; 84 + 85 + /** 86 + * struct klp_object - kernel object structure for live patching 87 + * @name: module name (or NULL for vmlinux) 88 + * @relocs: relocation entries to be applied at load time 89 + * @funcs: function entries for functions to be patched in the object 90 + * @kobj: kobject for sysfs resources 91 + * @mod: kernel module associated with the patched object 92 + * (NULL for vmlinux) 93 + * @state: tracks object-level patch application state 94 + */ 95 + struct klp_object { 96 + /* external */ 97 + const char *name; 98 + struct klp_reloc *relocs; 99 + struct klp_func *funcs; 100 + 101 + /* internal */ 102 + struct kobject *kobj; 103 + struct module *mod; 104 + enum klp_state state; 105 + }; 106 + 107 + /** 108 + * struct klp_patch - patch structure for live patching 109 + * @mod: reference to the live patch module 110 + * @objs: object entries for kernel objects to be patched 111 + * @list: list node for global list of registered patches 112 + * @kobj: kobject for sysfs resources 113 + * @state: tracks patch-level application state 114 + */ 115 + struct klp_patch { 116 + /* external */ 117 + struct module *mod; 118 + struct klp_object *objs; 119 + 120 + /* internal */ 121 + struct list_head list; 122 + struct kobject kobj; 123 + enum klp_state state; 124 + }; 125 + 126 + extern int klp_register_patch(struct klp_patch *); 127 + extern int klp_unregister_patch(struct klp_patch *); 128 + extern int klp_enable_patch(struct klp_patch *); 129 + extern int klp_disable_patch(struct klp_patch *); 130 + 131 + #endif /* CONFIG_LIVEPATCH */ 132 + 133 + #endif /* _LINUX_LIVEPATCH_H_ */
+1
kernel/Makefile
··· 26 26 obj-y += printk/ 27 27 obj-y += irq/ 28 28 obj-y += rcu/ 29 + obj-y += livepatch/ 29 30 30 31 obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o 31 32 obj-$(CONFIG_FREEZER) += freezer.o
+18
kernel/livepatch/Kconfig
··· 1 + config HAVE_LIVEPATCH 2 + bool 3 + help 4 + Arch supports kernel live patching 5 + 6 + config LIVEPATCH 7 + bool "Kernel Live Patching" 8 + depends on DYNAMIC_FTRACE_WITH_REGS 9 + depends on MODULES 10 + depends on SYSFS 11 + depends on KALLSYMS_ALL 12 + depends on HAVE_LIVEPATCH 13 + help 14 + Say Y here if you want to support kernel live patching. 15 + This option has no runtime impact until a kernel "patch" 16 + module uses the interface provided by this option to register 17 + a patch, causing calls to patched functions to be redirected 18 + to new function code contained in the patch module.
+3
kernel/livepatch/Makefile
··· 1 + obj-$(CONFIG_LIVEPATCH) += livepatch.o 2 + 3 + livepatch-objs := core.o
+1015
kernel/livepatch/core.c
··· 1 + /* 2 + * core.c - Kernel Live Patching Core 3 + * 4 + * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 5 + * Copyright (C) 2014 SUSE 6 + * 7 + * This program is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License 9 + * as published by the Free Software Foundation; either version 2 10 + * of the License, or (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 + 23 + #include <linux/module.h> 24 + #include <linux/kernel.h> 25 + #include <linux/mutex.h> 26 + #include <linux/slab.h> 27 + #include <linux/ftrace.h> 28 + #include <linux/list.h> 29 + #include <linux/kallsyms.h> 30 + #include <linux/livepatch.h> 31 + 32 + /** 33 + * struct klp_ops - structure for tracking registered ftrace ops structs 34 + * 35 + * A single ftrace_ops is shared between all enabled replacement functions 36 + * (klp_func structs) which have the same old_addr. This allows the switch 37 + * between function versions to happen instantaneously by updating the klp_ops 38 + * struct's func_stack list. The winner is the klp_func at the top of the 39 + * func_stack (front of the list). 40 + * 41 + * @node: node for the global klp_ops list 42 + * @func_stack: list head for the stack of klp_func's (active func is on top) 43 + * @fops: registered ftrace ops struct 44 + */ 45 + struct klp_ops { 46 + struct list_head node; 47 + struct list_head func_stack; 48 + struct ftrace_ops fops; 49 + }; 50 + 51 + /* 52 + * The klp_mutex protects the global lists and state transitions of any 53 + * structure reachable from them. References to any structure must be obtained 54 + * under mutex protection (except in klp_ftrace_handler(), which uses RCU to 55 + * ensure it gets consistent data). 56 + */ 57 + static DEFINE_MUTEX(klp_mutex); 58 + 59 + static LIST_HEAD(klp_patches); 60 + static LIST_HEAD(klp_ops); 61 + 62 + static struct kobject *klp_root_kobj; 63 + 64 + static struct klp_ops *klp_find_ops(unsigned long old_addr) 65 + { 66 + struct klp_ops *ops; 67 + struct klp_func *func; 68 + 69 + list_for_each_entry(ops, &klp_ops, node) { 70 + func = list_first_entry(&ops->func_stack, struct klp_func, 71 + stack_node); 72 + if (func->old_addr == old_addr) 73 + return ops; 74 + } 75 + 76 + return NULL; 77 + } 78 + 79 + static bool klp_is_module(struct klp_object *obj) 80 + { 81 + return obj->name; 82 + } 83 + 84 + static bool klp_is_object_loaded(struct klp_object *obj) 85 + { 86 + return !obj->name || obj->mod; 87 + } 88 + 89 + /* sets obj->mod if object is not vmlinux and module is found */ 90 + static void klp_find_object_module(struct klp_object *obj) 91 + { 92 + if (!klp_is_module(obj)) 93 + return; 94 + 95 + mutex_lock(&module_mutex); 96 + /* 97 + * We don't need to take a reference on the module here because we have 98 + * the klp_mutex, which is also taken by the module notifier. This 99 + * prevents any module from unloading until we release the klp_mutex. 100 + */ 101 + obj->mod = find_module(obj->name); 102 + mutex_unlock(&module_mutex); 103 + } 104 + 105 + /* klp_mutex must be held by caller */ 106 + static bool klp_is_patch_registered(struct klp_patch *patch) 107 + { 108 + struct klp_patch *mypatch; 109 + 110 + list_for_each_entry(mypatch, &klp_patches, list) 111 + if (mypatch == patch) 112 + return true; 113 + 114 + return false; 115 + } 116 + 117 + static bool klp_initialized(void) 118 + { 119 + return klp_root_kobj; 120 + } 121 + 122 + struct klp_find_arg { 123 + const char *objname; 124 + const char *name; 125 + unsigned long addr; 126 + /* 127 + * If count == 0, the symbol was not found. If count == 1, a unique 128 + * match was found and addr is set. If count > 1, there is 129 + * unresolvable ambiguity among "count" number of symbols with the same 130 + * name in the same object. 131 + */ 132 + unsigned long count; 133 + }; 134 + 135 + static int klp_find_callback(void *data, const char *name, 136 + struct module *mod, unsigned long addr) 137 + { 138 + struct klp_find_arg *args = data; 139 + 140 + if ((mod && !args->objname) || (!mod && args->objname)) 141 + return 0; 142 + 143 + if (strcmp(args->name, name)) 144 + return 0; 145 + 146 + if (args->objname && strcmp(args->objname, mod->name)) 147 + return 0; 148 + 149 + /* 150 + * args->addr might be overwritten if another match is found 151 + * but klp_find_object_symbol() handles this and only returns the 152 + * addr if count == 1. 153 + */ 154 + args->addr = addr; 155 + args->count++; 156 + 157 + return 0; 158 + } 159 + 160 + static int klp_find_object_symbol(const char *objname, const char *name, 161 + unsigned long *addr) 162 + { 163 + struct klp_find_arg args = { 164 + .objname = objname, 165 + .name = name, 166 + .addr = 0, 167 + .count = 0 168 + }; 169 + 170 + kallsyms_on_each_symbol(klp_find_callback, &args); 171 + 172 + if (args.count == 0) 173 + pr_err("symbol '%s' not found in symbol table\n", name); 174 + else if (args.count > 1) 175 + pr_err("unresolvable ambiguity (%lu matches) on symbol '%s' in object '%s'\n", 176 + args.count, name, objname); 177 + else { 178 + *addr = args.addr; 179 + return 0; 180 + } 181 + 182 + *addr = 0; 183 + return -EINVAL; 184 + } 185 + 186 + struct klp_verify_args { 187 + const char *name; 188 + const unsigned long addr; 189 + }; 190 + 191 + static int klp_verify_callback(void *data, const char *name, 192 + struct module *mod, unsigned long addr) 193 + { 194 + struct klp_verify_args *args = data; 195 + 196 + if (!mod && 197 + !strcmp(args->name, name) && 198 + args->addr == addr) 199 + return 1; 200 + 201 + return 0; 202 + } 203 + 204 + static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr) 205 + { 206 + struct klp_verify_args args = { 207 + .name = name, 208 + .addr = addr, 209 + }; 210 + 211 + if (kallsyms_on_each_symbol(klp_verify_callback, &args)) 212 + return 0; 213 + 214 + pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n", 215 + name, addr); 216 + return -EINVAL; 217 + } 218 + 219 + static int klp_find_verify_func_addr(struct klp_object *obj, 220 + struct klp_func *func) 221 + { 222 + int ret; 223 + 224 + #if defined(CONFIG_RANDOMIZE_BASE) 225 + /* KASLR is enabled, disregard old_addr from user */ 226 + func->old_addr = 0; 227 + #endif 228 + 229 + if (!func->old_addr || klp_is_module(obj)) 230 + ret = klp_find_object_symbol(obj->name, func->old_name, 231 + &func->old_addr); 232 + else 233 + ret = klp_verify_vmlinux_symbol(func->old_name, 234 + func->old_addr); 235 + 236 + return ret; 237 + } 238 + 239 + /* 240 + * external symbols are located outside the parent object (where the parent 241 + * object is either vmlinux or the kmod being patched). 242 + */ 243 + static int klp_find_external_symbol(struct module *pmod, const char *name, 244 + unsigned long *addr) 245 + { 246 + const struct kernel_symbol *sym; 247 + 248 + /* first, check if it's an exported symbol */ 249 + preempt_disable(); 250 + sym = find_symbol(name, NULL, NULL, true, true); 251 + preempt_enable(); 252 + if (sym) { 253 + *addr = sym->value; 254 + return 0; 255 + } 256 + 257 + /* otherwise check if it's in another .o within the patch module */ 258 + return klp_find_object_symbol(pmod->name, name, addr); 259 + } 260 + 261 + static int klp_write_object_relocations(struct module *pmod, 262 + struct klp_object *obj) 263 + { 264 + int ret; 265 + struct klp_reloc *reloc; 266 + 267 + if (WARN_ON(!klp_is_object_loaded(obj))) 268 + return -EINVAL; 269 + 270 + if (WARN_ON(!obj->relocs)) 271 + return -EINVAL; 272 + 273 + for (reloc = obj->relocs; reloc->name; reloc++) { 274 + if (!klp_is_module(obj)) { 275 + ret = klp_verify_vmlinux_symbol(reloc->name, 276 + reloc->val); 277 + if (ret) 278 + return ret; 279 + } else { 280 + /* module, reloc->val needs to be discovered */ 281 + if (reloc->external) 282 + ret = klp_find_external_symbol(pmod, 283 + reloc->name, 284 + &reloc->val); 285 + else 286 + ret = klp_find_object_symbol(obj->mod->name, 287 + reloc->name, 288 + &reloc->val); 289 + if (ret) 290 + return ret; 291 + } 292 + ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc, 293 + reloc->val + reloc->addend); 294 + if (ret) { 295 + pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n", 296 + reloc->name, reloc->val, ret); 297 + return ret; 298 + } 299 + } 300 + 301 + return 0; 302 + } 303 + 304 + static void notrace klp_ftrace_handler(unsigned long ip, 305 + unsigned long parent_ip, 306 + struct ftrace_ops *fops, 307 + struct pt_regs *regs) 308 + { 309 + struct klp_ops *ops; 310 + struct klp_func *func; 311 + 312 + ops = container_of(fops, struct klp_ops, fops); 313 + 314 + rcu_read_lock(); 315 + func = list_first_or_null_rcu(&ops->func_stack, struct klp_func, 316 + stack_node); 317 + rcu_read_unlock(); 318 + 319 + if (WARN_ON_ONCE(!func)) 320 + return; 321 + 322 + klp_arch_set_pc(regs, (unsigned long)func->new_func); 323 + } 324 + 325 + static int klp_disable_func(struct klp_func *func) 326 + { 327 + struct klp_ops *ops; 328 + int ret; 329 + 330 + if (WARN_ON(func->state != KLP_ENABLED)) 331 + return -EINVAL; 332 + 333 + if (WARN_ON(!func->old_addr)) 334 + return -EINVAL; 335 + 336 + ops = klp_find_ops(func->old_addr); 337 + if (WARN_ON(!ops)) 338 + return -EINVAL; 339 + 340 + if (list_is_singular(&ops->func_stack)) { 341 + ret = unregister_ftrace_function(&ops->fops); 342 + if (ret) { 343 + pr_err("failed to unregister ftrace handler for function '%s' (%d)\n", 344 + func->old_name, ret); 345 + return ret; 346 + } 347 + 348 + ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0); 349 + if (ret) 350 + pr_warn("function unregister succeeded but failed to clear the filter\n"); 351 + 352 + list_del_rcu(&func->stack_node); 353 + list_del(&ops->node); 354 + kfree(ops); 355 + } else { 356 + list_del_rcu(&func->stack_node); 357 + } 358 + 359 + func->state = KLP_DISABLED; 360 + 361 + return 0; 362 + } 363 + 364 + static int klp_enable_func(struct klp_func *func) 365 + { 366 + struct klp_ops *ops; 367 + int ret; 368 + 369 + if (WARN_ON(!func->old_addr)) 370 + return -EINVAL; 371 + 372 + if (WARN_ON(func->state != KLP_DISABLED)) 373 + return -EINVAL; 374 + 375 + ops = klp_find_ops(func->old_addr); 376 + if (!ops) { 377 + ops = kzalloc(sizeof(*ops), GFP_KERNEL); 378 + if (!ops) 379 + return -ENOMEM; 380 + 381 + ops->fops.func = klp_ftrace_handler; 382 + ops->fops.flags = FTRACE_OPS_FL_SAVE_REGS | 383 + FTRACE_OPS_FL_DYNAMIC | 384 + FTRACE_OPS_FL_IPMODIFY; 385 + 386 + list_add(&ops->node, &klp_ops); 387 + 388 + INIT_LIST_HEAD(&ops->func_stack); 389 + list_add_rcu(&func->stack_node, &ops->func_stack); 390 + 391 + ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 0, 0); 392 + if (ret) { 393 + pr_err("failed to set ftrace filter for function '%s' (%d)\n", 394 + func->old_name, ret); 395 + goto err; 396 + } 397 + 398 + ret = register_ftrace_function(&ops->fops); 399 + if (ret) { 400 + pr_err("failed to register ftrace handler for function '%s' (%d)\n", 401 + func->old_name, ret); 402 + ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0); 403 + goto err; 404 + } 405 + 406 + 407 + } else { 408 + list_add_rcu(&func->stack_node, &ops->func_stack); 409 + } 410 + 411 + func->state = KLP_ENABLED; 412 + 413 + return 0; 414 + 415 + err: 416 + list_del_rcu(&func->stack_node); 417 + list_del(&ops->node); 418 + kfree(ops); 419 + return ret; 420 + } 421 + 422 + static int klp_disable_object(struct klp_object *obj) 423 + { 424 + struct klp_func *func; 425 + int ret; 426 + 427 + for (func = obj->funcs; func->old_name; func++) { 428 + if (func->state != KLP_ENABLED) 429 + continue; 430 + 431 + ret = klp_disable_func(func); 432 + if (ret) 433 + return ret; 434 + } 435 + 436 + obj->state = KLP_DISABLED; 437 + 438 + return 0; 439 + } 440 + 441 + static int klp_enable_object(struct klp_object *obj) 442 + { 443 + struct klp_func *func; 444 + int ret; 445 + 446 + if (WARN_ON(obj->state != KLP_DISABLED)) 447 + return -EINVAL; 448 + 449 + if (WARN_ON(!klp_is_object_loaded(obj))) 450 + return -EINVAL; 451 + 452 + for (func = obj->funcs; func->old_name; func++) { 453 + ret = klp_enable_func(func); 454 + if (ret) 455 + goto unregister; 456 + } 457 + obj->state = KLP_ENABLED; 458 + 459 + return 0; 460 + 461 + unregister: 462 + WARN_ON(klp_disable_object(obj)); 463 + return ret; 464 + } 465 + 466 + static int __klp_disable_patch(struct klp_patch *patch) 467 + { 468 + struct klp_object *obj; 469 + int ret; 470 + 471 + /* enforce stacking: only the last enabled patch can be disabled */ 472 + if (!list_is_last(&patch->list, &klp_patches) && 473 + list_next_entry(patch, list)->state == KLP_ENABLED) 474 + return -EBUSY; 475 + 476 + pr_notice("disabling patch '%s'\n", patch->mod->name); 477 + 478 + for (obj = patch->objs; obj->funcs; obj++) { 479 + if (obj->state != KLP_ENABLED) 480 + continue; 481 + 482 + ret = klp_disable_object(obj); 483 + if (ret) 484 + return ret; 485 + } 486 + 487 + patch->state = KLP_DISABLED; 488 + 489 + return 0; 490 + } 491 + 492 + /** 493 + * klp_disable_patch() - disables a registered patch 494 + * @patch: The registered, enabled patch to be disabled 495 + * 496 + * Unregisters the patched functions from ftrace. 497 + * 498 + * Return: 0 on success, otherwise error 499 + */ 500 + int klp_disable_patch(struct klp_patch *patch) 501 + { 502 + int ret; 503 + 504 + mutex_lock(&klp_mutex); 505 + 506 + if (!klp_is_patch_registered(patch)) { 507 + ret = -EINVAL; 508 + goto err; 509 + } 510 + 511 + if (patch->state == KLP_DISABLED) { 512 + ret = -EINVAL; 513 + goto err; 514 + } 515 + 516 + ret = __klp_disable_patch(patch); 517 + 518 + err: 519 + mutex_unlock(&klp_mutex); 520 + return ret; 521 + } 522 + EXPORT_SYMBOL_GPL(klp_disable_patch); 523 + 524 + static int __klp_enable_patch(struct klp_patch *patch) 525 + { 526 + struct klp_object *obj; 527 + int ret; 528 + 529 + if (WARN_ON(patch->state != KLP_DISABLED)) 530 + return -EINVAL; 531 + 532 + /* enforce stacking: only the first disabled patch can be enabled */ 533 + if (patch->list.prev != &klp_patches && 534 + list_prev_entry(patch, list)->state == KLP_DISABLED) 535 + return -EBUSY; 536 + 537 + pr_notice_once("tainting kernel with TAINT_LIVEPATCH\n"); 538 + add_taint(TAINT_LIVEPATCH, LOCKDEP_STILL_OK); 539 + 540 + pr_notice("enabling patch '%s'\n", patch->mod->name); 541 + 542 + for (obj = patch->objs; obj->funcs; obj++) { 543 + klp_find_object_module(obj); 544 + 545 + if (!klp_is_object_loaded(obj)) 546 + continue; 547 + 548 + ret = klp_enable_object(obj); 549 + if (ret) 550 + goto unregister; 551 + } 552 + 553 + patch->state = KLP_ENABLED; 554 + 555 + return 0; 556 + 557 + unregister: 558 + WARN_ON(__klp_disable_patch(patch)); 559 + return ret; 560 + } 561 + 562 + /** 563 + * klp_enable_patch() - enables a registered patch 564 + * @patch: The registered, disabled patch to be enabled 565 + * 566 + * Performs the needed symbol lookups and code relocations, 567 + * then registers the patched functions with ftrace. 568 + * 569 + * Return: 0 on success, otherwise error 570 + */ 571 + int klp_enable_patch(struct klp_patch *patch) 572 + { 573 + int ret; 574 + 575 + mutex_lock(&klp_mutex); 576 + 577 + if (!klp_is_patch_registered(patch)) { 578 + ret = -EINVAL; 579 + goto err; 580 + } 581 + 582 + ret = __klp_enable_patch(patch); 583 + 584 + err: 585 + mutex_unlock(&klp_mutex); 586 + return ret; 587 + } 588 + EXPORT_SYMBOL_GPL(klp_enable_patch); 589 + 590 + /* 591 + * Sysfs Interface 592 + * 593 + * /sys/kernel/livepatch 594 + * /sys/kernel/livepatch/<patch> 595 + * /sys/kernel/livepatch/<patch>/enabled 596 + * /sys/kernel/livepatch/<patch>/<object> 597 + * /sys/kernel/livepatch/<patch>/<object>/<func> 598 + */ 599 + 600 + static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, 601 + const char *buf, size_t count) 602 + { 603 + struct klp_patch *patch; 604 + int ret; 605 + unsigned long val; 606 + 607 + ret = kstrtoul(buf, 10, &val); 608 + if (ret) 609 + return -EINVAL; 610 + 611 + if (val != KLP_DISABLED && val != KLP_ENABLED) 612 + return -EINVAL; 613 + 614 + patch = container_of(kobj, struct klp_patch, kobj); 615 + 616 + mutex_lock(&klp_mutex); 617 + 618 + if (val == patch->state) { 619 + /* already in requested state */ 620 + ret = -EINVAL; 621 + goto err; 622 + } 623 + 624 + if (val == KLP_ENABLED) { 625 + ret = __klp_enable_patch(patch); 626 + if (ret) 627 + goto err; 628 + } else { 629 + ret = __klp_disable_patch(patch); 630 + if (ret) 631 + goto err; 632 + } 633 + 634 + mutex_unlock(&klp_mutex); 635 + 636 + return count; 637 + 638 + err: 639 + mutex_unlock(&klp_mutex); 640 + return ret; 641 + } 642 + 643 + static ssize_t enabled_show(struct kobject *kobj, 644 + struct kobj_attribute *attr, char *buf) 645 + { 646 + struct klp_patch *patch; 647 + 648 + patch = container_of(kobj, struct klp_patch, kobj); 649 + return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->state); 650 + } 651 + 652 + static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); 653 + static struct attribute *klp_patch_attrs[] = { 654 + &enabled_kobj_attr.attr, 655 + NULL 656 + }; 657 + 658 + static void klp_kobj_release_patch(struct kobject *kobj) 659 + { 660 + /* 661 + * Once we have a consistency model we'll need to module_put() the 662 + * patch module here. See klp_register_patch() for more details. 663 + */ 664 + } 665 + 666 + static struct kobj_type klp_ktype_patch = { 667 + .release = klp_kobj_release_patch, 668 + .sysfs_ops = &kobj_sysfs_ops, 669 + .default_attrs = klp_patch_attrs, 670 + }; 671 + 672 + static void klp_kobj_release_func(struct kobject *kobj) 673 + { 674 + } 675 + 676 + static struct kobj_type klp_ktype_func = { 677 + .release = klp_kobj_release_func, 678 + .sysfs_ops = &kobj_sysfs_ops, 679 + }; 680 + 681 + /* 682 + * Free all functions' kobjects in the array up to some limit. When limit is 683 + * NULL, all kobjects are freed. 684 + */ 685 + static void klp_free_funcs_limited(struct klp_object *obj, 686 + struct klp_func *limit) 687 + { 688 + struct klp_func *func; 689 + 690 + for (func = obj->funcs; func->old_name && func != limit; func++) 691 + kobject_put(&func->kobj); 692 + } 693 + 694 + /* Clean up when a patched object is unloaded */ 695 + static void klp_free_object_loaded(struct klp_object *obj) 696 + { 697 + struct klp_func *func; 698 + 699 + obj->mod = NULL; 700 + 701 + for (func = obj->funcs; func->old_name; func++) 702 + func->old_addr = 0; 703 + } 704 + 705 + /* 706 + * Free all objects' kobjects in the array up to some limit. When limit is 707 + * NULL, all kobjects are freed. 708 + */ 709 + static void klp_free_objects_limited(struct klp_patch *patch, 710 + struct klp_object *limit) 711 + { 712 + struct klp_object *obj; 713 + 714 + for (obj = patch->objs; obj->funcs && obj != limit; obj++) { 715 + klp_free_funcs_limited(obj, NULL); 716 + kobject_put(obj->kobj); 717 + } 718 + } 719 + 720 + static void klp_free_patch(struct klp_patch *patch) 721 + { 722 + klp_free_objects_limited(patch, NULL); 723 + if (!list_empty(&patch->list)) 724 + list_del(&patch->list); 725 + kobject_put(&patch->kobj); 726 + } 727 + 728 + static int klp_init_func(struct klp_object *obj, struct klp_func *func) 729 + { 730 + INIT_LIST_HEAD(&func->stack_node); 731 + func->state = KLP_DISABLED; 732 + 733 + return kobject_init_and_add(&func->kobj, &klp_ktype_func, 734 + obj->kobj, func->old_name); 735 + } 736 + 737 + /* parts of the initialization that is done only when the object is loaded */ 738 + static int klp_init_object_loaded(struct klp_patch *patch, 739 + struct klp_object *obj) 740 + { 741 + struct klp_func *func; 742 + int ret; 743 + 744 + if (obj->relocs) { 745 + ret = klp_write_object_relocations(patch->mod, obj); 746 + if (ret) 747 + return ret; 748 + } 749 + 750 + for (func = obj->funcs; func->old_name; func++) { 751 + ret = klp_find_verify_func_addr(obj, func); 752 + if (ret) 753 + return ret; 754 + } 755 + 756 + return 0; 757 + } 758 + 759 + static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) 760 + { 761 + struct klp_func *func; 762 + int ret; 763 + const char *name; 764 + 765 + if (!obj->funcs) 766 + return -EINVAL; 767 + 768 + obj->state = KLP_DISABLED; 769 + 770 + klp_find_object_module(obj); 771 + 772 + name = klp_is_module(obj) ? obj->name : "vmlinux"; 773 + obj->kobj = kobject_create_and_add(name, &patch->kobj); 774 + if (!obj->kobj) 775 + return -ENOMEM; 776 + 777 + for (func = obj->funcs; func->old_name; func++) { 778 + ret = klp_init_func(obj, func); 779 + if (ret) 780 + goto free; 781 + } 782 + 783 + if (klp_is_object_loaded(obj)) { 784 + ret = klp_init_object_loaded(patch, obj); 785 + if (ret) 786 + goto free; 787 + } 788 + 789 + return 0; 790 + 791 + free: 792 + klp_free_funcs_limited(obj, func); 793 + kobject_put(obj->kobj); 794 + return ret; 795 + } 796 + 797 + static int klp_init_patch(struct klp_patch *patch) 798 + { 799 + struct klp_object *obj; 800 + int ret; 801 + 802 + if (!patch->objs) 803 + return -EINVAL; 804 + 805 + mutex_lock(&klp_mutex); 806 + 807 + patch->state = KLP_DISABLED; 808 + 809 + ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, 810 + klp_root_kobj, patch->mod->name); 811 + if (ret) 812 + goto unlock; 813 + 814 + for (obj = patch->objs; obj->funcs; obj++) { 815 + ret = klp_init_object(patch, obj); 816 + if (ret) 817 + goto free; 818 + } 819 + 820 + list_add_tail(&patch->list, &klp_patches); 821 + 822 + mutex_unlock(&klp_mutex); 823 + 824 + return 0; 825 + 826 + free: 827 + klp_free_objects_limited(patch, obj); 828 + kobject_put(&patch->kobj); 829 + unlock: 830 + mutex_unlock(&klp_mutex); 831 + return ret; 832 + } 833 + 834 + /** 835 + * klp_unregister_patch() - unregisters a patch 836 + * @patch: Disabled patch to be unregistered 837 + * 838 + * Frees the data structures and removes the sysfs interface. 839 + * 840 + * Return: 0 on success, otherwise error 841 + */ 842 + int klp_unregister_patch(struct klp_patch *patch) 843 + { 844 + int ret = 0; 845 + 846 + mutex_lock(&klp_mutex); 847 + 848 + if (!klp_is_patch_registered(patch)) { 849 + ret = -EINVAL; 850 + goto out; 851 + } 852 + 853 + if (patch->state == KLP_ENABLED) { 854 + ret = -EBUSY; 855 + goto out; 856 + } 857 + 858 + klp_free_patch(patch); 859 + 860 + out: 861 + mutex_unlock(&klp_mutex); 862 + return ret; 863 + } 864 + EXPORT_SYMBOL_GPL(klp_unregister_patch); 865 + 866 + /** 867 + * klp_register_patch() - registers a patch 868 + * @patch: Patch to be registered 869 + * 870 + * Initializes the data structure associated with the patch and 871 + * creates the sysfs interface. 872 + * 873 + * Return: 0 on success, otherwise error 874 + */ 875 + int klp_register_patch(struct klp_patch *patch) 876 + { 877 + int ret; 878 + 879 + if (!klp_initialized()) 880 + return -ENODEV; 881 + 882 + if (!patch || !patch->mod) 883 + return -EINVAL; 884 + 885 + /* 886 + * A reference is taken on the patch module to prevent it from being 887 + * unloaded. Right now, we don't allow patch modules to unload since 888 + * there is currently no method to determine if a thread is still 889 + * running in the patched code contained in the patch module once 890 + * the ftrace registration is successful. 891 + */ 892 + if (!try_module_get(patch->mod)) 893 + return -ENODEV; 894 + 895 + ret = klp_init_patch(patch); 896 + if (ret) 897 + module_put(patch->mod); 898 + 899 + return ret; 900 + } 901 + EXPORT_SYMBOL_GPL(klp_register_patch); 902 + 903 + static void klp_module_notify_coming(struct klp_patch *patch, 904 + struct klp_object *obj) 905 + { 906 + struct module *pmod = patch->mod; 907 + struct module *mod = obj->mod; 908 + int ret; 909 + 910 + ret = klp_init_object_loaded(patch, obj); 911 + if (ret) 912 + goto err; 913 + 914 + if (patch->state == KLP_DISABLED) 915 + return; 916 + 917 + pr_notice("applying patch '%s' to loading module '%s'\n", 918 + pmod->name, mod->name); 919 + 920 + ret = klp_enable_object(obj); 921 + if (!ret) 922 + return; 923 + 924 + err: 925 + pr_warn("failed to apply patch '%s' to module '%s' (%d)\n", 926 + pmod->name, mod->name, ret); 927 + } 928 + 929 + static void klp_module_notify_going(struct klp_patch *patch, 930 + struct klp_object *obj) 931 + { 932 + struct module *pmod = patch->mod; 933 + struct module *mod = obj->mod; 934 + int ret; 935 + 936 + if (patch->state == KLP_DISABLED) 937 + goto disabled; 938 + 939 + pr_notice("reverting patch '%s' on unloading module '%s'\n", 940 + pmod->name, mod->name); 941 + 942 + ret = klp_disable_object(obj); 943 + if (ret) 944 + pr_warn("failed to revert patch '%s' on module '%s' (%d)\n", 945 + pmod->name, mod->name, ret); 946 + 947 + disabled: 948 + klp_free_object_loaded(obj); 949 + } 950 + 951 + static int klp_module_notify(struct notifier_block *nb, unsigned long action, 952 + void *data) 953 + { 954 + struct module *mod = data; 955 + struct klp_patch *patch; 956 + struct klp_object *obj; 957 + 958 + if (action != MODULE_STATE_COMING && action != MODULE_STATE_GOING) 959 + return 0; 960 + 961 + mutex_lock(&klp_mutex); 962 + 963 + list_for_each_entry(patch, &klp_patches, list) { 964 + for (obj = patch->objs; obj->funcs; obj++) { 965 + if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 966 + continue; 967 + 968 + if (action == MODULE_STATE_COMING) { 969 + obj->mod = mod; 970 + klp_module_notify_coming(patch, obj); 971 + } else /* MODULE_STATE_GOING */ 972 + klp_module_notify_going(patch, obj); 973 + 974 + break; 975 + } 976 + } 977 + 978 + mutex_unlock(&klp_mutex); 979 + 980 + return 0; 981 + } 982 + 983 + static struct notifier_block klp_module_nb = { 984 + .notifier_call = klp_module_notify, 985 + .priority = INT_MIN+1, /* called late but before ftrace notifier */ 986 + }; 987 + 988 + static int klp_init(void) 989 + { 990 + int ret; 991 + 992 + ret = klp_check_compiler_support(); 993 + if (ret) { 994 + pr_info("Your compiler is too old; turning off.\n"); 995 + return -EINVAL; 996 + } 997 + 998 + ret = register_module_notifier(&klp_module_nb); 999 + if (ret) 1000 + return ret; 1001 + 1002 + klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj); 1003 + if (!klp_root_kobj) { 1004 + ret = -ENOMEM; 1005 + goto unregister; 1006 + } 1007 + 1008 + return 0; 1009 + 1010 + unregister: 1011 + unregister_module_notifier(&klp_module_nb); 1012 + return ret; 1013 + } 1014 + 1015 + module_init(klp_init);
+2
kernel/panic.c
··· 226 226 { TAINT_OOT_MODULE, 'O', ' ' }, 227 227 { TAINT_UNSIGNED_MODULE, 'E', ' ' }, 228 228 { TAINT_SOFTLOCKUP, 'L', ' ' }, 229 + { TAINT_LIVEPATCH, 'K', ' ' }, 229 230 }; 230 231 231 232 /** ··· 247 246 * 'O' - Out-of-tree module has been loaded. 248 247 * 'E' - Unsigned module has been loaded. 249 248 * 'L' - A soft lockup has previously occurred. 249 + * 'K' - Kernel has been live patched. 250 250 * 251 251 * The string is overwritten by the next call to print_tainted(). 252 252 */
+7
samples/Kconfig
··· 63 63 to communicate with an AMP-configured remote processor over 64 64 the rpmsg bus. 65 65 66 + config SAMPLE_LIVEPATCH 67 + tristate "Build live patching sample -- loadable modules only" 68 + depends on LIVEPATCH && m 69 + help 70 + Builds a sample live patch that replaces the procfs handler 71 + for /proc/cmdline to print "this has been live patched". 72 + 66 73 endif # SAMPLES
+1 -1
samples/Makefile
··· 1 1 # Makefile for Linux samples code 2 2 3 - obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ \ 3 + obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \ 4 4 hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/
+1
samples/livepatch/Makefile
··· 1 + obj-$(CONFIG_SAMPLE_LIVEPATCH) += livepatch-sample.o
+91
samples/livepatch/livepatch-sample.c
··· 1 + /* 2 + * livepatch-sample.c - Kernel Live Patching Sample Module 3 + * 4 + * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 2 9 + * of the License, or (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <linux/module.h> 21 + #include <linux/kernel.h> 22 + #include <linux/livepatch.h> 23 + 24 + /* 25 + * This (dumb) live patch overrides the function that prints the 26 + * kernel boot cmdline when /proc/cmdline is read. 27 + * 28 + * Example: 29 + * 30 + * $ cat /proc/cmdline 31 + * <your cmdline> 32 + * 33 + * $ insmod livepatch-sample.ko 34 + * $ cat /proc/cmdline 35 + * this has been live patched 36 + * 37 + * $ echo 0 > /sys/kernel/livepatch/livepatch_sample/enabled 38 + * $ cat /proc/cmdline 39 + * <your cmdline> 40 + */ 41 + 42 + #include <linux/seq_file.h> 43 + static int livepatch_cmdline_proc_show(struct seq_file *m, void *v) 44 + { 45 + seq_printf(m, "%s\n", "this has been live patched"); 46 + return 0; 47 + } 48 + 49 + static struct klp_func funcs[] = { 50 + { 51 + .old_name = "cmdline_proc_show", 52 + .new_func = livepatch_cmdline_proc_show, 53 + }, { } 54 + }; 55 + 56 + static struct klp_object objs[] = { 57 + { 58 + /* name being NULL means vmlinux */ 59 + .funcs = funcs, 60 + }, { } 61 + }; 62 + 63 + static struct klp_patch patch = { 64 + .mod = THIS_MODULE, 65 + .objs = objs, 66 + }; 67 + 68 + static int livepatch_init(void) 69 + { 70 + int ret; 71 + 72 + ret = klp_register_patch(&patch); 73 + if (ret) 74 + return ret; 75 + ret = klp_enable_patch(&patch); 76 + if (ret) { 77 + WARN_ON(klp_unregister_patch(&patch)); 78 + return ret; 79 + } 80 + return 0; 81 + } 82 + 83 + static void livepatch_exit(void) 84 + { 85 + WARN_ON(klp_disable_patch(&patch)); 86 + WARN_ON(klp_unregister_patch(&patch)); 87 + } 88 + 89 + module_init(livepatch_init); 90 + module_exit(livepatch_exit); 91 + MODULE_LICENSE("GPL");