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> 32b56b36eeSJosh Poimboeuf #include <asm/cacheflush.h> 33*c349cdcaSJosh Poimboeuf #include "patch.h" 34b700e7f0SSeth Jennings 353c33f5b9SJosh Poimboeuf /* 363c33f5b9SJosh Poimboeuf * The klp_mutex protects the global lists and state transitions of any 373c33f5b9SJosh Poimboeuf * structure reachable from them. References to any structure must be obtained 383c33f5b9SJosh Poimboeuf * under mutex protection (except in klp_ftrace_handler(), which uses RCU to 393c33f5b9SJosh Poimboeuf * ensure it gets consistent data). 403c33f5b9SJosh Poimboeuf */ 41b700e7f0SSeth Jennings static DEFINE_MUTEX(klp_mutex); 423c33f5b9SJosh Poimboeuf 43b700e7f0SSeth Jennings static LIST_HEAD(klp_patches); 44b700e7f0SSeth Jennings 45b700e7f0SSeth Jennings static struct kobject *klp_root_kobj; 46b700e7f0SSeth Jennings 4746c5a011SJosh Poimboeuf /* TODO: temporary stub */ 4846c5a011SJosh Poimboeuf void klp_update_patch_state(struct task_struct *task) {} 4946c5a011SJosh Poimboeuf 50b700e7f0SSeth Jennings static bool klp_is_module(struct klp_object *obj) 51b700e7f0SSeth Jennings { 52b700e7f0SSeth Jennings return obj->name; 53b700e7f0SSeth Jennings } 54b700e7f0SSeth Jennings 55b700e7f0SSeth Jennings static bool klp_is_object_loaded(struct klp_object *obj) 56b700e7f0SSeth Jennings { 57b700e7f0SSeth Jennings return !obj->name || obj->mod; 58b700e7f0SSeth Jennings } 59b700e7f0SSeth Jennings 60b700e7f0SSeth Jennings /* sets obj->mod if object is not vmlinux and module is found */ 61b700e7f0SSeth Jennings static void klp_find_object_module(struct klp_object *obj) 62b700e7f0SSeth Jennings { 638cb2c2dcSPetr Mladek struct module *mod; 648cb2c2dcSPetr Mladek 65b700e7f0SSeth Jennings if (!klp_is_module(obj)) 66b700e7f0SSeth Jennings return; 67b700e7f0SSeth Jennings 68b700e7f0SSeth Jennings mutex_lock(&module_mutex); 69b700e7f0SSeth Jennings /* 708cb2c2dcSPetr Mladek * We do not want to block removal of patched modules and therefore 718cb2c2dcSPetr Mladek * we do not take a reference here. The patches are removed by 727e545d6eSJessica Yu * klp_module_going() instead. 73b700e7f0SSeth Jennings */ 748cb2c2dcSPetr Mladek mod = find_module(obj->name); 758cb2c2dcSPetr Mladek /* 767e545d6eSJessica Yu * Do not mess work of klp_module_coming() and klp_module_going(). 777e545d6eSJessica Yu * Note that the patch might still be needed before klp_module_going() 788cb2c2dcSPetr Mladek * is called. Module functions can be called even in the GOING state 798cb2c2dcSPetr Mladek * until mod->exit() finishes. This is especially important for 808cb2c2dcSPetr Mladek * patches that modify semantic of the functions. 818cb2c2dcSPetr Mladek */ 828cb2c2dcSPetr Mladek if (mod && mod->klp_alive) 838cb2c2dcSPetr Mladek obj->mod = mod; 848cb2c2dcSPetr Mladek 85b700e7f0SSeth Jennings mutex_unlock(&module_mutex); 86b700e7f0SSeth Jennings } 87b700e7f0SSeth Jennings 88b700e7f0SSeth Jennings /* klp_mutex must be held by caller */ 89b700e7f0SSeth Jennings static bool klp_is_patch_registered(struct klp_patch *patch) 90b700e7f0SSeth Jennings { 91b700e7f0SSeth Jennings struct klp_patch *mypatch; 92b700e7f0SSeth Jennings 93b700e7f0SSeth Jennings list_for_each_entry(mypatch, &klp_patches, list) 94b700e7f0SSeth Jennings if (mypatch == patch) 95b700e7f0SSeth Jennings return true; 96b700e7f0SSeth Jennings 97b700e7f0SSeth Jennings return false; 98b700e7f0SSeth Jennings } 99b700e7f0SSeth Jennings 100b700e7f0SSeth Jennings static bool klp_initialized(void) 101b700e7f0SSeth Jennings { 102e76ff06aSNicholas Mc Guire return !!klp_root_kobj; 103b700e7f0SSeth Jennings } 104b700e7f0SSeth Jennings 105b700e7f0SSeth Jennings struct klp_find_arg { 106b700e7f0SSeth Jennings const char *objname; 107b700e7f0SSeth Jennings const char *name; 108b700e7f0SSeth Jennings unsigned long addr; 109b700e7f0SSeth Jennings unsigned long count; 110b2b018efSChris J Arges unsigned long pos; 111b700e7f0SSeth Jennings }; 112b700e7f0SSeth Jennings 113b700e7f0SSeth Jennings static int klp_find_callback(void *data, const char *name, 114b700e7f0SSeth Jennings struct module *mod, unsigned long addr) 115b700e7f0SSeth Jennings { 116b700e7f0SSeth Jennings struct klp_find_arg *args = data; 117b700e7f0SSeth Jennings 118b700e7f0SSeth Jennings if ((mod && !args->objname) || (!mod && args->objname)) 119b700e7f0SSeth Jennings return 0; 120b700e7f0SSeth Jennings 121b700e7f0SSeth Jennings if (strcmp(args->name, name)) 122b700e7f0SSeth Jennings return 0; 123b700e7f0SSeth Jennings 124b700e7f0SSeth Jennings if (args->objname && strcmp(args->objname, mod->name)) 125b700e7f0SSeth Jennings return 0; 126b700e7f0SSeth Jennings 127b700e7f0SSeth Jennings args->addr = addr; 128b700e7f0SSeth Jennings args->count++; 129b700e7f0SSeth Jennings 130b2b018efSChris J Arges /* 131b2b018efSChris J Arges * Finish the search when the symbol is found for the desired position 132b2b018efSChris J Arges * or the position is not defined for a non-unique symbol. 133b2b018efSChris J Arges */ 134b2b018efSChris J Arges if ((args->pos && (args->count == args->pos)) || 135b2b018efSChris J Arges (!args->pos && (args->count > 1))) 136b2b018efSChris J Arges return 1; 137b2b018efSChris J Arges 138b700e7f0SSeth Jennings return 0; 139b700e7f0SSeth Jennings } 140b700e7f0SSeth Jennings 141b700e7f0SSeth Jennings static int klp_find_object_symbol(const char *objname, const char *name, 142b2b018efSChris J Arges unsigned long sympos, unsigned long *addr) 143b700e7f0SSeth Jennings { 144b700e7f0SSeth Jennings struct klp_find_arg args = { 145b700e7f0SSeth Jennings .objname = objname, 146b700e7f0SSeth Jennings .name = name, 147b700e7f0SSeth Jennings .addr = 0, 148b2b018efSChris J Arges .count = 0, 149b2b018efSChris J Arges .pos = sympos, 150b700e7f0SSeth Jennings }; 151b700e7f0SSeth Jennings 1529a1bd63cSMiroslav Benes mutex_lock(&module_mutex); 153b700e7f0SSeth Jennings kallsyms_on_each_symbol(klp_find_callback, &args); 1549a1bd63cSMiroslav Benes mutex_unlock(&module_mutex); 155b700e7f0SSeth Jennings 156b2b018efSChris J Arges /* 157b2b018efSChris J Arges * Ensure an address was found. If sympos is 0, ensure symbol is unique; 158b2b018efSChris J Arges * otherwise ensure the symbol position count matches sympos. 159b2b018efSChris J Arges */ 160b2b018efSChris J Arges if (args.addr == 0) 161b700e7f0SSeth Jennings pr_err("symbol '%s' not found in symbol table\n", name); 162b2b018efSChris J Arges else if (args.count > 1 && sympos == 0) { 163f995b5f7SPetr Mladek pr_err("unresolvable ambiguity for symbol '%s' in object '%s'\n", 164f995b5f7SPetr Mladek name, objname); 165b2b018efSChris J Arges } else if (sympos != args.count && sympos > 0) { 166b2b018efSChris J Arges pr_err("symbol position %lu for symbol '%s' in object '%s' not found\n", 167b2b018efSChris J Arges sympos, name, objname ? objname : "vmlinux"); 168b2b018efSChris J Arges } else { 169b700e7f0SSeth Jennings *addr = args.addr; 170b700e7f0SSeth Jennings return 0; 171b700e7f0SSeth Jennings } 172b700e7f0SSeth Jennings 173b700e7f0SSeth Jennings *addr = 0; 174b700e7f0SSeth Jennings return -EINVAL; 175b700e7f0SSeth Jennings } 176b700e7f0SSeth Jennings 177425595a7SJessica Yu static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod) 178b700e7f0SSeth Jennings { 179425595a7SJessica Yu int i, cnt, vmlinux, ret; 180425595a7SJessica Yu char objname[MODULE_NAME_LEN]; 181425595a7SJessica Yu char symname[KSYM_NAME_LEN]; 182425595a7SJessica Yu char *strtab = pmod->core_kallsyms.strtab; 183425595a7SJessica Yu Elf_Rela *relas; 184425595a7SJessica Yu Elf_Sym *sym; 185425595a7SJessica Yu unsigned long sympos, addr; 186b700e7f0SSeth Jennings 187b2b018efSChris J Arges /* 188425595a7SJessica Yu * Since the field widths for objname and symname in the sscanf() 189425595a7SJessica Yu * call are hard-coded and correspond to MODULE_NAME_LEN and 190425595a7SJessica Yu * KSYM_NAME_LEN respectively, we must make sure that MODULE_NAME_LEN 191425595a7SJessica Yu * and KSYM_NAME_LEN have the values we expect them to have. 192425595a7SJessica Yu * 193425595a7SJessica Yu * Because the value of MODULE_NAME_LEN can differ among architectures, 194425595a7SJessica Yu * we use the smallest/strictest upper bound possible (56, based on 195425595a7SJessica Yu * the current definition of MODULE_NAME_LEN) to prevent overflows. 196b2b018efSChris J Arges */ 197425595a7SJessica Yu BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128); 198425595a7SJessica Yu 199425595a7SJessica Yu relas = (Elf_Rela *) relasec->sh_addr; 200425595a7SJessica Yu /* For each rela in this klp relocation section */ 201425595a7SJessica Yu for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) { 202425595a7SJessica Yu sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info); 203425595a7SJessica Yu if (sym->st_shndx != SHN_LIVEPATCH) { 204425595a7SJessica Yu pr_err("symbol %s is not marked as a livepatch symbol", 205425595a7SJessica Yu strtab + sym->st_name); 206425595a7SJessica Yu return -EINVAL; 207425595a7SJessica Yu } 208425595a7SJessica Yu 209425595a7SJessica Yu /* Format: .klp.sym.objname.symname,sympos */ 210425595a7SJessica Yu cnt = sscanf(strtab + sym->st_name, 211425595a7SJessica Yu ".klp.sym.%55[^.].%127[^,],%lu", 212425595a7SJessica Yu objname, symname, &sympos); 213425595a7SJessica Yu if (cnt != 3) { 214425595a7SJessica Yu pr_err("symbol %s has an incorrectly formatted name", 215425595a7SJessica Yu strtab + sym->st_name); 216425595a7SJessica Yu return -EINVAL; 217425595a7SJessica Yu } 218425595a7SJessica Yu 219425595a7SJessica Yu /* klp_find_object_symbol() treats a NULL objname as vmlinux */ 220425595a7SJessica Yu vmlinux = !strcmp(objname, "vmlinux"); 221425595a7SJessica Yu ret = klp_find_object_symbol(vmlinux ? NULL : objname, 222425595a7SJessica Yu symname, sympos, &addr); 223425595a7SJessica Yu if (ret) 224425595a7SJessica Yu return ret; 225425595a7SJessica Yu 226425595a7SJessica Yu sym->st_value = addr; 227425595a7SJessica Yu } 228425595a7SJessica Yu 229425595a7SJessica Yu return 0; 230b700e7f0SSeth Jennings } 231b700e7f0SSeth Jennings 232b700e7f0SSeth Jennings static int klp_write_object_relocations(struct module *pmod, 233b700e7f0SSeth Jennings struct klp_object *obj) 234b700e7f0SSeth Jennings { 235425595a7SJessica Yu int i, cnt, ret = 0; 236425595a7SJessica Yu const char *objname, *secname; 237425595a7SJessica Yu char sec_objname[MODULE_NAME_LEN]; 238425595a7SJessica Yu Elf_Shdr *sec; 239b700e7f0SSeth Jennings 240b700e7f0SSeth Jennings if (WARN_ON(!klp_is_object_loaded(obj))) 241b700e7f0SSeth Jennings return -EINVAL; 242b700e7f0SSeth Jennings 243425595a7SJessica Yu objname = klp_is_module(obj) ? obj->name : "vmlinux"; 244b700e7f0SSeth Jennings 245425595a7SJessica Yu /* For each klp relocation section */ 246425595a7SJessica Yu for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) { 247425595a7SJessica Yu sec = pmod->klp_info->sechdrs + i; 248425595a7SJessica Yu secname = pmod->klp_info->secstrings + sec->sh_name; 249425595a7SJessica Yu if (!(sec->sh_flags & SHF_RELA_LIVEPATCH)) 250425595a7SJessica Yu continue; 251b56b36eeSJosh Poimboeuf 252425595a7SJessica Yu /* 253425595a7SJessica Yu * Format: .klp.rela.sec_objname.section_name 254425595a7SJessica Yu * See comment in klp_resolve_symbols() for an explanation 255425595a7SJessica Yu * of the selected field width value. 256425595a7SJessica Yu */ 257425595a7SJessica Yu cnt = sscanf(secname, ".klp.rela.%55[^.]", sec_objname); 258425595a7SJessica Yu if (cnt != 1) { 259425595a7SJessica Yu pr_err("section %s has an incorrectly formatted name", 260425595a7SJessica Yu secname); 261b56b36eeSJosh Poimboeuf ret = -EINVAL; 262425595a7SJessica Yu break; 263b700e7f0SSeth Jennings } 264425595a7SJessica Yu 265425595a7SJessica Yu if (strcmp(objname, sec_objname)) 266425595a7SJessica Yu continue; 267425595a7SJessica Yu 268425595a7SJessica Yu ret = klp_resolve_symbols(sec, pmod); 269064c89dfSChris J Arges if (ret) 270425595a7SJessica Yu break; 271064c89dfSChris J Arges 272425595a7SJessica Yu ret = apply_relocate_add(pmod->klp_info->sechdrs, 273425595a7SJessica Yu pmod->core_kallsyms.strtab, 274425595a7SJessica Yu pmod->klp_info->symndx, i, pmod); 275425595a7SJessica Yu if (ret) 276425595a7SJessica Yu break; 277b700e7f0SSeth Jennings } 278b700e7f0SSeth Jennings 279b56b36eeSJosh Poimboeuf return ret; 280b700e7f0SSeth Jennings } 281b700e7f0SSeth Jennings 282b700e7f0SSeth Jennings static int __klp_disable_patch(struct klp_patch *patch) 283b700e7f0SSeth Jennings { 284b700e7f0SSeth Jennings struct klp_object *obj; 285b700e7f0SSeth Jennings 28683a90bb1SJosh Poimboeuf /* enforce stacking: only the last enabled patch can be disabled */ 28783a90bb1SJosh Poimboeuf if (!list_is_last(&patch->list, &klp_patches) && 2880dade9f3SJosh Poimboeuf list_next_entry(patch, list)->enabled) 28983a90bb1SJosh Poimboeuf return -EBUSY; 29083a90bb1SJosh Poimboeuf 291b700e7f0SSeth Jennings pr_notice("disabling patch '%s'\n", patch->mod->name); 292b700e7f0SSeth Jennings 2938cdd043aSJiri Slaby klp_for_each_object(patch, obj) { 2940dade9f3SJosh Poimboeuf if (obj->patched) 2950dade9f3SJosh Poimboeuf klp_unpatch_object(obj); 296b700e7f0SSeth Jennings } 297b700e7f0SSeth Jennings 2980dade9f3SJosh Poimboeuf patch->enabled = false; 299b700e7f0SSeth Jennings 300b700e7f0SSeth Jennings return 0; 301b700e7f0SSeth Jennings } 302b700e7f0SSeth Jennings 303b700e7f0SSeth Jennings /** 304b700e7f0SSeth Jennings * klp_disable_patch() - disables a registered patch 305b700e7f0SSeth Jennings * @patch: The registered, enabled patch to be disabled 306b700e7f0SSeth Jennings * 307b700e7f0SSeth Jennings * Unregisters the patched functions from ftrace. 308b700e7f0SSeth Jennings * 309b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 310b700e7f0SSeth Jennings */ 311b700e7f0SSeth Jennings int klp_disable_patch(struct klp_patch *patch) 312b700e7f0SSeth Jennings { 313b700e7f0SSeth Jennings int ret; 314b700e7f0SSeth Jennings 315b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 316b700e7f0SSeth Jennings 317b700e7f0SSeth Jennings if (!klp_is_patch_registered(patch)) { 318b700e7f0SSeth Jennings ret = -EINVAL; 319b700e7f0SSeth Jennings goto err; 320b700e7f0SSeth Jennings } 321b700e7f0SSeth Jennings 3220dade9f3SJosh Poimboeuf if (!patch->enabled) { 323b700e7f0SSeth Jennings ret = -EINVAL; 324b700e7f0SSeth Jennings goto err; 325b700e7f0SSeth Jennings } 326b700e7f0SSeth Jennings 327b700e7f0SSeth Jennings ret = __klp_disable_patch(patch); 328b700e7f0SSeth Jennings 329b700e7f0SSeth Jennings err: 330b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 331b700e7f0SSeth Jennings return ret; 332b700e7f0SSeth Jennings } 333b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_disable_patch); 334b700e7f0SSeth Jennings 335b700e7f0SSeth Jennings static int __klp_enable_patch(struct klp_patch *patch) 336b700e7f0SSeth Jennings { 337b700e7f0SSeth Jennings struct klp_object *obj; 338b700e7f0SSeth Jennings int ret; 339b700e7f0SSeth Jennings 3400dade9f3SJosh Poimboeuf if (WARN_ON(patch->enabled)) 341b700e7f0SSeth Jennings return -EINVAL; 342b700e7f0SSeth Jennings 34383a90bb1SJosh Poimboeuf /* enforce stacking: only the first disabled patch can be enabled */ 34483a90bb1SJosh Poimboeuf if (patch->list.prev != &klp_patches && 3450dade9f3SJosh Poimboeuf !list_prev_entry(patch, list)->enabled) 34683a90bb1SJosh Poimboeuf return -EBUSY; 34783a90bb1SJosh Poimboeuf 348b700e7f0SSeth Jennings pr_notice("enabling patch '%s'\n", patch->mod->name); 349b700e7f0SSeth Jennings 3508cdd043aSJiri Slaby klp_for_each_object(patch, obj) { 351b700e7f0SSeth Jennings if (!klp_is_object_loaded(obj)) 352b700e7f0SSeth Jennings continue; 353b700e7f0SSeth Jennings 3540dade9f3SJosh Poimboeuf ret = klp_patch_object(obj); 355b700e7f0SSeth Jennings if (ret) 356b700e7f0SSeth Jennings goto unregister; 357b700e7f0SSeth Jennings } 358b700e7f0SSeth Jennings 3590dade9f3SJosh Poimboeuf patch->enabled = true; 360b700e7f0SSeth Jennings 361b700e7f0SSeth Jennings return 0; 362b700e7f0SSeth Jennings 363b700e7f0SSeth Jennings unregister: 364b700e7f0SSeth Jennings WARN_ON(__klp_disable_patch(patch)); 365b700e7f0SSeth Jennings return ret; 366b700e7f0SSeth Jennings } 367b700e7f0SSeth Jennings 368b700e7f0SSeth Jennings /** 369b700e7f0SSeth Jennings * klp_enable_patch() - enables a registered patch 370b700e7f0SSeth Jennings * @patch: The registered, disabled patch to be enabled 371b700e7f0SSeth Jennings * 372b700e7f0SSeth Jennings * Performs the needed symbol lookups and code relocations, 373b700e7f0SSeth Jennings * then registers the patched functions with ftrace. 374b700e7f0SSeth Jennings * 375b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 376b700e7f0SSeth Jennings */ 377b700e7f0SSeth Jennings int klp_enable_patch(struct klp_patch *patch) 378b700e7f0SSeth Jennings { 379b700e7f0SSeth Jennings int ret; 380b700e7f0SSeth Jennings 381b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 382b700e7f0SSeth Jennings 383b700e7f0SSeth Jennings if (!klp_is_patch_registered(patch)) { 384b700e7f0SSeth Jennings ret = -EINVAL; 385b700e7f0SSeth Jennings goto err; 386b700e7f0SSeth Jennings } 387b700e7f0SSeth Jennings 388b700e7f0SSeth Jennings ret = __klp_enable_patch(patch); 389b700e7f0SSeth Jennings 390b700e7f0SSeth Jennings err: 391b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 392b700e7f0SSeth Jennings return ret; 393b700e7f0SSeth Jennings } 394b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_enable_patch); 395b700e7f0SSeth Jennings 396b700e7f0SSeth Jennings /* 397b700e7f0SSeth Jennings * Sysfs Interface 398b700e7f0SSeth Jennings * 399b700e7f0SSeth Jennings * /sys/kernel/livepatch 400b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch> 401b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch>/enabled 402b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch>/<object> 403444f9e99SChris J Arges * /sys/kernel/livepatch/<patch>/<object>/<function,sympos> 404b700e7f0SSeth Jennings */ 405b700e7f0SSeth Jennings 406b700e7f0SSeth Jennings static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, 407b700e7f0SSeth Jennings const char *buf, size_t count) 408b700e7f0SSeth Jennings { 409b700e7f0SSeth Jennings struct klp_patch *patch; 410b700e7f0SSeth Jennings int ret; 411b700e7f0SSeth Jennings unsigned long val; 412b700e7f0SSeth Jennings 413b700e7f0SSeth Jennings ret = kstrtoul(buf, 10, &val); 414b700e7f0SSeth Jennings if (ret) 415b700e7f0SSeth Jennings return -EINVAL; 416b700e7f0SSeth Jennings 4170dade9f3SJosh Poimboeuf if (val > 1) 418b700e7f0SSeth Jennings return -EINVAL; 419b700e7f0SSeth Jennings 420b700e7f0SSeth Jennings patch = container_of(kobj, struct klp_patch, kobj); 421b700e7f0SSeth Jennings 422b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 423b700e7f0SSeth Jennings 4240dade9f3SJosh Poimboeuf if (patch->enabled == val) { 425b700e7f0SSeth Jennings /* already in requested state */ 426b700e7f0SSeth Jennings ret = -EINVAL; 427b700e7f0SSeth Jennings goto err; 428b700e7f0SSeth Jennings } 429b700e7f0SSeth Jennings 4300dade9f3SJosh Poimboeuf if (val) { 431b700e7f0SSeth Jennings ret = __klp_enable_patch(patch); 432b700e7f0SSeth Jennings if (ret) 433b700e7f0SSeth Jennings goto err; 434b700e7f0SSeth Jennings } else { 435b700e7f0SSeth Jennings ret = __klp_disable_patch(patch); 436b700e7f0SSeth Jennings if (ret) 437b700e7f0SSeth Jennings goto err; 438b700e7f0SSeth Jennings } 439b700e7f0SSeth Jennings 440b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 441b700e7f0SSeth Jennings 442b700e7f0SSeth Jennings return count; 443b700e7f0SSeth Jennings 444b700e7f0SSeth Jennings err: 445b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 446b700e7f0SSeth Jennings return ret; 447b700e7f0SSeth Jennings } 448b700e7f0SSeth Jennings 449b700e7f0SSeth Jennings static ssize_t enabled_show(struct kobject *kobj, 450b700e7f0SSeth Jennings struct kobj_attribute *attr, char *buf) 451b700e7f0SSeth Jennings { 452b700e7f0SSeth Jennings struct klp_patch *patch; 453b700e7f0SSeth Jennings 454b700e7f0SSeth Jennings patch = container_of(kobj, struct klp_patch, kobj); 4550dade9f3SJosh Poimboeuf return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->enabled); 456b700e7f0SSeth Jennings } 457b700e7f0SSeth Jennings 458b700e7f0SSeth Jennings static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); 459b700e7f0SSeth Jennings static struct attribute *klp_patch_attrs[] = { 460b700e7f0SSeth Jennings &enabled_kobj_attr.attr, 461b700e7f0SSeth Jennings NULL 462b700e7f0SSeth Jennings }; 463b700e7f0SSeth Jennings 464b700e7f0SSeth Jennings static void klp_kobj_release_patch(struct kobject *kobj) 465b700e7f0SSeth Jennings { 466b700e7f0SSeth Jennings /* 467b700e7f0SSeth Jennings * Once we have a consistency model we'll need to module_put() the 468b700e7f0SSeth Jennings * patch module here. See klp_register_patch() for more details. 469b700e7f0SSeth Jennings */ 470b700e7f0SSeth Jennings } 471b700e7f0SSeth Jennings 472b700e7f0SSeth Jennings static struct kobj_type klp_ktype_patch = { 473b700e7f0SSeth Jennings .release = klp_kobj_release_patch, 474b700e7f0SSeth Jennings .sysfs_ops = &kobj_sysfs_ops, 475b700e7f0SSeth Jennings .default_attrs = klp_patch_attrs, 476b700e7f0SSeth Jennings }; 477b700e7f0SSeth Jennings 478cad706dfSMiroslav Benes static void klp_kobj_release_object(struct kobject *kobj) 479cad706dfSMiroslav Benes { 480cad706dfSMiroslav Benes } 481cad706dfSMiroslav Benes 482cad706dfSMiroslav Benes static struct kobj_type klp_ktype_object = { 483cad706dfSMiroslav Benes .release = klp_kobj_release_object, 484cad706dfSMiroslav Benes .sysfs_ops = &kobj_sysfs_ops, 485cad706dfSMiroslav Benes }; 486cad706dfSMiroslav Benes 487b700e7f0SSeth Jennings static void klp_kobj_release_func(struct kobject *kobj) 488b700e7f0SSeth Jennings { 489b700e7f0SSeth Jennings } 490b700e7f0SSeth Jennings 491b700e7f0SSeth Jennings static struct kobj_type klp_ktype_func = { 492b700e7f0SSeth Jennings .release = klp_kobj_release_func, 493b700e7f0SSeth Jennings .sysfs_ops = &kobj_sysfs_ops, 494b700e7f0SSeth Jennings }; 495b700e7f0SSeth Jennings 496b700e7f0SSeth Jennings /* 497b700e7f0SSeth Jennings * Free all functions' kobjects in the array up to some limit. When limit is 498b700e7f0SSeth Jennings * NULL, all kobjects are freed. 499b700e7f0SSeth Jennings */ 500b700e7f0SSeth Jennings static void klp_free_funcs_limited(struct klp_object *obj, 501b700e7f0SSeth Jennings struct klp_func *limit) 502b700e7f0SSeth Jennings { 503b700e7f0SSeth Jennings struct klp_func *func; 504b700e7f0SSeth Jennings 505b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name && func != limit; func++) 506b700e7f0SSeth Jennings kobject_put(&func->kobj); 507b700e7f0SSeth Jennings } 508b700e7f0SSeth Jennings 509b700e7f0SSeth Jennings /* Clean up when a patched object is unloaded */ 510b700e7f0SSeth Jennings static void klp_free_object_loaded(struct klp_object *obj) 511b700e7f0SSeth Jennings { 512b700e7f0SSeth Jennings struct klp_func *func; 513b700e7f0SSeth Jennings 514b700e7f0SSeth Jennings obj->mod = NULL; 515b700e7f0SSeth Jennings 5168cdd043aSJiri Slaby klp_for_each_func(obj, func) 517b700e7f0SSeth Jennings func->old_addr = 0; 518b700e7f0SSeth Jennings } 519b700e7f0SSeth Jennings 520b700e7f0SSeth Jennings /* 521b700e7f0SSeth Jennings * Free all objects' kobjects in the array up to some limit. When limit is 522b700e7f0SSeth Jennings * NULL, all kobjects are freed. 523b700e7f0SSeth Jennings */ 524b700e7f0SSeth Jennings static void klp_free_objects_limited(struct klp_patch *patch, 525b700e7f0SSeth Jennings struct klp_object *limit) 526b700e7f0SSeth Jennings { 527b700e7f0SSeth Jennings struct klp_object *obj; 528b700e7f0SSeth Jennings 529b700e7f0SSeth Jennings for (obj = patch->objs; obj->funcs && obj != limit; obj++) { 530b700e7f0SSeth Jennings klp_free_funcs_limited(obj, NULL); 531cad706dfSMiroslav Benes kobject_put(&obj->kobj); 532b700e7f0SSeth Jennings } 533b700e7f0SSeth Jennings } 534b700e7f0SSeth Jennings 535b700e7f0SSeth Jennings static void klp_free_patch(struct klp_patch *patch) 536b700e7f0SSeth Jennings { 537b700e7f0SSeth Jennings klp_free_objects_limited(patch, NULL); 538b700e7f0SSeth Jennings if (!list_empty(&patch->list)) 539b700e7f0SSeth Jennings list_del(&patch->list); 540b700e7f0SSeth Jennings kobject_put(&patch->kobj); 541b700e7f0SSeth Jennings } 542b700e7f0SSeth Jennings 543b700e7f0SSeth Jennings static int klp_init_func(struct klp_object *obj, struct klp_func *func) 544b700e7f0SSeth Jennings { 545f09d9086SMiroslav Benes if (!func->old_name || !func->new_func) 546f09d9086SMiroslav Benes return -EINVAL; 547f09d9086SMiroslav Benes 5483c33f5b9SJosh Poimboeuf INIT_LIST_HEAD(&func->stack_node); 5490dade9f3SJosh Poimboeuf func->patched = false; 550b700e7f0SSeth Jennings 551444f9e99SChris J Arges /* The format for the sysfs directory is <function,sympos> where sympos 552444f9e99SChris J Arges * is the nth occurrence of this symbol in kallsyms for the patched 553444f9e99SChris J Arges * object. If the user selects 0 for old_sympos, then 1 will be used 554444f9e99SChris J Arges * since a unique symbol will be the first occurrence. 555444f9e99SChris J Arges */ 5563c33f5b9SJosh Poimboeuf return kobject_init_and_add(&func->kobj, &klp_ktype_func, 557444f9e99SChris J Arges &obj->kobj, "%s,%lu", func->old_name, 558444f9e99SChris J Arges func->old_sympos ? func->old_sympos : 1); 559b700e7f0SSeth Jennings } 560b700e7f0SSeth Jennings 561255e732cSJessica Yu /* Arches may override this to finish any remaining arch-specific tasks */ 562255e732cSJessica Yu void __weak arch_klp_init_object_loaded(struct klp_patch *patch, 563255e732cSJessica Yu struct klp_object *obj) 564255e732cSJessica Yu { 565255e732cSJessica Yu } 566255e732cSJessica Yu 567b700e7f0SSeth Jennings /* parts of the initialization that is done only when the object is loaded */ 568b700e7f0SSeth Jennings static int klp_init_object_loaded(struct klp_patch *patch, 569b700e7f0SSeth Jennings struct klp_object *obj) 570b700e7f0SSeth Jennings { 571b700e7f0SSeth Jennings struct klp_func *func; 572b700e7f0SSeth Jennings int ret; 573b700e7f0SSeth Jennings 574255e732cSJessica Yu module_disable_ro(patch->mod); 575b700e7f0SSeth Jennings ret = klp_write_object_relocations(patch->mod, obj); 576255e732cSJessica Yu if (ret) { 577255e732cSJessica Yu module_enable_ro(patch->mod, true); 578b700e7f0SSeth Jennings return ret; 579255e732cSJessica Yu } 580255e732cSJessica Yu 581255e732cSJessica Yu arch_klp_init_object_loaded(patch, obj); 582255e732cSJessica Yu module_enable_ro(patch->mod, true); 583b700e7f0SSeth Jennings 5848cdd043aSJiri Slaby klp_for_each_func(obj, func) { 585b2b018efSChris J Arges ret = klp_find_object_symbol(obj->name, func->old_name, 586b2b018efSChris J Arges func->old_sympos, 587b2b018efSChris J Arges &func->old_addr); 588b700e7f0SSeth Jennings if (ret) 589b700e7f0SSeth Jennings return ret; 590b700e7f0SSeth Jennings } 591b700e7f0SSeth Jennings 592b700e7f0SSeth Jennings return 0; 593b700e7f0SSeth Jennings } 594b700e7f0SSeth Jennings 595b700e7f0SSeth Jennings static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) 596b700e7f0SSeth Jennings { 597b700e7f0SSeth Jennings struct klp_func *func; 598b700e7f0SSeth Jennings int ret; 599b700e7f0SSeth Jennings const char *name; 600b700e7f0SSeth Jennings 601b700e7f0SSeth Jennings if (!obj->funcs) 602b700e7f0SSeth Jennings return -EINVAL; 603b700e7f0SSeth Jennings 6040dade9f3SJosh Poimboeuf obj->patched = false; 6058cb2c2dcSPetr Mladek obj->mod = NULL; 606b700e7f0SSeth Jennings 607b700e7f0SSeth Jennings klp_find_object_module(obj); 608b700e7f0SSeth Jennings 609b700e7f0SSeth Jennings name = klp_is_module(obj) ? obj->name : "vmlinux"; 610cad706dfSMiroslav Benes ret = kobject_init_and_add(&obj->kobj, &klp_ktype_object, 611cad706dfSMiroslav Benes &patch->kobj, "%s", name); 612cad706dfSMiroslav Benes if (ret) 613cad706dfSMiroslav Benes return ret; 614b700e7f0SSeth Jennings 6158cdd043aSJiri Slaby klp_for_each_func(obj, func) { 616b700e7f0SSeth Jennings ret = klp_init_func(obj, func); 617b700e7f0SSeth Jennings if (ret) 618b700e7f0SSeth Jennings goto free; 619b700e7f0SSeth Jennings } 620b700e7f0SSeth Jennings 621b700e7f0SSeth Jennings if (klp_is_object_loaded(obj)) { 622b700e7f0SSeth Jennings ret = klp_init_object_loaded(patch, obj); 623b700e7f0SSeth Jennings if (ret) 624b700e7f0SSeth Jennings goto free; 625b700e7f0SSeth Jennings } 626b700e7f0SSeth Jennings 627b700e7f0SSeth Jennings return 0; 628b700e7f0SSeth Jennings 629b700e7f0SSeth Jennings free: 630b700e7f0SSeth Jennings klp_free_funcs_limited(obj, func); 631cad706dfSMiroslav Benes kobject_put(&obj->kobj); 632b700e7f0SSeth Jennings return ret; 633b700e7f0SSeth Jennings } 634b700e7f0SSeth Jennings 635b700e7f0SSeth Jennings static int klp_init_patch(struct klp_patch *patch) 636b700e7f0SSeth Jennings { 637b700e7f0SSeth Jennings struct klp_object *obj; 638b700e7f0SSeth Jennings int ret; 639b700e7f0SSeth Jennings 640b700e7f0SSeth Jennings if (!patch->objs) 641b700e7f0SSeth Jennings return -EINVAL; 642b700e7f0SSeth Jennings 643b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 644b700e7f0SSeth Jennings 6450dade9f3SJosh Poimboeuf patch->enabled = false; 646b700e7f0SSeth Jennings 647b700e7f0SSeth Jennings ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, 648e0b561eeSJiri Kosina klp_root_kobj, "%s", patch->mod->name); 649b700e7f0SSeth Jennings if (ret) 650b700e7f0SSeth Jennings goto unlock; 651b700e7f0SSeth Jennings 6528cdd043aSJiri Slaby klp_for_each_object(patch, obj) { 653b700e7f0SSeth Jennings ret = klp_init_object(patch, obj); 654b700e7f0SSeth Jennings if (ret) 655b700e7f0SSeth Jennings goto free; 656b700e7f0SSeth Jennings } 657b700e7f0SSeth Jennings 65899590ba5SJosh Poimboeuf list_add_tail(&patch->list, &klp_patches); 659b700e7f0SSeth Jennings 660b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 661b700e7f0SSeth Jennings 662b700e7f0SSeth Jennings return 0; 663b700e7f0SSeth Jennings 664b700e7f0SSeth Jennings free: 665b700e7f0SSeth Jennings klp_free_objects_limited(patch, obj); 666b700e7f0SSeth Jennings kobject_put(&patch->kobj); 667b700e7f0SSeth Jennings unlock: 668b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 669b700e7f0SSeth Jennings return ret; 670b700e7f0SSeth Jennings } 671b700e7f0SSeth Jennings 672b700e7f0SSeth Jennings /** 673b700e7f0SSeth Jennings * klp_unregister_patch() - unregisters a patch 674b700e7f0SSeth Jennings * @patch: Disabled patch to be unregistered 675b700e7f0SSeth Jennings * 676b700e7f0SSeth Jennings * Frees the data structures and removes the sysfs interface. 677b700e7f0SSeth Jennings * 678b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 679b700e7f0SSeth Jennings */ 680b700e7f0SSeth Jennings int klp_unregister_patch(struct klp_patch *patch) 681b700e7f0SSeth Jennings { 682b700e7f0SSeth Jennings int ret = 0; 683b700e7f0SSeth Jennings 684b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 685b700e7f0SSeth Jennings 686b700e7f0SSeth Jennings if (!klp_is_patch_registered(patch)) { 687b700e7f0SSeth Jennings ret = -EINVAL; 688b700e7f0SSeth Jennings goto out; 689b700e7f0SSeth Jennings } 690b700e7f0SSeth Jennings 6910dade9f3SJosh Poimboeuf if (patch->enabled) { 692b700e7f0SSeth Jennings ret = -EBUSY; 693b700e7f0SSeth Jennings goto out; 694b700e7f0SSeth Jennings } 695b700e7f0SSeth Jennings 696b700e7f0SSeth Jennings klp_free_patch(patch); 697b700e7f0SSeth Jennings 698b700e7f0SSeth Jennings out: 699b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 700b700e7f0SSeth Jennings return ret; 701b700e7f0SSeth Jennings } 702b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_unregister_patch); 703b700e7f0SSeth Jennings 704b700e7f0SSeth Jennings /** 705b700e7f0SSeth Jennings * klp_register_patch() - registers a patch 706b700e7f0SSeth Jennings * @patch: Patch to be registered 707b700e7f0SSeth Jennings * 708b700e7f0SSeth Jennings * Initializes the data structure associated with the patch and 709b700e7f0SSeth Jennings * creates the sysfs interface. 710b700e7f0SSeth Jennings * 711b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 712b700e7f0SSeth Jennings */ 713b700e7f0SSeth Jennings int klp_register_patch(struct klp_patch *patch) 714b700e7f0SSeth Jennings { 715b700e7f0SSeth Jennings int ret; 716b700e7f0SSeth Jennings 717b700e7f0SSeth Jennings if (!patch || !patch->mod) 718b700e7f0SSeth Jennings return -EINVAL; 719b700e7f0SSeth Jennings 720425595a7SJessica Yu if (!is_livepatch_module(patch->mod)) { 721425595a7SJessica Yu pr_err("module %s is not marked as a livepatch module", 722425595a7SJessica Yu patch->mod->name); 723425595a7SJessica Yu return -EINVAL; 724425595a7SJessica Yu } 725425595a7SJessica Yu 726b700e7f0SSeth Jennings if (!klp_initialized()) 727b700e7f0SSeth Jennings return -ENODEV; 728b700e7f0SSeth Jennings 729b700e7f0SSeth Jennings /* 730b700e7f0SSeth Jennings * A reference is taken on the patch module to prevent it from being 731b700e7f0SSeth Jennings * unloaded. Right now, we don't allow patch modules to unload since 732b700e7f0SSeth Jennings * there is currently no method to determine if a thread is still 733b700e7f0SSeth Jennings * running in the patched code contained in the patch module once 734b700e7f0SSeth Jennings * the ftrace registration is successful. 735b700e7f0SSeth Jennings */ 736b700e7f0SSeth Jennings if (!try_module_get(patch->mod)) 737b700e7f0SSeth Jennings return -ENODEV; 738b700e7f0SSeth Jennings 739b700e7f0SSeth Jennings ret = klp_init_patch(patch); 740b700e7f0SSeth Jennings if (ret) 741b700e7f0SSeth Jennings module_put(patch->mod); 742b700e7f0SSeth Jennings 743b700e7f0SSeth Jennings return ret; 744b700e7f0SSeth Jennings } 745b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_register_patch); 746b700e7f0SSeth Jennings 7477e545d6eSJessica Yu int klp_module_coming(struct module *mod) 748b700e7f0SSeth Jennings { 74936e505c1SMinfei Huang int ret; 750b700e7f0SSeth Jennings struct klp_patch *patch; 751b700e7f0SSeth Jennings struct klp_object *obj; 752b700e7f0SSeth Jennings 7537e545d6eSJessica Yu if (WARN_ON(mod->state != MODULE_STATE_COMING)) 7547e545d6eSJessica Yu return -EINVAL; 755b700e7f0SSeth Jennings 756b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 7578cb2c2dcSPetr Mladek /* 7587e545d6eSJessica Yu * Each module has to know that klp_module_coming() 7597e545d6eSJessica Yu * has been called. We never know what module will 7607e545d6eSJessica Yu * get patched by a new patch. 7618cb2c2dcSPetr Mladek */ 7628cb2c2dcSPetr Mladek mod->klp_alive = true; 7638cb2c2dcSPetr Mladek 764b700e7f0SSeth Jennings list_for_each_entry(patch, &klp_patches, list) { 7658cdd043aSJiri Slaby klp_for_each_object(patch, obj) { 766b700e7f0SSeth Jennings if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 767b700e7f0SSeth Jennings continue; 768b700e7f0SSeth Jennings 769b700e7f0SSeth Jennings obj->mod = mod; 7707e545d6eSJessica Yu 7717e545d6eSJessica Yu ret = klp_init_object_loaded(patch, obj); 77236e505c1SMinfei Huang if (ret) { 7737e545d6eSJessica Yu pr_warn("failed to initialize patch '%s' for module '%s' (%d)\n", 7747e545d6eSJessica Yu patch->mod->name, obj->mod->name, ret); 7757e545d6eSJessica Yu goto err; 77636e505c1SMinfei Huang } 7777e545d6eSJessica Yu 7780dade9f3SJosh Poimboeuf if (!patch->enabled) 7797e545d6eSJessica Yu break; 7807e545d6eSJessica Yu 7817e545d6eSJessica Yu pr_notice("applying patch '%s' to loading module '%s'\n", 7827e545d6eSJessica Yu patch->mod->name, obj->mod->name); 7837e545d6eSJessica Yu 7840dade9f3SJosh Poimboeuf ret = klp_patch_object(obj); 7857e545d6eSJessica Yu if (ret) { 7867e545d6eSJessica Yu pr_warn("failed to apply patch '%s' to module '%s' (%d)\n", 7877e545d6eSJessica Yu patch->mod->name, obj->mod->name, ret); 7887e545d6eSJessica Yu goto err; 7897e545d6eSJessica Yu } 790b700e7f0SSeth Jennings 791b700e7f0SSeth Jennings break; 792b700e7f0SSeth Jennings } 793b700e7f0SSeth Jennings } 794b700e7f0SSeth Jennings 795b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 796b700e7f0SSeth Jennings 797b700e7f0SSeth Jennings return 0; 7987e545d6eSJessica Yu 7997e545d6eSJessica Yu err: 8007e545d6eSJessica Yu /* 8017e545d6eSJessica Yu * If a patch is unsuccessfully applied, return 8027e545d6eSJessica Yu * error to the module loader. 8037e545d6eSJessica Yu */ 8047e545d6eSJessica Yu pr_warn("patch '%s' failed for module '%s', refusing to load module '%s'\n", 8057e545d6eSJessica Yu patch->mod->name, obj->mod->name, obj->mod->name); 8067e545d6eSJessica Yu mod->klp_alive = false; 8077e545d6eSJessica Yu klp_free_object_loaded(obj); 8087e545d6eSJessica Yu mutex_unlock(&klp_mutex); 8097e545d6eSJessica Yu 8107e545d6eSJessica Yu return ret; 811b700e7f0SSeth Jennings } 812b700e7f0SSeth Jennings 8137e545d6eSJessica Yu void klp_module_going(struct module *mod) 8147e545d6eSJessica Yu { 8157e545d6eSJessica Yu struct klp_patch *patch; 8167e545d6eSJessica Yu struct klp_object *obj; 8177e545d6eSJessica Yu 8187e545d6eSJessica Yu if (WARN_ON(mod->state != MODULE_STATE_GOING && 8197e545d6eSJessica Yu mod->state != MODULE_STATE_COMING)) 8207e545d6eSJessica Yu return; 8217e545d6eSJessica Yu 8227e545d6eSJessica Yu mutex_lock(&klp_mutex); 8237e545d6eSJessica Yu /* 8247e545d6eSJessica Yu * Each module has to know that klp_module_going() 8257e545d6eSJessica Yu * has been called. We never know what module will 8267e545d6eSJessica Yu * get patched by a new patch. 8277e545d6eSJessica Yu */ 8287e545d6eSJessica Yu mod->klp_alive = false; 8297e545d6eSJessica Yu 8307e545d6eSJessica Yu list_for_each_entry(patch, &klp_patches, list) { 8317e545d6eSJessica Yu klp_for_each_object(patch, obj) { 8327e545d6eSJessica Yu if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 8337e545d6eSJessica Yu continue; 8347e545d6eSJessica Yu 8350dade9f3SJosh Poimboeuf if (patch->enabled) { 8367e545d6eSJessica Yu pr_notice("reverting patch '%s' on unloading module '%s'\n", 8377e545d6eSJessica Yu patch->mod->name, obj->mod->name); 8380dade9f3SJosh Poimboeuf klp_unpatch_object(obj); 8397e545d6eSJessica Yu } 8407e545d6eSJessica Yu 8417e545d6eSJessica Yu klp_free_object_loaded(obj); 8427e545d6eSJessica Yu break; 8437e545d6eSJessica Yu } 8447e545d6eSJessica Yu } 8457e545d6eSJessica Yu 8467e545d6eSJessica Yu mutex_unlock(&klp_mutex); 8477e545d6eSJessica Yu } 848b700e7f0SSeth Jennings 84926029d88SMinfei Huang static int __init klp_init(void) 850b700e7f0SSeth Jennings { 851b700e7f0SSeth Jennings int ret; 852b700e7f0SSeth Jennings 853b9dfe0beSJiri Kosina ret = klp_check_compiler_support(); 854b9dfe0beSJiri Kosina if (ret) { 855b9dfe0beSJiri Kosina pr_info("Your compiler is too old; turning off.\n"); 856b9dfe0beSJiri Kosina return -EINVAL; 857b9dfe0beSJiri Kosina } 858b9dfe0beSJiri Kosina 859b700e7f0SSeth Jennings klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj); 8607e545d6eSJessica Yu if (!klp_root_kobj) 8617e545d6eSJessica Yu return -ENOMEM; 862b700e7f0SSeth Jennings 863b700e7f0SSeth Jennings return 0; 864b700e7f0SSeth Jennings } 865b700e7f0SSeth Jennings 866b700e7f0SSeth Jennings module_init(klp_init); 867