1 /* 2 * livepatch.h - Kernel Live Patching Core 3 * 4 * Copyright (C) 2014 Seth Jennings <[email protected]> 5 * Copyright (C) 2014 SUSE 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef _LINUX_LIVEPATCH_H_ 22 #define _LINUX_LIVEPATCH_H_ 23 24 #include <linux/module.h> 25 #include <linux/ftrace.h> 26 27 #if IS_ENABLED(CONFIG_LIVEPATCH) 28 29 #include <asm/livepatch.h> 30 31 /** 32 * struct klp_func - function structure for live patching 33 * @old_name: name of the function to be patched 34 * @new_func: pointer to the patched function code 35 * @old_sympos: a hint indicating which symbol position the old function 36 * can be found (optional) 37 * @old_addr: the address of the function being patched 38 * @kobj: kobject for sysfs resources 39 * @stack_node: list node for klp_ops func_stack list 40 * @old_size: size of the old function 41 * @new_size: size of the new function 42 * @patched: the func has been added to the klp_ops list 43 */ 44 struct klp_func { 45 /* external */ 46 const char *old_name; 47 void *new_func; 48 /* 49 * The old_sympos field is optional and can be used to resolve 50 * duplicate symbol names in livepatch objects. If this field is zero, 51 * it is expected the symbol is unique, otherwise patching fails. If 52 * this value is greater than zero then that occurrence of the symbol 53 * in kallsyms for the given object is used. 54 */ 55 unsigned long old_sympos; 56 57 /* internal */ 58 unsigned long old_addr; 59 struct kobject kobj; 60 struct list_head stack_node; 61 unsigned long old_size, new_size; 62 bool patched; 63 }; 64 65 /** 66 * struct klp_object - kernel object structure for live patching 67 * @name: module name (or NULL for vmlinux) 68 * @funcs: function entries for functions to be patched in the object 69 * @kobj: kobject for sysfs resources 70 * @mod: kernel module associated with the patched object 71 * (NULL for vmlinux) 72 * @patched: the object's funcs have been added to the klp_ops list 73 */ 74 struct klp_object { 75 /* external */ 76 const char *name; 77 struct klp_func *funcs; 78 79 /* internal */ 80 struct kobject kobj; 81 struct module *mod; 82 bool patched; 83 }; 84 85 /** 86 * struct klp_patch - patch structure for live patching 87 * @mod: reference to the live patch module 88 * @objs: object entries for kernel objects to be patched 89 * @list: list node for global list of registered patches 90 * @kobj: kobject for sysfs resources 91 * @enabled: the patch is enabled (but operation may be incomplete) 92 */ 93 struct klp_patch { 94 /* external */ 95 struct module *mod; 96 struct klp_object *objs; 97 98 /* internal */ 99 struct list_head list; 100 struct kobject kobj; 101 bool enabled; 102 }; 103 104 #define klp_for_each_object(patch, obj) \ 105 for (obj = patch->objs; obj->funcs || obj->name; obj++) 106 107 #define klp_for_each_func(obj, func) \ 108 for (func = obj->funcs; \ 109 func->old_name || func->new_func || func->old_sympos; \ 110 func++) 111 112 int klp_register_patch(struct klp_patch *); 113 int klp_unregister_patch(struct klp_patch *); 114 int klp_enable_patch(struct klp_patch *); 115 int klp_disable_patch(struct klp_patch *); 116 117 void arch_klp_init_object_loaded(struct klp_patch *patch, 118 struct klp_object *obj); 119 120 /* Called from the module loader during module coming/going states */ 121 int klp_module_coming(struct module *mod); 122 void klp_module_going(struct module *mod); 123 124 void klp_update_patch_state(struct task_struct *task); 125 126 #else /* !CONFIG_LIVEPATCH */ 127 128 static inline int klp_module_coming(struct module *mod) { return 0; } 129 static inline void klp_module_going(struct module *mod) {} 130 static inline void klp_update_patch_state(struct task_struct *task) {} 131 132 #endif /* CONFIG_LIVEPATCH */ 133 134 #endif /* _LINUX_LIVEPATCH_H_ */ 135