xref: /linux-6.15/kernel/livepatch/core.c (revision ef8daf8e)
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/list.h>
28b700e7f0SSeth Jennings #include <linux/kallsyms.h>
29b700e7f0SSeth Jennings #include <linux/livepatch.h>
30425595a7SJessica Yu #include <linux/elf.h>
31425595a7SJessica Yu #include <linux/moduleloader.h>
323ec24776SJosh Poimboeuf #include <linux/completion.h>
33b56b36eeSJosh Poimboeuf #include <asm/cacheflush.h>
3410517429SJiri Kosina #include "core.h"
35c349cdcaSJosh Poimboeuf #include "patch.h"
36d83a7cb3SJosh Poimboeuf #include "transition.h"
37b700e7f0SSeth Jennings 
383c33f5b9SJosh Poimboeuf /*
39d83a7cb3SJosh Poimboeuf  * klp_mutex is a coarse lock which serializes access to klp data.  All
40d83a7cb3SJosh Poimboeuf  * accesses to klp-related variables and structures must have mutex protection,
41d83a7cb3SJosh Poimboeuf  * except within the following functions which carefully avoid the need for it:
42d83a7cb3SJosh Poimboeuf  *
43d83a7cb3SJosh Poimboeuf  * - klp_ftrace_handler()
44d83a7cb3SJosh Poimboeuf  * - klp_update_patch_state()
453c33f5b9SJosh Poimboeuf  */
46d83a7cb3SJosh Poimboeuf DEFINE_MUTEX(klp_mutex);
473c33f5b9SJosh Poimboeuf 
48b700e7f0SSeth Jennings static LIST_HEAD(klp_patches);
49b700e7f0SSeth Jennings 
50b700e7f0SSeth Jennings static struct kobject *klp_root_kobj;
51b700e7f0SSeth Jennings 
52b700e7f0SSeth Jennings static bool klp_is_module(struct klp_object *obj)
53b700e7f0SSeth Jennings {
54b700e7f0SSeth Jennings 	return obj->name;
55b700e7f0SSeth Jennings }
56b700e7f0SSeth Jennings 
57b700e7f0SSeth Jennings static bool klp_is_object_loaded(struct klp_object *obj)
58b700e7f0SSeth Jennings {
59b700e7f0SSeth Jennings 	return !obj->name || obj->mod;
60b700e7f0SSeth Jennings }
61b700e7f0SSeth Jennings 
62b700e7f0SSeth Jennings /* sets obj->mod if object is not vmlinux and module is found */
63b700e7f0SSeth Jennings static void klp_find_object_module(struct klp_object *obj)
64b700e7f0SSeth Jennings {
658cb2c2dcSPetr Mladek 	struct module *mod;
668cb2c2dcSPetr Mladek 
67b700e7f0SSeth Jennings 	if (!klp_is_module(obj))
68b700e7f0SSeth Jennings 		return;
69b700e7f0SSeth Jennings 
70b700e7f0SSeth Jennings 	mutex_lock(&module_mutex);
71b700e7f0SSeth Jennings 	/*
728cb2c2dcSPetr Mladek 	 * We do not want to block removal of patched modules and therefore
738cb2c2dcSPetr Mladek 	 * we do not take a reference here. The patches are removed by
747e545d6eSJessica Yu 	 * klp_module_going() instead.
75b700e7f0SSeth Jennings 	 */
768cb2c2dcSPetr Mladek 	mod = find_module(obj->name);
778cb2c2dcSPetr Mladek 	/*
787e545d6eSJessica Yu 	 * Do not mess work of klp_module_coming() and klp_module_going().
797e545d6eSJessica Yu 	 * Note that the patch might still be needed before klp_module_going()
808cb2c2dcSPetr Mladek 	 * is called. Module functions can be called even in the GOING state
818cb2c2dcSPetr Mladek 	 * until mod->exit() finishes. This is especially important for
828cb2c2dcSPetr Mladek 	 * patches that modify semantic of the functions.
838cb2c2dcSPetr Mladek 	 */
848cb2c2dcSPetr Mladek 	if (mod && mod->klp_alive)
858cb2c2dcSPetr Mladek 		obj->mod = mod;
868cb2c2dcSPetr Mladek 
87b700e7f0SSeth Jennings 	mutex_unlock(&module_mutex);
88b700e7f0SSeth Jennings }
89b700e7f0SSeth Jennings 
90b700e7f0SSeth Jennings static bool klp_is_patch_registered(struct klp_patch *patch)
91b700e7f0SSeth Jennings {
92b700e7f0SSeth Jennings 	struct klp_patch *mypatch;
93b700e7f0SSeth Jennings 
94b700e7f0SSeth Jennings 	list_for_each_entry(mypatch, &klp_patches, list)
95b700e7f0SSeth Jennings 		if (mypatch == patch)
96b700e7f0SSeth Jennings 			return true;
97b700e7f0SSeth Jennings 
98b700e7f0SSeth Jennings 	return false;
99b700e7f0SSeth Jennings }
100b700e7f0SSeth Jennings 
101b700e7f0SSeth Jennings static bool klp_initialized(void)
102b700e7f0SSeth Jennings {
103e76ff06aSNicholas Mc Guire 	return !!klp_root_kobj;
104b700e7f0SSeth Jennings }
105b700e7f0SSeth Jennings 
106b700e7f0SSeth Jennings struct klp_find_arg {
107b700e7f0SSeth Jennings 	const char *objname;
108b700e7f0SSeth Jennings 	const char *name;
109b700e7f0SSeth Jennings 	unsigned long addr;
110b700e7f0SSeth Jennings 	unsigned long count;
111b2b018efSChris J Arges 	unsigned long pos;
112b700e7f0SSeth Jennings };
113b700e7f0SSeth Jennings 
114b700e7f0SSeth Jennings static int klp_find_callback(void *data, const char *name,
115b700e7f0SSeth Jennings 			     struct module *mod, unsigned long addr)
116b700e7f0SSeth Jennings {
117b700e7f0SSeth Jennings 	struct klp_find_arg *args = data;
118b700e7f0SSeth Jennings 
119b700e7f0SSeth Jennings 	if ((mod && !args->objname) || (!mod && args->objname))
120b700e7f0SSeth Jennings 		return 0;
121b700e7f0SSeth Jennings 
122b700e7f0SSeth Jennings 	if (strcmp(args->name, name))
123b700e7f0SSeth Jennings 		return 0;
124b700e7f0SSeth Jennings 
125b700e7f0SSeth Jennings 	if (args->objname && strcmp(args->objname, mod->name))
126b700e7f0SSeth Jennings 		return 0;
127b700e7f0SSeth Jennings 
128b700e7f0SSeth Jennings 	args->addr = addr;
129b700e7f0SSeth Jennings 	args->count++;
130b700e7f0SSeth Jennings 
131b2b018efSChris J Arges 	/*
132b2b018efSChris J Arges 	 * Finish the search when the symbol is found for the desired position
133b2b018efSChris J Arges 	 * or the position is not defined for a non-unique symbol.
134b2b018efSChris J Arges 	 */
135b2b018efSChris J Arges 	if ((args->pos && (args->count == args->pos)) ||
136b2b018efSChris J Arges 	    (!args->pos && (args->count > 1)))
137b2b018efSChris J Arges 		return 1;
138b2b018efSChris J Arges 
139b700e7f0SSeth Jennings 	return 0;
140b700e7f0SSeth Jennings }
141b700e7f0SSeth Jennings 
142b700e7f0SSeth Jennings static int klp_find_object_symbol(const char *objname, const char *name,
143b2b018efSChris J Arges 				  unsigned long sympos, unsigned long *addr)
144b700e7f0SSeth Jennings {
145b700e7f0SSeth Jennings 	struct klp_find_arg args = {
146b700e7f0SSeth Jennings 		.objname = objname,
147b700e7f0SSeth Jennings 		.name = name,
148b700e7f0SSeth Jennings 		.addr = 0,
149b2b018efSChris J Arges 		.count = 0,
150b2b018efSChris J Arges 		.pos = sympos,
151b700e7f0SSeth Jennings 	};
152b700e7f0SSeth Jennings 
1539a1bd63cSMiroslav Benes 	mutex_lock(&module_mutex);
15472f04b50SZhou Chengming 	if (objname)
15572f04b50SZhou Chengming 		module_kallsyms_on_each_symbol(klp_find_callback, &args);
15672f04b50SZhou Chengming 	else
157b700e7f0SSeth Jennings 		kallsyms_on_each_symbol(klp_find_callback, &args);
1589a1bd63cSMiroslav Benes 	mutex_unlock(&module_mutex);
159b700e7f0SSeth Jennings 
160b2b018efSChris J Arges 	/*
161b2b018efSChris J Arges 	 * Ensure an address was found. If sympos is 0, ensure symbol is unique;
162b2b018efSChris J Arges 	 * otherwise ensure the symbol position count matches sympos.
163b2b018efSChris J Arges 	 */
164b2b018efSChris J Arges 	if (args.addr == 0)
165b700e7f0SSeth Jennings 		pr_err("symbol '%s' not found in symbol table\n", name);
166b2b018efSChris J Arges 	else if (args.count > 1 && sympos == 0) {
167f995b5f7SPetr Mladek 		pr_err("unresolvable ambiguity for symbol '%s' in object '%s'\n",
168f995b5f7SPetr Mladek 		       name, objname);
169b2b018efSChris J Arges 	} else if (sympos != args.count && sympos > 0) {
170b2b018efSChris J Arges 		pr_err("symbol position %lu for symbol '%s' in object '%s' not found\n",
171b2b018efSChris J Arges 		       sympos, name, objname ? objname : "vmlinux");
172b2b018efSChris J Arges 	} else {
173b700e7f0SSeth Jennings 		*addr = args.addr;
174b700e7f0SSeth Jennings 		return 0;
175b700e7f0SSeth Jennings 	}
176b700e7f0SSeth Jennings 
177b700e7f0SSeth Jennings 	*addr = 0;
178b700e7f0SSeth Jennings 	return -EINVAL;
179b700e7f0SSeth Jennings }
180b700e7f0SSeth Jennings 
181425595a7SJessica Yu static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod)
182b700e7f0SSeth Jennings {
183425595a7SJessica Yu 	int i, cnt, vmlinux, ret;
184425595a7SJessica Yu 	char objname[MODULE_NAME_LEN];
185425595a7SJessica Yu 	char symname[KSYM_NAME_LEN];
186425595a7SJessica Yu 	char *strtab = pmod->core_kallsyms.strtab;
187425595a7SJessica Yu 	Elf_Rela *relas;
188425595a7SJessica Yu 	Elf_Sym *sym;
189425595a7SJessica Yu 	unsigned long sympos, addr;
190b700e7f0SSeth Jennings 
191b2b018efSChris J Arges 	/*
192425595a7SJessica Yu 	 * Since the field widths for objname and symname in the sscanf()
193425595a7SJessica Yu 	 * call are hard-coded and correspond to MODULE_NAME_LEN and
194425595a7SJessica Yu 	 * KSYM_NAME_LEN respectively, we must make sure that MODULE_NAME_LEN
195425595a7SJessica Yu 	 * and KSYM_NAME_LEN have the values we expect them to have.
196425595a7SJessica Yu 	 *
197425595a7SJessica Yu 	 * Because the value of MODULE_NAME_LEN can differ among architectures,
198425595a7SJessica Yu 	 * we use the smallest/strictest upper bound possible (56, based on
199425595a7SJessica Yu 	 * the current definition of MODULE_NAME_LEN) to prevent overflows.
200b2b018efSChris J Arges 	 */
201425595a7SJessica Yu 	BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128);
202425595a7SJessica Yu 
203425595a7SJessica Yu 	relas = (Elf_Rela *) relasec->sh_addr;
204425595a7SJessica Yu 	/* For each rela in this klp relocation section */
205425595a7SJessica Yu 	for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
206425595a7SJessica Yu 		sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info);
207425595a7SJessica Yu 		if (sym->st_shndx != SHN_LIVEPATCH) {
20877f8f39aSJosh Poimboeuf 			pr_err("symbol %s is not marked as a livepatch symbol\n",
209425595a7SJessica Yu 			       strtab + sym->st_name);
210425595a7SJessica Yu 			return -EINVAL;
211425595a7SJessica Yu 		}
212425595a7SJessica Yu 
213425595a7SJessica Yu 		/* Format: .klp.sym.objname.symname,sympos */
214425595a7SJessica Yu 		cnt = sscanf(strtab + sym->st_name,
215425595a7SJessica Yu 			     ".klp.sym.%55[^.].%127[^,],%lu",
216425595a7SJessica Yu 			     objname, symname, &sympos);
217425595a7SJessica Yu 		if (cnt != 3) {
21877f8f39aSJosh Poimboeuf 			pr_err("symbol %s has an incorrectly formatted name\n",
219425595a7SJessica Yu 			       strtab + sym->st_name);
220425595a7SJessica Yu 			return -EINVAL;
221425595a7SJessica Yu 		}
222425595a7SJessica Yu 
223425595a7SJessica Yu 		/* klp_find_object_symbol() treats a NULL objname as vmlinux */
224425595a7SJessica Yu 		vmlinux = !strcmp(objname, "vmlinux");
225425595a7SJessica Yu 		ret = klp_find_object_symbol(vmlinux ? NULL : objname,
226425595a7SJessica Yu 					     symname, sympos, &addr);
227425595a7SJessica Yu 		if (ret)
228425595a7SJessica Yu 			return ret;
229425595a7SJessica Yu 
230425595a7SJessica Yu 		sym->st_value = addr;
231425595a7SJessica Yu 	}
232425595a7SJessica Yu 
233425595a7SJessica Yu 	return 0;
234b700e7f0SSeth Jennings }
235b700e7f0SSeth Jennings 
236b700e7f0SSeth Jennings static int klp_write_object_relocations(struct module *pmod,
237b700e7f0SSeth Jennings 					struct klp_object *obj)
238b700e7f0SSeth Jennings {
239425595a7SJessica Yu 	int i, cnt, ret = 0;
240425595a7SJessica Yu 	const char *objname, *secname;
241425595a7SJessica Yu 	char sec_objname[MODULE_NAME_LEN];
242425595a7SJessica Yu 	Elf_Shdr *sec;
243b700e7f0SSeth Jennings 
244b700e7f0SSeth Jennings 	if (WARN_ON(!klp_is_object_loaded(obj)))
245b700e7f0SSeth Jennings 		return -EINVAL;
246b700e7f0SSeth Jennings 
247425595a7SJessica Yu 	objname = klp_is_module(obj) ? obj->name : "vmlinux";
248b700e7f0SSeth Jennings 
249425595a7SJessica Yu 	/* For each klp relocation section */
250425595a7SJessica Yu 	for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) {
251425595a7SJessica Yu 		sec = pmod->klp_info->sechdrs + i;
252425595a7SJessica Yu 		secname = pmod->klp_info->secstrings + sec->sh_name;
253425595a7SJessica Yu 		if (!(sec->sh_flags & SHF_RELA_LIVEPATCH))
254425595a7SJessica Yu 			continue;
255b56b36eeSJosh Poimboeuf 
256425595a7SJessica Yu 		/*
257425595a7SJessica Yu 		 * Format: .klp.rela.sec_objname.section_name
258425595a7SJessica Yu 		 * See comment in klp_resolve_symbols() for an explanation
259425595a7SJessica Yu 		 * of the selected field width value.
260425595a7SJessica Yu 		 */
261425595a7SJessica Yu 		cnt = sscanf(secname, ".klp.rela.%55[^.]", sec_objname);
262425595a7SJessica Yu 		if (cnt != 1) {
26377f8f39aSJosh Poimboeuf 			pr_err("section %s has an incorrectly formatted name\n",
264425595a7SJessica Yu 			       secname);
265b56b36eeSJosh Poimboeuf 			ret = -EINVAL;
266425595a7SJessica Yu 			break;
267b700e7f0SSeth Jennings 		}
268425595a7SJessica Yu 
269425595a7SJessica Yu 		if (strcmp(objname, sec_objname))
270425595a7SJessica Yu 			continue;
271425595a7SJessica Yu 
272425595a7SJessica Yu 		ret = klp_resolve_symbols(sec, pmod);
273064c89dfSChris J Arges 		if (ret)
274425595a7SJessica Yu 			break;
275064c89dfSChris J Arges 
276425595a7SJessica Yu 		ret = apply_relocate_add(pmod->klp_info->sechdrs,
277425595a7SJessica Yu 					 pmod->core_kallsyms.strtab,
278425595a7SJessica Yu 					 pmod->klp_info->symndx, i, pmod);
279425595a7SJessica Yu 		if (ret)
280425595a7SJessica Yu 			break;
281b700e7f0SSeth Jennings 	}
282b700e7f0SSeth Jennings 
283b56b36eeSJosh Poimboeuf 	return ret;
284b700e7f0SSeth Jennings }
285b700e7f0SSeth Jennings 
286b700e7f0SSeth Jennings static int __klp_disable_patch(struct klp_patch *patch)
287b700e7f0SSeth Jennings {
288d83a7cb3SJosh Poimboeuf 	if (klp_transition_patch)
289d83a7cb3SJosh Poimboeuf 		return -EBUSY;
290b700e7f0SSeth Jennings 
29183a90bb1SJosh Poimboeuf 	/* enforce stacking: only the last enabled patch can be disabled */
29283a90bb1SJosh Poimboeuf 	if (!list_is_last(&patch->list, &klp_patches) &&
2930dade9f3SJosh Poimboeuf 	    list_next_entry(patch, list)->enabled)
29483a90bb1SJosh Poimboeuf 		return -EBUSY;
29583a90bb1SJosh Poimboeuf 
296d83a7cb3SJosh Poimboeuf 	klp_init_transition(patch, KLP_UNPATCHED);
297b700e7f0SSeth Jennings 
298d83a7cb3SJosh Poimboeuf 	/*
299d83a7cb3SJosh Poimboeuf 	 * Enforce the order of the func->transition writes in
300d83a7cb3SJosh Poimboeuf 	 * klp_init_transition() and the TIF_PATCH_PENDING writes in
301d83a7cb3SJosh Poimboeuf 	 * klp_start_transition().  In the rare case where klp_ftrace_handler()
302d83a7cb3SJosh Poimboeuf 	 * is called shortly after klp_update_patch_state() switches the task,
303d83a7cb3SJosh Poimboeuf 	 * this ensures the handler sees that func->transition is set.
304d83a7cb3SJosh Poimboeuf 	 */
305d83a7cb3SJosh Poimboeuf 	smp_wmb();
306b700e7f0SSeth Jennings 
307d83a7cb3SJosh Poimboeuf 	klp_start_transition();
308d83a7cb3SJosh Poimboeuf 	klp_try_complete_transition();
3090dade9f3SJosh Poimboeuf 	patch->enabled = false;
310b700e7f0SSeth Jennings 
311b700e7f0SSeth Jennings 	return 0;
312b700e7f0SSeth Jennings }
313b700e7f0SSeth Jennings 
314b700e7f0SSeth Jennings /**
315b700e7f0SSeth Jennings  * klp_disable_patch() - disables a registered patch
316b700e7f0SSeth Jennings  * @patch:	The registered, enabled patch to be disabled
317b700e7f0SSeth Jennings  *
318b700e7f0SSeth Jennings  * Unregisters the patched functions from ftrace.
319b700e7f0SSeth Jennings  *
320b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
321b700e7f0SSeth Jennings  */
322b700e7f0SSeth Jennings int klp_disable_patch(struct klp_patch *patch)
323b700e7f0SSeth Jennings {
324b700e7f0SSeth Jennings 	int ret;
325b700e7f0SSeth Jennings 
326b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
327b700e7f0SSeth Jennings 
328b700e7f0SSeth Jennings 	if (!klp_is_patch_registered(patch)) {
329b700e7f0SSeth Jennings 		ret = -EINVAL;
330b700e7f0SSeth Jennings 		goto err;
331b700e7f0SSeth Jennings 	}
332b700e7f0SSeth Jennings 
3330dade9f3SJosh Poimboeuf 	if (!patch->enabled) {
334b700e7f0SSeth Jennings 		ret = -EINVAL;
335b700e7f0SSeth Jennings 		goto err;
336b700e7f0SSeth Jennings 	}
337b700e7f0SSeth Jennings 
338b700e7f0SSeth Jennings 	ret = __klp_disable_patch(patch);
339b700e7f0SSeth Jennings 
340b700e7f0SSeth Jennings err:
341b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
342b700e7f0SSeth Jennings 	return ret;
343b700e7f0SSeth Jennings }
344b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_disable_patch);
345b700e7f0SSeth Jennings 
346b700e7f0SSeth Jennings static int __klp_enable_patch(struct klp_patch *patch)
347b700e7f0SSeth Jennings {
348b700e7f0SSeth Jennings 	struct klp_object *obj;
349b700e7f0SSeth Jennings 	int ret;
350b700e7f0SSeth Jennings 
351d83a7cb3SJosh Poimboeuf 	if (klp_transition_patch)
352d83a7cb3SJosh Poimboeuf 		return -EBUSY;
353d83a7cb3SJosh Poimboeuf 
3540dade9f3SJosh Poimboeuf 	if (WARN_ON(patch->enabled))
355b700e7f0SSeth Jennings 		return -EINVAL;
356b700e7f0SSeth Jennings 
35783a90bb1SJosh Poimboeuf 	/* enforce stacking: only the first disabled patch can be enabled */
35883a90bb1SJosh Poimboeuf 	if (patch->list.prev != &klp_patches &&
3590dade9f3SJosh Poimboeuf 	    !list_prev_entry(patch, list)->enabled)
36083a90bb1SJosh Poimboeuf 		return -EBUSY;
36183a90bb1SJosh Poimboeuf 
3623ec24776SJosh Poimboeuf 	/*
3633ec24776SJosh Poimboeuf 	 * A reference is taken on the patch module to prevent it from being
3643ec24776SJosh Poimboeuf 	 * unloaded.
3653ec24776SJosh Poimboeuf 	 *
3663ec24776SJosh Poimboeuf 	 * Note: For immediate (no consistency model) patches we don't allow
3673ec24776SJosh Poimboeuf 	 * patch modules to unload since there is no safe/sane method to
3683ec24776SJosh Poimboeuf 	 * determine if a thread is still running in the patched code contained
3693ec24776SJosh Poimboeuf 	 * in the patch module once the ftrace registration is successful.
3703ec24776SJosh Poimboeuf 	 */
3713ec24776SJosh Poimboeuf 	if (!try_module_get(patch->mod))
3723ec24776SJosh Poimboeuf 		return -ENODEV;
3733ec24776SJosh Poimboeuf 
374b700e7f0SSeth Jennings 	pr_notice("enabling patch '%s'\n", patch->mod->name);
375b700e7f0SSeth Jennings 
376d83a7cb3SJosh Poimboeuf 	klp_init_transition(patch, KLP_PATCHED);
377d83a7cb3SJosh Poimboeuf 
378d83a7cb3SJosh Poimboeuf 	/*
379d83a7cb3SJosh Poimboeuf 	 * Enforce the order of the func->transition writes in
380d83a7cb3SJosh Poimboeuf 	 * klp_init_transition() and the ops->func_stack writes in
381d83a7cb3SJosh Poimboeuf 	 * klp_patch_object(), so that klp_ftrace_handler() will see the
382d83a7cb3SJosh Poimboeuf 	 * func->transition updates before the handler is registered and the
383d83a7cb3SJosh Poimboeuf 	 * new funcs become visible to the handler.
384d83a7cb3SJosh Poimboeuf 	 */
385d83a7cb3SJosh Poimboeuf 	smp_wmb();
386d83a7cb3SJosh Poimboeuf 
3878cdd043aSJiri Slaby 	klp_for_each_object(patch, obj) {
388b700e7f0SSeth Jennings 		if (!klp_is_object_loaded(obj))
389b700e7f0SSeth Jennings 			continue;
390b700e7f0SSeth Jennings 
3910dade9f3SJosh Poimboeuf 		ret = klp_patch_object(obj);
392d83a7cb3SJosh Poimboeuf 		if (ret) {
393d83a7cb3SJosh Poimboeuf 			pr_warn("failed to enable patch '%s'\n",
394d83a7cb3SJosh Poimboeuf 				patch->mod->name);
395d83a7cb3SJosh Poimboeuf 
396d83a7cb3SJosh Poimboeuf 			klp_cancel_transition();
397d83a7cb3SJosh Poimboeuf 			return ret;
398d83a7cb3SJosh Poimboeuf 		}
399b700e7f0SSeth Jennings 	}
400b700e7f0SSeth Jennings 
401d83a7cb3SJosh Poimboeuf 	klp_start_transition();
402d83a7cb3SJosh Poimboeuf 	klp_try_complete_transition();
4030dade9f3SJosh Poimboeuf 	patch->enabled = true;
404b700e7f0SSeth Jennings 
405b700e7f0SSeth Jennings 	return 0;
406b700e7f0SSeth Jennings }
407b700e7f0SSeth Jennings 
408b700e7f0SSeth Jennings /**
409b700e7f0SSeth Jennings  * klp_enable_patch() - enables a registered patch
410b700e7f0SSeth Jennings  * @patch:	The registered, disabled patch to be enabled
411b700e7f0SSeth Jennings  *
412b700e7f0SSeth Jennings  * Performs the needed symbol lookups and code relocations,
413b700e7f0SSeth Jennings  * then registers the patched functions with ftrace.
414b700e7f0SSeth Jennings  *
415b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
416b700e7f0SSeth Jennings  */
417b700e7f0SSeth Jennings int klp_enable_patch(struct klp_patch *patch)
418b700e7f0SSeth Jennings {
419b700e7f0SSeth Jennings 	int ret;
420b700e7f0SSeth Jennings 
421b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
422b700e7f0SSeth Jennings 
423b700e7f0SSeth Jennings 	if (!klp_is_patch_registered(patch)) {
424b700e7f0SSeth Jennings 		ret = -EINVAL;
425b700e7f0SSeth Jennings 		goto err;
426b700e7f0SSeth Jennings 	}
427b700e7f0SSeth Jennings 
428b700e7f0SSeth Jennings 	ret = __klp_enable_patch(patch);
429b700e7f0SSeth Jennings 
430b700e7f0SSeth Jennings err:
431b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
432b700e7f0SSeth Jennings 	return ret;
433b700e7f0SSeth Jennings }
434b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_enable_patch);
435b700e7f0SSeth Jennings 
436b700e7f0SSeth Jennings /*
437b700e7f0SSeth Jennings  * Sysfs Interface
438b700e7f0SSeth Jennings  *
439b700e7f0SSeth Jennings  * /sys/kernel/livepatch
440b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>
441b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>/enabled
442d83a7cb3SJosh Poimboeuf  * /sys/kernel/livepatch/<patch>/transition
443b700e7f0SSeth Jennings  * /sys/kernel/livepatch/<patch>/<object>
444444f9e99SChris J Arges  * /sys/kernel/livepatch/<patch>/<object>/<function,sympos>
445b700e7f0SSeth Jennings  */
446b700e7f0SSeth Jennings 
447b700e7f0SSeth Jennings static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr,
448b700e7f0SSeth Jennings 			     const char *buf, size_t count)
449b700e7f0SSeth Jennings {
450b700e7f0SSeth Jennings 	struct klp_patch *patch;
451b700e7f0SSeth Jennings 	int ret;
45268ae4b2bSJosh Poimboeuf 	bool enabled;
453b700e7f0SSeth Jennings 
45468ae4b2bSJosh Poimboeuf 	ret = kstrtobool(buf, &enabled);
455b700e7f0SSeth Jennings 	if (ret)
45668ae4b2bSJosh Poimboeuf 		return ret;
457b700e7f0SSeth Jennings 
458b700e7f0SSeth Jennings 	patch = container_of(kobj, struct klp_patch, kobj);
459b700e7f0SSeth Jennings 
460b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
461b700e7f0SSeth Jennings 
4623ec24776SJosh Poimboeuf 	if (!klp_is_patch_registered(patch)) {
4633ec24776SJosh Poimboeuf 		/*
4643ec24776SJosh Poimboeuf 		 * Module with the patch could either disappear meanwhile or is
4653ec24776SJosh Poimboeuf 		 * not properly initialized yet.
4663ec24776SJosh Poimboeuf 		 */
4673ec24776SJosh Poimboeuf 		ret = -EINVAL;
4683ec24776SJosh Poimboeuf 		goto err;
4693ec24776SJosh Poimboeuf 	}
4703ec24776SJosh Poimboeuf 
47168ae4b2bSJosh Poimboeuf 	if (patch->enabled == enabled) {
472b700e7f0SSeth Jennings 		/* already in requested state */
473b700e7f0SSeth Jennings 		ret = -EINVAL;
474b700e7f0SSeth Jennings 		goto err;
475b700e7f0SSeth Jennings 	}
476b700e7f0SSeth Jennings 
477d83a7cb3SJosh Poimboeuf 	if (patch == klp_transition_patch) {
478d83a7cb3SJosh Poimboeuf 		klp_reverse_transition();
479d83a7cb3SJosh Poimboeuf 	} else if (enabled) {
480b700e7f0SSeth Jennings 		ret = __klp_enable_patch(patch);
481b700e7f0SSeth Jennings 		if (ret)
482b700e7f0SSeth Jennings 			goto err;
483b700e7f0SSeth Jennings 	} else {
484b700e7f0SSeth Jennings 		ret = __klp_disable_patch(patch);
485b700e7f0SSeth Jennings 		if (ret)
486b700e7f0SSeth Jennings 			goto err;
487b700e7f0SSeth Jennings 	}
488b700e7f0SSeth Jennings 
489b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
490b700e7f0SSeth Jennings 
491b700e7f0SSeth Jennings 	return count;
492b700e7f0SSeth Jennings 
493b700e7f0SSeth Jennings err:
494b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
495b700e7f0SSeth Jennings 	return ret;
496b700e7f0SSeth Jennings }
497b700e7f0SSeth Jennings 
498b700e7f0SSeth Jennings static ssize_t enabled_show(struct kobject *kobj,
499b700e7f0SSeth Jennings 			    struct kobj_attribute *attr, char *buf)
500b700e7f0SSeth Jennings {
501b700e7f0SSeth Jennings 	struct klp_patch *patch;
502b700e7f0SSeth Jennings 
503b700e7f0SSeth Jennings 	patch = container_of(kobj, struct klp_patch, kobj);
5040dade9f3SJosh Poimboeuf 	return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->enabled);
505b700e7f0SSeth Jennings }
506b700e7f0SSeth Jennings 
507d83a7cb3SJosh Poimboeuf static ssize_t transition_show(struct kobject *kobj,
508d83a7cb3SJosh Poimboeuf 			       struct kobj_attribute *attr, char *buf)
509d83a7cb3SJosh Poimboeuf {
510d83a7cb3SJosh Poimboeuf 	struct klp_patch *patch;
511d83a7cb3SJosh Poimboeuf 
512d83a7cb3SJosh Poimboeuf 	patch = container_of(kobj, struct klp_patch, kobj);
513d83a7cb3SJosh Poimboeuf 	return snprintf(buf, PAGE_SIZE-1, "%d\n",
514d83a7cb3SJosh Poimboeuf 			patch == klp_transition_patch);
515b700e7f0SSeth Jennings }
516b700e7f0SSeth Jennings 
517b700e7f0SSeth Jennings static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled);
518d83a7cb3SJosh Poimboeuf static struct kobj_attribute transition_kobj_attr = __ATTR_RO(transition);
519b700e7f0SSeth Jennings static struct attribute *klp_patch_attrs[] = {
520b700e7f0SSeth Jennings 	&enabled_kobj_attr.attr,
521d83a7cb3SJosh Poimboeuf 	&transition_kobj_attr.attr,
522b700e7f0SSeth Jennings 	NULL
523b700e7f0SSeth Jennings };
524b700e7f0SSeth Jennings 
525b700e7f0SSeth Jennings static void klp_kobj_release_patch(struct kobject *kobj)
526b700e7f0SSeth Jennings {
5273ec24776SJosh Poimboeuf 	struct klp_patch *patch;
5283ec24776SJosh Poimboeuf 
5293ec24776SJosh Poimboeuf 	patch = container_of(kobj, struct klp_patch, kobj);
5303ec24776SJosh Poimboeuf 	complete(&patch->finish);
531b700e7f0SSeth Jennings }
532b700e7f0SSeth Jennings 
533b700e7f0SSeth Jennings static struct kobj_type klp_ktype_patch = {
534b700e7f0SSeth Jennings 	.release = klp_kobj_release_patch,
535b700e7f0SSeth Jennings 	.sysfs_ops = &kobj_sysfs_ops,
536b700e7f0SSeth Jennings 	.default_attrs = klp_patch_attrs,
537b700e7f0SSeth Jennings };
538b700e7f0SSeth Jennings 
539cad706dfSMiroslav Benes static void klp_kobj_release_object(struct kobject *kobj)
540cad706dfSMiroslav Benes {
541cad706dfSMiroslav Benes }
542cad706dfSMiroslav Benes 
543cad706dfSMiroslav Benes static struct kobj_type klp_ktype_object = {
544cad706dfSMiroslav Benes 	.release = klp_kobj_release_object,
545cad706dfSMiroslav Benes 	.sysfs_ops = &kobj_sysfs_ops,
546cad706dfSMiroslav Benes };
547cad706dfSMiroslav Benes 
548b700e7f0SSeth Jennings static void klp_kobj_release_func(struct kobject *kobj)
549b700e7f0SSeth Jennings {
550b700e7f0SSeth Jennings }
551b700e7f0SSeth Jennings 
552b700e7f0SSeth Jennings static struct kobj_type klp_ktype_func = {
553b700e7f0SSeth Jennings 	.release = klp_kobj_release_func,
554b700e7f0SSeth Jennings 	.sysfs_ops = &kobj_sysfs_ops,
555b700e7f0SSeth Jennings };
556b700e7f0SSeth Jennings 
557b700e7f0SSeth Jennings /*
558b700e7f0SSeth Jennings  * Free all functions' kobjects in the array up to some limit. When limit is
559b700e7f0SSeth Jennings  * NULL, all kobjects are freed.
560b700e7f0SSeth Jennings  */
561b700e7f0SSeth Jennings static void klp_free_funcs_limited(struct klp_object *obj,
562b700e7f0SSeth Jennings 				   struct klp_func *limit)
563b700e7f0SSeth Jennings {
564b700e7f0SSeth Jennings 	struct klp_func *func;
565b700e7f0SSeth Jennings 
566b700e7f0SSeth Jennings 	for (func = obj->funcs; func->old_name && func != limit; func++)
567b700e7f0SSeth Jennings 		kobject_put(&func->kobj);
568b700e7f0SSeth Jennings }
569b700e7f0SSeth Jennings 
570b700e7f0SSeth Jennings /* Clean up when a patched object is unloaded */
571b700e7f0SSeth Jennings static void klp_free_object_loaded(struct klp_object *obj)
572b700e7f0SSeth Jennings {
573b700e7f0SSeth Jennings 	struct klp_func *func;
574b700e7f0SSeth Jennings 
575b700e7f0SSeth Jennings 	obj->mod = NULL;
576b700e7f0SSeth Jennings 
5778cdd043aSJiri Slaby 	klp_for_each_func(obj, func)
578b700e7f0SSeth Jennings 		func->old_addr = 0;
579b700e7f0SSeth Jennings }
580b700e7f0SSeth Jennings 
581b700e7f0SSeth Jennings /*
582b700e7f0SSeth Jennings  * Free all objects' kobjects in the array up to some limit. When limit is
583b700e7f0SSeth Jennings  * NULL, all kobjects are freed.
584b700e7f0SSeth Jennings  */
585b700e7f0SSeth Jennings static void klp_free_objects_limited(struct klp_patch *patch,
586b700e7f0SSeth Jennings 				     struct klp_object *limit)
587b700e7f0SSeth Jennings {
588b700e7f0SSeth Jennings 	struct klp_object *obj;
589b700e7f0SSeth Jennings 
590b700e7f0SSeth Jennings 	for (obj = patch->objs; obj->funcs && obj != limit; obj++) {
591b700e7f0SSeth Jennings 		klp_free_funcs_limited(obj, NULL);
592cad706dfSMiroslav Benes 		kobject_put(&obj->kobj);
593b700e7f0SSeth Jennings 	}
594b700e7f0SSeth Jennings }
595b700e7f0SSeth Jennings 
596b700e7f0SSeth Jennings static void klp_free_patch(struct klp_patch *patch)
597b700e7f0SSeth Jennings {
598b700e7f0SSeth Jennings 	klp_free_objects_limited(patch, NULL);
599b700e7f0SSeth Jennings 	if (!list_empty(&patch->list))
600b700e7f0SSeth Jennings 		list_del(&patch->list);
601b700e7f0SSeth Jennings }
602b700e7f0SSeth Jennings 
603b700e7f0SSeth Jennings static int klp_init_func(struct klp_object *obj, struct klp_func *func)
604b700e7f0SSeth Jennings {
605f09d9086SMiroslav Benes 	if (!func->old_name || !func->new_func)
606f09d9086SMiroslav Benes 		return -EINVAL;
607f09d9086SMiroslav Benes 
6083c33f5b9SJosh Poimboeuf 	INIT_LIST_HEAD(&func->stack_node);
6090dade9f3SJosh Poimboeuf 	func->patched = false;
610d83a7cb3SJosh Poimboeuf 	func->transition = false;
611b700e7f0SSeth Jennings 
612444f9e99SChris J Arges 	/* The format for the sysfs directory is <function,sympos> where sympos
613444f9e99SChris J Arges 	 * is the nth occurrence of this symbol in kallsyms for the patched
614444f9e99SChris J Arges 	 * object. If the user selects 0 for old_sympos, then 1 will be used
615444f9e99SChris J Arges 	 * since a unique symbol will be the first occurrence.
616444f9e99SChris J Arges 	 */
6173c33f5b9SJosh Poimboeuf 	return kobject_init_and_add(&func->kobj, &klp_ktype_func,
618444f9e99SChris J Arges 				    &obj->kobj, "%s,%lu", func->old_name,
619444f9e99SChris J Arges 				    func->old_sympos ? func->old_sympos : 1);
620b700e7f0SSeth Jennings }
621b700e7f0SSeth Jennings 
622255e732cSJessica Yu /* Arches may override this to finish any remaining arch-specific tasks */
623255e732cSJessica Yu void __weak arch_klp_init_object_loaded(struct klp_patch *patch,
624255e732cSJessica Yu 					struct klp_object *obj)
625255e732cSJessica Yu {
626255e732cSJessica Yu }
627255e732cSJessica Yu 
628b700e7f0SSeth Jennings /* parts of the initialization that is done only when the object is loaded */
629b700e7f0SSeth Jennings static int klp_init_object_loaded(struct klp_patch *patch,
630b700e7f0SSeth Jennings 				  struct klp_object *obj)
631b700e7f0SSeth Jennings {
632b700e7f0SSeth Jennings 	struct klp_func *func;
633b700e7f0SSeth Jennings 	int ret;
634b700e7f0SSeth Jennings 
635255e732cSJessica Yu 	module_disable_ro(patch->mod);
636b700e7f0SSeth Jennings 	ret = klp_write_object_relocations(patch->mod, obj);
637255e732cSJessica Yu 	if (ret) {
638255e732cSJessica Yu 		module_enable_ro(patch->mod, true);
639b700e7f0SSeth Jennings 		return ret;
640255e732cSJessica Yu 	}
641255e732cSJessica Yu 
642255e732cSJessica Yu 	arch_klp_init_object_loaded(patch, obj);
643255e732cSJessica Yu 	module_enable_ro(patch->mod, true);
644b700e7f0SSeth Jennings 
6458cdd043aSJiri Slaby 	klp_for_each_func(obj, func) {
646b2b018efSChris J Arges 		ret = klp_find_object_symbol(obj->name, func->old_name,
647b2b018efSChris J Arges 					     func->old_sympos,
648b2b018efSChris J Arges 					     &func->old_addr);
649b700e7f0SSeth Jennings 		if (ret)
650b700e7f0SSeth Jennings 			return ret;
651f5e547f4SJosh Poimboeuf 
652f5e547f4SJosh Poimboeuf 		ret = kallsyms_lookup_size_offset(func->old_addr,
653f5e547f4SJosh Poimboeuf 						  &func->old_size, NULL);
654f5e547f4SJosh Poimboeuf 		if (!ret) {
655f5e547f4SJosh Poimboeuf 			pr_err("kallsyms size lookup failed for '%s'\n",
656f5e547f4SJosh Poimboeuf 			       func->old_name);
657f5e547f4SJosh Poimboeuf 			return -ENOENT;
658f5e547f4SJosh Poimboeuf 		}
659f5e547f4SJosh Poimboeuf 
660f5e547f4SJosh Poimboeuf 		ret = kallsyms_lookup_size_offset((unsigned long)func->new_func,
661f5e547f4SJosh Poimboeuf 						  &func->new_size, NULL);
662f5e547f4SJosh Poimboeuf 		if (!ret) {
663f5e547f4SJosh Poimboeuf 			pr_err("kallsyms size lookup failed for '%s' replacement\n",
664f5e547f4SJosh Poimboeuf 			       func->old_name);
665f5e547f4SJosh Poimboeuf 			return -ENOENT;
666f5e547f4SJosh Poimboeuf 		}
667b700e7f0SSeth Jennings 	}
668b700e7f0SSeth Jennings 
669b700e7f0SSeth Jennings 	return 0;
670b700e7f0SSeth Jennings }
671b700e7f0SSeth Jennings 
672b700e7f0SSeth Jennings static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
673b700e7f0SSeth Jennings {
674b700e7f0SSeth Jennings 	struct klp_func *func;
675b700e7f0SSeth Jennings 	int ret;
676b700e7f0SSeth Jennings 	const char *name;
677b700e7f0SSeth Jennings 
678b700e7f0SSeth Jennings 	if (!obj->funcs)
679b700e7f0SSeth Jennings 		return -EINVAL;
680b700e7f0SSeth Jennings 
6810dade9f3SJosh Poimboeuf 	obj->patched = false;
6828cb2c2dcSPetr Mladek 	obj->mod = NULL;
683b700e7f0SSeth Jennings 
684b700e7f0SSeth Jennings 	klp_find_object_module(obj);
685b700e7f0SSeth Jennings 
686b700e7f0SSeth Jennings 	name = klp_is_module(obj) ? obj->name : "vmlinux";
687cad706dfSMiroslav Benes 	ret = kobject_init_and_add(&obj->kobj, &klp_ktype_object,
688cad706dfSMiroslav Benes 				   &patch->kobj, "%s", name);
689cad706dfSMiroslav Benes 	if (ret)
690cad706dfSMiroslav Benes 		return ret;
691b700e7f0SSeth Jennings 
6928cdd043aSJiri Slaby 	klp_for_each_func(obj, func) {
693b700e7f0SSeth Jennings 		ret = klp_init_func(obj, func);
694b700e7f0SSeth Jennings 		if (ret)
695b700e7f0SSeth Jennings 			goto free;
696b700e7f0SSeth Jennings 	}
697b700e7f0SSeth Jennings 
698b700e7f0SSeth Jennings 	if (klp_is_object_loaded(obj)) {
699b700e7f0SSeth Jennings 		ret = klp_init_object_loaded(patch, obj);
700b700e7f0SSeth Jennings 		if (ret)
701b700e7f0SSeth Jennings 			goto free;
702b700e7f0SSeth Jennings 	}
703b700e7f0SSeth Jennings 
704b700e7f0SSeth Jennings 	return 0;
705b700e7f0SSeth Jennings 
706b700e7f0SSeth Jennings free:
707b700e7f0SSeth Jennings 	klp_free_funcs_limited(obj, func);
708cad706dfSMiroslav Benes 	kobject_put(&obj->kobj);
709b700e7f0SSeth Jennings 	return ret;
710b700e7f0SSeth Jennings }
711b700e7f0SSeth Jennings 
712b700e7f0SSeth Jennings static int klp_init_patch(struct klp_patch *patch)
713b700e7f0SSeth Jennings {
714b700e7f0SSeth Jennings 	struct klp_object *obj;
715b700e7f0SSeth Jennings 	int ret;
716b700e7f0SSeth Jennings 
717b700e7f0SSeth Jennings 	if (!patch->objs)
718b700e7f0SSeth Jennings 		return -EINVAL;
719b700e7f0SSeth Jennings 
720b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
721b700e7f0SSeth Jennings 
7220dade9f3SJosh Poimboeuf 	patch->enabled = false;
7233ec24776SJosh Poimboeuf 	init_completion(&patch->finish);
724b700e7f0SSeth Jennings 
725b700e7f0SSeth Jennings 	ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch,
726e0b561eeSJiri Kosina 				   klp_root_kobj, "%s", patch->mod->name);
7273ec24776SJosh Poimboeuf 	if (ret) {
7283ec24776SJosh Poimboeuf 		mutex_unlock(&klp_mutex);
7293ec24776SJosh Poimboeuf 		return ret;
7303ec24776SJosh Poimboeuf 	}
731b700e7f0SSeth Jennings 
7328cdd043aSJiri Slaby 	klp_for_each_object(patch, obj) {
733b700e7f0SSeth Jennings 		ret = klp_init_object(patch, obj);
734b700e7f0SSeth Jennings 		if (ret)
735b700e7f0SSeth Jennings 			goto free;
736b700e7f0SSeth Jennings 	}
737b700e7f0SSeth Jennings 
73899590ba5SJosh Poimboeuf 	list_add_tail(&patch->list, &klp_patches);
739b700e7f0SSeth Jennings 
740b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
741b700e7f0SSeth Jennings 
742b700e7f0SSeth Jennings 	return 0;
743b700e7f0SSeth Jennings 
744b700e7f0SSeth Jennings free:
745b700e7f0SSeth Jennings 	klp_free_objects_limited(patch, obj);
7463ec24776SJosh Poimboeuf 
747b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
7483ec24776SJosh Poimboeuf 
7493ec24776SJosh Poimboeuf 	kobject_put(&patch->kobj);
7503ec24776SJosh Poimboeuf 	wait_for_completion(&patch->finish);
7513ec24776SJosh Poimboeuf 
752b700e7f0SSeth Jennings 	return ret;
753b700e7f0SSeth Jennings }
754b700e7f0SSeth Jennings 
755b700e7f0SSeth Jennings /**
756b700e7f0SSeth Jennings  * klp_unregister_patch() - unregisters a patch
757b700e7f0SSeth Jennings  * @patch:	Disabled patch to be unregistered
758b700e7f0SSeth Jennings  *
759b700e7f0SSeth Jennings  * Frees the data structures and removes the sysfs interface.
760b700e7f0SSeth Jennings  *
761b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
762b700e7f0SSeth Jennings  */
763b700e7f0SSeth Jennings int klp_unregister_patch(struct klp_patch *patch)
764b700e7f0SSeth Jennings {
7653ec24776SJosh Poimboeuf 	int ret;
766b700e7f0SSeth Jennings 
767b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
768b700e7f0SSeth Jennings 
769b700e7f0SSeth Jennings 	if (!klp_is_patch_registered(patch)) {
770b700e7f0SSeth Jennings 		ret = -EINVAL;
7713ec24776SJosh Poimboeuf 		goto err;
772b700e7f0SSeth Jennings 	}
773b700e7f0SSeth Jennings 
7740dade9f3SJosh Poimboeuf 	if (patch->enabled) {
775b700e7f0SSeth Jennings 		ret = -EBUSY;
7763ec24776SJosh Poimboeuf 		goto err;
777b700e7f0SSeth Jennings 	}
778b700e7f0SSeth Jennings 
779b700e7f0SSeth Jennings 	klp_free_patch(patch);
780b700e7f0SSeth Jennings 
7813ec24776SJosh Poimboeuf 	mutex_unlock(&klp_mutex);
7823ec24776SJosh Poimboeuf 
7833ec24776SJosh Poimboeuf 	kobject_put(&patch->kobj);
7843ec24776SJosh Poimboeuf 	wait_for_completion(&patch->finish);
7853ec24776SJosh Poimboeuf 
7863ec24776SJosh Poimboeuf 	return 0;
7873ec24776SJosh Poimboeuf err:
788b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
789b700e7f0SSeth Jennings 	return ret;
790b700e7f0SSeth Jennings }
791b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_unregister_patch);
792b700e7f0SSeth Jennings 
793b700e7f0SSeth Jennings /**
794b700e7f0SSeth Jennings  * klp_register_patch() - registers a patch
795b700e7f0SSeth Jennings  * @patch:	Patch to be registered
796b700e7f0SSeth Jennings  *
797b700e7f0SSeth Jennings  * Initializes the data structure associated with the patch and
798b700e7f0SSeth Jennings  * creates the sysfs interface.
799b700e7f0SSeth Jennings  *
8003ec24776SJosh Poimboeuf  * There is no need to take the reference on the patch module here. It is done
8013ec24776SJosh Poimboeuf  * later when the patch is enabled.
8023ec24776SJosh Poimboeuf  *
803b700e7f0SSeth Jennings  * Return: 0 on success, otherwise error
804b700e7f0SSeth Jennings  */
805b700e7f0SSeth Jennings int klp_register_patch(struct klp_patch *patch)
806b700e7f0SSeth Jennings {
807b700e7f0SSeth Jennings 	if (!patch || !patch->mod)
808b700e7f0SSeth Jennings 		return -EINVAL;
809b700e7f0SSeth Jennings 
810425595a7SJessica Yu 	if (!is_livepatch_module(patch->mod)) {
81177f8f39aSJosh Poimboeuf 		pr_err("module %s is not marked as a livepatch module\n",
812425595a7SJessica Yu 		       patch->mod->name);
813425595a7SJessica Yu 		return -EINVAL;
814425595a7SJessica Yu 	}
815425595a7SJessica Yu 
816b700e7f0SSeth Jennings 	if (!klp_initialized())
817b700e7f0SSeth Jennings 		return -ENODEV;
818b700e7f0SSeth Jennings 
819b700e7f0SSeth Jennings 	/*
820d83a7cb3SJosh Poimboeuf 	 * Architectures without reliable stack traces have to set
821d83a7cb3SJosh Poimboeuf 	 * patch->immediate because there's currently no way to patch kthreads
822d83a7cb3SJosh Poimboeuf 	 * with the consistency model.
823b700e7f0SSeth Jennings 	 */
824d83a7cb3SJosh Poimboeuf 	if (!klp_have_reliable_stack() && !patch->immediate) {
825d83a7cb3SJosh Poimboeuf 		pr_err("This architecture doesn't have support for the livepatch consistency model.\n");
826d83a7cb3SJosh Poimboeuf 		return -ENOSYS;
827d83a7cb3SJosh Poimboeuf 	}
828b700e7f0SSeth Jennings 
8293ec24776SJosh Poimboeuf 	return klp_init_patch(patch);
830b700e7f0SSeth Jennings }
831b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_register_patch);
832b700e7f0SSeth Jennings 
833*ef8daf8eSJoe Lawrence /*
834*ef8daf8eSJoe Lawrence  * Remove parts of patches that touch a given kernel module. The list of
835*ef8daf8eSJoe Lawrence  * patches processed might be limited. When limit is NULL, all patches
836*ef8daf8eSJoe Lawrence  * will be handled.
837*ef8daf8eSJoe Lawrence  */
838*ef8daf8eSJoe Lawrence static void klp_cleanup_module_patches_limited(struct module *mod,
839*ef8daf8eSJoe Lawrence 					       struct klp_patch *limit)
840*ef8daf8eSJoe Lawrence {
841*ef8daf8eSJoe Lawrence 	struct klp_patch *patch;
842*ef8daf8eSJoe Lawrence 	struct klp_object *obj;
843*ef8daf8eSJoe Lawrence 
844*ef8daf8eSJoe Lawrence 	list_for_each_entry(patch, &klp_patches, list) {
845*ef8daf8eSJoe Lawrence 		if (patch == limit)
846*ef8daf8eSJoe Lawrence 			break;
847*ef8daf8eSJoe Lawrence 
848*ef8daf8eSJoe Lawrence 		klp_for_each_object(patch, obj) {
849*ef8daf8eSJoe Lawrence 			if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
850*ef8daf8eSJoe Lawrence 				continue;
851*ef8daf8eSJoe Lawrence 
852*ef8daf8eSJoe Lawrence 			/*
853*ef8daf8eSJoe Lawrence 			 * Only unpatch the module if the patch is enabled or
854*ef8daf8eSJoe Lawrence 			 * is in transition.
855*ef8daf8eSJoe Lawrence 			 */
856*ef8daf8eSJoe Lawrence 			if (patch->enabled || patch == klp_transition_patch) {
857*ef8daf8eSJoe Lawrence 				pr_notice("reverting patch '%s' on unloading module '%s'\n",
858*ef8daf8eSJoe Lawrence 					  patch->mod->name, obj->mod->name);
859*ef8daf8eSJoe Lawrence 				klp_unpatch_object(obj);
860*ef8daf8eSJoe Lawrence 			}
861*ef8daf8eSJoe Lawrence 
862*ef8daf8eSJoe Lawrence 			klp_free_object_loaded(obj);
863*ef8daf8eSJoe Lawrence 			break;
864*ef8daf8eSJoe Lawrence 		}
865*ef8daf8eSJoe Lawrence 	}
866*ef8daf8eSJoe Lawrence }
867*ef8daf8eSJoe Lawrence 
8687e545d6eSJessica Yu int klp_module_coming(struct module *mod)
869b700e7f0SSeth Jennings {
87036e505c1SMinfei Huang 	int ret;
871b700e7f0SSeth Jennings 	struct klp_patch *patch;
872b700e7f0SSeth Jennings 	struct klp_object *obj;
873b700e7f0SSeth Jennings 
8747e545d6eSJessica Yu 	if (WARN_ON(mod->state != MODULE_STATE_COMING))
8757e545d6eSJessica Yu 		return -EINVAL;
876b700e7f0SSeth Jennings 
877b700e7f0SSeth Jennings 	mutex_lock(&klp_mutex);
8788cb2c2dcSPetr Mladek 	/*
8797e545d6eSJessica Yu 	 * Each module has to know that klp_module_coming()
8807e545d6eSJessica Yu 	 * has been called. We never know what module will
8817e545d6eSJessica Yu 	 * get patched by a new patch.
8828cb2c2dcSPetr Mladek 	 */
8838cb2c2dcSPetr Mladek 	mod->klp_alive = true;
8848cb2c2dcSPetr Mladek 
885b700e7f0SSeth Jennings 	list_for_each_entry(patch, &klp_patches, list) {
8868cdd043aSJiri Slaby 		klp_for_each_object(patch, obj) {
887b700e7f0SSeth Jennings 			if (!klp_is_module(obj) || strcmp(obj->name, mod->name))
888b700e7f0SSeth Jennings 				continue;
889b700e7f0SSeth Jennings 
890b700e7f0SSeth Jennings 			obj->mod = mod;
8917e545d6eSJessica Yu 
8927e545d6eSJessica Yu 			ret = klp_init_object_loaded(patch, obj);
89336e505c1SMinfei Huang 			if (ret) {
8947e545d6eSJessica Yu 				pr_warn("failed to initialize patch '%s' for module '%s' (%d)\n",
8957e545d6eSJessica Yu 					patch->mod->name, obj->mod->name, ret);
8967e545d6eSJessica Yu 				goto err;
89736e505c1SMinfei Huang 			}
8987e545d6eSJessica Yu 
899d83a7cb3SJosh Poimboeuf 			/*
900d83a7cb3SJosh Poimboeuf 			 * Only patch the module if the patch is enabled or is
901d83a7cb3SJosh Poimboeuf 			 * in transition.
902d83a7cb3SJosh Poimboeuf 			 */
903d83a7cb3SJosh Poimboeuf 			if (!patch->enabled && patch != klp_transition_patch)
9047e545d6eSJessica Yu 				break;
9057e545d6eSJessica Yu 
9067e545d6eSJessica Yu 			pr_notice("applying patch '%s' to loading module '%s'\n",
9077e545d6eSJessica Yu 				  patch->mod->name, obj->mod->name);
9087e545d6eSJessica Yu 
9090dade9f3SJosh Poimboeuf 			ret = klp_patch_object(obj);
9107e545d6eSJessica Yu 			if (ret) {
9117e545d6eSJessica Yu 				pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
9127e545d6eSJessica Yu 					patch->mod->name, obj->mod->name, ret);
9137e545d6eSJessica Yu 				goto err;
9147e545d6eSJessica Yu 			}
915b700e7f0SSeth Jennings 
916b700e7f0SSeth Jennings 			break;
917b700e7f0SSeth Jennings 		}
918b700e7f0SSeth Jennings 	}
919b700e7f0SSeth Jennings 
920b700e7f0SSeth Jennings 	mutex_unlock(&klp_mutex);
921b700e7f0SSeth Jennings 
922b700e7f0SSeth Jennings 	return 0;
9237e545d6eSJessica Yu 
9247e545d6eSJessica Yu err:
9257e545d6eSJessica Yu 	/*
9267e545d6eSJessica Yu 	 * If a patch is unsuccessfully applied, return
9277e545d6eSJessica Yu 	 * error to the module loader.
9287e545d6eSJessica Yu 	 */
9297e545d6eSJessica Yu 	pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n",
9307e545d6eSJessica Yu 		patch->mod->name, obj->mod->name, obj->mod->name);
9317e545d6eSJessica Yu 	mod->klp_alive = false;
932*ef8daf8eSJoe Lawrence 	klp_cleanup_module_patches_limited(mod, patch);
9337e545d6eSJessica Yu 	mutex_unlock(&klp_mutex);
9347e545d6eSJessica Yu 
9357e545d6eSJessica Yu 	return ret;
936b700e7f0SSeth Jennings }
937b700e7f0SSeth Jennings 
9387e545d6eSJessica Yu void klp_module_going(struct module *mod)
9397e545d6eSJessica Yu {
9407e545d6eSJessica Yu 	if (WARN_ON(mod->state != MODULE_STATE_GOING &&
9417e545d6eSJessica Yu 		    mod->state != MODULE_STATE_COMING))
9427e545d6eSJessica Yu 		return;
9437e545d6eSJessica Yu 
9447e545d6eSJessica Yu 	mutex_lock(&klp_mutex);
9457e545d6eSJessica Yu 	/*
9467e545d6eSJessica Yu 	 * Each module has to know that klp_module_going()
9477e545d6eSJessica Yu 	 * has been called. We never know what module will
9487e545d6eSJessica Yu 	 * get patched by a new patch.
9497e545d6eSJessica Yu 	 */
9507e545d6eSJessica Yu 	mod->klp_alive = false;
9517e545d6eSJessica Yu 
952*ef8daf8eSJoe Lawrence 	klp_cleanup_module_patches_limited(mod, NULL);
9537e545d6eSJessica Yu 
9547e545d6eSJessica Yu 	mutex_unlock(&klp_mutex);
9557e545d6eSJessica Yu }
956b700e7f0SSeth Jennings 
95726029d88SMinfei Huang static int __init klp_init(void)
958b700e7f0SSeth Jennings {
959b700e7f0SSeth Jennings 	int ret;
960b700e7f0SSeth Jennings 
961b9dfe0beSJiri Kosina 	ret = klp_check_compiler_support();
962b9dfe0beSJiri Kosina 	if (ret) {
963b9dfe0beSJiri Kosina 		pr_info("Your compiler is too old; turning off.\n");
964b9dfe0beSJiri Kosina 		return -EINVAL;
965b9dfe0beSJiri Kosina 	}
966b9dfe0beSJiri Kosina 
967b700e7f0SSeth Jennings 	klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj);
9687e545d6eSJessica Yu 	if (!klp_root_kobj)
9697e545d6eSJessica Yu 		return -ENOMEM;
970b700e7f0SSeth Jennings 
971b700e7f0SSeth Jennings 	return 0;
972b700e7f0SSeth Jennings }
973b700e7f0SSeth Jennings 
974b700e7f0SSeth Jennings module_init(klp_init);
975