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