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