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