1439e7271SJoe Lawrence /* 2439e7271SJoe Lawrence * shadow.c - Shadow Variables 3439e7271SJoe Lawrence * 4439e7271SJoe Lawrence * Copyright (C) 2014 Josh Poimboeuf <[email protected]> 5439e7271SJoe Lawrence * Copyright (C) 2014 Seth Jennings <[email protected]> 6439e7271SJoe Lawrence * Copyright (C) 2017 Joe Lawrence <[email protected]> 7439e7271SJoe Lawrence * 8439e7271SJoe Lawrence * This program is free software; you can redistribute it and/or 9439e7271SJoe Lawrence * modify it under the terms of the GNU General Public License 10439e7271SJoe Lawrence * as published by the Free Software Foundation; either version 2 11439e7271SJoe Lawrence * of the License, or (at your option) any later version. 12439e7271SJoe Lawrence * 13439e7271SJoe Lawrence * This program is distributed in the hope that it will be useful, 14439e7271SJoe Lawrence * but WITHOUT ANY WARRANTY; without even the implied warranty of 15439e7271SJoe Lawrence * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16439e7271SJoe Lawrence * GNU General Public License for more details. 17439e7271SJoe Lawrence * 18439e7271SJoe Lawrence * You should have received a copy of the GNU General Public License 19439e7271SJoe Lawrence * along with this program; if not, see <http://www.gnu.org/licenses/>. 20439e7271SJoe Lawrence */ 21439e7271SJoe Lawrence 22439e7271SJoe Lawrence /** 23439e7271SJoe Lawrence * DOC: Shadow variable API concurrency notes: 24439e7271SJoe Lawrence * 25439e7271SJoe Lawrence * The shadow variable API provides a simple relationship between an 26439e7271SJoe Lawrence * <obj, id> pair and a pointer value. It is the responsibility of the 27439e7271SJoe Lawrence * caller to provide any mutual exclusion required of the shadow data. 28439e7271SJoe Lawrence * 29439e7271SJoe Lawrence * Once a shadow variable is attached to its parent object via the 30439e7271SJoe Lawrence * klp_shadow_*alloc() API calls, it is considered live: any subsequent 31439e7271SJoe Lawrence * call to klp_shadow_get() may then return the shadow variable's data 32439e7271SJoe Lawrence * pointer. Callers of klp_shadow_*alloc() should prepare shadow data 33439e7271SJoe Lawrence * accordingly. 34439e7271SJoe Lawrence * 35439e7271SJoe Lawrence * The klp_shadow_*alloc() API calls may allocate memory for new shadow 36439e7271SJoe Lawrence * variable structures. Their implementation does not call kmalloc 37439e7271SJoe Lawrence * inside any spinlocks, but API callers should pass GFP flags according 38439e7271SJoe Lawrence * to their specific needs. 39439e7271SJoe Lawrence * 40439e7271SJoe Lawrence * The klp_shadow_hash is an RCU-enabled hashtable and is safe against 41439e7271SJoe Lawrence * concurrent klp_shadow_free() and klp_shadow_get() operations. 42439e7271SJoe Lawrence */ 43439e7271SJoe Lawrence 44439e7271SJoe Lawrence #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 45439e7271SJoe Lawrence 46439e7271SJoe Lawrence #include <linux/hashtable.h> 47439e7271SJoe Lawrence #include <linux/slab.h> 48439e7271SJoe Lawrence #include <linux/livepatch.h> 49439e7271SJoe Lawrence 50439e7271SJoe Lawrence static DEFINE_HASHTABLE(klp_shadow_hash, 12); 51439e7271SJoe Lawrence 52439e7271SJoe Lawrence /* 53439e7271SJoe Lawrence * klp_shadow_lock provides exclusive access to the klp_shadow_hash and 54439e7271SJoe Lawrence * the shadow variables it references. 55439e7271SJoe Lawrence */ 56439e7271SJoe Lawrence static DEFINE_SPINLOCK(klp_shadow_lock); 57439e7271SJoe Lawrence 58439e7271SJoe Lawrence /** 59439e7271SJoe Lawrence * struct klp_shadow - shadow variable structure 60439e7271SJoe Lawrence * @node: klp_shadow_hash hash table node 61439e7271SJoe Lawrence * @rcu_head: RCU is used to safely free this structure 62439e7271SJoe Lawrence * @obj: pointer to parent object 63439e7271SJoe Lawrence * @id: data identifier 64439e7271SJoe Lawrence * @data: data area 65439e7271SJoe Lawrence */ 66439e7271SJoe Lawrence struct klp_shadow { 67439e7271SJoe Lawrence struct hlist_node node; 68439e7271SJoe Lawrence struct rcu_head rcu_head; 69439e7271SJoe Lawrence void *obj; 70439e7271SJoe Lawrence unsigned long id; 71439e7271SJoe Lawrence char data[]; 72439e7271SJoe Lawrence }; 73439e7271SJoe Lawrence 74439e7271SJoe Lawrence /** 75439e7271SJoe Lawrence * klp_shadow_match() - verify a shadow variable matches given <obj, id> 76439e7271SJoe Lawrence * @shadow: shadow variable to match 77439e7271SJoe Lawrence * @obj: pointer to parent object 78439e7271SJoe Lawrence * @id: data identifier 79439e7271SJoe Lawrence * 80439e7271SJoe Lawrence * Return: true if the shadow variable matches. 81439e7271SJoe Lawrence */ 82439e7271SJoe Lawrence static inline bool klp_shadow_match(struct klp_shadow *shadow, void *obj, 83439e7271SJoe Lawrence unsigned long id) 84439e7271SJoe Lawrence { 85439e7271SJoe Lawrence return shadow->obj == obj && shadow->id == id; 86439e7271SJoe Lawrence } 87439e7271SJoe Lawrence 88439e7271SJoe Lawrence /** 89439e7271SJoe Lawrence * klp_shadow_get() - retrieve a shadow variable data pointer 90439e7271SJoe Lawrence * @obj: pointer to parent object 91439e7271SJoe Lawrence * @id: data identifier 92439e7271SJoe Lawrence * 93439e7271SJoe Lawrence * Return: the shadow variable data element, NULL on failure. 94439e7271SJoe Lawrence */ 95439e7271SJoe Lawrence void *klp_shadow_get(void *obj, unsigned long id) 96439e7271SJoe Lawrence { 97439e7271SJoe Lawrence struct klp_shadow *shadow; 98439e7271SJoe Lawrence 99439e7271SJoe Lawrence rcu_read_lock(); 100439e7271SJoe Lawrence 101439e7271SJoe Lawrence hash_for_each_possible_rcu(klp_shadow_hash, shadow, node, 102439e7271SJoe Lawrence (unsigned long)obj) { 103439e7271SJoe Lawrence 104439e7271SJoe Lawrence if (klp_shadow_match(shadow, obj, id)) { 105439e7271SJoe Lawrence rcu_read_unlock(); 106439e7271SJoe Lawrence return shadow->data; 107439e7271SJoe Lawrence } 108439e7271SJoe Lawrence } 109439e7271SJoe Lawrence 110439e7271SJoe Lawrence rcu_read_unlock(); 111439e7271SJoe Lawrence 112439e7271SJoe Lawrence return NULL; 113439e7271SJoe Lawrence } 114439e7271SJoe Lawrence EXPORT_SYMBOL_GPL(klp_shadow_get); 115439e7271SJoe Lawrence 116*e91c2518SPetr Mladek static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, 117*e91c2518SPetr Mladek size_t size, gfp_t gfp_flags, 118*e91c2518SPetr Mladek klp_shadow_ctor_t ctor, void *ctor_data, 119*e91c2518SPetr Mladek bool warn_on_exist) 120439e7271SJoe Lawrence { 121439e7271SJoe Lawrence struct klp_shadow *new_shadow; 122439e7271SJoe Lawrence void *shadow_data; 123439e7271SJoe Lawrence unsigned long flags; 124439e7271SJoe Lawrence 125439e7271SJoe Lawrence /* Check if the shadow variable already exists */ 126439e7271SJoe Lawrence shadow_data = klp_shadow_get(obj, id); 127439e7271SJoe Lawrence if (shadow_data) 128439e7271SJoe Lawrence goto exists; 129439e7271SJoe Lawrence 130*e91c2518SPetr Mladek /* 131*e91c2518SPetr Mladek * Allocate a new shadow variable. Fill it with zeroes by default. 132*e91c2518SPetr Mladek * More complex setting can be done by @ctor function. But it is 133*e91c2518SPetr Mladek * called only when the buffer is really used (under klp_shadow_lock). 134*e91c2518SPetr Mladek */ 135439e7271SJoe Lawrence new_shadow = kzalloc(size + sizeof(*new_shadow), gfp_flags); 136439e7271SJoe Lawrence if (!new_shadow) 137439e7271SJoe Lawrence return NULL; 138439e7271SJoe Lawrence 139439e7271SJoe Lawrence /* Look for <obj, id> again under the lock */ 140439e7271SJoe Lawrence spin_lock_irqsave(&klp_shadow_lock, flags); 141439e7271SJoe Lawrence shadow_data = klp_shadow_get(obj, id); 142439e7271SJoe Lawrence if (unlikely(shadow_data)) { 143439e7271SJoe Lawrence /* 144439e7271SJoe Lawrence * Shadow variable was found, throw away speculative 145439e7271SJoe Lawrence * allocation. 146439e7271SJoe Lawrence */ 147439e7271SJoe Lawrence spin_unlock_irqrestore(&klp_shadow_lock, flags); 148439e7271SJoe Lawrence kfree(new_shadow); 149439e7271SJoe Lawrence goto exists; 150439e7271SJoe Lawrence } 151439e7271SJoe Lawrence 152*e91c2518SPetr Mladek new_shadow->obj = obj; 153*e91c2518SPetr Mladek new_shadow->id = id; 154*e91c2518SPetr Mladek 155*e91c2518SPetr Mladek if (ctor) { 156*e91c2518SPetr Mladek int err; 157*e91c2518SPetr Mladek 158*e91c2518SPetr Mladek err = ctor(obj, new_shadow->data, ctor_data); 159*e91c2518SPetr Mladek if (err) { 160*e91c2518SPetr Mladek spin_unlock_irqrestore(&klp_shadow_lock, flags); 161*e91c2518SPetr Mladek kfree(new_shadow); 162*e91c2518SPetr Mladek pr_err("Failed to construct shadow variable <%p, %lx> (%d)\n", 163*e91c2518SPetr Mladek obj, id, err); 164*e91c2518SPetr Mladek return NULL; 165*e91c2518SPetr Mladek } 166*e91c2518SPetr Mladek } 167*e91c2518SPetr Mladek 168439e7271SJoe Lawrence /* No <obj, id> found, so attach the newly allocated one */ 169439e7271SJoe Lawrence hash_add_rcu(klp_shadow_hash, &new_shadow->node, 170439e7271SJoe Lawrence (unsigned long)new_shadow->obj); 171439e7271SJoe Lawrence spin_unlock_irqrestore(&klp_shadow_lock, flags); 172439e7271SJoe Lawrence 173439e7271SJoe Lawrence return new_shadow->data; 174439e7271SJoe Lawrence 175439e7271SJoe Lawrence exists: 176439e7271SJoe Lawrence if (warn_on_exist) { 177439e7271SJoe Lawrence WARN(1, "Duplicate shadow variable <%p, %lx>\n", obj, id); 178439e7271SJoe Lawrence return NULL; 179439e7271SJoe Lawrence } 180439e7271SJoe Lawrence 181439e7271SJoe Lawrence return shadow_data; 182439e7271SJoe Lawrence } 183439e7271SJoe Lawrence 184439e7271SJoe Lawrence /** 185439e7271SJoe Lawrence * klp_shadow_alloc() - allocate and add a new shadow variable 186439e7271SJoe Lawrence * @obj: pointer to parent object 187439e7271SJoe Lawrence * @id: data identifier 188439e7271SJoe Lawrence * @size: size of attached data 189439e7271SJoe Lawrence * @gfp_flags: GFP mask for allocation 190*e91c2518SPetr Mladek * @ctor: custom constructor to initialize the shadow data (optional) 191*e91c2518SPetr Mladek * @ctor_data: pointer to any data needed by @ctor (optional) 192439e7271SJoe Lawrence * 193*e91c2518SPetr Mladek * Allocates @size bytes for new shadow variable data using @gfp_flags. 194*e91c2518SPetr Mladek * The data are zeroed by default. They are further initialized by @ctor 195*e91c2518SPetr Mladek * function if it is not NULL. The new shadow variable is then added 196*e91c2518SPetr Mladek * to the global hashtable. 197439e7271SJoe Lawrence * 198*e91c2518SPetr Mladek * If an existing <obj, id> shadow variable can be found, this routine will 199*e91c2518SPetr Mladek * issue a WARN, exit early and return NULL. 200*e91c2518SPetr Mladek * 201*e91c2518SPetr Mladek * This function guarantees that the constructor function is called only when 202*e91c2518SPetr Mladek * the variable did not exist before. The cost is that @ctor is called 203*e91c2518SPetr Mladek * in atomic context under a spin lock. 204439e7271SJoe Lawrence * 205439e7271SJoe Lawrence * Return: the shadow variable data element, NULL on duplicate or 206439e7271SJoe Lawrence * failure. 207439e7271SJoe Lawrence */ 208*e91c2518SPetr Mladek void *klp_shadow_alloc(void *obj, unsigned long id, 209*e91c2518SPetr Mladek size_t size, gfp_t gfp_flags, 210*e91c2518SPetr Mladek klp_shadow_ctor_t ctor, void *ctor_data) 211439e7271SJoe Lawrence { 212*e91c2518SPetr Mladek return __klp_shadow_get_or_alloc(obj, id, size, gfp_flags, 213*e91c2518SPetr Mladek ctor, ctor_data, true); 214439e7271SJoe Lawrence } 215439e7271SJoe Lawrence EXPORT_SYMBOL_GPL(klp_shadow_alloc); 216439e7271SJoe Lawrence 217439e7271SJoe Lawrence /** 218439e7271SJoe Lawrence * klp_shadow_get_or_alloc() - get existing or allocate a new shadow variable 219439e7271SJoe Lawrence * @obj: pointer to parent object 220439e7271SJoe Lawrence * @id: data identifier 221439e7271SJoe Lawrence * @size: size of attached data 222439e7271SJoe Lawrence * @gfp_flags: GFP mask for allocation 223*e91c2518SPetr Mladek * @ctor: custom constructor to initialize the shadow data (optional) 224*e91c2518SPetr Mladek * @ctor_data: pointer to any data needed by @ctor (optional) 225439e7271SJoe Lawrence * 226439e7271SJoe Lawrence * Returns a pointer to existing shadow data if an <obj, id> shadow 227439e7271SJoe Lawrence * variable is already present. Otherwise, it creates a new shadow 228439e7271SJoe Lawrence * variable like klp_shadow_alloc(). 229439e7271SJoe Lawrence * 230*e91c2518SPetr Mladek * This function guarantees that only one shadow variable exists with the given 231*e91c2518SPetr Mladek * @id for the given @obj. It also guarantees that the constructor function 232*e91c2518SPetr Mladek * will be called only when the variable did not exist before. The cost is 233*e91c2518SPetr Mladek * that @ctor is called in atomic context under a spin lock. 234439e7271SJoe Lawrence * 235439e7271SJoe Lawrence * Return: the shadow variable data element, NULL on failure. 236439e7271SJoe Lawrence */ 237*e91c2518SPetr Mladek void *klp_shadow_get_or_alloc(void *obj, unsigned long id, 238*e91c2518SPetr Mladek size_t size, gfp_t gfp_flags, 239*e91c2518SPetr Mladek klp_shadow_ctor_t ctor, void *ctor_data) 240439e7271SJoe Lawrence { 241*e91c2518SPetr Mladek return __klp_shadow_get_or_alloc(obj, id, size, gfp_flags, 242*e91c2518SPetr Mladek ctor, ctor_data, false); 243439e7271SJoe Lawrence } 244439e7271SJoe Lawrence EXPORT_SYMBOL_GPL(klp_shadow_get_or_alloc); 245439e7271SJoe Lawrence 246439e7271SJoe Lawrence /** 247439e7271SJoe Lawrence * klp_shadow_free() - detach and free a <obj, id> shadow variable 248439e7271SJoe Lawrence * @obj: pointer to parent object 249439e7271SJoe Lawrence * @id: data identifier 250439e7271SJoe Lawrence * 251439e7271SJoe Lawrence * This function releases the memory for this <obj, id> shadow variable 252439e7271SJoe Lawrence * instance, callers should stop referencing it accordingly. 253439e7271SJoe Lawrence */ 254439e7271SJoe Lawrence void klp_shadow_free(void *obj, unsigned long id) 255439e7271SJoe Lawrence { 256439e7271SJoe Lawrence struct klp_shadow *shadow; 257439e7271SJoe Lawrence unsigned long flags; 258439e7271SJoe Lawrence 259439e7271SJoe Lawrence spin_lock_irqsave(&klp_shadow_lock, flags); 260439e7271SJoe Lawrence 261439e7271SJoe Lawrence /* Delete <obj, id> from hash */ 262439e7271SJoe Lawrence hash_for_each_possible(klp_shadow_hash, shadow, node, 263439e7271SJoe Lawrence (unsigned long)obj) { 264439e7271SJoe Lawrence 265439e7271SJoe Lawrence if (klp_shadow_match(shadow, obj, id)) { 266439e7271SJoe Lawrence hash_del_rcu(&shadow->node); 267439e7271SJoe Lawrence kfree_rcu(shadow, rcu_head); 268439e7271SJoe Lawrence break; 269439e7271SJoe Lawrence } 270439e7271SJoe Lawrence } 271439e7271SJoe Lawrence 272439e7271SJoe Lawrence spin_unlock_irqrestore(&klp_shadow_lock, flags); 273439e7271SJoe Lawrence } 274439e7271SJoe Lawrence EXPORT_SYMBOL_GPL(klp_shadow_free); 275439e7271SJoe Lawrence 276439e7271SJoe Lawrence /** 277439e7271SJoe Lawrence * klp_shadow_free_all() - detach and free all <*, id> shadow variables 278439e7271SJoe Lawrence * @id: data identifier 279439e7271SJoe Lawrence * 280439e7271SJoe Lawrence * This function releases the memory for all <*, id> shadow variable 281439e7271SJoe Lawrence * instances, callers should stop referencing them accordingly. 282439e7271SJoe Lawrence */ 283439e7271SJoe Lawrence void klp_shadow_free_all(unsigned long id) 284439e7271SJoe Lawrence { 285439e7271SJoe Lawrence struct klp_shadow *shadow; 286439e7271SJoe Lawrence unsigned long flags; 287439e7271SJoe Lawrence int i; 288439e7271SJoe Lawrence 289439e7271SJoe Lawrence spin_lock_irqsave(&klp_shadow_lock, flags); 290439e7271SJoe Lawrence 291439e7271SJoe Lawrence /* Delete all <*, id> from hash */ 292439e7271SJoe Lawrence hash_for_each(klp_shadow_hash, i, shadow, node) { 293439e7271SJoe Lawrence if (klp_shadow_match(shadow, shadow->obj, id)) { 294439e7271SJoe Lawrence hash_del_rcu(&shadow->node); 295439e7271SJoe Lawrence kfree_rcu(shadow, rcu_head); 296439e7271SJoe Lawrence } 297439e7271SJoe Lawrence } 298439e7271SJoe Lawrence 299439e7271SJoe Lawrence spin_unlock_irqrestore(&klp_shadow_lock, flags); 300439e7271SJoe Lawrence } 301439e7271SJoe Lawrence EXPORT_SYMBOL_GPL(klp_shadow_free_all); 302