hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/include/linux/livepatch.h
....@@ -1,21 +1,9 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * livepatch.h - Kernel Live Patching Core
34 *
45 * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
56 * 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/>.
197 */
208
219 #ifndef _LINUX_LIVEPATCH_H_
....@@ -24,6 +12,7 @@
2412 #include <linux/module.h>
2513 #include <linux/ftrace.h>
2614 #include <linux/completion.h>
15
+#include <linux/list.h>
2716
2817 #if IS_ENABLED(CONFIG_LIVEPATCH)
2918
....@@ -40,11 +29,13 @@
4029 * @new_func: pointer to the patched function code
4130 * @old_sympos: a hint indicating which symbol position the old function
4231 * can be found (optional)
43
- * @old_addr: the address of the function being patched
32
+ * @old_func: pointer to the function being patched
4433 * @kobj: kobject for sysfs resources
34
+ * @node: list node for klp_object func_list
4535 * @stack_node: list node for klp_ops func_stack list
4636 * @old_size: size of the old function
4737 * @new_size: size of the new function
38
+ * @nop: temporary patch to use the original code again; dyn. allocated
4839 * @patched: the func has been added to the klp_ops list
4940 * @transition: the func is currently being applied or reverted
5041 *
....@@ -77,10 +68,12 @@
7768 unsigned long old_sympos;
7869
7970 /* internal */
80
- unsigned long old_addr;
71
+ void *old_func;
8172 struct kobject kobj;
73
+ struct list_head node;
8274 struct list_head stack_node;
8375 unsigned long old_size, new_size;
76
+ bool nop;
8477 bool patched;
8578 bool transition;
8679 };
....@@ -115,8 +108,11 @@
115108 * @funcs: function entries for functions to be patched in the object
116109 * @callbacks: functions to be executed pre/post (un)patching
117110 * @kobj: kobject for sysfs resources
111
+ * @func_list: dynamic list of the function entries
112
+ * @node: list node for klp_patch obj_list
118113 * @mod: kernel module associated with the patched object
119114 * (NULL for vmlinux)
115
+ * @dynamic: temporary object for nop functions; dynamically allocated
120116 * @patched: the object's funcs have been added to the klp_ops list
121117 */
122118 struct klp_object {
....@@ -127,46 +123,77 @@
127123
128124 /* internal */
129125 struct kobject kobj;
126
+ struct list_head func_list;
127
+ struct list_head node;
130128 struct module *mod;
129
+ bool dynamic;
131130 bool patched;
131
+};
132
+
133
+/**
134
+ * struct klp_state - state of the system modified by the livepatch
135
+ * @id: system state identifier (non-zero)
136
+ * @version: version of the change
137
+ * @data: custom data
138
+ */
139
+struct klp_state {
140
+ unsigned long id;
141
+ unsigned int version;
142
+ void *data;
132143 };
133144
134145 /**
135146 * struct klp_patch - patch structure for live patching
136147 * @mod: reference to the live patch module
137148 * @objs: object entries for kernel objects to be patched
138
- * @list: list node for global list of registered patches
149
+ * @states: system states that can get modified
150
+ * @replace: replace all actively used patches
151
+ * @list: list node for global list of actively used patches
139152 * @kobj: kobject for sysfs resources
153
+ * @obj_list: dynamic list of the object entries
140154 * @enabled: the patch is enabled (but operation may be incomplete)
155
+ * @forced: was involved in a forced transition
156
+ * @free_work: patch cleanup from workqueue-context
141157 * @finish: for waiting till it is safe to remove the patch module
142158 */
143159 struct klp_patch {
144160 /* external */
145161 struct module *mod;
146162 struct klp_object *objs;
163
+ struct klp_state *states;
164
+ bool replace;
147165
148166 /* internal */
149167 struct list_head list;
150168 struct kobject kobj;
169
+ struct list_head obj_list;
151170 bool enabled;
171
+ bool forced;
172
+ struct work_struct free_work;
152173 struct completion finish;
153174 };
154175
155
-#define klp_for_each_object(patch, obj) \
176
+#define klp_for_each_object_static(patch, obj) \
156177 for (obj = patch->objs; obj->funcs || obj->name; obj++)
157178
158
-#define klp_for_each_func(obj, func) \
179
+#define klp_for_each_object_safe(patch, obj, tmp_obj) \
180
+ list_for_each_entry_safe(obj, tmp_obj, &patch->obj_list, node)
181
+
182
+#define klp_for_each_object(patch, obj) \
183
+ list_for_each_entry(obj, &patch->obj_list, node)
184
+
185
+#define klp_for_each_func_static(obj, func) \
159186 for (func = obj->funcs; \
160187 func->old_name || func->new_func || func->old_sympos; \
161188 func++)
162189
163
-int klp_register_patch(struct klp_patch *);
164
-int klp_unregister_patch(struct klp_patch *);
165
-int klp_enable_patch(struct klp_patch *);
166
-int klp_disable_patch(struct klp_patch *);
190
+#define klp_for_each_func_safe(obj, func, tmp_func) \
191
+ list_for_each_entry_safe(func, tmp_func, &obj->func_list, node)
167192
168
-void arch_klp_init_object_loaded(struct klp_patch *patch,
169
- struct klp_object *obj);
193
+#define klp_for_each_func(obj, func) \
194
+ list_for_each_entry(func, &obj->func_list, node)
195
+
196
+int klp_enable_patch(struct klp_patch *);
170197
171198 /* Called from the module loader during module coming/going states */
172199 int klp_module_coming(struct module *mod);
....@@ -201,6 +228,14 @@
201228 void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor);
202229 void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor);
203230
231
+struct klp_state *klp_get_state(struct klp_patch *patch, unsigned long id);
232
+struct klp_state *klp_get_prev_state(unsigned long id);
233
+
234
+int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
235
+ const char *shstrtab, const char *strtab,
236
+ unsigned int symindex, unsigned int secindex,
237
+ const char *objname);
238
+
204239 #else /* !CONFIG_LIVEPATCH */
205240
206241 static inline int klp_module_coming(struct module *mod) { return 0; }
....@@ -209,6 +244,15 @@
209244 static inline void klp_update_patch_state(struct task_struct *task) {}
210245 static inline void klp_copy_process(struct task_struct *child) {}
211246
247
+static inline
248
+int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
249
+ const char *shstrtab, const char *strtab,
250
+ unsigned int symindex, unsigned int secindex,
251
+ const char *objname)
252
+{
253
+ return 0;
254
+}
255
+
212256 #endif /* CONFIG_LIVEPATCH */
213257
214258 #endif /* _LINUX_LIVEPATCH_H_ */