summaryrefslogtreecommitdiffstats
path: root/include/linux/livepatch.h
diff options
context:
space:
mode:
authorSeth Jennings <sjenning@redhat.com>2014-12-16 12:58:19 -0500
committerJiri Kosina <jkosina@suse.cz>2014-12-22 09:40:49 -0500
commitb700e7f03df5d92f85fa5247fe1f557528d3363d (patch)
treed6da8186d1bd9c42bbd5db9f23deeb1e47bb6dec /include/linux/livepatch.h
parentc5f4546593e9911800f0926c1090959b58bc5c93 (diff)
livepatch: kernel: add support for live patching
This commit introduces code for the live patching core. It implements an ftrace-based mechanism and kernel interface for doing live patching of kernel and kernel module functions. It represents the greatest common functionality set between kpatch and kgraft and can accept patches built using either method. This first version does not implement any consistency mechanism that ensures that old and new code do not run together. In practice, ~90% of CVEs are safe to apply in this way, since they simply add a conditional check. However, any function change that can not execute safely with the old version of the function can _not_ be safely applied in this version. [ jkosina@suse.cz: due to the number of contributions that got folded into this original patch from Seth Jennings, add SUSE's copyright as well, as discussed via e-mail ] Signed-off-by: Seth Jennings <sjenning@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Reviewed-by: Miroslav Benes <mbenes@suse.cz> Reviewed-by: Petr Mladek <pmladek@suse.cz> Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Miroslav Benes <mbenes@suse.cz> Signed-off-by: Petr Mladek <pmladek@suse.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'include/linux/livepatch.h')
-rw-r--r--include/linux/livepatch.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
new file mode 100644
index 000000000000..950bc615842f
--- /dev/null
+++ b/include/linux/livepatch.h
@@ -0,0 +1,133 @@
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_LIVE_PATCHING)
28
29#include <asm/livepatch.h>
30
31enum 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 * @fops: ftrace operations structure
44 * @state: tracks function-level patch application state
45 */
46struct 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 struct ftrace_ops *fops;
63 enum klp_state state;
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 */
76struct 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 */
95struct 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 */
115struct 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
126extern int klp_register_patch(struct klp_patch *);
127extern int klp_unregister_patch(struct klp_patch *);
128extern int klp_enable_patch(struct klp_patch *);
129extern int klp_disable_patch(struct klp_patch *);
130
131#endif /* CONFIG_LIVE_PATCHING */
132
133#endif /* _LINUX_LIVEPATCH_H_ */