xref: /linux-6.15/kernel/livepatch/core.c (revision e41b104c)
1b700e7f0SSeth Jennings /*
2b700e7f0SSeth Jennings  * core.c - Kernel Live Patching Core
3b700e7f0SSeth Jennings  *
4b700e7f0SSeth Jennings  * Copyright (C) 2014 Seth Jennings <[email protected]>
5b700e7f0SSeth Jennings  * Copyright (C) 2014 SUSE
6b700e7f0SSeth Jennings  *
7b700e7f0SSeth Jennings  * This program is free software; you can redistribute it and/or
8b700e7f0SSeth Jennings  * modify it under the terms of the GNU General Public License
9b700e7f0SSeth Jennings  * as published by the Free Software Foundation; either version 2
10b700e7f0SSeth Jennings  * of the License, or (at your option) any later version.
11b700e7f0SSeth Jennings  *
12b700e7f0SSeth Jennings  * This program is distributed in the hope that it will be useful,
13b700e7f0SSeth Jennings  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14b700e7f0SSeth Jennings  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b700e7f0SSeth Jennings  * GNU General Public License for more details.
16b700e7f0SSeth Jennings  *
17b700e7f0SSeth Jennings  * You should have received a copy of the GNU General Public License
18b700e7f0SSeth Jennings  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19b700e7f0SSeth Jennings  */
20b700e7f0SSeth Jennings 
21b700e7f0SSeth Jennings #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22b700e7f0SSeth Jennings 
23b700e7f0SSeth Jennings #include <linux/module.h>
24b700e7f0SSeth Jennings #include <linux/kernel.h>
25b700e7f0SSeth Jennings #include <linux/mutex.h>
26b700e7f0SSeth Jennings #include <linux/slab.h>
27b700e7f0SSeth Jennings #include <linux/ftrace.h>
28b700e7f0SSeth Jennings #include <linux/list.h>
29b700e7f0SSeth Jennings #include <linux/kallsyms.h>
30b700e7f0SSeth Jennings #include <linux/livepatch.h>
31b700e7f0SSeth Jennings 
323c33f5b9SJosh Poimboeuf /**
333c33f5b9SJosh Poimboeuf  * struct klp_ops - structure for tracking registered ftrace ops structs
343c33f5b9SJosh Poimboeuf  *
353c33f5b9SJosh Poimboeuf  * A single ftrace_ops is shared between all enabled replacement functions
363c33f5b9SJosh Poimboeuf  * (klp_func structs) which have the same old_addr.  This allows the switch
373c33f5b9SJosh Poimboeuf  * between function versions to happen instantaneously by updating the klp_ops
383c33f5b9SJosh Poimboeuf  * struct's func_stack list.  The winner is the klp_func at the top of the
393c33f5b9SJosh Poimboeuf  * func_stack (front of the list).
403c33f5b9SJosh Poimboeuf  *
413c33f5b9SJosh Poimboeuf  * @node:	node for the global klp_ops list
423c33f5b9SJosh Poimboeuf  * @func_stack:	list head for the stack of klp_func's (active func is on top)
433c33f5b9SJosh Poimboeuf  * @fops:	registered ftrace ops struct
44b700e7f0SSeth Jennings  */
453c33f5b9SJosh Poimboeuf struct klp_ops {
463c33f5b9SJosh Poimboeuf 	struct list_head node;
473c33f5b9SJosh Poimboeuf 	struct list_head func_stack;
483c33f5b9SJosh Poimboeuf 	struct ftrace_ops fops;
493c33f5b9SJosh Poimboeuf };
50b700e7f0SSeth Jennings 
513c33f5b9SJosh Poimboeuf /*
523c33f5b9SJosh Poimboeuf  * The klp_mutex protects the global lists and state transitions of any
533c33f5b9SJosh Poimboeuf  * structure reachable from them.  References to any structure must be obtained
543c33f5b9SJosh Poimboeuf  * under mutex protection (except in klp_ftrace_handler(), which uses RCU to
553c33f5b9SJosh Poimboeuf  * ensure it gets consistent data).
563c33f5b9SJosh Poimboeuf  */
57b700e7f0SSeth Jennings static DEFINE_MUTEX(klp_mutex);
583c33f5b9SJosh Poimboeuf 
59b700e7f0SSeth Jennings static LIST_HEAD(klp_patches);
603c33f5b9SJosh Poimboeuf static LIST_HEAD(klp_ops);
61b700e7f0SSeth Jennings 
62b700e7f0SSeth Jennings static struct kobject *klp_root_kobj;
63b700e7f0SSeth Jennings 
643c33f5b9SJosh Poimboeuf static struct klp_ops *klp_find_ops(unsigned long old_addr)
653c33f5b9SJosh Poimboeuf {
663c33f5b9SJosh Poimboeuf 	struct klp_ops *ops;
673c33f5b9SJosh Poimboeuf 	struct klp_func *func;
683c33f5b9SJosh Poimboeuf 
693c33f5b9SJosh Poimboeuf 	list_for_each_entry(ops, &klp_ops, node) {
703c33f5b9SJosh Poimboeuf 		func = list_first_entry(&ops->func_stack, struct klp_func,
713c33f5b9SJosh Poimboeuf 					stack_node);
723c33f5b9SJosh Poimboeuf 		if (func->old_addr == old_addr)
733c33f5b9SJosh Poimboeuf 			return ops;
743c33f5b9SJosh Poimboeuf 	}
753c33f5b9SJosh Poimboeuf 
763c33f5b9SJosh Poimboeuf 	return NULL;
773c33f5b9SJosh Poimboeuf }
783c33f5b9SJosh Poimboeuf 
79b700e7f0SSeth Jennings static bool klp_is_module(struct klp_object *obj)
80b700e7f0SSeth Jennings {
81b700e7f0SSeth Jennings 	return obj->name;
82b700e7f0SSeth Jennings }
83b700e7f0SSeth Jennings 
84b700e7f0SSeth Jennings static bool klp_is_object_loaded(struct klp_object *obj)
85b700e7f0SSeth Jennings {
86b700e7f0SSeth Jennings 	return !obj->name || obj->mod;
87b700e7f0SSeth Jennings }
88b700e7f0SSeth Jennings 
89b700e7f0SSeth Jennings /* sets obj->mod if object is not vmlinux and module is found */
90b700e7f0SSeth Jennings static void klp_find_object_module(struct klp_object *obj)
91b700e7f0SSeth Jennings {
928cb2c2dcSPetr Mladek 	struct module *mod;
938cb2c2dcSPetr Mladek 
94b700e7f0SSeth Jennings 	if (!klp_is_module(obj))
95b700e7f0SSeth Jennings 		return;
96b700e7f0SSeth Jennings 
97b700e7f0SSeth Jennings 	mutex_lock(&module_mutex);
98b700e7f0SSeth Jennings 	/*
998cb2c2dcSPetr Mladek 	 * We do not want to block removal of patched modules and therefore
1008cb2c2dcSPetr Mladek 	 * we do not take a reference here. The patches are removed by
1018cb2c2dcSPetr Mladek 	 * a going module handler instead.
102b700e7f0SSeth Jennings 	 */
1038cb2c2dcSPetr Mladek 	mod = find_module(obj->name);
1048cb2c2dcSPetr Mladek 	/*
1058cb2c2dcSPetr Mladek 	 * Do not mess work of the module coming and going notifiers.
1068cb2c2dcSPetr Mladek 	 * Note that the patch might still be needed before the going handler
1078cb2c2dcSPetr Mladek 	 * is called. Module functions can be called even in the GOING state
1088cb2c2dcSPetr Mladek 	 * until mod->exit() finishes. This is especially important for
1098cb2c2dcSPetr Mladek 	 * patches that modify semantic of the functions.
1108cb2c2dcSPetr Mladek 	 */
1118cb2c2dcSPetr Mladek 	if (mod && mod->klp_alive)
1128cb2c2dcSPetr Mladek 		obj->mod = mod;
1138cb2c2dcSPetr Mladek 
114b700e7f0SSeth Jennings 	mutex_unlock(&module_mutex);
115b700e7f0SSeth Jennings }
116b700e7f0SSeth Jennings 
117b700e7f0SSeth Jennings /* klp_mutex must be held by caller */
118b700e7f0SSeth Jennings static bool klp_is_patch_registered(struct klp_patch *patch)
119b700e7f0SSeth Jennings {
120b700e7f0SSeth Jennings 	struct klp_patch *mypatch;
121b700e7f0SSeth Jennings 
122b700e7f0SSeth Jennings 	list_for_each_entry(mypatch, &klp_patches, list)
123b700e7f0SSeth Jennings 		if (mypatch == patch)
124b700e7f0SSeth Jennings 			return true;
125b700e7f0SSeth Jennings 
126b700e7f0SSeth Jennings 	return false;
127b700e7f0SSeth Jennings }
128b700e7f0SSeth Jennings 
129b700e7f0SSeth Jennings static bool klp_initialized(void)
130b700e7f0SSeth Jennings {
131e76ff06aSNicholas Mc Guire 	return !!klp_root_kobj;
132b700e7f0SSeth Jennings }
133b700e7f0SSeth Jennings 
134b700e7f0SSeth Jennings struct klp_find_arg {
135b700e7f0SSeth Jennings 	const char *objname;
136b700e7f0SSeth Jennings 	const char *name;
137b700e7f0SSeth Jennings 	unsigned long addr;
138b700e7f0SSeth Jennings 	/*
139b700e7f0SSeth Jennings 	 * If count == 0, the symbol was not found. If count == 1, a unique
140b700e7f0SSeth Jennings 	 * match was found and addr is set.  If count > 1, there is
141b700e7f0SSeth Jennings 	 * unresolvable ambiguity among "count" number of symbols with the same
142b700e7f0SSeth Jennings 	 * name in the same object.
143b700e7f0SSeth Jennings 	 */
144b700e7f0SSeth Jennings 	unsigned long count;
145b700e7f0SSeth Jennings };
146b700e7f0SSeth Jennings 
147b700e7f0SSeth Jennings static int klp_find_callback(void *data, const char *name,
148b700e7f0SSeth Jennings 			     struct module *mod, unsigned long addr)
149b700e7f0SSeth Jennings {
150b700e7f0SSeth Jennings 	struct klp_find_arg *args = data;
151b700e7f0SSeth Jennings 
152b700e7f0SSeth Jennings 	if ((mod && !args->objname) || (!mod && args->objname))
153b700e7f0SSeth Jennings 		return 0;
154b700e7f0SSeth Jennings 
155b700e7f0SSeth Jennings 	if (strcmp(args->name, name))
156b700e7f0SSeth Jennings 		return 0;
157b700e7f0SSeth Jennings 
158b700e7f0SSeth Jennings 	if (args->objname && strcmp(args->objname, mod->name))
159b700e7f0SSeth Jennings 		return 0;
160b700e7f0SSeth Jennings 
161b700e7f0SSeth Jennings 	/*
162b700e7f0SSeth Jennings 	 * args->addr might be overwritten if another match is found
163b700e7f0SSeth Jennings 	 * but klp_find_object_symbol() handles this and only returns the
164b700e7f0SSeth Jennings 	 * addr if count == 1.
165b700e7f0SSeth Jennings 	 */
166b700e7f0SSeth Jennings 	args->addr = addr;
167b700e7f0SSeth Jennings 	args->count++;
168b700e7f0SSeth Jennings 
169b700e7f0SSeth Jennings 	return 0;
170b700e7f0SSeth Jennings }
171b700e7f0SSeth Jennings 
172b700e7f0SSeth Jennings static int klp_find_object_symbol(const char *objname, const char *name,
173b700e7f0SSeth Jennings 				  unsigned long *addr)
174b700e7f0SSeth Jennings {
175b700e7f0SSeth Jennings 	struct klp_find_arg args = {
176b700e7f0SSeth Jennings 		.objname = objname,
177b700e7f0SSeth Jennings 		.name = name,
178b700e7f0SSeth Jennings 		.addr = 0,
179b700e7f0SSeth Jennings 		.count = 0
180b700e7f0SSeth Jennings 	};
181b700e7f0SSeth Jennings 
1829a1bd63cSMiroslav Benes 	mutex_lock(&module_mutex);
183b700e7f0SSeth Jennings 	kallsyms_on_each_symbol(klp_find_callback, &args);
1849a1bd63cSMiroslav Benes 	mutex_unlock(&module_mutex);
185b700e7f0SSeth Jennings 
186b700e7f0SSeth Jennings 	if (args.count == 0)
187b700e7f0SSeth Jennings 		pr_err("symbol '%s' not found in symbol table\n", name);
188b700e7f0SSeth Jennings 	else if (args.count > 1)
189b700e7f0SSeth Jennings 		pr_err("unresolvable ambiguity (%lu matches) on symbol '%s' in object '%s'\n",
190b700e7f0SSeth Jennings 		       args.count, name, objname);
191b700e7f0SSeth Jennings 	else {
192b700e7f0SSeth Jennings 		*addr = args.addr;
193b700e7f0SSeth Jennings 		return 0;
194b700e7f0SSeth Jennings 	}
195b700e7f0SSeth Jennings 
196b700e7f0SSeth Jennings 	*addr = 0;
197b700e7f0SSeth Jennings 	return -EINVAL;
198b700e7f0SSeth Jennings }
199b700e7f0SSeth Jennings 
200b700e7f0SSeth Jennings struct klp_verify_args {
201b700e7f0SSeth Jennings 	const char *name;
202b700e7f0SSeth Jennings 	const unsigned long addr;
203b700e7f0SSeth Jennings };
204b700e7f0SSeth Jennings 
205b700e7f0SSeth Jennings static int klp_verify_callback(void *data, const char *name,
206b700e7f0SSeth Jennings 			       struct module *mod, unsigned long addr)
207b700e7f0SSeth Jennings {
208b700e7f0SSeth Jennings 	struct klp_verify_args *args = data;
209b700e7f0SSeth Jennings 
210b700e7f0SSeth Jennings 	if (!mod &&
211b700e7f0SSeth Jennings 	    !strcmp(args->name, name) &&
212b700e7f0SSeth Jennings 	    args->addr == addr)
213b700e7f0SSeth Jennings 		return 1;
214b700e7f0SSeth Jennings 
215b700e7f0SSeth Jennings 	return 0;
216b700e7f0SSeth Jennings }
217b700e7f0SSeth Jennings 
218b700e7f0SSeth Jennings static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr)
219b700e7f0SSeth Jennings {
220b700e7f0SSeth Jennings 	struct klp_verify_args args = {
221b700e7f0SSeth Jennings 		.name = name,
222b700e7f0SSeth Jennings 		.addr = addr,
223b700e7f0SSeth Jennings 	};
2249a1bd63cSMiroslav Benes 	int ret;
225b700e7f0SSeth Jennings 
2269a1bd63cSMiroslav Benes 	mutex_lock(&module_mutex);
2279a1bd63cSMiroslav Benes 	ret = kallsyms_on_each_symbol(klp_verify_callback, &args);
2289a1bd63cSMiroslav Benes 	mutex_unlock(&module_mutex);
229b700e7f0SSeth Jennings 
2309a1bd63cSMiroslav Benes 	if (!ret) {
231f638f4dcSJosh Poimboeuf 		pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n",
232b700e7f0SSeth Jennings 			name, addr);
233b700e7f0SSeth Jennings 		return -EINVAL;
234b700e7f0SSeth Jennings 	}
235b700e7f0SSeth Jennings 
2369a1bd63cSMiroslav Benes 	return 0;
2379a1bd63cSMiroslav Benes }
2389a1bd63cSMiroslav Benes 
239b700e7f0SSeth Jennings static int klp_find_verify_func_addr(struct klp_object *obj,
240b700e7f0SSeth Jennings 				     struct klp_func *func)
241b700e7f0SSeth Jennings {
242b700e7f0SSeth Jennings 	int ret;
243b700e7f0SSeth Jennings 
244b700e7f0SSeth Jennings #if defined(CONFIG_RANDOMIZE_BASE)
2455d4351baSJiri Kosina 	/* If KASLR has been enabled, adjust old_addr accordingly */
2465d4351baSJiri Kosina 	if (kaslr_enabled() && func->old_addr)
2475d4351baSJiri Kosina 		func->old_addr += kaslr_offset();
248b700e7f0SSeth Jennings #endif
249b700e7f0SSeth Jennings 
250b700e7f0SSeth Jennings 	if (!func->old_addr || klp_is_module(obj))
251b700e7f0SSeth Jennings 		ret = klp_find_object_symbol(obj->name, func->old_name,
252b700e7f0SSeth Jennings 					     &func->old_addr);
253b700e7f0SSeth Jennings 	else
254b700e7f0SSeth Jennings 		ret = klp_verify_vmlinux_symbol(func->old_name,
255b700e7f0SSeth Jennings 						func->old_addr);
256b700e7f0SSeth Jennings 
257b700e7f0SSeth Jennings 	return ret;
258b700e7f0SSeth Jennings }
259b700e7f0SSeth Jennings 
260b700e7f0SSeth Jennings /*
261b700e7f0SSeth Jennings  * external symbols are located outside the parent object (where the parent
262b700e7f0SSeth Jennings  * object is either vmlinux or the kmod being patched).
263b700e7f0SSeth Jennings  */
264b700e7f0SSeth Jennings static int klp_find_external_symbol(struct module *pmod, const char *name,
265b700e7f0SSeth Jennings 				    unsigned long *addr)
266b700e7f0SSeth Jennings {
267b700e7f0SSeth Jennings 	const struct kernel_symbol *sym;
268b700e7f0SSeth Jennings 
269b700e7f0SSeth Jennings 	/* first, check if it's an exported symbol */
270b700e7f0SSeth Jennings 	preempt_disable();
271b700e7f0SSeth Jennings 	sym = find_symbol(name, NULL, NULL, true, true);
272b700e7f0SSeth Jennings 	if (sym) {
273b700e7f0SSeth Jennings 		*addr = sym->value;
274c064a0deSPeter Zijlstra 		preempt_enable();
275b700e7f0SSeth Jennings 		return 0;
276b700e7f0SSeth Jennings 	}
277c064a0deSPeter Zijlstra 	preempt_enable();
278b700e7f0SSeth Jennings 
279b700e7f0SSeth Jennings 	/* otherwise check if it's in another .o within the patch module */
280b700e7f0SSeth Jennings 	return klp_find_object_symbol(pmod->name, name, addr);
281b700e7f0SSeth Jennings }
282b700e7f0SSeth Jennings 
283b700e7f0SSeth Jennings static int klp_write_object_relocations(struct module *pmod,
284b700e7f0SSeth Jennings 					struct klp_object *obj)
285b700e7f0SSeth Jennings {
286b700e7f0SSeth Jennings 	int ret;
287b700e7f0SSeth Jennings 	struct klp_reloc *reloc;
288b700e7f0SSeth Jennings 
289b700e7f0SSeth Jennings 	if (WARN_ON(!klp_is_object_loaded(obj)))
290b700e7f0SSeth Jennings 		return -EINVAL;
291b700e7f0SSeth Jennings 
292b700e7f0SSeth Jennings 	if (WARN_ON(!obj->relocs))
293b700e7f0SSeth Jennings 		return -EINVAL;
294b700e7f0SSeth Jennings 
295b700e7f0SSeth Jennings 	for (reloc = obj->relocs; reloc->name; reloc++) {
296b700e7f0SSeth Jennings 		if (!klp_is_module(obj)) {
297*e41b104cSZhou Chengming 
298*e41b104cSZhou Chengming #if defined(CONFIG_RANDOMIZE_BASE)
299*e41b104cSZhou Chengming 			/* If KASLR has been enabled, adjust old value accordingly */
300*e41b104cSZhou Chengming 			if (kaslr_enabled())
301*e41b104cSZhou Chengming 				reloc->val += kaslr_offset();
302*e41b104cSZhou Chengming #endif
303b700e7f0SSeth Jennings 			ret = klp_verify_vmlinux_symbol(reloc->name,
304b700e7f0SSeth Jennings 							reloc->val);
305b700e7f0SSeth Jennings 			if (ret)
306b700e7f0SSeth Jennings 				return ret;
307b700e7f0SSeth Jennings 		} else {
308b700e7f0SSeth Jennings 			/* module, reloc->val needs to be discovered */
309b700e7f0SSeth Jennings 			if (reloc->external)
310b700e7f0SSeth Jennings 				ret = klp_find_external_symbol(pmod,
311b700e7f0SSeth Jennings 							       reloc->name,
312b700e7f0SSeth Jennings 							       &reloc->val);
313b700e7f0SSeth Jennings 			else
314b700e7f0SSeth Jennings 				ret = klp_find_object_symbol(obj->mod->name,
315b700e7f0SSeth Jennings 							     reloc->name,
316b700e7f0SSeth Jennings 							     &reloc->val);
317b700e7f0SSeth Jennings 			if (ret)
318b700e7f0SSeth Jennings 				return ret;
319b700e7f0SSeth Jennings 		}
320b700e7f0SSeth Jennings 		ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc,
321b700e7f0SSeth Jennings 					     reloc->val + reloc->addend);
322b700e7f0SSeth Jennings 		if (ret) {
323b700e7f0SSeth Jennings 			pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n",
324b700e7f0SSeth Jennings 			       reloc->name, reloc->val, ret);
325b700e7f0SSeth Jennings 			return ret;
326b700e7f0SSeth Jennings 		}
327b700e7f0SSeth Jennings 	}
328b700e7f0SSeth Jennings 
329b700e7f0SSeth Jennings 	return 0;
330b700e7f0SSeth Jennings }
331b700e7f0SSeth Jennings 
332b700e7f0SSeth Jennings static void notrace klp_ftrace_handler(unsigned long ip,
333b700e7f0SSeth Jennings 				       unsigned long parent_ip,
3343c33f5b9SJosh Poimboeuf 				       struct ftrace_ops *fops,
335b700e7f0SSeth Jennings 				       struct pt_regs *regs)
336b700e7f0SSeth Jennings {
3373c33f5b9SJosh Poimboeuf 	struct klp_ops *ops;
3383c33f5b9SJosh Poimboeuf 	struct klp_func *func;
3393c33f5b9SJosh Poimboeuf 
3403c33f5b9SJosh Poimboeuf 	ops = container_of(fops, struct klp_ops, fops);
3413c33f5b9SJosh Poimboeuf 
3423c33f5b9SJosh Poimboeuf 	rcu_read_lock();
3433c33f5b9SJosh Poimboeuf 	func = list_first_or_null_rcu(&ops->func_stack, struct klp_func,
3443c33f5b9SJosh Poimboeuf 				      stack_node);
3453c33f5b9SJosh Poimboeuf 	if (WARN_ON_ONCE(!func))
346c4ce0da8SPetr Mladek 		goto unlock;
347b700e7f0SSeth Jennings 
348b5bfc517SLi Bin 	klp_arch_set_pc(regs, (unsigned long)func->new_func);
349c4ce0da8SPetr Mladek unlock:
350c4ce0da8SPetr Mladek 	rcu_read_unlock();
351b700e7f0SSeth Jennings }
352b700e7f0SSeth Jennings 
3530937e3b0SJosh Poimboeuf static void klp_disable_func(struct klp_func *func)
354b700e7f0SSeth Jennings {
3553c33f5b9SJosh Poimboeuf 	struct klp_ops *ops;
356b700e7f0SSeth Jennings 
357225f58fbSMinfei Huang 	if (WARN_ON(func->state != KLP_ENABLED))
358225f58fbSMinfei Huang 		return;
359225f58fbSMinfei Huang 	if (WARN_ON(!func->old_addr))
360225f58fbSMinfei Huang 		return;
361b700e7f0SSeth Jennings 
3623c33f5b9SJosh Poimboeuf 	ops = klp_find_ops(func->old_addr);
3633c33f5b9SJosh Poimboeuf 	if (WARN_ON(!ops))
3640937e3b0SJosh Poimboeuf 		return;
3653c33f5b9SJosh Poimboeuf 
3663c33f5b9SJosh Poimboeuf 	if (list_is_singular(&ops->func_stack)) {
3670937e3b0SJosh Poimboeuf 		WARN_ON(unregister_ftrace_function(&ops->fops));
3680937e3b0SJosh Poimboeuf 		WARN_ON(ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0));
369b700e7f0SSeth Jennings 
3703c33f5b9SJosh Poimboeuf 		list_del_rcu(&func->stack_node);
3713c33f5b9SJosh Poimboeuf 		list_del(&ops->node);
3723c33f5b9SJosh Poimboeuf 		kfree(ops);
3733c33f5b9SJosh Poimboeuf 	} else {
3743c33f5b9SJosh Poimboeuf 		list_del_rcu(&func->stack_node);
3753c33f5b9SJosh Poimboeuf 	}
3763c33f5b9SJosh Poimboeuf 
377b700e7f0SSeth Jennings 	func->state = KLP_DISABLED;
378b700e7f0SSeth Jennings }
379b700e7f0SSeth Jennings 
380b700e7f0SSeth Jennings static int klp_enable_func(struct klp_func *func)
381b700e7f0SSeth Jennings {
3823c33f5b9SJosh Poimboeuf 	struct klp_ops *ops;
383b700e7f0SSeth Jennings 	int ret;
384b700e7f0SSeth Jennings 
385b700e7f0SSeth Jennings 	if (WARN_ON(!func->old_addr))
386b700e7f0SSeth Jennings 		return -EINVAL;
387b700e7f0SSeth Jennings 
388b700e7f0SSeth Jennings 	if (WARN_ON(func->state != KLP_DISABLED))
389b700e7f0SSeth Jennings 		return -EINVAL;
390b700e7f0SSeth Jennings 
3913c33f5b9SJosh Poimboeuf 	ops = klp_find_ops(func->old_addr);
3923c33f5b9SJosh Poimboeuf 	if (!ops) {
3933c33f5b9SJosh Poimboeuf 		ops = kzalloc(sizeof(*ops), GFP_KERNEL);
3943c33f5b9SJosh Poimboeuf 		if (!ops)
3953c33f5b9SJosh Poimboeuf 			return -ENOMEM;
3963c33f5b9SJosh Poimboeuf 
3973c33f5b9SJosh Poimboeuf 		ops->fops.func = klp_ftrace_handler;
3983c33f5b9SJosh Poimboeuf 		ops->fops.flags = FTRACE_OPS_FL_SAVE_REGS |
3993c33f5b9SJosh Poimboeuf 				  FTRACE_OPS_FL_DYNAMIC |
4003c33f5b9SJosh Poimboeuf 				  FTRACE_OPS_FL_IPMODIFY;
4013c33f5b9SJosh Poimboeuf 
4023c33f5b9SJosh Poimboeuf 		list_add(&ops->node, &klp_ops);
4033c33f5b9SJosh Poimboeuf 
4043c33f5b9SJosh Poimboeuf 		INIT_LIST_HEAD(&ops->func_stack);
4053c33f5b9SJosh Poimboeuf 		list_add_rcu(&func->stack_node, &ops->func_stack);
4063c33f5b9SJosh Poimboeuf 
4073c33f5b9SJosh Poimboeuf 		ret = ftrace_set_filter_ip(&ops->fops, func->old_addr, 0, 0);
408b700e7f0SSeth Jennings 		if (ret) {
409b700e7f0SSeth Jennings 			pr_err("failed to set ftrace filter for function '%s' (%d)\n",
410b700e7f0SSeth Jennings 			       func->old_name, ret);
4113c33f5b9SJosh Poimboeuf 			goto err;
412b700e7f0SSeth Jennings 		}
413b700e7f0SSeth Jennings 
4143c33f5b9SJosh Poimboeuf 		ret = register_ftrace_function(&ops->fops);
415b700e7f0SSeth Jennings 		if (ret) {
416b700e7f0SSeth Jennings 			pr_err("failed to register ftrace handler for function '%s' (%d)\n",
417b700e7f0SSeth Jennings 			       func->old_name, ret);
4183c33f5b9SJosh Poimboeuf 			ftrace_set_filter_ip(&ops->fops, func->old_addr, 1, 0);
4193c33f5b9SJosh Poimboeuf 			goto err;
420b700e7f0SSeth Jennings 		}
421b700e7f0SSeth Jennings 
4223c33f5b9SJosh Poimboeuf 
4233c33f5b9SJosh Poimboeuf 	} else {
4243c33f5b9SJosh Poimboeuf 		list_add_rcu(&func->stack_node, &ops->func_stack);
4253c33f5b9SJosh Poimboeuf 	}
4263c33f5b9SJosh Poimboeuf 
4273c33f5b9SJosh Poimboeuf 	func->state = KLP_ENABLED;
4283c33f5b9SJosh Poimboeuf 
429dbed7ddaSJosh Poimboeuf 	return 0;
4303c33f5b9SJosh Poimboeuf 
4313c33f5b9SJosh Poimboeuf err:
4323c33f5b9SJosh Poimboeuf 	list_del_rcu(&func->stack_node);
4333c33f5b9SJosh Poimboeuf 	list_del(&ops->node);
4343c33f5b9SJosh Poimboeuf 	kfree(ops);
435b700e7f0SSeth Jennings 	return ret;
436b700e7f0SSeth Jennings }
437b700e7f0SSeth Jennings 
4380937e3b0SJosh Poimboeuf static void klp_disable_object(struct klp_object *obj)
439b700e7f0SSeth Jennings {
440b700e7f0SSeth Jennings 	struct klp_func *func;
441b700e7f0SSeth Jennings 
4428cdd043aSJiri Slaby 	klp_for_each_func(obj, func)
4430937e3b0SJosh Poimboeuf 		if (func->state == KLP_ENABLED)
4440937e3b0SJosh Poimboeuf 			klp_disable_func(func);
445b700e7f0SSeth Jennings 
446b700e7f0SSeth Jennings 	obj->state = KLP_DISABLED;
447b700e7f0SSeth Jennings }
448b700e7f0SSeth Jennings 
449b700e7f0SSeth Jennings static int klp_enable_object(struct klp_object *obj)
450b700e7f0SSeth Jennings {
451b700e7f0SSeth Jennings 	struct klp_func *func;
452b700e7f0SSeth Jennings 	int ret;
453b700e7f0SSeth Jennings 
454b700e7f0SSeth Jennings 	if (WARN_ON(obj->state != KLP_DISABLED))
455b700e7f0SSeth Jennings 		return -EINVAL;
456b700e7f0SSeth Jennings 
457b700e7f0SSeth Jennings 	if (WARN_ON(!klp_is_object_loaded(obj)))
458b700e7f0SSeth Jennings 		return -EINVAL;
459b700e7f0SSeth Jennings 
4608cdd043aSJiri Slaby 	klp_for_each_func(obj, func) {
461b700e7f0SSeth Jennings 		ret = klp_enable_func(func);
4620937e3b0SJosh Poimboeuf 		if (ret) {
4630937e3b0SJosh Poimboeuf 			klp_disable_object(obj);
4640937e3b0SJosh Poimboeuf 			return ret;
4650937e3b0SJosh Poimboeuf 		}
466b700e7f0SSeth Jennings 	}
467b700e7f0SSeth Jennings 	obj->state = KLP_ENABLED;
468b700e7f0SSeth Jennings 
469b700e7f0SSeth Jennings 	return 0;
470b700e7f0SSeth Jennings }
471b700e7f0SSeth Jennings 
472b700e7f0SSeth Jennings static int __klp_disable_patch(struct klp_patch *patch)
473b700e7f0SSeth Jennings {
474b700e7f0SSeth Jennings 	struct klp_object *obj;
475b700e7f0SSeth Jennings 
47683a90bb1SJosh Poimboeuf 	/* enforce stacking: only the last enabled patch can be disabled */
47783a90bb1SJosh Poimboeuf 	if (!list_is_last(&patch->list, &klp_patches) &&
47883a90bb1SJosh Poimboeuf 	    list_next_entry(patch, list)->state == KLP_ENABLED)
47983a90bb1SJosh Poimboeuf 		return -EBUSY;
48083a90bb1SJosh Poimboeuf 
481b700e7f0SSeth Jennings 	pr_notice("disabling patch '%s'\n", patch->mod->name);
482b700e7f0SSeth Jennings 
4838cdd043aSJiri Slaby 	klp_for_each_object(patch, obj) {
4840937e3b0SJosh Poimboeuf 		if (obj->state == KLP_ENABLED)
4850937e3b0SJosh Poimboeuf 			klp_disable_object(obj);
486b700e7f0SSeth Jennings 	}
487b700e7f0SSeth Jennings 
488b700e7f0SSeth Jennings 	patch->state = KLP_DISABLED;
489b700e7f0SSeth Jennings 
490b700e7f0SSeth Jennings 	return 0;
491b700e7f0SSeth Jennings }
492b700e7f0SSeth Jennings 
493b700e7f0SSeth Jennings /**
494b700e7f0SSeth Jennings  * klp_disable_patch() - disables a registered patch
495b700e7f0SSeth Jennings  * @patch:	The registered, enabled patch to be disabled
496b700e7f0SSeth Jennings  *
497b700e7f0SSeth Jennings  * Unregisters the patched functions from ftrace.
498b700e7f0SSeth Jennings  *
499b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
500b700e7f0SSeth Jennings  */
501b700e7f0SSeth Jennings int klp_disable_patch(struct klp_patch *patch)
502b700e7f0SSeth Jennings {
503b700e7f0SSeth Jennings 	int ret;
504b700e7f0SSeth Jennings 
505b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
506b700e7f0SSeth Jennings 
507b700e7f0SSeth Jennings 	if (!klp_is_patch_registered(patch)) {
508b700e7f0SSeth Jennings 		ret = -EINVAL;
509b700e7f0SSeth Jennings 		goto err;
510b700e7f0SSeth Jennings 	}
511b700e7f0SSeth Jennings 
512b700e7f0SSeth Jennings 	if (patch->state == KLP_DISABLED) {
513b700e7f0SSeth Jennings 		ret = -EINVAL;
514b700e7f0SSeth Jennings 		goto err;
515b700e7f0SSeth Jennings 	}
516b700e7f0SSeth Jennings 
517b700e7f0SSeth Jennings 	ret = __klp_disable_patch(patch);
518b700e7f0SSeth Jennings 
519b700e7f0SSeth Jennings err:
520b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
521b700e7f0SSeth Jennings 	return ret;
522b700e7f0SSeth Jennings }
523b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_disable_patch);
524b700e7f0SSeth Jennings 
525b700e7f0SSeth Jennings static int __klp_enable_patch(struct klp_patch *patch)
526b700e7f0SSeth Jennings {
527b700e7f0SSeth Jennings 	struct klp_object *obj;
528b700e7f0SSeth Jennings 	int ret;
529b700e7f0SSeth Jennings 
530b700e7f0SSeth Jennings 	if (WARN_ON(patch->state != KLP_DISABLED))
531b700e7f0SSeth Jennings 		return -EINVAL;
532b700e7f0SSeth Jennings 
53383a90bb1SJosh Poimboeuf 	/* enforce stacking: only the first disabled patch can be enabled */
53483a90bb1SJosh Poimboeuf 	if (patch->list.prev != &klp_patches &&
53583a90bb1SJosh Poimboeuf 	    list_prev_entry(patch, list)->state == KLP_DISABLED)
53683a90bb1SJosh Poimboeuf 		return -EBUSY;
53783a90bb1SJosh Poimboeuf 
538b700e7f0SSeth Jennings 	pr_notice_once("tainting kernel with TAINT_LIVEPATCH\n");
539b700e7f0SSeth Jennings 	add_taint(TAINT_LIVEPATCH, LOCKDEP_STILL_OK);
540b700e7f0SSeth Jennings 
541b700e7f0SSeth Jennings 	pr_notice("enabling patch '%s'\n", patch->mod->name);
542b700e7f0SSeth Jennings 
5438cdd043aSJiri Slaby 	klp_for_each_object(patch, obj) {
544b700e7f0SSeth Jennings 		if (!klp_is_object_loaded(obj))
545b700e7f0SSeth Jennings 			continue;
546b700e7f0SSeth Jennings 
547b700e7f0SSeth Jennings 		ret = klp_enable_object(obj);
548b700e7f0SSeth Jennings 		if (ret)
549b700e7f0SSeth Jennings 			goto unregister;
550b700e7f0SSeth Jennings 	}
551b700e7f0SSeth Jennings 
552b700e7f0SSeth Jennings 	patch->state = KLP_ENABLED;
553b700e7f0SSeth Jennings 
554b700e7f0SSeth Jennings 	return 0;
555b700e7f0SSeth Jennings 
556b700e7f0SSeth Jennings unregister:
557b700e7f0SSeth Jennings 	WARN_ON(__klp_disable_patch(patch));
558b700e7f0SSeth Jennings 	return ret;
559b700e7f0SSeth Jennings }
560b700e7f0SSeth Jennings 
561b700e7f0SSeth Jennings /**
562b700e7f0SSeth Jennings  * klp_enable_patch() - enables a registered patch
563b700e7f0SSeth Jennings  * @patch:	The registered, disabled patch to be enabled
564b700e7f0SSeth Jennings  *
565b700e7f0SSeth Jennings  * Performs the needed symbol lookups and code relocations,
566b700e7f0SSeth Jennings  * then registers the patched functions with ftrace.
567b700e7f0SSeth Jennings  *
568b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
569b700e7f0SSeth Jennings  */
570b700e7f0SSeth Jennings int klp_enable_patch(struct klp_patch *patch)
571b700e7f0SSeth Jennings {
572b700e7f0SSeth Jennings 	int ret;
573b700e7f0SSeth Jennings 
574b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
575b700e7f0SSeth Jennings 
576b700e7f0SSeth Jennings 	if (!klp_is_patch_registered(patch)) {
577b700e7f0SSeth Jennings 		ret = -EINVAL;
578b700e7f0SSeth Jennings 		goto err;
579b700e7f0SSeth Jennings 	}
580b700e7f0SSeth Jennings 
581b700e7f0SSeth Jennings 	ret = __klp_enable_patch(patch);
582b700e7f0SSeth Jennings 
583b700e7f0SSeth Jennings err:
584b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
585b700e7f0SSeth Jennings 	return ret;
586b700e7f0SSeth Jennings }
587b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_enable_patch);
588b700e7f0SSeth Jennings 
589b700e7f0SSeth Jennings /*
590b700e7f0SSeth Jennings  * Sysfs Interface
591b700e7f0SSeth Jennings  *
592b700e7f0SSeth Jennings  * /sys/kernel/livepatch
593b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>
594b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>/enabled
595b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>/<object>
596b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>/<object>/<func>
597b700e7f0SSeth Jennings  */
598b700e7f0SSeth Jennings 
599b700e7f0SSeth Jennings static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr,
600b700e7f0SSeth Jennings 			     const char *buf, size_t count)
601b700e7f0SSeth Jennings {
602b700e7f0SSeth Jennings 	struct klp_patch *patch;
603b700e7f0SSeth Jennings 	int ret;
604b700e7f0SSeth Jennings 	unsigned long val;
605b700e7f0SSeth Jennings 
606b700e7f0SSeth Jennings 	ret = kstrtoul(buf, 10, &val);
607b700e7f0SSeth Jennings 	if (ret)
608b700e7f0SSeth Jennings 		return -EINVAL;
609b700e7f0SSeth Jennings 
610b700e7f0SSeth Jennings 	if (val != KLP_DISABLED && val != KLP_ENABLED)
611b700e7f0SSeth Jennings 		return -EINVAL;
612b700e7f0SSeth Jennings 
613b700e7f0SSeth Jennings 	patch = container_of(kobj, struct klp_patch, kobj);
614b700e7f0SSeth Jennings 
615b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
616b700e7f0SSeth Jennings 
617b700e7f0SSeth Jennings 	if (val == patch->state) {
618b700e7f0SSeth Jennings 		/* already in requested state */
619b700e7f0SSeth Jennings 		ret = -EINVAL;
620b700e7f0SSeth Jennings 		goto err;
621b700e7f0SSeth Jennings 	}
622b700e7f0SSeth Jennings 
623b700e7f0SSeth Jennings 	if (val == KLP_ENABLED) {
624b700e7f0SSeth Jennings 		ret = __klp_enable_patch(patch);
625b700e7f0SSeth Jennings 		if (ret)
626b700e7f0SSeth Jennings 			goto err;
627b700e7f0SSeth Jennings 	} else {
628b700e7f0SSeth Jennings 		ret = __klp_disable_patch(patch);
629b700e7f0SSeth Jennings 		if (ret)
630b700e7f0SSeth Jennings 			goto err;
631b700e7f0SSeth Jennings 	}
632b700e7f0SSeth Jennings 
633b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
634b700e7f0SSeth Jennings 
635b700e7f0SSeth Jennings 	return count;
636b700e7f0SSeth Jennings 
637b700e7f0SSeth Jennings err:
638b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
639b700e7f0SSeth Jennings 	return ret;
640b700e7f0SSeth Jennings }
641b700e7f0SSeth Jennings 
642b700e7f0SSeth Jennings static ssize_t enabled_show(struct kobject *kobj,
643b700e7f0SSeth Jennings 			    struct kobj_attribute *attr, char *buf)
644b700e7f0SSeth Jennings {
645b700e7f0SSeth Jennings 	struct klp_patch *patch;
646b700e7f0SSeth Jennings 
647b700e7f0SSeth Jennings 	patch = container_of(kobj, struct klp_patch, kobj);
648b700e7f0SSeth Jennings 	return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->state);
649b700e7f0SSeth Jennings }
650b700e7f0SSeth Jennings 
651b700e7f0SSeth Jennings static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled);
652b700e7f0SSeth Jennings static struct attribute *klp_patch_attrs[] = {
653b700e7f0SSeth Jennings 	&enabled_kobj_attr.attr,
654b700e7f0SSeth Jennings 	NULL
655b700e7f0SSeth Jennings };
656b700e7f0SSeth Jennings 
657b700e7f0SSeth Jennings static void klp_kobj_release_patch(struct kobject *kobj)
658b700e7f0SSeth Jennings {
659b700e7f0SSeth Jennings 	/*
660b700e7f0SSeth Jennings 	 * Once we have a consistency model we'll need to module_put() the
661b700e7f0SSeth Jennings 	 * patch module here.  See klp_register_patch() for more details.
662b700e7f0SSeth Jennings 	 */
663b700e7f0SSeth Jennings }
664b700e7f0SSeth Jennings 
665b700e7f0SSeth Jennings static struct kobj_type klp_ktype_patch = {
666b700e7f0SSeth Jennings 	.release = klp_kobj_release_patch,
667b700e7f0SSeth Jennings 	.sysfs_ops = &kobj_sysfs_ops,
668b700e7f0SSeth Jennings 	.default_attrs = klp_patch_attrs,
669b700e7f0SSeth Jennings };
670b700e7f0SSeth Jennings 
671cad706dfSMiroslav Benes static void klp_kobj_release_object(struct kobject *kobj)
672cad706dfSMiroslav Benes {
673cad706dfSMiroslav Benes }
674cad706dfSMiroslav Benes 
675cad706dfSMiroslav Benes static struct kobj_type klp_ktype_object = {
676cad706dfSMiroslav Benes 	.release = klp_kobj_release_object,
677cad706dfSMiroslav Benes 	.sysfs_ops = &kobj_sysfs_ops,
678cad706dfSMiroslav Benes };
679cad706dfSMiroslav Benes 
680b700e7f0SSeth Jennings static void klp_kobj_release_func(struct kobject *kobj)
681b700e7f0SSeth Jennings {
682b700e7f0SSeth Jennings }
683b700e7f0SSeth Jennings 
684b700e7f0SSeth Jennings static struct kobj_type klp_ktype_func = {
685b700e7f0SSeth Jennings 	.release = klp_kobj_release_func,
686b700e7f0SSeth Jennings 	.sysfs_ops = &kobj_sysfs_ops,
687b700e7f0SSeth Jennings };
688b700e7f0SSeth Jennings 
689b700e7f0SSeth Jennings /*
690b700e7f0SSeth Jennings  * Free all functions' kobjects in the array up to some limit. When limit is
691b700e7f0SSeth Jennings  * NULL, all kobjects are freed.
692b700e7f0SSeth Jennings  */
693b700e7f0SSeth Jennings static void klp_free_funcs_limited(struct klp_object *obj,
694b700e7f0SSeth Jennings 				   struct klp_func *limit)
695b700e7f0SSeth Jennings {
696b700e7f0SSeth Jennings 	struct klp_func *func;
697b700e7f0SSeth Jennings 
698b700e7f0SSeth Jennings 	for (func = obj->funcs; func->old_name && func != limit; func++)
699b700e7f0SSeth Jennings 		kobject_put(&func->kobj);
700b700e7f0SSeth Jennings }
701b700e7f0SSeth Jennings 
702b700e7f0SSeth Jennings /* Clean up when a patched object is unloaded */
703b700e7f0SSeth Jennings static void klp_free_object_loaded(struct klp_object *obj)
704b700e7f0SSeth Jennings {
705b700e7f0SSeth Jennings 	struct klp_func *func;
706b700e7f0SSeth Jennings 
707b700e7f0SSeth Jennings 	obj->mod = NULL;
708b700e7f0SSeth Jennings 
7098cdd043aSJiri Slaby 	klp_for_each_func(obj, func)
710b700e7f0SSeth Jennings 		func->old_addr = 0;
711b700e7f0SSeth Jennings }
712b700e7f0SSeth Jennings 
713b700e7f0SSeth Jennings /*
714b700e7f0SSeth Jennings  * Free all objects' kobjects in the array up to some limit. When limit is
715b700e7f0SSeth Jennings  * NULL, all kobjects are freed.
716b700e7f0SSeth Jennings  */
717b700e7f0SSeth Jennings static void klp_free_objects_limited(struct klp_patch *patch,
718b700e7f0SSeth Jennings 				     struct klp_object *limit)
719b700e7f0SSeth Jennings {
720b700e7f0SSeth Jennings 	struct klp_object *obj;
721b700e7f0SSeth Jennings 
722b700e7f0SSeth Jennings 	for (obj = patch->objs; obj->funcs && obj != limit; obj++) {
723b700e7f0SSeth Jennings 		klp_free_funcs_limited(obj, NULL);
724cad706dfSMiroslav Benes 		kobject_put(&obj->kobj);
725b700e7f0SSeth Jennings 	}
726b700e7f0SSeth Jennings }
727b700e7f0SSeth Jennings 
728b700e7f0SSeth Jennings static void klp_free_patch(struct klp_patch *patch)
729b700e7f0SSeth Jennings {
730b700e7f0SSeth Jennings 	klp_free_objects_limited(patch, NULL);
731b700e7f0SSeth Jennings 	if (!list_empty(&patch->list))
732b700e7f0SSeth Jennings 		list_del(&patch->list);
733b700e7f0SSeth Jennings 	kobject_put(&patch->kobj);
734b700e7f0SSeth Jennings }
735b700e7f0SSeth Jennings 
736b700e7f0SSeth Jennings static int klp_init_func(struct klp_object *obj, struct klp_func *func)
737b700e7f0SSeth Jennings {
7383c33f5b9SJosh Poimboeuf 	INIT_LIST_HEAD(&func->stack_node);
739b700e7f0SSeth Jennings 	func->state = KLP_DISABLED;
740b700e7f0SSeth Jennings 
7413c33f5b9SJosh Poimboeuf 	return kobject_init_and_add(&func->kobj, &klp_ktype_func,
742cad706dfSMiroslav Benes 				    &obj->kobj, "%s", func->old_name);
743b700e7f0SSeth Jennings }
744b700e7f0SSeth Jennings 
745b700e7f0SSeth Jennings /* parts of the initialization that is done only when the object is loaded */
746b700e7f0SSeth Jennings static int klp_init_object_loaded(struct klp_patch *patch,
747b700e7f0SSeth Jennings 				  struct klp_object *obj)
748b700e7f0SSeth Jennings {
749b700e7f0SSeth Jennings 	struct klp_func *func;
750b700e7f0SSeth Jennings 	int ret;
751b700e7f0SSeth Jennings 
752b700e7f0SSeth Jennings 	if (obj->relocs) {
753b700e7f0SSeth Jennings 		ret = klp_write_object_relocations(patch->mod, obj);
754b700e7f0SSeth Jennings 		if (ret)
755b700e7f0SSeth Jennings 			return ret;
756b700e7f0SSeth Jennings 	}
757b700e7f0SSeth Jennings 
7588cdd043aSJiri Slaby 	klp_for_each_func(obj, func) {
759b700e7f0SSeth Jennings 		ret = klp_find_verify_func_addr(obj, func);
760b700e7f0SSeth Jennings 		if (ret)
761b700e7f0SSeth Jennings 			return ret;
762b700e7f0SSeth Jennings 	}
763b700e7f0SSeth Jennings 
764b700e7f0SSeth Jennings 	return 0;
765b700e7f0SSeth Jennings }
766b700e7f0SSeth Jennings 
767b700e7f0SSeth Jennings static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
768b700e7f0SSeth Jennings {
769b700e7f0SSeth Jennings 	struct klp_func *func;
770b700e7f0SSeth Jennings 	int ret;
771b700e7f0SSeth Jennings 	const char *name;
772b700e7f0SSeth Jennings 
773b700e7f0SSeth Jennings 	if (!obj->funcs)
774b700e7f0SSeth Jennings 		return -EINVAL;
775b700e7f0SSeth Jennings 
776b700e7f0SSeth Jennings 	obj->state = KLP_DISABLED;
7778cb2c2dcSPetr Mladek 	obj->mod = NULL;
778b700e7f0SSeth Jennings 
779b700e7f0SSeth Jennings 	klp_find_object_module(obj);
780b700e7f0SSeth Jennings 
781b700e7f0SSeth Jennings 	name = klp_is_module(obj) ? obj->name : "vmlinux";
782cad706dfSMiroslav Benes 	ret = kobject_init_and_add(&obj->kobj, &klp_ktype_object,
783cad706dfSMiroslav Benes 				   &patch->kobj, "%s", name);
784cad706dfSMiroslav Benes 	if (ret)
785cad706dfSMiroslav Benes 		return ret;
786b700e7f0SSeth Jennings 
7878cdd043aSJiri Slaby 	klp_for_each_func(obj, func) {
788b700e7f0SSeth Jennings 		ret = klp_init_func(obj, func);
789b700e7f0SSeth Jennings 		if (ret)
790b700e7f0SSeth Jennings 			goto free;
791b700e7f0SSeth Jennings 	}
792b700e7f0SSeth Jennings 
793b700e7f0SSeth Jennings 	if (klp_is_object_loaded(obj)) {
794b700e7f0SSeth Jennings 		ret = klp_init_object_loaded(patch, obj);
795b700e7f0SSeth Jennings 		if (ret)
796b700e7f0SSeth Jennings 			goto free;
797b700e7f0SSeth Jennings 	}
798b700e7f0SSeth Jennings 
799b700e7f0SSeth Jennings 	return 0;
800b700e7f0SSeth Jennings 
801b700e7f0SSeth Jennings free:
802b700e7f0SSeth Jennings 	klp_free_funcs_limited(obj, func);
803cad706dfSMiroslav Benes 	kobject_put(&obj->kobj);
804b700e7f0SSeth Jennings 	return ret;
805b700e7f0SSeth Jennings }
806b700e7f0SSeth Jennings 
807b700e7f0SSeth Jennings static int klp_init_patch(struct klp_patch *patch)
808b700e7f0SSeth Jennings {
809b700e7f0SSeth Jennings 	struct klp_object *obj;
810b700e7f0SSeth Jennings 	int ret;
811b700e7f0SSeth Jennings 
812b700e7f0SSeth Jennings 	if (!patch->objs)
813b700e7f0SSeth Jennings 		return -EINVAL;
814b700e7f0SSeth Jennings 
815b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
816b700e7f0SSeth Jennings 
817b700e7f0SSeth Jennings 	patch->state = KLP_DISABLED;
818b700e7f0SSeth Jennings 
819b700e7f0SSeth Jennings 	ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch,
820e0b561eeSJiri Kosina 				   klp_root_kobj, "%s", patch->mod->name);
821b700e7f0SSeth Jennings 	if (ret)
822b700e7f0SSeth Jennings 		goto unlock;
823b700e7f0SSeth Jennings 
8248cdd043aSJiri Slaby 	klp_for_each_object(patch, obj) {
825b700e7f0SSeth Jennings 		ret = klp_init_object(patch, obj);
826b700e7f0SSeth Jennings 		if (ret)
827b700e7f0SSeth Jennings 			goto free;
828b700e7f0SSeth Jennings 	}
829b700e7f0SSeth Jennings 
83099590ba5SJosh Poimboeuf 	list_add_tail(&patch->list, &klp_patches);
831b700e7f0SSeth Jennings 
832b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
833b700e7f0SSeth Jennings 
834b700e7f0SSeth Jennings 	return 0;
835b700e7f0SSeth Jennings 
836b700e7f0SSeth Jennings free:
837b700e7f0SSeth Jennings 	klp_free_objects_limited(patch, obj);
838b700e7f0SSeth Jennings 	kobject_put(&patch->kobj);
839b700e7f0SSeth Jennings unlock:
840b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
841b700e7f0SSeth Jennings 	return ret;
842b700e7f0SSeth Jennings }
843b700e7f0SSeth Jennings 
844b700e7f0SSeth Jennings /**
845b700e7f0SSeth Jennings  * klp_unregister_patch() - unregisters a patch
846b700e7f0SSeth Jennings  * @patch:	Disabled patch to be unregistered
847b700e7f0SSeth Jennings  *
848b700e7f0SSeth Jennings  * Frees the data structures and removes the sysfs interface.
849b700e7f0SSeth Jennings  *
850b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
851b700e7f0SSeth Jennings  */
852b700e7f0SSeth Jennings int klp_unregister_patch(struct klp_patch *patch)
853b700e7f0SSeth Jennings {
854b700e7f0SSeth Jennings 	int ret = 0;
855b700e7f0SSeth Jennings 
856b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
857b700e7f0SSeth Jennings 
858b700e7f0SSeth Jennings 	if (!klp_is_patch_registered(patch)) {
859b700e7f0SSeth Jennings 		ret = -EINVAL;
860b700e7f0SSeth Jennings 		goto out;
861b700e7f0SSeth Jennings 	}
862b700e7f0SSeth Jennings 
863b700e7f0SSeth Jennings 	if (patch->state == KLP_ENABLED) {
864b700e7f0SSeth Jennings 		ret = -EBUSY;
865b700e7f0SSeth Jennings 		goto out;
866b700e7f0SSeth Jennings 	}
867b700e7f0SSeth Jennings 
868b700e7f0SSeth Jennings 	klp_free_patch(patch);
869b700e7f0SSeth Jennings 
870b700e7f0SSeth Jennings out:
871b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
872b700e7f0SSeth Jennings 	return ret;
873b700e7f0SSeth Jennings }
874b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_unregister_patch);
875b700e7f0SSeth Jennings 
876b700e7f0SSeth Jennings /**
877b700e7f0SSeth Jennings  * klp_register_patch() - registers a patch
878b700e7f0SSeth Jennings  * @patch:	Patch to be registered
879b700e7f0SSeth Jennings  *
880b700e7f0SSeth Jennings  * Initializes the data structure associated with the patch and
881b700e7f0SSeth Jennings  * creates the sysfs interface.
882b700e7f0SSeth Jennings  *
883b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
884b700e7f0SSeth Jennings  */
885b700e7f0SSeth Jennings int klp_register_patch(struct klp_patch *patch)
886b700e7f0SSeth Jennings {
887b700e7f0SSeth Jennings 	int ret;
888b700e7f0SSeth Jennings 
889b700e7f0SSeth Jennings 	if (!klp_initialized())
890b700e7f0SSeth Jennings 		return -ENODEV;
891b700e7f0SSeth Jennings 
892b700e7f0SSeth Jennings 	if (!patch || !patch->mod)
893b700e7f0SSeth Jennings 		return -EINVAL;
894b700e7f0SSeth Jennings 
895b700e7f0SSeth Jennings 	/*
896b700e7f0SSeth Jennings 	 * A reference is taken on the patch module to prevent it from being
897b700e7f0SSeth Jennings 	 * unloaded.  Right now, we don't allow patch modules to unload since
898b700e7f0SSeth Jennings 	 * there is currently no method to determine if a thread is still
899b700e7f0SSeth Jennings 	 * running in the patched code contained in the patch module once
900b700e7f0SSeth Jennings 	 * the ftrace registration is successful.
901b700e7f0SSeth Jennings 	 */
902b700e7f0SSeth Jennings 	if (!try_module_get(patch->mod))
903b700e7f0SSeth Jennings 		return -ENODEV;
904b700e7f0SSeth Jennings 
905b700e7f0SSeth Jennings 	ret = klp_init_patch(patch);
906b700e7f0SSeth Jennings 	if (ret)
907b700e7f0SSeth Jennings 		module_put(patch->mod);
908b700e7f0SSeth Jennings 
909b700e7f0SSeth Jennings 	return ret;
910b700e7f0SSeth Jennings }
911b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_register_patch);
912b700e7f0SSeth Jennings 
91336e505c1SMinfei Huang static int klp_module_notify_coming(struct klp_patch *patch,
914b700e7f0SSeth Jennings 				     struct klp_object *obj)
915b700e7f0SSeth Jennings {
916b700e7f0SSeth Jennings 	struct module *pmod = patch->mod;
917b700e7f0SSeth Jennings 	struct module *mod = obj->mod;
918b700e7f0SSeth Jennings 	int ret;
919b700e7f0SSeth Jennings 
920b700e7f0SSeth Jennings 	ret = klp_init_object_loaded(patch, obj);
92136e505c1SMinfei Huang 	if (ret) {
92236e505c1SMinfei Huang 		pr_warn("failed to initialize patch '%s' for module '%s' (%d)\n",
92336e505c1SMinfei Huang 			pmod->name, mod->name, ret);
92436e505c1SMinfei Huang 		return ret;
92536e505c1SMinfei Huang 	}
926b700e7f0SSeth Jennings 
927b700e7f0SSeth Jennings 	if (patch->state == KLP_DISABLED)
92836e505c1SMinfei Huang 		return 0;
929b700e7f0SSeth Jennings 
930b700e7f0SSeth Jennings 	pr_notice("applying patch '%s' to loading module '%s'\n",
931b700e7f0SSeth Jennings 		  pmod->name, mod->name);
932b700e7f0SSeth Jennings 
933b700e7f0SSeth Jennings 	ret = klp_enable_object(obj);
93436e505c1SMinfei Huang 	if (ret)
935b700e7f0SSeth Jennings 		pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
936b700e7f0SSeth Jennings 			pmod->name, mod->name, ret);
93736e505c1SMinfei Huang 	return ret;
938b700e7f0SSeth Jennings }
939b700e7f0SSeth Jennings 
940b700e7f0SSeth Jennings static void klp_module_notify_going(struct klp_patch *patch,
941b700e7f0SSeth Jennings 				    struct klp_object *obj)
942b700e7f0SSeth Jennings {
943b700e7f0SSeth Jennings 	struct module *pmod = patch->mod;
944b700e7f0SSeth Jennings 	struct module *mod = obj->mod;
945b700e7f0SSeth Jennings 
946b700e7f0SSeth Jennings 	if (patch->state == KLP_DISABLED)
947b700e7f0SSeth Jennings 		goto disabled;
948b700e7f0SSeth Jennings 
949b700e7f0SSeth Jennings 	pr_notice("reverting patch '%s' on unloading module '%s'\n",
950b700e7f0SSeth Jennings 		  pmod->name, mod->name);
951b700e7f0SSeth Jennings 
9520937e3b0SJosh Poimboeuf 	klp_disable_object(obj);
953b700e7f0SSeth Jennings 
954b700e7f0SSeth Jennings disabled:
955b700e7f0SSeth Jennings 	klp_free_object_loaded(obj);
956b700e7f0SSeth Jennings }
957b700e7f0SSeth Jennings 
958b700e7f0SSeth Jennings static int klp_module_notify(struct notifier_block *nb, unsigned long action,
959b700e7f0SSeth Jennings 			     void *data)
960b700e7f0SSeth Jennings {
96136e505c1SMinfei Huang 	int ret;
962b700e7f0SSeth Jennings 	struct module *mod = data;
963b700e7f0SSeth Jennings 	struct klp_patch *patch;
964b700e7f0SSeth Jennings 	struct klp_object *obj;
965b700e7f0SSeth Jennings 
966b700e7f0SSeth Jennings 	if (action != MODULE_STATE_COMING && action != MODULE_STATE_GOING)
967b700e7f0SSeth Jennings 		return 0;
968b700e7f0SSeth Jennings 
969b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
970b700e7f0SSeth Jennings 
9718cb2c2dcSPetr Mladek 	/*
9728cb2c2dcSPetr Mladek 	 * Each module has to know that the notifier has been called.
9738cb2c2dcSPetr Mladek 	 * We never know what module will get patched by a new patch.
9748cb2c2dcSPetr Mladek 	 */
9758cb2c2dcSPetr Mladek 	if (action == MODULE_STATE_COMING)
9768cb2c2dcSPetr Mladek 		mod->klp_alive = true;
9778cb2c2dcSPetr Mladek 	else /* MODULE_STATE_GOING */
9788cb2c2dcSPetr Mladek 		mod->klp_alive = false;
9798cb2c2dcSPetr Mladek 
980b700e7f0SSeth Jennings 	list_for_each_entry(patch, &klp_patches, list) {
9818cdd043aSJiri Slaby 		klp_for_each_object(patch, obj) {
982b700e7f0SSeth Jennings 			if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
983b700e7f0SSeth Jennings 				continue;
984b700e7f0SSeth Jennings 
985b700e7f0SSeth Jennings 			if (action == MODULE_STATE_COMING) {
986b700e7f0SSeth Jennings 				obj->mod = mod;
98736e505c1SMinfei Huang 				ret = klp_module_notify_coming(patch, obj);
98836e505c1SMinfei Huang 				if (ret) {
98936e505c1SMinfei Huang 					obj->mod = NULL;
99036e505c1SMinfei Huang 					pr_warn("patch '%s' is in an inconsistent state!\n",
99136e505c1SMinfei Huang 						patch->mod->name);
99236e505c1SMinfei Huang 				}
993b700e7f0SSeth Jennings 			} else /* MODULE_STATE_GOING */
994b700e7f0SSeth Jennings 				klp_module_notify_going(patch, obj);
995b700e7f0SSeth Jennings 
996b700e7f0SSeth Jennings 			break;
997b700e7f0SSeth Jennings 		}
998b700e7f0SSeth Jennings 	}
999b700e7f0SSeth Jennings 
1000b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
1001b700e7f0SSeth Jennings 
1002b700e7f0SSeth Jennings 	return 0;
1003b700e7f0SSeth Jennings }
1004b700e7f0SSeth Jennings 
1005b700e7f0SSeth Jennings static struct notifier_block klp_module_nb = {
1006b700e7f0SSeth Jennings 	.notifier_call = klp_module_notify,
1007b700e7f0SSeth Jennings 	.priority = INT_MIN+1, /* called late but before ftrace notifier */
1008b700e7f0SSeth Jennings };
1009b700e7f0SSeth Jennings 
101026029d88SMinfei Huang static int __init klp_init(void)
1011b700e7f0SSeth Jennings {
1012b700e7f0SSeth Jennings 	int ret;
1013b700e7f0SSeth Jennings 
1014b9dfe0beSJiri Kosina 	ret = klp_check_compiler_support();
1015b9dfe0beSJiri Kosina 	if (ret) {
1016b9dfe0beSJiri Kosina 		pr_info("Your compiler is too old; turning off.\n");
1017b9dfe0beSJiri Kosina 		return -EINVAL;
1018b9dfe0beSJiri Kosina 	}
1019b9dfe0beSJiri Kosina 
1020b700e7f0SSeth Jennings 	ret = register_module_notifier(&klp_module_nb);
1021b700e7f0SSeth Jennings 	if (ret)
1022b700e7f0SSeth Jennings 		return ret;
1023b700e7f0SSeth Jennings 
1024b700e7f0SSeth Jennings 	klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
1025b700e7f0SSeth Jennings 	if (!klp_root_kobj) {
1026b700e7f0SSeth Jennings 		ret = -ENOMEM;
1027b700e7f0SSeth Jennings 		goto unregister;
1028b700e7f0SSeth Jennings 	}
1029b700e7f0SSeth Jennings 
1030b700e7f0SSeth Jennings 	return 0;
1031b700e7f0SSeth Jennings 
1032b700e7f0SSeth Jennings unregister:
1033b700e7f0SSeth Jennings 	unregister_module_notifier(&klp_module_nb);
1034b700e7f0SSeth Jennings 	return ret;
1035b700e7f0SSeth Jennings }
1036b700e7f0SSeth Jennings 
1037b700e7f0SSeth Jennings module_init(klp_init);
1038