1b700e7f0SSeth Jennings /* 2b700e7f0SSeth Jennings * core.c - Kernel Live Patching Core 3b700e7f0SSeth Jennings * 4b700e7f0SSeth Jennings * Copyright (C) 2014 Seth Jennings <[email protected]> 5b700e7f0SSeth Jennings * Copyright (C) 2014 SUSE 6b700e7f0SSeth Jennings * 7b700e7f0SSeth Jennings * This program is free software; you can redistribute it and/or 8b700e7f0SSeth Jennings * modify it under the terms of the GNU General Public License 9b700e7f0SSeth Jennings * as published by the Free Software Foundation; either version 2 10b700e7f0SSeth Jennings * of the License, or (at your option) any later version. 11b700e7f0SSeth Jennings * 12b700e7f0SSeth Jennings * This program is distributed in the hope that it will be useful, 13b700e7f0SSeth Jennings * but WITHOUT ANY WARRANTY; without even the implied warranty of 14b700e7f0SSeth Jennings * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15b700e7f0SSeth Jennings * GNU General Public License for more details. 16b700e7f0SSeth Jennings * 17b700e7f0SSeth Jennings * You should have received a copy of the GNU General Public License 18b700e7f0SSeth Jennings * along with this program; if not, see <http://www.gnu.org/licenses/>. 19b700e7f0SSeth Jennings */ 20b700e7f0SSeth Jennings 21b700e7f0SSeth Jennings #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22b700e7f0SSeth Jennings 23b700e7f0SSeth Jennings #include <linux/module.h> 24b700e7f0SSeth Jennings #include <linux/kernel.h> 25b700e7f0SSeth Jennings #include <linux/mutex.h> 26b700e7f0SSeth Jennings #include <linux/slab.h> 27b700e7f0SSeth Jennings #include <linux/ftrace.h> 28b700e7f0SSeth Jennings #include <linux/list.h> 29b700e7f0SSeth Jennings #include <linux/kallsyms.h> 30b700e7f0SSeth Jennings #include <linux/livepatch.h> 31b700e7f0SSeth Jennings 32b700e7f0SSeth Jennings /* 33b700e7f0SSeth Jennings * The klp_mutex protects the klp_patches list and state transitions of any 34b700e7f0SSeth Jennings * structure reachable from the patches list. References to any structure must 35b700e7f0SSeth Jennings * be obtained under mutex protection. 36b700e7f0SSeth Jennings */ 37b700e7f0SSeth Jennings 38b700e7f0SSeth Jennings static DEFINE_MUTEX(klp_mutex); 39b700e7f0SSeth Jennings static LIST_HEAD(klp_patches); 40b700e7f0SSeth Jennings 41b700e7f0SSeth Jennings static struct kobject *klp_root_kobj; 42b700e7f0SSeth Jennings 43b700e7f0SSeth Jennings static bool klp_is_module(struct klp_object *obj) 44b700e7f0SSeth Jennings { 45b700e7f0SSeth Jennings return obj->name; 46b700e7f0SSeth Jennings } 47b700e7f0SSeth Jennings 48b700e7f0SSeth Jennings static bool klp_is_object_loaded(struct klp_object *obj) 49b700e7f0SSeth Jennings { 50b700e7f0SSeth Jennings return !obj->name || obj->mod; 51b700e7f0SSeth Jennings } 52b700e7f0SSeth Jennings 53b700e7f0SSeth Jennings /* sets obj->mod if object is not vmlinux and module is found */ 54b700e7f0SSeth Jennings static void klp_find_object_module(struct klp_object *obj) 55b700e7f0SSeth Jennings { 56b700e7f0SSeth Jennings if (!klp_is_module(obj)) 57b700e7f0SSeth Jennings return; 58b700e7f0SSeth Jennings 59b700e7f0SSeth Jennings mutex_lock(&module_mutex); 60b700e7f0SSeth Jennings /* 61b700e7f0SSeth Jennings * We don't need to take a reference on the module here because we have 62b700e7f0SSeth Jennings * the klp_mutex, which is also taken by the module notifier. This 63b700e7f0SSeth Jennings * prevents any module from unloading until we release the klp_mutex. 64b700e7f0SSeth Jennings */ 65b700e7f0SSeth Jennings obj->mod = find_module(obj->name); 66b700e7f0SSeth Jennings mutex_unlock(&module_mutex); 67b700e7f0SSeth Jennings } 68b700e7f0SSeth Jennings 69b700e7f0SSeth Jennings /* klp_mutex must be held by caller */ 70b700e7f0SSeth Jennings static bool klp_is_patch_registered(struct klp_patch *patch) 71b700e7f0SSeth Jennings { 72b700e7f0SSeth Jennings struct klp_patch *mypatch; 73b700e7f0SSeth Jennings 74b700e7f0SSeth Jennings list_for_each_entry(mypatch, &klp_patches, list) 75b700e7f0SSeth Jennings if (mypatch == patch) 76b700e7f0SSeth Jennings return true; 77b700e7f0SSeth Jennings 78b700e7f0SSeth Jennings return false; 79b700e7f0SSeth Jennings } 80b700e7f0SSeth Jennings 81b700e7f0SSeth Jennings static bool klp_initialized(void) 82b700e7f0SSeth Jennings { 83b700e7f0SSeth Jennings return klp_root_kobj; 84b700e7f0SSeth Jennings } 85b700e7f0SSeth Jennings 86b700e7f0SSeth Jennings struct klp_find_arg { 87b700e7f0SSeth Jennings const char *objname; 88b700e7f0SSeth Jennings const char *name; 89b700e7f0SSeth Jennings unsigned long addr; 90b700e7f0SSeth Jennings /* 91b700e7f0SSeth Jennings * If count == 0, the symbol was not found. If count == 1, a unique 92b700e7f0SSeth Jennings * match was found and addr is set. If count > 1, there is 93b700e7f0SSeth Jennings * unresolvable ambiguity among "count" number of symbols with the same 94b700e7f0SSeth Jennings * name in the same object. 95b700e7f0SSeth Jennings */ 96b700e7f0SSeth Jennings unsigned long count; 97b700e7f0SSeth Jennings }; 98b700e7f0SSeth Jennings 99b700e7f0SSeth Jennings static int klp_find_callback(void *data, const char *name, 100b700e7f0SSeth Jennings struct module *mod, unsigned long addr) 101b700e7f0SSeth Jennings { 102b700e7f0SSeth Jennings struct klp_find_arg *args = data; 103b700e7f0SSeth Jennings 104b700e7f0SSeth Jennings if ((mod && !args->objname) || (!mod && args->objname)) 105b700e7f0SSeth Jennings return 0; 106b700e7f0SSeth Jennings 107b700e7f0SSeth Jennings if (strcmp(args->name, name)) 108b700e7f0SSeth Jennings return 0; 109b700e7f0SSeth Jennings 110b700e7f0SSeth Jennings if (args->objname && strcmp(args->objname, mod->name)) 111b700e7f0SSeth Jennings return 0; 112b700e7f0SSeth Jennings 113b700e7f0SSeth Jennings /* 114b700e7f0SSeth Jennings * args->addr might be overwritten if another match is found 115b700e7f0SSeth Jennings * but klp_find_object_symbol() handles this and only returns the 116b700e7f0SSeth Jennings * addr if count == 1. 117b700e7f0SSeth Jennings */ 118b700e7f0SSeth Jennings args->addr = addr; 119b700e7f0SSeth Jennings args->count++; 120b700e7f0SSeth Jennings 121b700e7f0SSeth Jennings return 0; 122b700e7f0SSeth Jennings } 123b700e7f0SSeth Jennings 124b700e7f0SSeth Jennings static int klp_find_object_symbol(const char *objname, const char *name, 125b700e7f0SSeth Jennings unsigned long *addr) 126b700e7f0SSeth Jennings { 127b700e7f0SSeth Jennings struct klp_find_arg args = { 128b700e7f0SSeth Jennings .objname = objname, 129b700e7f0SSeth Jennings .name = name, 130b700e7f0SSeth Jennings .addr = 0, 131b700e7f0SSeth Jennings .count = 0 132b700e7f0SSeth Jennings }; 133b700e7f0SSeth Jennings 134b700e7f0SSeth Jennings kallsyms_on_each_symbol(klp_find_callback, &args); 135b700e7f0SSeth Jennings 136b700e7f0SSeth Jennings if (args.count == 0) 137b700e7f0SSeth Jennings pr_err("symbol '%s' not found in symbol table\n", name); 138b700e7f0SSeth Jennings else if (args.count > 1) 139b700e7f0SSeth Jennings pr_err("unresolvable ambiguity (%lu matches) on symbol '%s' in object '%s'\n", 140b700e7f0SSeth Jennings args.count, name, objname); 141b700e7f0SSeth Jennings else { 142b700e7f0SSeth Jennings *addr = args.addr; 143b700e7f0SSeth Jennings return 0; 144b700e7f0SSeth Jennings } 145b700e7f0SSeth Jennings 146b700e7f0SSeth Jennings *addr = 0; 147b700e7f0SSeth Jennings return -EINVAL; 148b700e7f0SSeth Jennings } 149b700e7f0SSeth Jennings 150b700e7f0SSeth Jennings struct klp_verify_args { 151b700e7f0SSeth Jennings const char *name; 152b700e7f0SSeth Jennings const unsigned long addr; 153b700e7f0SSeth Jennings }; 154b700e7f0SSeth Jennings 155b700e7f0SSeth Jennings static int klp_verify_callback(void *data, const char *name, 156b700e7f0SSeth Jennings struct module *mod, unsigned long addr) 157b700e7f0SSeth Jennings { 158b700e7f0SSeth Jennings struct klp_verify_args *args = data; 159b700e7f0SSeth Jennings 160b700e7f0SSeth Jennings if (!mod && 161b700e7f0SSeth Jennings !strcmp(args->name, name) && 162b700e7f0SSeth Jennings args->addr == addr) 163b700e7f0SSeth Jennings return 1; 164b700e7f0SSeth Jennings 165b700e7f0SSeth Jennings return 0; 166b700e7f0SSeth Jennings } 167b700e7f0SSeth Jennings 168b700e7f0SSeth Jennings static int klp_verify_vmlinux_symbol(const char *name, unsigned long addr) 169b700e7f0SSeth Jennings { 170b700e7f0SSeth Jennings struct klp_verify_args args = { 171b700e7f0SSeth Jennings .name = name, 172b700e7f0SSeth Jennings .addr = addr, 173b700e7f0SSeth Jennings }; 174b700e7f0SSeth Jennings 175b700e7f0SSeth Jennings if (kallsyms_on_each_symbol(klp_verify_callback, &args)) 176b700e7f0SSeth Jennings return 0; 177b700e7f0SSeth Jennings 178b700e7f0SSeth Jennings pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?", 179b700e7f0SSeth Jennings name, addr); 180b700e7f0SSeth Jennings return -EINVAL; 181b700e7f0SSeth Jennings } 182b700e7f0SSeth Jennings 183b700e7f0SSeth Jennings static int klp_find_verify_func_addr(struct klp_object *obj, 184b700e7f0SSeth Jennings struct klp_func *func) 185b700e7f0SSeth Jennings { 186b700e7f0SSeth Jennings int ret; 187b700e7f0SSeth Jennings 188b700e7f0SSeth Jennings #if defined(CONFIG_RANDOMIZE_BASE) 189b700e7f0SSeth Jennings /* KASLR is enabled, disregard old_addr from user */ 190b700e7f0SSeth Jennings func->old_addr = 0; 191b700e7f0SSeth Jennings #endif 192b700e7f0SSeth Jennings 193b700e7f0SSeth Jennings if (!func->old_addr || klp_is_module(obj)) 194b700e7f0SSeth Jennings ret = klp_find_object_symbol(obj->name, func->old_name, 195b700e7f0SSeth Jennings &func->old_addr); 196b700e7f0SSeth Jennings else 197b700e7f0SSeth Jennings ret = klp_verify_vmlinux_symbol(func->old_name, 198b700e7f0SSeth Jennings func->old_addr); 199b700e7f0SSeth Jennings 200b700e7f0SSeth Jennings return ret; 201b700e7f0SSeth Jennings } 202b700e7f0SSeth Jennings 203b700e7f0SSeth Jennings /* 204b700e7f0SSeth Jennings * external symbols are located outside the parent object (where the parent 205b700e7f0SSeth Jennings * object is either vmlinux or the kmod being patched). 206b700e7f0SSeth Jennings */ 207b700e7f0SSeth Jennings static int klp_find_external_symbol(struct module *pmod, const char *name, 208b700e7f0SSeth Jennings unsigned long *addr) 209b700e7f0SSeth Jennings { 210b700e7f0SSeth Jennings const struct kernel_symbol *sym; 211b700e7f0SSeth Jennings 212b700e7f0SSeth Jennings /* first, check if it's an exported symbol */ 213b700e7f0SSeth Jennings preempt_disable(); 214b700e7f0SSeth Jennings sym = find_symbol(name, NULL, NULL, true, true); 215b700e7f0SSeth Jennings preempt_enable(); 216b700e7f0SSeth Jennings if (sym) { 217b700e7f0SSeth Jennings *addr = sym->value; 218b700e7f0SSeth Jennings return 0; 219b700e7f0SSeth Jennings } 220b700e7f0SSeth Jennings 221b700e7f0SSeth Jennings /* otherwise check if it's in another .o within the patch module */ 222b700e7f0SSeth Jennings return klp_find_object_symbol(pmod->name, name, addr); 223b700e7f0SSeth Jennings } 224b700e7f0SSeth Jennings 225b700e7f0SSeth Jennings static int klp_write_object_relocations(struct module *pmod, 226b700e7f0SSeth Jennings struct klp_object *obj) 227b700e7f0SSeth Jennings { 228b700e7f0SSeth Jennings int ret; 229b700e7f0SSeth Jennings struct klp_reloc *reloc; 230b700e7f0SSeth Jennings 231b700e7f0SSeth Jennings if (WARN_ON(!klp_is_object_loaded(obj))) 232b700e7f0SSeth Jennings return -EINVAL; 233b700e7f0SSeth Jennings 234b700e7f0SSeth Jennings if (WARN_ON(!obj->relocs)) 235b700e7f0SSeth Jennings return -EINVAL; 236b700e7f0SSeth Jennings 237b700e7f0SSeth Jennings for (reloc = obj->relocs; reloc->name; reloc++) { 238b700e7f0SSeth Jennings if (!klp_is_module(obj)) { 239b700e7f0SSeth Jennings ret = klp_verify_vmlinux_symbol(reloc->name, 240b700e7f0SSeth Jennings reloc->val); 241b700e7f0SSeth Jennings if (ret) 242b700e7f0SSeth Jennings return ret; 243b700e7f0SSeth Jennings } else { 244b700e7f0SSeth Jennings /* module, reloc->val needs to be discovered */ 245b700e7f0SSeth Jennings if (reloc->external) 246b700e7f0SSeth Jennings ret = klp_find_external_symbol(pmod, 247b700e7f0SSeth Jennings reloc->name, 248b700e7f0SSeth Jennings &reloc->val); 249b700e7f0SSeth Jennings else 250b700e7f0SSeth Jennings ret = klp_find_object_symbol(obj->mod->name, 251b700e7f0SSeth Jennings reloc->name, 252b700e7f0SSeth Jennings &reloc->val); 253b700e7f0SSeth Jennings if (ret) 254b700e7f0SSeth Jennings return ret; 255b700e7f0SSeth Jennings } 256b700e7f0SSeth Jennings ret = klp_write_module_reloc(pmod, reloc->type, reloc->loc, 257b700e7f0SSeth Jennings reloc->val + reloc->addend); 258b700e7f0SSeth Jennings if (ret) { 259b700e7f0SSeth Jennings pr_err("relocation failed for symbol '%s' at 0x%016lx (%d)\n", 260b700e7f0SSeth Jennings reloc->name, reloc->val, ret); 261b700e7f0SSeth Jennings return ret; 262b700e7f0SSeth Jennings } 263b700e7f0SSeth Jennings } 264b700e7f0SSeth Jennings 265b700e7f0SSeth Jennings return 0; 266b700e7f0SSeth Jennings } 267b700e7f0SSeth Jennings 268b700e7f0SSeth Jennings static void notrace klp_ftrace_handler(unsigned long ip, 269b700e7f0SSeth Jennings unsigned long parent_ip, 270b700e7f0SSeth Jennings struct ftrace_ops *ops, 271b700e7f0SSeth Jennings struct pt_regs *regs) 272b700e7f0SSeth Jennings { 273b700e7f0SSeth Jennings struct klp_func *func = ops->private; 274b700e7f0SSeth Jennings 275b5bfc517SLi Bin klp_arch_set_pc(regs, (unsigned long)func->new_func); 276b700e7f0SSeth Jennings } 277b700e7f0SSeth Jennings 278b700e7f0SSeth Jennings static int klp_disable_func(struct klp_func *func) 279b700e7f0SSeth Jennings { 280b700e7f0SSeth Jennings int ret; 281b700e7f0SSeth Jennings 282b700e7f0SSeth Jennings if (WARN_ON(func->state != KLP_ENABLED)) 283b700e7f0SSeth Jennings return -EINVAL; 284b700e7f0SSeth Jennings 285b700e7f0SSeth Jennings if (WARN_ON(!func->old_addr)) 286b700e7f0SSeth Jennings return -EINVAL; 287b700e7f0SSeth Jennings 288b700e7f0SSeth Jennings ret = unregister_ftrace_function(func->fops); 289b700e7f0SSeth Jennings if (ret) { 290b700e7f0SSeth Jennings pr_err("failed to unregister ftrace handler for function '%s' (%d)\n", 291b700e7f0SSeth Jennings func->old_name, ret); 292b700e7f0SSeth Jennings return ret; 293b700e7f0SSeth Jennings } 294b700e7f0SSeth Jennings 295b700e7f0SSeth Jennings ret = ftrace_set_filter_ip(func->fops, func->old_addr, 1, 0); 296b700e7f0SSeth Jennings if (ret) 297b700e7f0SSeth Jennings pr_warn("function unregister succeeded but failed to clear the filter\n"); 298b700e7f0SSeth Jennings 299b700e7f0SSeth Jennings func->state = KLP_DISABLED; 300b700e7f0SSeth Jennings 301b700e7f0SSeth Jennings return 0; 302b700e7f0SSeth Jennings } 303b700e7f0SSeth Jennings 304b700e7f0SSeth Jennings static int klp_enable_func(struct klp_func *func) 305b700e7f0SSeth Jennings { 306b700e7f0SSeth Jennings int ret; 307b700e7f0SSeth Jennings 308b700e7f0SSeth Jennings if (WARN_ON(!func->old_addr)) 309b700e7f0SSeth Jennings return -EINVAL; 310b700e7f0SSeth Jennings 311b700e7f0SSeth Jennings if (WARN_ON(func->state != KLP_DISABLED)) 312b700e7f0SSeth Jennings return -EINVAL; 313b700e7f0SSeth Jennings 314b700e7f0SSeth Jennings ret = ftrace_set_filter_ip(func->fops, func->old_addr, 0, 0); 315b700e7f0SSeth Jennings if (ret) { 316b700e7f0SSeth Jennings pr_err("failed to set ftrace filter for function '%s' (%d)\n", 317b700e7f0SSeth Jennings func->old_name, ret); 318b700e7f0SSeth Jennings return ret; 319b700e7f0SSeth Jennings } 320b700e7f0SSeth Jennings 321b700e7f0SSeth Jennings ret = register_ftrace_function(func->fops); 322b700e7f0SSeth Jennings if (ret) { 323b700e7f0SSeth Jennings pr_err("failed to register ftrace handler for function '%s' (%d)\n", 324b700e7f0SSeth Jennings func->old_name, ret); 325b700e7f0SSeth Jennings ftrace_set_filter_ip(func->fops, func->old_addr, 1, 0); 326b700e7f0SSeth Jennings } else { 327b700e7f0SSeth Jennings func->state = KLP_ENABLED; 328b700e7f0SSeth Jennings } 329b700e7f0SSeth Jennings 330b700e7f0SSeth Jennings return ret; 331b700e7f0SSeth Jennings } 332b700e7f0SSeth Jennings 333b700e7f0SSeth Jennings static int klp_disable_object(struct klp_object *obj) 334b700e7f0SSeth Jennings { 335b700e7f0SSeth Jennings struct klp_func *func; 336b700e7f0SSeth Jennings int ret; 337b700e7f0SSeth Jennings 338b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name; func++) { 339b700e7f0SSeth Jennings if (func->state != KLP_ENABLED) 340b700e7f0SSeth Jennings continue; 341b700e7f0SSeth Jennings 342b700e7f0SSeth Jennings ret = klp_disable_func(func); 343b700e7f0SSeth Jennings if (ret) 344b700e7f0SSeth Jennings return ret; 345b700e7f0SSeth Jennings } 346b700e7f0SSeth Jennings 347b700e7f0SSeth Jennings obj->state = KLP_DISABLED; 348b700e7f0SSeth Jennings 349b700e7f0SSeth Jennings return 0; 350b700e7f0SSeth Jennings } 351b700e7f0SSeth Jennings 352b700e7f0SSeth Jennings static int klp_enable_object(struct klp_object *obj) 353b700e7f0SSeth Jennings { 354b700e7f0SSeth Jennings struct klp_func *func; 355b700e7f0SSeth Jennings int ret; 356b700e7f0SSeth Jennings 357b700e7f0SSeth Jennings if (WARN_ON(obj->state != KLP_DISABLED)) 358b700e7f0SSeth Jennings return -EINVAL; 359b700e7f0SSeth Jennings 360b700e7f0SSeth Jennings if (WARN_ON(!klp_is_object_loaded(obj))) 361b700e7f0SSeth Jennings return -EINVAL; 362b700e7f0SSeth Jennings 363b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name; func++) { 364b700e7f0SSeth Jennings ret = klp_enable_func(func); 365b700e7f0SSeth Jennings if (ret) 366b700e7f0SSeth Jennings goto unregister; 367b700e7f0SSeth Jennings } 368b700e7f0SSeth Jennings obj->state = KLP_ENABLED; 369b700e7f0SSeth Jennings 370b700e7f0SSeth Jennings return 0; 371b700e7f0SSeth Jennings 372b700e7f0SSeth Jennings unregister: 373b700e7f0SSeth Jennings WARN_ON(klp_disable_object(obj)); 374b700e7f0SSeth Jennings return ret; 375b700e7f0SSeth Jennings } 376b700e7f0SSeth Jennings 377b700e7f0SSeth Jennings static int __klp_disable_patch(struct klp_patch *patch) 378b700e7f0SSeth Jennings { 379b700e7f0SSeth Jennings struct klp_object *obj; 380b700e7f0SSeth Jennings int ret; 381b700e7f0SSeth Jennings 382b700e7f0SSeth Jennings pr_notice("disabling patch '%s'\n", patch->mod->name); 383b700e7f0SSeth Jennings 384b700e7f0SSeth Jennings for (obj = patch->objs; obj->funcs; obj++) { 385b700e7f0SSeth Jennings if (obj->state != KLP_ENABLED) 386b700e7f0SSeth Jennings continue; 387b700e7f0SSeth Jennings 388b700e7f0SSeth Jennings ret = klp_disable_object(obj); 389b700e7f0SSeth Jennings if (ret) 390b700e7f0SSeth Jennings return ret; 391b700e7f0SSeth Jennings } 392b700e7f0SSeth Jennings 393b700e7f0SSeth Jennings patch->state = KLP_DISABLED; 394b700e7f0SSeth Jennings 395b700e7f0SSeth Jennings return 0; 396b700e7f0SSeth Jennings } 397b700e7f0SSeth Jennings 398b700e7f0SSeth Jennings /** 399b700e7f0SSeth Jennings * klp_disable_patch() - disables a registered patch 400b700e7f0SSeth Jennings * @patch: The registered, enabled patch to be disabled 401b700e7f0SSeth Jennings * 402b700e7f0SSeth Jennings * Unregisters the patched functions from ftrace. 403b700e7f0SSeth Jennings * 404b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 405b700e7f0SSeth Jennings */ 406b700e7f0SSeth Jennings int klp_disable_patch(struct klp_patch *patch) 407b700e7f0SSeth Jennings { 408b700e7f0SSeth Jennings int ret; 409b700e7f0SSeth Jennings 410b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 411b700e7f0SSeth Jennings 412b700e7f0SSeth Jennings if (!klp_is_patch_registered(patch)) { 413b700e7f0SSeth Jennings ret = -EINVAL; 414b700e7f0SSeth Jennings goto err; 415b700e7f0SSeth Jennings } 416b700e7f0SSeth Jennings 417b700e7f0SSeth Jennings if (patch->state == KLP_DISABLED) { 418b700e7f0SSeth Jennings ret = -EINVAL; 419b700e7f0SSeth Jennings goto err; 420b700e7f0SSeth Jennings } 421b700e7f0SSeth Jennings 422b700e7f0SSeth Jennings ret = __klp_disable_patch(patch); 423b700e7f0SSeth Jennings 424b700e7f0SSeth Jennings err: 425b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 426b700e7f0SSeth Jennings return ret; 427b700e7f0SSeth Jennings } 428b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_disable_patch); 429b700e7f0SSeth Jennings 430b700e7f0SSeth Jennings static int __klp_enable_patch(struct klp_patch *patch) 431b700e7f0SSeth Jennings { 432b700e7f0SSeth Jennings struct klp_object *obj; 433b700e7f0SSeth Jennings int ret; 434b700e7f0SSeth Jennings 435b700e7f0SSeth Jennings if (WARN_ON(patch->state != KLP_DISABLED)) 436b700e7f0SSeth Jennings return -EINVAL; 437b700e7f0SSeth Jennings 438b700e7f0SSeth Jennings pr_notice_once("tainting kernel with TAINT_LIVEPATCH\n"); 439b700e7f0SSeth Jennings add_taint(TAINT_LIVEPATCH, LOCKDEP_STILL_OK); 440b700e7f0SSeth Jennings 441b700e7f0SSeth Jennings pr_notice("enabling patch '%s'\n", patch->mod->name); 442b700e7f0SSeth Jennings 443b700e7f0SSeth Jennings for (obj = patch->objs; obj->funcs; obj++) { 444b700e7f0SSeth Jennings klp_find_object_module(obj); 445b700e7f0SSeth Jennings 446b700e7f0SSeth Jennings if (!klp_is_object_loaded(obj)) 447b700e7f0SSeth Jennings continue; 448b700e7f0SSeth Jennings 449b700e7f0SSeth Jennings ret = klp_enable_object(obj); 450b700e7f0SSeth Jennings if (ret) 451b700e7f0SSeth Jennings goto unregister; 452b700e7f0SSeth Jennings } 453b700e7f0SSeth Jennings 454b700e7f0SSeth Jennings patch->state = KLP_ENABLED; 455b700e7f0SSeth Jennings 456b700e7f0SSeth Jennings return 0; 457b700e7f0SSeth Jennings 458b700e7f0SSeth Jennings unregister: 459b700e7f0SSeth Jennings WARN_ON(__klp_disable_patch(patch)); 460b700e7f0SSeth Jennings return ret; 461b700e7f0SSeth Jennings } 462b700e7f0SSeth Jennings 463b700e7f0SSeth Jennings /** 464b700e7f0SSeth Jennings * klp_enable_patch() - enables a registered patch 465b700e7f0SSeth Jennings * @patch: The registered, disabled patch to be enabled 466b700e7f0SSeth Jennings * 467b700e7f0SSeth Jennings * Performs the needed symbol lookups and code relocations, 468b700e7f0SSeth Jennings * then registers the patched functions with ftrace. 469b700e7f0SSeth Jennings * 470b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 471b700e7f0SSeth Jennings */ 472b700e7f0SSeth Jennings int klp_enable_patch(struct klp_patch *patch) 473b700e7f0SSeth Jennings { 474b700e7f0SSeth Jennings int ret; 475b700e7f0SSeth Jennings 476b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 477b700e7f0SSeth Jennings 478b700e7f0SSeth Jennings if (!klp_is_patch_registered(patch)) { 479b700e7f0SSeth Jennings ret = -EINVAL; 480b700e7f0SSeth Jennings goto err; 481b700e7f0SSeth Jennings } 482b700e7f0SSeth Jennings 483b700e7f0SSeth Jennings ret = __klp_enable_patch(patch); 484b700e7f0SSeth Jennings 485b700e7f0SSeth Jennings err: 486b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 487b700e7f0SSeth Jennings return ret; 488b700e7f0SSeth Jennings } 489b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_enable_patch); 490b700e7f0SSeth Jennings 491b700e7f0SSeth Jennings /* 492b700e7f0SSeth Jennings * Sysfs Interface 493b700e7f0SSeth Jennings * 494b700e7f0SSeth Jennings * /sys/kernel/livepatch 495b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch> 496b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch>/enabled 497b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch>/<object> 498b700e7f0SSeth Jennings * /sys/kernel/livepatch/<patch>/<object>/<func> 499b700e7f0SSeth Jennings */ 500b700e7f0SSeth Jennings 501b700e7f0SSeth Jennings static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, 502b700e7f0SSeth Jennings const char *buf, size_t count) 503b700e7f0SSeth Jennings { 504b700e7f0SSeth Jennings struct klp_patch *patch; 505b700e7f0SSeth Jennings int ret; 506b700e7f0SSeth Jennings unsigned long val; 507b700e7f0SSeth Jennings 508b700e7f0SSeth Jennings ret = kstrtoul(buf, 10, &val); 509b700e7f0SSeth Jennings if (ret) 510b700e7f0SSeth Jennings return -EINVAL; 511b700e7f0SSeth Jennings 512b700e7f0SSeth Jennings if (val != KLP_DISABLED && val != KLP_ENABLED) 513b700e7f0SSeth Jennings return -EINVAL; 514b700e7f0SSeth Jennings 515b700e7f0SSeth Jennings patch = container_of(kobj, struct klp_patch, kobj); 516b700e7f0SSeth Jennings 517b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 518b700e7f0SSeth Jennings 519b700e7f0SSeth Jennings if (val == patch->state) { 520b700e7f0SSeth Jennings /* already in requested state */ 521b700e7f0SSeth Jennings ret = -EINVAL; 522b700e7f0SSeth Jennings goto err; 523b700e7f0SSeth Jennings } 524b700e7f0SSeth Jennings 525b700e7f0SSeth Jennings if (val == KLP_ENABLED) { 526b700e7f0SSeth Jennings ret = __klp_enable_patch(patch); 527b700e7f0SSeth Jennings if (ret) 528b700e7f0SSeth Jennings goto err; 529b700e7f0SSeth Jennings } else { 530b700e7f0SSeth Jennings ret = __klp_disable_patch(patch); 531b700e7f0SSeth Jennings if (ret) 532b700e7f0SSeth Jennings goto err; 533b700e7f0SSeth Jennings } 534b700e7f0SSeth Jennings 535b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 536b700e7f0SSeth Jennings 537b700e7f0SSeth Jennings return count; 538b700e7f0SSeth Jennings 539b700e7f0SSeth Jennings err: 540b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 541b700e7f0SSeth Jennings return ret; 542b700e7f0SSeth Jennings } 543b700e7f0SSeth Jennings 544b700e7f0SSeth Jennings static ssize_t enabled_show(struct kobject *kobj, 545b700e7f0SSeth Jennings struct kobj_attribute *attr, char *buf) 546b700e7f0SSeth Jennings { 547b700e7f0SSeth Jennings struct klp_patch *patch; 548b700e7f0SSeth Jennings 549b700e7f0SSeth Jennings patch = container_of(kobj, struct klp_patch, kobj); 550b700e7f0SSeth Jennings return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->state); 551b700e7f0SSeth Jennings } 552b700e7f0SSeth Jennings 553b700e7f0SSeth Jennings static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); 554b700e7f0SSeth Jennings static struct attribute *klp_patch_attrs[] = { 555b700e7f0SSeth Jennings &enabled_kobj_attr.attr, 556b700e7f0SSeth Jennings NULL 557b700e7f0SSeth Jennings }; 558b700e7f0SSeth Jennings 559b700e7f0SSeth Jennings static void klp_kobj_release_patch(struct kobject *kobj) 560b700e7f0SSeth Jennings { 561b700e7f0SSeth Jennings /* 562b700e7f0SSeth Jennings * Once we have a consistency model we'll need to module_put() the 563b700e7f0SSeth Jennings * patch module here. See klp_register_patch() for more details. 564b700e7f0SSeth Jennings */ 565b700e7f0SSeth Jennings } 566b700e7f0SSeth Jennings 567b700e7f0SSeth Jennings static struct kobj_type klp_ktype_patch = { 568b700e7f0SSeth Jennings .release = klp_kobj_release_patch, 569b700e7f0SSeth Jennings .sysfs_ops = &kobj_sysfs_ops, 570b700e7f0SSeth Jennings .default_attrs = klp_patch_attrs, 571b700e7f0SSeth Jennings }; 572b700e7f0SSeth Jennings 573b700e7f0SSeth Jennings static void klp_kobj_release_func(struct kobject *kobj) 574b700e7f0SSeth Jennings { 575b700e7f0SSeth Jennings struct klp_func *func; 576b700e7f0SSeth Jennings 577b700e7f0SSeth Jennings func = container_of(kobj, struct klp_func, kobj); 578b700e7f0SSeth Jennings kfree(func->fops); 579b700e7f0SSeth Jennings } 580b700e7f0SSeth Jennings 581b700e7f0SSeth Jennings static struct kobj_type klp_ktype_func = { 582b700e7f0SSeth Jennings .release = klp_kobj_release_func, 583b700e7f0SSeth Jennings .sysfs_ops = &kobj_sysfs_ops, 584b700e7f0SSeth Jennings }; 585b700e7f0SSeth Jennings 586b700e7f0SSeth Jennings /* 587b700e7f0SSeth Jennings * Free all functions' kobjects in the array up to some limit. When limit is 588b700e7f0SSeth Jennings * NULL, all kobjects are freed. 589b700e7f0SSeth Jennings */ 590b700e7f0SSeth Jennings static void klp_free_funcs_limited(struct klp_object *obj, 591b700e7f0SSeth Jennings struct klp_func *limit) 592b700e7f0SSeth Jennings { 593b700e7f0SSeth Jennings struct klp_func *func; 594b700e7f0SSeth Jennings 595b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name && func != limit; func++) 596b700e7f0SSeth Jennings kobject_put(&func->kobj); 597b700e7f0SSeth Jennings } 598b700e7f0SSeth Jennings 599b700e7f0SSeth Jennings /* Clean up when a patched object is unloaded */ 600b700e7f0SSeth Jennings static void klp_free_object_loaded(struct klp_object *obj) 601b700e7f0SSeth Jennings { 602b700e7f0SSeth Jennings struct klp_func *func; 603b700e7f0SSeth Jennings 604b700e7f0SSeth Jennings obj->mod = NULL; 605b700e7f0SSeth Jennings 606b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name; func++) 607b700e7f0SSeth Jennings func->old_addr = 0; 608b700e7f0SSeth Jennings } 609b700e7f0SSeth Jennings 610b700e7f0SSeth Jennings /* 611b700e7f0SSeth Jennings * Free all objects' kobjects in the array up to some limit. When limit is 612b700e7f0SSeth Jennings * NULL, all kobjects are freed. 613b700e7f0SSeth Jennings */ 614b700e7f0SSeth Jennings static void klp_free_objects_limited(struct klp_patch *patch, 615b700e7f0SSeth Jennings struct klp_object *limit) 616b700e7f0SSeth Jennings { 617b700e7f0SSeth Jennings struct klp_object *obj; 618b700e7f0SSeth Jennings 619b700e7f0SSeth Jennings for (obj = patch->objs; obj->funcs && obj != limit; obj++) { 620b700e7f0SSeth Jennings klp_free_funcs_limited(obj, NULL); 621b700e7f0SSeth Jennings kobject_put(obj->kobj); 622b700e7f0SSeth Jennings } 623b700e7f0SSeth Jennings } 624b700e7f0SSeth Jennings 625b700e7f0SSeth Jennings static void klp_free_patch(struct klp_patch *patch) 626b700e7f0SSeth Jennings { 627b700e7f0SSeth Jennings klp_free_objects_limited(patch, NULL); 628b700e7f0SSeth Jennings if (!list_empty(&patch->list)) 629b700e7f0SSeth Jennings list_del(&patch->list); 630b700e7f0SSeth Jennings kobject_put(&patch->kobj); 631b700e7f0SSeth Jennings } 632b700e7f0SSeth Jennings 633b700e7f0SSeth Jennings static int klp_init_func(struct klp_object *obj, struct klp_func *func) 634b700e7f0SSeth Jennings { 635b700e7f0SSeth Jennings struct ftrace_ops *ops; 636b700e7f0SSeth Jennings int ret; 637b700e7f0SSeth Jennings 638b700e7f0SSeth Jennings ops = kzalloc(sizeof(*ops), GFP_KERNEL); 639b700e7f0SSeth Jennings if (!ops) 640b700e7f0SSeth Jennings return -ENOMEM; 641b700e7f0SSeth Jennings 642b700e7f0SSeth Jennings ops->private = func; 643b700e7f0SSeth Jennings ops->func = klp_ftrace_handler; 64433e8612fSJosh Poimboeuf ops->flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_DYNAMIC | 64533e8612fSJosh Poimboeuf FTRACE_OPS_FL_IPMODIFY; 646b700e7f0SSeth Jennings func->fops = ops; 647b700e7f0SSeth Jennings func->state = KLP_DISABLED; 648b700e7f0SSeth Jennings 649b700e7f0SSeth Jennings ret = kobject_init_and_add(&func->kobj, &klp_ktype_func, 650b700e7f0SSeth Jennings obj->kobj, func->old_name); 651b700e7f0SSeth Jennings if (ret) { 652b700e7f0SSeth Jennings kfree(func->fops); 653b700e7f0SSeth Jennings return ret; 654b700e7f0SSeth Jennings } 655b700e7f0SSeth Jennings 656b700e7f0SSeth Jennings return 0; 657b700e7f0SSeth Jennings } 658b700e7f0SSeth Jennings 659b700e7f0SSeth Jennings /* parts of the initialization that is done only when the object is loaded */ 660b700e7f0SSeth Jennings static int klp_init_object_loaded(struct klp_patch *patch, 661b700e7f0SSeth Jennings struct klp_object *obj) 662b700e7f0SSeth Jennings { 663b700e7f0SSeth Jennings struct klp_func *func; 664b700e7f0SSeth Jennings int ret; 665b700e7f0SSeth Jennings 666b700e7f0SSeth Jennings if (obj->relocs) { 667b700e7f0SSeth Jennings ret = klp_write_object_relocations(patch->mod, obj); 668b700e7f0SSeth Jennings if (ret) 669b700e7f0SSeth Jennings return ret; 670b700e7f0SSeth Jennings } 671b700e7f0SSeth Jennings 672b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name; func++) { 673b700e7f0SSeth Jennings ret = klp_find_verify_func_addr(obj, func); 674b700e7f0SSeth Jennings if (ret) 675b700e7f0SSeth Jennings return ret; 676b700e7f0SSeth Jennings } 677b700e7f0SSeth Jennings 678b700e7f0SSeth Jennings return 0; 679b700e7f0SSeth Jennings } 680b700e7f0SSeth Jennings 681b700e7f0SSeth Jennings static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) 682b700e7f0SSeth Jennings { 683b700e7f0SSeth Jennings struct klp_func *func; 684b700e7f0SSeth Jennings int ret; 685b700e7f0SSeth Jennings const char *name; 686b700e7f0SSeth Jennings 687b700e7f0SSeth Jennings if (!obj->funcs) 688b700e7f0SSeth Jennings return -EINVAL; 689b700e7f0SSeth Jennings 690b700e7f0SSeth Jennings obj->state = KLP_DISABLED; 691b700e7f0SSeth Jennings 692b700e7f0SSeth Jennings klp_find_object_module(obj); 693b700e7f0SSeth Jennings 694b700e7f0SSeth Jennings name = klp_is_module(obj) ? obj->name : "vmlinux"; 695b700e7f0SSeth Jennings obj->kobj = kobject_create_and_add(name, &patch->kobj); 696b700e7f0SSeth Jennings if (!obj->kobj) 697b700e7f0SSeth Jennings return -ENOMEM; 698b700e7f0SSeth Jennings 699b700e7f0SSeth Jennings for (func = obj->funcs; func->old_name; func++) { 700b700e7f0SSeth Jennings ret = klp_init_func(obj, func); 701b700e7f0SSeth Jennings if (ret) 702b700e7f0SSeth Jennings goto free; 703b700e7f0SSeth Jennings } 704b700e7f0SSeth Jennings 705b700e7f0SSeth Jennings if (klp_is_object_loaded(obj)) { 706b700e7f0SSeth Jennings ret = klp_init_object_loaded(patch, obj); 707b700e7f0SSeth Jennings if (ret) 708b700e7f0SSeth Jennings goto free; 709b700e7f0SSeth Jennings } 710b700e7f0SSeth Jennings 711b700e7f0SSeth Jennings return 0; 712b700e7f0SSeth Jennings 713b700e7f0SSeth Jennings free: 714b700e7f0SSeth Jennings klp_free_funcs_limited(obj, func); 715b700e7f0SSeth Jennings kobject_put(obj->kobj); 716b700e7f0SSeth Jennings return ret; 717b700e7f0SSeth Jennings } 718b700e7f0SSeth Jennings 719b700e7f0SSeth Jennings static int klp_init_patch(struct klp_patch *patch) 720b700e7f0SSeth Jennings { 721b700e7f0SSeth Jennings struct klp_object *obj; 722b700e7f0SSeth Jennings int ret; 723b700e7f0SSeth Jennings 724b700e7f0SSeth Jennings if (!patch->objs) 725b700e7f0SSeth Jennings return -EINVAL; 726b700e7f0SSeth Jennings 727b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 728b700e7f0SSeth Jennings 729b700e7f0SSeth Jennings patch->state = KLP_DISABLED; 730b700e7f0SSeth Jennings 731b700e7f0SSeth Jennings ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, 732b700e7f0SSeth Jennings klp_root_kobj, patch->mod->name); 733b700e7f0SSeth Jennings if (ret) 734b700e7f0SSeth Jennings goto unlock; 735b700e7f0SSeth Jennings 736b700e7f0SSeth Jennings for (obj = patch->objs; obj->funcs; obj++) { 737b700e7f0SSeth Jennings ret = klp_init_object(patch, obj); 738b700e7f0SSeth Jennings if (ret) 739b700e7f0SSeth Jennings goto free; 740b700e7f0SSeth Jennings } 741b700e7f0SSeth Jennings 742b700e7f0SSeth Jennings list_add(&patch->list, &klp_patches); 743b700e7f0SSeth Jennings 744b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 745b700e7f0SSeth Jennings 746b700e7f0SSeth Jennings return 0; 747b700e7f0SSeth Jennings 748b700e7f0SSeth Jennings free: 749b700e7f0SSeth Jennings klp_free_objects_limited(patch, obj); 750b700e7f0SSeth Jennings kobject_put(&patch->kobj); 751b700e7f0SSeth Jennings unlock: 752b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 753b700e7f0SSeth Jennings return ret; 754b700e7f0SSeth Jennings } 755b700e7f0SSeth Jennings 756b700e7f0SSeth Jennings /** 757b700e7f0SSeth Jennings * klp_unregister_patch() - unregisters a patch 758b700e7f0SSeth Jennings * @patch: Disabled patch to be unregistered 759b700e7f0SSeth Jennings * 760b700e7f0SSeth Jennings * Frees the data structures and removes the sysfs interface. 761b700e7f0SSeth Jennings * 762b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 763b700e7f0SSeth Jennings */ 764b700e7f0SSeth Jennings int klp_unregister_patch(struct klp_patch *patch) 765b700e7f0SSeth Jennings { 766b700e7f0SSeth Jennings int ret = 0; 767b700e7f0SSeth Jennings 768b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 769b700e7f0SSeth Jennings 770b700e7f0SSeth Jennings if (!klp_is_patch_registered(patch)) { 771b700e7f0SSeth Jennings ret = -EINVAL; 772b700e7f0SSeth Jennings goto out; 773b700e7f0SSeth Jennings } 774b700e7f0SSeth Jennings 775b700e7f0SSeth Jennings if (patch->state == KLP_ENABLED) { 776b700e7f0SSeth Jennings ret = -EBUSY; 777b700e7f0SSeth Jennings goto out; 778b700e7f0SSeth Jennings } 779b700e7f0SSeth Jennings 780b700e7f0SSeth Jennings klp_free_patch(patch); 781b700e7f0SSeth Jennings 782b700e7f0SSeth Jennings out: 783b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 784b700e7f0SSeth Jennings return ret; 785b700e7f0SSeth Jennings } 786b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_unregister_patch); 787b700e7f0SSeth Jennings 788b700e7f0SSeth Jennings /** 789b700e7f0SSeth Jennings * klp_register_patch() - registers a patch 790b700e7f0SSeth Jennings * @patch: Patch to be registered 791b700e7f0SSeth Jennings * 792b700e7f0SSeth Jennings * Initializes the data structure associated with the patch and 793b700e7f0SSeth Jennings * creates the sysfs interface. 794b700e7f0SSeth Jennings * 795b700e7f0SSeth Jennings * Return: 0 on success, otherwise error 796b700e7f0SSeth Jennings */ 797b700e7f0SSeth Jennings int klp_register_patch(struct klp_patch *patch) 798b700e7f0SSeth Jennings { 799b700e7f0SSeth Jennings int ret; 800b700e7f0SSeth Jennings 801b700e7f0SSeth Jennings if (!klp_initialized()) 802b700e7f0SSeth Jennings return -ENODEV; 803b700e7f0SSeth Jennings 804b700e7f0SSeth Jennings if (!patch || !patch->mod) 805b700e7f0SSeth Jennings return -EINVAL; 806b700e7f0SSeth Jennings 807b700e7f0SSeth Jennings /* 808b700e7f0SSeth Jennings * A reference is taken on the patch module to prevent it from being 809b700e7f0SSeth Jennings * unloaded. Right now, we don't allow patch modules to unload since 810b700e7f0SSeth Jennings * there is currently no method to determine if a thread is still 811b700e7f0SSeth Jennings * running in the patched code contained in the patch module once 812b700e7f0SSeth Jennings * the ftrace registration is successful. 813b700e7f0SSeth Jennings */ 814b700e7f0SSeth Jennings if (!try_module_get(patch->mod)) 815b700e7f0SSeth Jennings return -ENODEV; 816b700e7f0SSeth Jennings 817b700e7f0SSeth Jennings ret = klp_init_patch(patch); 818b700e7f0SSeth Jennings if (ret) 819b700e7f0SSeth Jennings module_put(patch->mod); 820b700e7f0SSeth Jennings 821b700e7f0SSeth Jennings return ret; 822b700e7f0SSeth Jennings } 823b700e7f0SSeth Jennings EXPORT_SYMBOL_GPL(klp_register_patch); 824b700e7f0SSeth Jennings 825b700e7f0SSeth Jennings static void klp_module_notify_coming(struct klp_patch *patch, 826b700e7f0SSeth Jennings struct klp_object *obj) 827b700e7f0SSeth Jennings { 828b700e7f0SSeth Jennings struct module *pmod = patch->mod; 829b700e7f0SSeth Jennings struct module *mod = obj->mod; 830b700e7f0SSeth Jennings int ret; 831b700e7f0SSeth Jennings 832b700e7f0SSeth Jennings ret = klp_init_object_loaded(patch, obj); 833b700e7f0SSeth Jennings if (ret) 834b700e7f0SSeth Jennings goto err; 835b700e7f0SSeth Jennings 836b700e7f0SSeth Jennings if (patch->state == KLP_DISABLED) 837b700e7f0SSeth Jennings return; 838b700e7f0SSeth Jennings 839b700e7f0SSeth Jennings pr_notice("applying patch '%s' to loading module '%s'\n", 840b700e7f0SSeth Jennings pmod->name, mod->name); 841b700e7f0SSeth Jennings 842b700e7f0SSeth Jennings ret = klp_enable_object(obj); 843b700e7f0SSeth Jennings if (!ret) 844b700e7f0SSeth Jennings return; 845b700e7f0SSeth Jennings 846b700e7f0SSeth Jennings err: 847b700e7f0SSeth Jennings pr_warn("failed to apply patch '%s' to module '%s' (%d)\n", 848b700e7f0SSeth Jennings pmod->name, mod->name, ret); 849b700e7f0SSeth Jennings } 850b700e7f0SSeth Jennings 851b700e7f0SSeth Jennings static void klp_module_notify_going(struct klp_patch *patch, 852b700e7f0SSeth Jennings struct klp_object *obj) 853b700e7f0SSeth Jennings { 854b700e7f0SSeth Jennings struct module *pmod = patch->mod; 855b700e7f0SSeth Jennings struct module *mod = obj->mod; 856b700e7f0SSeth Jennings int ret; 857b700e7f0SSeth Jennings 858b700e7f0SSeth Jennings if (patch->state == KLP_DISABLED) 859b700e7f0SSeth Jennings goto disabled; 860b700e7f0SSeth Jennings 861b700e7f0SSeth Jennings pr_notice("reverting patch '%s' on unloading module '%s'\n", 862b700e7f0SSeth Jennings pmod->name, mod->name); 863b700e7f0SSeth Jennings 864b700e7f0SSeth Jennings ret = klp_disable_object(obj); 865b700e7f0SSeth Jennings if (ret) 866b700e7f0SSeth Jennings pr_warn("failed to revert patch '%s' on module '%s' (%d)\n", 867b700e7f0SSeth Jennings pmod->name, mod->name, ret); 868b700e7f0SSeth Jennings 869b700e7f0SSeth Jennings disabled: 870b700e7f0SSeth Jennings klp_free_object_loaded(obj); 871b700e7f0SSeth Jennings } 872b700e7f0SSeth Jennings 873b700e7f0SSeth Jennings static int klp_module_notify(struct notifier_block *nb, unsigned long action, 874b700e7f0SSeth Jennings void *data) 875b700e7f0SSeth Jennings { 876b700e7f0SSeth Jennings struct module *mod = data; 877b700e7f0SSeth Jennings struct klp_patch *patch; 878b700e7f0SSeth Jennings struct klp_object *obj; 879b700e7f0SSeth Jennings 880b700e7f0SSeth Jennings if (action != MODULE_STATE_COMING && action != MODULE_STATE_GOING) 881b700e7f0SSeth Jennings return 0; 882b700e7f0SSeth Jennings 883b700e7f0SSeth Jennings mutex_lock(&klp_mutex); 884b700e7f0SSeth Jennings 885b700e7f0SSeth Jennings list_for_each_entry(patch, &klp_patches, list) { 886b700e7f0SSeth Jennings for (obj = patch->objs; obj->funcs; obj++) { 887b700e7f0SSeth Jennings if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) 888b700e7f0SSeth Jennings continue; 889b700e7f0SSeth Jennings 890b700e7f0SSeth Jennings if (action == MODULE_STATE_COMING) { 891b700e7f0SSeth Jennings obj->mod = mod; 892b700e7f0SSeth Jennings klp_module_notify_coming(patch, obj); 893b700e7f0SSeth Jennings } else /* MODULE_STATE_GOING */ 894b700e7f0SSeth Jennings klp_module_notify_going(patch, obj); 895b700e7f0SSeth Jennings 896b700e7f0SSeth Jennings break; 897b700e7f0SSeth Jennings } 898b700e7f0SSeth Jennings } 899b700e7f0SSeth Jennings 900b700e7f0SSeth Jennings mutex_unlock(&klp_mutex); 901b700e7f0SSeth Jennings 902b700e7f0SSeth Jennings return 0; 903b700e7f0SSeth Jennings } 904b700e7f0SSeth Jennings 905b700e7f0SSeth Jennings static struct notifier_block klp_module_nb = { 906b700e7f0SSeth Jennings .notifier_call = klp_module_notify, 907b700e7f0SSeth Jennings .priority = INT_MIN+1, /* called late but before ftrace notifier */ 908b700e7f0SSeth Jennings }; 909b700e7f0SSeth Jennings 910b700e7f0SSeth Jennings static int klp_init(void) 911b700e7f0SSeth Jennings { 912b700e7f0SSeth Jennings int ret; 913b700e7f0SSeth Jennings 914*b9dfe0beSJiri Kosina ret = klp_check_compiler_support(); 915*b9dfe0beSJiri Kosina if (ret) { 916*b9dfe0beSJiri Kosina pr_info("Your compiler is too old; turning off.\n"); 917*b9dfe0beSJiri Kosina return -EINVAL; 918*b9dfe0beSJiri Kosina } 919*b9dfe0beSJiri Kosina 920b700e7f0SSeth Jennings ret = register_module_notifier(&klp_module_nb); 921b700e7f0SSeth Jennings if (ret) 922b700e7f0SSeth Jennings return ret; 923b700e7f0SSeth Jennings 924b700e7f0SSeth Jennings klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj); 925b700e7f0SSeth Jennings if (!klp_root_kobj) { 926b700e7f0SSeth Jennings ret = -ENOMEM; 927b700e7f0SSeth Jennings goto unregister; 928b700e7f0SSeth Jennings } 929b700e7f0SSeth Jennings 930b700e7f0SSeth Jennings return 0; 931b700e7f0SSeth Jennings 932b700e7f0SSeth Jennings unregister: 933b700e7f0SSeth Jennings unregister_module_notifier(&klp_module_nb); 934b700e7f0SSeth Jennings return ret; 935b700e7f0SSeth Jennings } 936b700e7f0SSeth Jennings 937b700e7f0SSeth Jennings module_init(klp_init); 938