1b700e7f0SSeth Jennings /* 2b700e7f0SSeth Jennings * livepatch.h - 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 #ifndef _LINUX_LIVEPATCH_H_ 22b700e7f0SSeth Jennings #define _LINUX_LIVEPATCH_H_ 23b700e7f0SSeth Jennings 24b700e7f0SSeth Jennings #include <linux/module.h> 25b700e7f0SSeth Jennings #include <linux/ftrace.h> 26b700e7f0SSeth Jennings 27*7e545d6eSJessica Yu #if IS_ENABLED(CONFIG_LIVEPATCH) 28*7e545d6eSJessica Yu 29b700e7f0SSeth Jennings #include <asm/livepatch.h> 30b700e7f0SSeth Jennings 31b700e7f0SSeth Jennings enum klp_state { 32b700e7f0SSeth Jennings KLP_DISABLED, 33b700e7f0SSeth Jennings KLP_ENABLED 34b700e7f0SSeth Jennings }; 35b700e7f0SSeth Jennings 36b700e7f0SSeth Jennings /** 37b700e7f0SSeth Jennings * struct klp_func - function structure for live patching 38b700e7f0SSeth Jennings * @old_name: name of the function to be patched 39b700e7f0SSeth Jennings * @new_func: pointer to the patched function code 40b2b018efSChris J Arges * @old_sympos: a hint indicating which symbol position the old function 41b2b018efSChris J Arges * can be found (optional) 42b2b018efSChris J Arges * @old_addr: the address of the function being patched 43b700e7f0SSeth Jennings * @kobj: kobject for sysfs resources 44b700e7f0SSeth Jennings * @state: tracks function-level patch application state 453c33f5b9SJosh Poimboeuf * @stack_node: list node for klp_ops func_stack list 46b700e7f0SSeth Jennings */ 47b700e7f0SSeth Jennings struct klp_func { 48b700e7f0SSeth Jennings /* external */ 49b700e7f0SSeth Jennings const char *old_name; 50b700e7f0SSeth Jennings void *new_func; 51b700e7f0SSeth Jennings /* 52b2b018efSChris J Arges * The old_sympos field is optional and can be used to resolve 53b2b018efSChris J Arges * duplicate symbol names in livepatch objects. If this field is zero, 54b2b018efSChris J Arges * it is expected the symbol is unique, otherwise patching fails. If 55b2b018efSChris J Arges * this value is greater than zero then that occurrence of the symbol 56b2b018efSChris J Arges * in kallsyms for the given object is used. 57b700e7f0SSeth Jennings */ 58b2b018efSChris J Arges unsigned long old_sympos; 59b700e7f0SSeth Jennings 60b700e7f0SSeth Jennings /* internal */ 61b2b018efSChris J Arges unsigned long old_addr; 62b700e7f0SSeth Jennings struct kobject kobj; 63b700e7f0SSeth Jennings enum klp_state state; 643c33f5b9SJosh Poimboeuf struct list_head stack_node; 65b700e7f0SSeth Jennings }; 66b700e7f0SSeth Jennings 67b700e7f0SSeth Jennings /** 68b700e7f0SSeth Jennings * struct klp_reloc - relocation structure for live patching 69b700e7f0SSeth Jennings * @loc: address where the relocation will be written 70064c89dfSChris J Arges * @sympos: position in kallsyms to disambiguate symbols (optional) 71b700e7f0SSeth Jennings * @type: ELF relocation type 72b700e7f0SSeth Jennings * @name: name of the referenced symbol (for lookup/verification) 73b700e7f0SSeth Jennings * @addend: offset from the referenced symbol 74b700e7f0SSeth Jennings * @external: symbol is either exported or within the live patch module itself 75b700e7f0SSeth Jennings */ 76b700e7f0SSeth Jennings struct klp_reloc { 77b700e7f0SSeth Jennings unsigned long loc; 78064c89dfSChris J Arges unsigned long sympos; 79b700e7f0SSeth Jennings unsigned long type; 80b700e7f0SSeth Jennings const char *name; 81b700e7f0SSeth Jennings int addend; 82b700e7f0SSeth Jennings int external; 83b700e7f0SSeth Jennings }; 84b700e7f0SSeth Jennings 85b700e7f0SSeth Jennings /** 86b700e7f0SSeth Jennings * struct klp_object - kernel object structure for live patching 87b700e7f0SSeth Jennings * @name: module name (or NULL for vmlinux) 88b700e7f0SSeth Jennings * @relocs: relocation entries to be applied at load time 89b700e7f0SSeth Jennings * @funcs: function entries for functions to be patched in the object 90b700e7f0SSeth Jennings * @kobj: kobject for sysfs resources 91b700e7f0SSeth Jennings * @mod: kernel module associated with the patched object 92b700e7f0SSeth Jennings * (NULL for vmlinux) 93b700e7f0SSeth Jennings * @state: tracks object-level patch application state 94b700e7f0SSeth Jennings */ 95b700e7f0SSeth Jennings struct klp_object { 96b700e7f0SSeth Jennings /* external */ 97b700e7f0SSeth Jennings const char *name; 98b700e7f0SSeth Jennings struct klp_reloc *relocs; 99b700e7f0SSeth Jennings struct klp_func *funcs; 100b700e7f0SSeth Jennings 101b700e7f0SSeth Jennings /* internal */ 102cad706dfSMiroslav Benes struct kobject kobj; 103b700e7f0SSeth Jennings struct module *mod; 104b700e7f0SSeth Jennings enum klp_state state; 105b700e7f0SSeth Jennings }; 106b700e7f0SSeth Jennings 107b700e7f0SSeth Jennings /** 108b700e7f0SSeth Jennings * struct klp_patch - patch structure for live patching 109b700e7f0SSeth Jennings * @mod: reference to the live patch module 110b700e7f0SSeth Jennings * @objs: object entries for kernel objects to be patched 111b700e7f0SSeth Jennings * @list: list node for global list of registered patches 112b700e7f0SSeth Jennings * @kobj: kobject for sysfs resources 113b700e7f0SSeth Jennings * @state: tracks patch-level application state 114b700e7f0SSeth Jennings */ 115b700e7f0SSeth Jennings struct klp_patch { 116b700e7f0SSeth Jennings /* external */ 117b700e7f0SSeth Jennings struct module *mod; 118b700e7f0SSeth Jennings struct klp_object *objs; 119b700e7f0SSeth Jennings 120b700e7f0SSeth Jennings /* internal */ 121b700e7f0SSeth Jennings struct list_head list; 122b700e7f0SSeth Jennings struct kobject kobj; 123b700e7f0SSeth Jennings enum klp_state state; 124b700e7f0SSeth Jennings }; 125b700e7f0SSeth Jennings 1268cdd043aSJiri Slaby #define klp_for_each_object(patch, obj) \ 1278cdd043aSJiri Slaby for (obj = patch->objs; obj->funcs; obj++) 1288cdd043aSJiri Slaby 1298cdd043aSJiri Slaby #define klp_for_each_func(obj, func) \ 1308cdd043aSJiri Slaby for (func = obj->funcs; func->old_name; func++) 1318cdd043aSJiri Slaby 1324421f8f0SMiroslav Benes int klp_register_patch(struct klp_patch *); 1334421f8f0SMiroslav Benes int klp_unregister_patch(struct klp_patch *); 1344421f8f0SMiroslav Benes int klp_enable_patch(struct klp_patch *); 1354421f8f0SMiroslav Benes int klp_disable_patch(struct klp_patch *); 136b700e7f0SSeth Jennings 137*7e545d6eSJessica Yu /* Called from the module loader during module coming/going states */ 138*7e545d6eSJessica Yu int klp_module_coming(struct module *mod); 139*7e545d6eSJessica Yu void klp_module_going(struct module *mod); 140*7e545d6eSJessica Yu 141*7e545d6eSJessica Yu #else /* !CONFIG_LIVEPATCH */ 142*7e545d6eSJessica Yu 143*7e545d6eSJessica Yu static inline int klp_module_coming(struct module *mod) { return 0; } 144*7e545d6eSJessica Yu static inline void klp_module_going(struct module *mod) { } 145*7e545d6eSJessica Yu 146*7e545d6eSJessica Yu #endif /* CONFIG_LIVEPATCH */ 147*7e545d6eSJessica Yu 148b700e7f0SSeth Jennings #endif /* _LINUX_LIVEPATCH_H_ */ 149