| .. | .. | 
|---|
|  | 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | 
|---|
| 1 | 2 | /* | 
|---|
| 2 | 3 | * core.c - Kernel Live Patching Core | 
|---|
| 3 | 4 | * | 
|---|
| 4 | 5 | * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com> | 
|---|
| 5 | 6 | * 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 | 7 | */ | 
|---|
| 20 | 8 |  | 
|---|
| 21 | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 
|---|
| .. | .. | 
|---|
| 34 | 22 | #include <asm/cacheflush.h> | 
|---|
| 35 | 23 | #include "core.h" | 
|---|
| 36 | 24 | #include "patch.h" | 
|---|
|  | 25 | +#include "state.h" | 
|---|
| 37 | 26 | #include "transition.h" | 
|---|
| 38 | 27 |  | 
|---|
| 39 | 28 | /* | 
|---|
| .. | .. | 
|---|
| 46 | 35 | */ | 
|---|
| 47 | 36 | DEFINE_MUTEX(klp_mutex); | 
|---|
| 48 | 37 |  | 
|---|
| 49 |  | -static LIST_HEAD(klp_patches); | 
|---|
|  | 38 | +/* | 
|---|
|  | 39 | + * Actively used patches: enabled or in transition. Note that replaced | 
|---|
|  | 40 | + * or disabled patches are not listed even though the related kernel | 
|---|
|  | 41 | + * module still can be loaded. | 
|---|
|  | 42 | + */ | 
|---|
|  | 43 | +LIST_HEAD(klp_patches); | 
|---|
| 50 | 44 |  | 
|---|
| 51 | 45 | static struct kobject *klp_root_kobj; | 
|---|
| 52 | 46 |  | 
|---|
| .. | .. | 
|---|
| 83 | 77 | mutex_unlock(&module_mutex); | 
|---|
| 84 | 78 | } | 
|---|
| 85 | 79 |  | 
|---|
| 86 |  | -static bool klp_is_patch_registered(struct klp_patch *patch) | 
|---|
| 87 |  | -{ | 
|---|
| 88 |  | -	struct klp_patch *mypatch; | 
|---|
| 89 |  | - | 
|---|
| 90 |  | -	list_for_each_entry(mypatch, &klp_patches, list) | 
|---|
| 91 |  | -		if (mypatch == patch) | 
|---|
| 92 |  | -			return true; | 
|---|
| 93 |  | - | 
|---|
| 94 |  | -	return false; | 
|---|
| 95 |  | -} | 
|---|
| 96 |  | - | 
|---|
| 97 | 80 | static bool klp_initialized(void) | 
|---|
| 98 | 81 | { | 
|---|
| 99 | 82 | return !!klp_root_kobj; | 
|---|
|  | 83 | +} | 
|---|
|  | 84 | + | 
|---|
|  | 85 | +static struct klp_func *klp_find_func(struct klp_object *obj, | 
|---|
|  | 86 | +				      struct klp_func *old_func) | 
|---|
|  | 87 | +{ | 
|---|
|  | 88 | +	struct klp_func *func; | 
|---|
|  | 89 | + | 
|---|
|  | 90 | +	klp_for_each_func(obj, func) { | 
|---|
|  | 91 | +		if ((strcmp(old_func->old_name, func->old_name) == 0) && | 
|---|
|  | 92 | +		    (old_func->old_sympos == func->old_sympos)) { | 
|---|
|  | 93 | +			return func; | 
|---|
|  | 94 | +		} | 
|---|
|  | 95 | +	} | 
|---|
|  | 96 | + | 
|---|
|  | 97 | +	return NULL; | 
|---|
|  | 98 | +} | 
|---|
|  | 99 | + | 
|---|
|  | 100 | +static struct klp_object *klp_find_object(struct klp_patch *patch, | 
|---|
|  | 101 | +					  struct klp_object *old_obj) | 
|---|
|  | 102 | +{ | 
|---|
|  | 103 | +	struct klp_object *obj; | 
|---|
|  | 104 | + | 
|---|
|  | 105 | +	klp_for_each_object(patch, obj) { | 
|---|
|  | 106 | +		if (klp_is_module(old_obj)) { | 
|---|
|  | 107 | +			if (klp_is_module(obj) && | 
|---|
|  | 108 | +			    strcmp(old_obj->name, obj->name) == 0) { | 
|---|
|  | 109 | +				return obj; | 
|---|
|  | 110 | +			} | 
|---|
|  | 111 | +		} else if (!klp_is_module(obj)) { | 
|---|
|  | 112 | +			return obj; | 
|---|
|  | 113 | +		} | 
|---|
|  | 114 | +	} | 
|---|
|  | 115 | + | 
|---|
|  | 116 | +	return NULL; | 
|---|
| 100 | 117 | } | 
|---|
| 101 | 118 |  | 
|---|
| 102 | 119 | struct klp_find_arg { | 
|---|
| .. | .. | 
|---|
| 174 | 191 | return -EINVAL; | 
|---|
| 175 | 192 | } | 
|---|
| 176 | 193 |  | 
|---|
| 177 |  | -static int klp_resolve_symbols(Elf_Shdr *relasec, struct module *pmod) | 
|---|
|  | 194 | +static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab, | 
|---|
|  | 195 | +			       unsigned int symndx, Elf_Shdr *relasec, | 
|---|
|  | 196 | +			       const char *sec_objname) | 
|---|
| 178 | 197 | { | 
|---|
| 179 |  | -	int i, cnt, vmlinux, ret; | 
|---|
| 180 |  | -	char objname[MODULE_NAME_LEN]; | 
|---|
| 181 |  | -	char symname[KSYM_NAME_LEN]; | 
|---|
| 182 |  | -	char *strtab = pmod->core_kallsyms.strtab; | 
|---|
|  | 198 | +	int i, cnt, ret; | 
|---|
|  | 199 | +	char sym_objname[MODULE_NAME_LEN]; | 
|---|
|  | 200 | +	char sym_name[KSYM_NAME_LEN]; | 
|---|
| 183 | 201 | Elf_Rela *relas; | 
|---|
| 184 | 202 | Elf_Sym *sym; | 
|---|
| 185 | 203 | unsigned long sympos, addr; | 
|---|
|  | 204 | +	bool sym_vmlinux; | 
|---|
|  | 205 | +	bool sec_vmlinux = !strcmp(sec_objname, "vmlinux"); | 
|---|
| 186 | 206 |  | 
|---|
| 187 | 207 | /* | 
|---|
| 188 |  | -	 * Since the field widths for objname and symname in the sscanf() | 
|---|
|  | 208 | +	 * Since the field widths for sym_objname and sym_name in the sscanf() | 
|---|
| 189 | 209 | * call are hard-coded and correspond to MODULE_NAME_LEN and | 
|---|
| 190 | 210 | * KSYM_NAME_LEN respectively, we must make sure that MODULE_NAME_LEN | 
|---|
| 191 | 211 | * and KSYM_NAME_LEN have the values we expect them to have. | 
|---|
| .. | .. | 
|---|
| 199 | 219 | relas = (Elf_Rela *) relasec->sh_addr; | 
|---|
| 200 | 220 | /* For each rela in this klp relocation section */ | 
|---|
| 201 | 221 | for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) { | 
|---|
| 202 |  | -		sym = pmod->core_kallsyms.symtab + ELF_R_SYM(relas[i].r_info); | 
|---|
|  | 222 | +		sym = (Elf_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info); | 
|---|
| 203 | 223 | if (sym->st_shndx != SHN_LIVEPATCH) { | 
|---|
| 204 | 224 | pr_err("symbol %s is not marked as a livepatch symbol\n", | 
|---|
| 205 | 225 | strtab + sym->st_name); | 
|---|
| 206 | 226 | return -EINVAL; | 
|---|
| 207 | 227 | } | 
|---|
| 208 | 228 |  | 
|---|
| 209 |  | -		/* Format: .klp.sym.objname.symname,sympos */ | 
|---|
|  | 229 | +		/* Format: .klp.sym.sym_objname.sym_name,sympos */ | 
|---|
| 210 | 230 | cnt = sscanf(strtab + sym->st_name, | 
|---|
| 211 | 231 | ".klp.sym.%55[^.].%127[^,],%lu", | 
|---|
| 212 |  | -			     objname, symname, &sympos); | 
|---|
|  | 232 | +			     sym_objname, sym_name, &sympos); | 
|---|
| 213 | 233 | if (cnt != 3) { | 
|---|
| 214 | 234 | pr_err("symbol %s has an incorrectly formatted name\n", | 
|---|
| 215 | 235 | strtab + sym->st_name); | 
|---|
| 216 | 236 | return -EINVAL; | 
|---|
| 217 | 237 | } | 
|---|
| 218 | 238 |  | 
|---|
|  | 239 | +		sym_vmlinux = !strcmp(sym_objname, "vmlinux"); | 
|---|
|  | 240 | + | 
|---|
|  | 241 | +		/* | 
|---|
|  | 242 | +		 * Prevent module-specific KLP rela sections from referencing | 
|---|
|  | 243 | +		 * vmlinux symbols.  This helps prevent ordering issues with | 
|---|
|  | 244 | +		 * module special section initializations.  Presumably such | 
|---|
|  | 245 | +		 * symbols are exported and normal relas can be used instead. | 
|---|
|  | 246 | +		 */ | 
|---|
|  | 247 | +		if (!sec_vmlinux && sym_vmlinux) { | 
|---|
|  | 248 | +			pr_err("invalid access to vmlinux symbol '%s' from module-specific livepatch relocation section", | 
|---|
|  | 249 | +			       sym_name); | 
|---|
|  | 250 | +			return -EINVAL; | 
|---|
|  | 251 | +		} | 
|---|
|  | 252 | + | 
|---|
| 219 | 253 | /* klp_find_object_symbol() treats a NULL objname as vmlinux */ | 
|---|
| 220 |  | -		vmlinux = !strcmp(objname, "vmlinux"); | 
|---|
| 221 |  | -		ret = klp_find_object_symbol(vmlinux ? NULL : objname, | 
|---|
| 222 |  | -					     symname, sympos, &addr); | 
|---|
|  | 254 | +		ret = klp_find_object_symbol(sym_vmlinux ? NULL : sym_objname, | 
|---|
|  | 255 | +					     sym_name, sympos, &addr); | 
|---|
| 223 | 256 | if (ret) | 
|---|
| 224 | 257 | return ret; | 
|---|
| 225 | 258 |  | 
|---|
| .. | .. | 
|---|
| 229 | 262 | return 0; | 
|---|
| 230 | 263 | } | 
|---|
| 231 | 264 |  | 
|---|
| 232 |  | -static int klp_write_object_relocations(struct module *pmod, | 
|---|
| 233 |  | -					struct klp_object *obj) | 
|---|
|  | 265 | +/* | 
|---|
|  | 266 | + * At a high-level, there are two types of klp relocation sections: those which | 
|---|
|  | 267 | + * reference symbols which live in vmlinux; and those which reference symbols | 
|---|
|  | 268 | + * which live in other modules.  This function is called for both types: | 
|---|
|  | 269 | + * | 
|---|
|  | 270 | + * 1) When a klp module itself loads, the module code calls this function to | 
|---|
|  | 271 | + *    write vmlinux-specific klp relocations (.klp.rela.vmlinux.* sections). | 
|---|
|  | 272 | + *    These relocations are written to the klp module text to allow the patched | 
|---|
|  | 273 | + *    code/data to reference unexported vmlinux symbols.  They're written as | 
|---|
|  | 274 | + *    early as possible to ensure that other module init code (.e.g., | 
|---|
|  | 275 | + *    jump_label_apply_nops) can access any unexported vmlinux symbols which | 
|---|
|  | 276 | + *    might be referenced by the klp module's special sections. | 
|---|
|  | 277 | + * | 
|---|
|  | 278 | + * 2) When a to-be-patched module loads -- or is already loaded when a | 
|---|
|  | 279 | + *    corresponding klp module loads -- klp code calls this function to write | 
|---|
|  | 280 | + *    module-specific klp relocations (.klp.rela.{module}.* sections).  These | 
|---|
|  | 281 | + *    are written to the klp module text to allow the patched code/data to | 
|---|
|  | 282 | + *    reference symbols which live in the to-be-patched module or one of its | 
|---|
|  | 283 | + *    module dependencies.  Exported symbols are supported, in addition to | 
|---|
|  | 284 | + *    unexported symbols, in order to enable late module patching, which allows | 
|---|
|  | 285 | + *    the to-be-patched module to be loaded and patched sometime *after* the | 
|---|
|  | 286 | + *    klp module is loaded. | 
|---|
|  | 287 | + */ | 
|---|
|  | 288 | +int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs, | 
|---|
|  | 289 | +			     const char *shstrtab, const char *strtab, | 
|---|
|  | 290 | +			     unsigned int symndx, unsigned int secndx, | 
|---|
|  | 291 | +			     const char *objname) | 
|---|
| 234 | 292 | { | 
|---|
| 235 |  | -	int i, cnt, ret = 0; | 
|---|
| 236 |  | -	const char *objname, *secname; | 
|---|
|  | 293 | +	int cnt, ret; | 
|---|
| 237 | 294 | char sec_objname[MODULE_NAME_LEN]; | 
|---|
| 238 |  | -	Elf_Shdr *sec; | 
|---|
|  | 295 | +	Elf_Shdr *sec = sechdrs + secndx; | 
|---|
| 239 | 296 |  | 
|---|
| 240 |  | -	if (WARN_ON(!klp_is_object_loaded(obj))) | 
|---|
|  | 297 | +	/* | 
|---|
|  | 298 | +	 * Format: .klp.rela.sec_objname.section_name | 
|---|
|  | 299 | +	 * See comment in klp_resolve_symbols() for an explanation | 
|---|
|  | 300 | +	 * of the selected field width value. | 
|---|
|  | 301 | +	 */ | 
|---|
|  | 302 | +	cnt = sscanf(shstrtab + sec->sh_name, ".klp.rela.%55[^.]", | 
|---|
|  | 303 | +		     sec_objname); | 
|---|
|  | 304 | +	if (cnt != 1) { | 
|---|
|  | 305 | +		pr_err("section %s has an incorrectly formatted name\n", | 
|---|
|  | 306 | +		       shstrtab + sec->sh_name); | 
|---|
|  | 307 | +		return -EINVAL; | 
|---|
|  | 308 | +	} | 
|---|
|  | 309 | + | 
|---|
|  | 310 | +	if (strcmp(objname ? objname : "vmlinux", sec_objname)) | 
|---|
|  | 311 | +		return 0; | 
|---|
|  | 312 | + | 
|---|
|  | 313 | +	ret = klp_resolve_symbols(sechdrs, strtab, symndx, sec, sec_objname); | 
|---|
|  | 314 | +	if (ret) | 
|---|
|  | 315 | +		return ret; | 
|---|
|  | 316 | + | 
|---|
|  | 317 | +	return apply_relocate_add(sechdrs, strtab, symndx, secndx, pmod); | 
|---|
|  | 318 | +} | 
|---|
|  | 319 | + | 
|---|
|  | 320 | +/* | 
|---|
|  | 321 | + * Sysfs Interface | 
|---|
|  | 322 | + * | 
|---|
|  | 323 | + * /sys/kernel/livepatch | 
|---|
|  | 324 | + * /sys/kernel/livepatch/<patch> | 
|---|
|  | 325 | + * /sys/kernel/livepatch/<patch>/enabled | 
|---|
|  | 326 | + * /sys/kernel/livepatch/<patch>/transition | 
|---|
|  | 327 | + * /sys/kernel/livepatch/<patch>/force | 
|---|
|  | 328 | + * /sys/kernel/livepatch/<patch>/<object> | 
|---|
|  | 329 | + * /sys/kernel/livepatch/<patch>/<object>/<function,sympos> | 
|---|
|  | 330 | + */ | 
|---|
|  | 331 | +static int __klp_disable_patch(struct klp_patch *patch); | 
|---|
|  | 332 | + | 
|---|
|  | 333 | +static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, | 
|---|
|  | 334 | +			     const char *buf, size_t count) | 
|---|
|  | 335 | +{ | 
|---|
|  | 336 | +	struct klp_patch *patch; | 
|---|
|  | 337 | +	int ret; | 
|---|
|  | 338 | +	bool enabled; | 
|---|
|  | 339 | + | 
|---|
|  | 340 | +	ret = kstrtobool(buf, &enabled); | 
|---|
|  | 341 | +	if (ret) | 
|---|
|  | 342 | +		return ret; | 
|---|
|  | 343 | + | 
|---|
|  | 344 | +	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
|  | 345 | + | 
|---|
|  | 346 | +	mutex_lock(&klp_mutex); | 
|---|
|  | 347 | + | 
|---|
|  | 348 | +	if (patch->enabled == enabled) { | 
|---|
|  | 349 | +		/* already in requested state */ | 
|---|
|  | 350 | +		ret = -EINVAL; | 
|---|
|  | 351 | +		goto out; | 
|---|
|  | 352 | +	} | 
|---|
|  | 353 | + | 
|---|
|  | 354 | +	/* | 
|---|
|  | 355 | +	 * Allow to reverse a pending transition in both ways. It might be | 
|---|
|  | 356 | +	 * necessary to complete the transition without forcing and breaking | 
|---|
|  | 357 | +	 * the system integrity. | 
|---|
|  | 358 | +	 * | 
|---|
|  | 359 | +	 * Do not allow to re-enable a disabled patch. | 
|---|
|  | 360 | +	 */ | 
|---|
|  | 361 | +	if (patch == klp_transition_patch) | 
|---|
|  | 362 | +		klp_reverse_transition(); | 
|---|
|  | 363 | +	else if (!enabled) | 
|---|
|  | 364 | +		ret = __klp_disable_patch(patch); | 
|---|
|  | 365 | +	else | 
|---|
|  | 366 | +		ret = -EINVAL; | 
|---|
|  | 367 | + | 
|---|
|  | 368 | +out: | 
|---|
|  | 369 | +	mutex_unlock(&klp_mutex); | 
|---|
|  | 370 | + | 
|---|
|  | 371 | +	if (ret) | 
|---|
|  | 372 | +		return ret; | 
|---|
|  | 373 | +	return count; | 
|---|
|  | 374 | +} | 
|---|
|  | 375 | + | 
|---|
|  | 376 | +static ssize_t enabled_show(struct kobject *kobj, | 
|---|
|  | 377 | +			    struct kobj_attribute *attr, char *buf) | 
|---|
|  | 378 | +{ | 
|---|
|  | 379 | +	struct klp_patch *patch; | 
|---|
|  | 380 | + | 
|---|
|  | 381 | +	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
|  | 382 | +	return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->enabled); | 
|---|
|  | 383 | +} | 
|---|
|  | 384 | + | 
|---|
|  | 385 | +static ssize_t transition_show(struct kobject *kobj, | 
|---|
|  | 386 | +			       struct kobj_attribute *attr, char *buf) | 
|---|
|  | 387 | +{ | 
|---|
|  | 388 | +	struct klp_patch *patch; | 
|---|
|  | 389 | + | 
|---|
|  | 390 | +	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
|  | 391 | +	return snprintf(buf, PAGE_SIZE-1, "%d\n", | 
|---|
|  | 392 | +			patch == klp_transition_patch); | 
|---|
|  | 393 | +} | 
|---|
|  | 394 | + | 
|---|
|  | 395 | +static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr, | 
|---|
|  | 396 | +			   const char *buf, size_t count) | 
|---|
|  | 397 | +{ | 
|---|
|  | 398 | +	struct klp_patch *patch; | 
|---|
|  | 399 | +	int ret; | 
|---|
|  | 400 | +	bool val; | 
|---|
|  | 401 | + | 
|---|
|  | 402 | +	ret = kstrtobool(buf, &val); | 
|---|
|  | 403 | +	if (ret) | 
|---|
|  | 404 | +		return ret; | 
|---|
|  | 405 | + | 
|---|
|  | 406 | +	if (!val) | 
|---|
|  | 407 | +		return count; | 
|---|
|  | 408 | + | 
|---|
|  | 409 | +	mutex_lock(&klp_mutex); | 
|---|
|  | 410 | + | 
|---|
|  | 411 | +	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
|  | 412 | +	if (patch != klp_transition_patch) { | 
|---|
|  | 413 | +		mutex_unlock(&klp_mutex); | 
|---|
|  | 414 | +		return -EINVAL; | 
|---|
|  | 415 | +	} | 
|---|
|  | 416 | + | 
|---|
|  | 417 | +	klp_force_transition(); | 
|---|
|  | 418 | + | 
|---|
|  | 419 | +	mutex_unlock(&klp_mutex); | 
|---|
|  | 420 | + | 
|---|
|  | 421 | +	return count; | 
|---|
|  | 422 | +} | 
|---|
|  | 423 | + | 
|---|
|  | 424 | +static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); | 
|---|
|  | 425 | +static struct kobj_attribute transition_kobj_attr = __ATTR_RO(transition); | 
|---|
|  | 426 | +static struct kobj_attribute force_kobj_attr = __ATTR_WO(force); | 
|---|
|  | 427 | +static struct attribute *klp_patch_attrs[] = { | 
|---|
|  | 428 | +	&enabled_kobj_attr.attr, | 
|---|
|  | 429 | +	&transition_kobj_attr.attr, | 
|---|
|  | 430 | +	&force_kobj_attr.attr, | 
|---|
|  | 431 | +	NULL | 
|---|
|  | 432 | +}; | 
|---|
|  | 433 | +ATTRIBUTE_GROUPS(klp_patch); | 
|---|
|  | 434 | + | 
|---|
|  | 435 | +static void klp_free_object_dynamic(struct klp_object *obj) | 
|---|
|  | 436 | +{ | 
|---|
|  | 437 | +	kfree(obj->name); | 
|---|
|  | 438 | +	kfree(obj); | 
|---|
|  | 439 | +} | 
|---|
|  | 440 | + | 
|---|
|  | 441 | +static void klp_init_func_early(struct klp_object *obj, | 
|---|
|  | 442 | +				struct klp_func *func); | 
|---|
|  | 443 | +static void klp_init_object_early(struct klp_patch *patch, | 
|---|
|  | 444 | +				  struct klp_object *obj); | 
|---|
|  | 445 | + | 
|---|
|  | 446 | +static struct klp_object *klp_alloc_object_dynamic(const char *name, | 
|---|
|  | 447 | +						   struct klp_patch *patch) | 
|---|
|  | 448 | +{ | 
|---|
|  | 449 | +	struct klp_object *obj; | 
|---|
|  | 450 | + | 
|---|
|  | 451 | +	obj = kzalloc(sizeof(*obj), GFP_KERNEL); | 
|---|
|  | 452 | +	if (!obj) | 
|---|
|  | 453 | +		return NULL; | 
|---|
|  | 454 | + | 
|---|
|  | 455 | +	if (name) { | 
|---|
|  | 456 | +		obj->name = kstrdup(name, GFP_KERNEL); | 
|---|
|  | 457 | +		if (!obj->name) { | 
|---|
|  | 458 | +			kfree(obj); | 
|---|
|  | 459 | +			return NULL; | 
|---|
|  | 460 | +		} | 
|---|
|  | 461 | +	} | 
|---|
|  | 462 | + | 
|---|
|  | 463 | +	klp_init_object_early(patch, obj); | 
|---|
|  | 464 | +	obj->dynamic = true; | 
|---|
|  | 465 | + | 
|---|
|  | 466 | +	return obj; | 
|---|
|  | 467 | +} | 
|---|
|  | 468 | + | 
|---|
|  | 469 | +static void klp_free_func_nop(struct klp_func *func) | 
|---|
|  | 470 | +{ | 
|---|
|  | 471 | +	kfree(func->old_name); | 
|---|
|  | 472 | +	kfree(func); | 
|---|
|  | 473 | +} | 
|---|
|  | 474 | + | 
|---|
|  | 475 | +static struct klp_func *klp_alloc_func_nop(struct klp_func *old_func, | 
|---|
|  | 476 | +					   struct klp_object *obj) | 
|---|
|  | 477 | +{ | 
|---|
|  | 478 | +	struct klp_func *func; | 
|---|
|  | 479 | + | 
|---|
|  | 480 | +	func = kzalloc(sizeof(*func), GFP_KERNEL); | 
|---|
|  | 481 | +	if (!func) | 
|---|
|  | 482 | +		return NULL; | 
|---|
|  | 483 | + | 
|---|
|  | 484 | +	if (old_func->old_name) { | 
|---|
|  | 485 | +		func->old_name = kstrdup(old_func->old_name, GFP_KERNEL); | 
|---|
|  | 486 | +		if (!func->old_name) { | 
|---|
|  | 487 | +			kfree(func); | 
|---|
|  | 488 | +			return NULL; | 
|---|
|  | 489 | +		} | 
|---|
|  | 490 | +	} | 
|---|
|  | 491 | + | 
|---|
|  | 492 | +	klp_init_func_early(obj, func); | 
|---|
|  | 493 | +	/* | 
|---|
|  | 494 | +	 * func->new_func is same as func->old_func. These addresses are | 
|---|
|  | 495 | +	 * set when the object is loaded, see klp_init_object_loaded(). | 
|---|
|  | 496 | +	 */ | 
|---|
|  | 497 | +	func->old_sympos = old_func->old_sympos; | 
|---|
|  | 498 | +	func->nop = true; | 
|---|
|  | 499 | + | 
|---|
|  | 500 | +	return func; | 
|---|
|  | 501 | +} | 
|---|
|  | 502 | + | 
|---|
|  | 503 | +static int klp_add_object_nops(struct klp_patch *patch, | 
|---|
|  | 504 | +			       struct klp_object *old_obj) | 
|---|
|  | 505 | +{ | 
|---|
|  | 506 | +	struct klp_object *obj; | 
|---|
|  | 507 | +	struct klp_func *func, *old_func; | 
|---|
|  | 508 | + | 
|---|
|  | 509 | +	obj = klp_find_object(patch, old_obj); | 
|---|
|  | 510 | + | 
|---|
|  | 511 | +	if (!obj) { | 
|---|
|  | 512 | +		obj = klp_alloc_object_dynamic(old_obj->name, patch); | 
|---|
|  | 513 | +		if (!obj) | 
|---|
|  | 514 | +			return -ENOMEM; | 
|---|
|  | 515 | +	} | 
|---|
|  | 516 | + | 
|---|
|  | 517 | +	klp_for_each_func(old_obj, old_func) { | 
|---|
|  | 518 | +		func = klp_find_func(obj, old_func); | 
|---|
|  | 519 | +		if (func) | 
|---|
|  | 520 | +			continue; | 
|---|
|  | 521 | + | 
|---|
|  | 522 | +		func = klp_alloc_func_nop(old_func, obj); | 
|---|
|  | 523 | +		if (!func) | 
|---|
|  | 524 | +			return -ENOMEM; | 
|---|
|  | 525 | +	} | 
|---|
|  | 526 | + | 
|---|
|  | 527 | +	return 0; | 
|---|
|  | 528 | +} | 
|---|
|  | 529 | + | 
|---|
|  | 530 | +/* | 
|---|
|  | 531 | + * Add 'nop' functions which simply return to the caller to run | 
|---|
|  | 532 | + * the original function. The 'nop' functions are added to a | 
|---|
|  | 533 | + * patch to facilitate a 'replace' mode. | 
|---|
|  | 534 | + */ | 
|---|
|  | 535 | +static int klp_add_nops(struct klp_patch *patch) | 
|---|
|  | 536 | +{ | 
|---|
|  | 537 | +	struct klp_patch *old_patch; | 
|---|
|  | 538 | +	struct klp_object *old_obj; | 
|---|
|  | 539 | + | 
|---|
|  | 540 | +	klp_for_each_patch(old_patch) { | 
|---|
|  | 541 | +		klp_for_each_object(old_patch, old_obj) { | 
|---|
|  | 542 | +			int err; | 
|---|
|  | 543 | + | 
|---|
|  | 544 | +			err = klp_add_object_nops(patch, old_obj); | 
|---|
|  | 545 | +			if (err) | 
|---|
|  | 546 | +				return err; | 
|---|
|  | 547 | +		} | 
|---|
|  | 548 | +	} | 
|---|
|  | 549 | + | 
|---|
|  | 550 | +	return 0; | 
|---|
|  | 551 | +} | 
|---|
|  | 552 | + | 
|---|
|  | 553 | +static void klp_kobj_release_patch(struct kobject *kobj) | 
|---|
|  | 554 | +{ | 
|---|
|  | 555 | +	struct klp_patch *patch; | 
|---|
|  | 556 | + | 
|---|
|  | 557 | +	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
|  | 558 | +	complete(&patch->finish); | 
|---|
|  | 559 | +} | 
|---|
|  | 560 | + | 
|---|
|  | 561 | +static struct kobj_type klp_ktype_patch = { | 
|---|
|  | 562 | +	.release = klp_kobj_release_patch, | 
|---|
|  | 563 | +	.sysfs_ops = &kobj_sysfs_ops, | 
|---|
|  | 564 | +	.default_groups = klp_patch_groups, | 
|---|
|  | 565 | +}; | 
|---|
|  | 566 | + | 
|---|
|  | 567 | +static void klp_kobj_release_object(struct kobject *kobj) | 
|---|
|  | 568 | +{ | 
|---|
|  | 569 | +	struct klp_object *obj; | 
|---|
|  | 570 | + | 
|---|
|  | 571 | +	obj = container_of(kobj, struct klp_object, kobj); | 
|---|
|  | 572 | + | 
|---|
|  | 573 | +	if (obj->dynamic) | 
|---|
|  | 574 | +		klp_free_object_dynamic(obj); | 
|---|
|  | 575 | +} | 
|---|
|  | 576 | + | 
|---|
|  | 577 | +static struct kobj_type klp_ktype_object = { | 
|---|
|  | 578 | +	.release = klp_kobj_release_object, | 
|---|
|  | 579 | +	.sysfs_ops = &kobj_sysfs_ops, | 
|---|
|  | 580 | +}; | 
|---|
|  | 581 | + | 
|---|
|  | 582 | +static void klp_kobj_release_func(struct kobject *kobj) | 
|---|
|  | 583 | +{ | 
|---|
|  | 584 | +	struct klp_func *func; | 
|---|
|  | 585 | + | 
|---|
|  | 586 | +	func = container_of(kobj, struct klp_func, kobj); | 
|---|
|  | 587 | + | 
|---|
|  | 588 | +	if (func->nop) | 
|---|
|  | 589 | +		klp_free_func_nop(func); | 
|---|
|  | 590 | +} | 
|---|
|  | 591 | + | 
|---|
|  | 592 | +static struct kobj_type klp_ktype_func = { | 
|---|
|  | 593 | +	.release = klp_kobj_release_func, | 
|---|
|  | 594 | +	.sysfs_ops = &kobj_sysfs_ops, | 
|---|
|  | 595 | +}; | 
|---|
|  | 596 | + | 
|---|
|  | 597 | +static void __klp_free_funcs(struct klp_object *obj, bool nops_only) | 
|---|
|  | 598 | +{ | 
|---|
|  | 599 | +	struct klp_func *func, *tmp_func; | 
|---|
|  | 600 | + | 
|---|
|  | 601 | +	klp_for_each_func_safe(obj, func, tmp_func) { | 
|---|
|  | 602 | +		if (nops_only && !func->nop) | 
|---|
|  | 603 | +			continue; | 
|---|
|  | 604 | + | 
|---|
|  | 605 | +		list_del(&func->node); | 
|---|
|  | 606 | +		kobject_put(&func->kobj); | 
|---|
|  | 607 | +	} | 
|---|
|  | 608 | +} | 
|---|
|  | 609 | + | 
|---|
|  | 610 | +/* Clean up when a patched object is unloaded */ | 
|---|
|  | 611 | +static void klp_free_object_loaded(struct klp_object *obj) | 
|---|
|  | 612 | +{ | 
|---|
|  | 613 | +	struct klp_func *func; | 
|---|
|  | 614 | + | 
|---|
|  | 615 | +	obj->mod = NULL; | 
|---|
|  | 616 | + | 
|---|
|  | 617 | +	klp_for_each_func(obj, func) { | 
|---|
|  | 618 | +		func->old_func = NULL; | 
|---|
|  | 619 | + | 
|---|
|  | 620 | +		if (func->nop) | 
|---|
|  | 621 | +			func->new_func = NULL; | 
|---|
|  | 622 | +	} | 
|---|
|  | 623 | +} | 
|---|
|  | 624 | + | 
|---|
|  | 625 | +static void __klp_free_objects(struct klp_patch *patch, bool nops_only) | 
|---|
|  | 626 | +{ | 
|---|
|  | 627 | +	struct klp_object *obj, *tmp_obj; | 
|---|
|  | 628 | + | 
|---|
|  | 629 | +	klp_for_each_object_safe(patch, obj, tmp_obj) { | 
|---|
|  | 630 | +		__klp_free_funcs(obj, nops_only); | 
|---|
|  | 631 | + | 
|---|
|  | 632 | +		if (nops_only && !obj->dynamic) | 
|---|
|  | 633 | +			continue; | 
|---|
|  | 634 | + | 
|---|
|  | 635 | +		list_del(&obj->node); | 
|---|
|  | 636 | +		kobject_put(&obj->kobj); | 
|---|
|  | 637 | +	} | 
|---|
|  | 638 | +} | 
|---|
|  | 639 | + | 
|---|
|  | 640 | +static void klp_free_objects(struct klp_patch *patch) | 
|---|
|  | 641 | +{ | 
|---|
|  | 642 | +	__klp_free_objects(patch, false); | 
|---|
|  | 643 | +} | 
|---|
|  | 644 | + | 
|---|
|  | 645 | +static void klp_free_objects_dynamic(struct klp_patch *patch) | 
|---|
|  | 646 | +{ | 
|---|
|  | 647 | +	__klp_free_objects(patch, true); | 
|---|
|  | 648 | +} | 
|---|
|  | 649 | + | 
|---|
|  | 650 | +/* | 
|---|
|  | 651 | + * This function implements the free operations that can be called safely | 
|---|
|  | 652 | + * under klp_mutex. | 
|---|
|  | 653 | + * | 
|---|
|  | 654 | + * The operation must be completed by calling klp_free_patch_finish() | 
|---|
|  | 655 | + * outside klp_mutex. | 
|---|
|  | 656 | + */ | 
|---|
|  | 657 | +static void klp_free_patch_start(struct klp_patch *patch) | 
|---|
|  | 658 | +{ | 
|---|
|  | 659 | +	if (!list_empty(&patch->list)) | 
|---|
|  | 660 | +		list_del(&patch->list); | 
|---|
|  | 661 | + | 
|---|
|  | 662 | +	klp_free_objects(patch); | 
|---|
|  | 663 | +} | 
|---|
|  | 664 | + | 
|---|
|  | 665 | +/* | 
|---|
|  | 666 | + * This function implements the free part that must be called outside | 
|---|
|  | 667 | + * klp_mutex. | 
|---|
|  | 668 | + * | 
|---|
|  | 669 | + * It must be called after klp_free_patch_start(). And it has to be | 
|---|
|  | 670 | + * the last function accessing the livepatch structures when the patch | 
|---|
|  | 671 | + * gets disabled. | 
|---|
|  | 672 | + */ | 
|---|
|  | 673 | +static void klp_free_patch_finish(struct klp_patch *patch) | 
|---|
|  | 674 | +{ | 
|---|
|  | 675 | +	/* | 
|---|
|  | 676 | +	 * Avoid deadlock with enabled_store() sysfs callback by | 
|---|
|  | 677 | +	 * calling this outside klp_mutex. It is safe because | 
|---|
|  | 678 | +	 * this is called when the patch gets disabled and it | 
|---|
|  | 679 | +	 * cannot get enabled again. | 
|---|
|  | 680 | +	 */ | 
|---|
|  | 681 | +	kobject_put(&patch->kobj); | 
|---|
|  | 682 | +	wait_for_completion(&patch->finish); | 
|---|
|  | 683 | + | 
|---|
|  | 684 | +	/* Put the module after the last access to struct klp_patch. */ | 
|---|
|  | 685 | +	if (!patch->forced) | 
|---|
|  | 686 | +		module_put(patch->mod); | 
|---|
|  | 687 | +} | 
|---|
|  | 688 | + | 
|---|
|  | 689 | +/* | 
|---|
|  | 690 | + * The livepatch might be freed from sysfs interface created by the patch. | 
|---|
|  | 691 | + * This work allows to wait until the interface is destroyed in a separate | 
|---|
|  | 692 | + * context. | 
|---|
|  | 693 | + */ | 
|---|
|  | 694 | +static void klp_free_patch_work_fn(struct work_struct *work) | 
|---|
|  | 695 | +{ | 
|---|
|  | 696 | +	struct klp_patch *patch = | 
|---|
|  | 697 | +		container_of(work, struct klp_patch, free_work); | 
|---|
|  | 698 | + | 
|---|
|  | 699 | +	klp_free_patch_finish(patch); | 
|---|
|  | 700 | +} | 
|---|
|  | 701 | + | 
|---|
|  | 702 | +void klp_free_patch_async(struct klp_patch *patch) | 
|---|
|  | 703 | +{ | 
|---|
|  | 704 | +	klp_free_patch_start(patch); | 
|---|
|  | 705 | +	schedule_work(&patch->free_work); | 
|---|
|  | 706 | +} | 
|---|
|  | 707 | + | 
|---|
|  | 708 | +void klp_free_replaced_patches_async(struct klp_patch *new_patch) | 
|---|
|  | 709 | +{ | 
|---|
|  | 710 | +	struct klp_patch *old_patch, *tmp_patch; | 
|---|
|  | 711 | + | 
|---|
|  | 712 | +	klp_for_each_patch_safe(old_patch, tmp_patch) { | 
|---|
|  | 713 | +		if (old_patch == new_patch) | 
|---|
|  | 714 | +			return; | 
|---|
|  | 715 | +		klp_free_patch_async(old_patch); | 
|---|
|  | 716 | +	} | 
|---|
|  | 717 | +} | 
|---|
|  | 718 | + | 
|---|
|  | 719 | +static int klp_init_func(struct klp_object *obj, struct klp_func *func) | 
|---|
|  | 720 | +{ | 
|---|
|  | 721 | +	if (!func->old_name) | 
|---|
| 241 | 722 | return -EINVAL; | 
|---|
| 242 | 723 |  | 
|---|
| 243 |  | -	objname = klp_is_module(obj) ? obj->name : "vmlinux"; | 
|---|
|  | 724 | +	/* | 
|---|
|  | 725 | +	 * NOPs get the address later. The patched module must be loaded, | 
|---|
|  | 726 | +	 * see klp_init_object_loaded(). | 
|---|
|  | 727 | +	 */ | 
|---|
|  | 728 | +	if (!func->new_func && !func->nop) | 
|---|
|  | 729 | +		return -EINVAL; | 
|---|
| 244 | 730 |  | 
|---|
| 245 |  | -	/* For each klp relocation section */ | 
|---|
| 246 |  | -	for (i = 1; i < pmod->klp_info->hdr.e_shnum; i++) { | 
|---|
| 247 |  | -		sec = pmod->klp_info->sechdrs + i; | 
|---|
| 248 |  | -		secname = pmod->klp_info->secstrings + sec->sh_name; | 
|---|
|  | 731 | +	if (strlen(func->old_name) >= KSYM_NAME_LEN) | 
|---|
|  | 732 | +		return -EINVAL; | 
|---|
|  | 733 | + | 
|---|
|  | 734 | +	INIT_LIST_HEAD(&func->stack_node); | 
|---|
|  | 735 | +	func->patched = false; | 
|---|
|  | 736 | +	func->transition = false; | 
|---|
|  | 737 | + | 
|---|
|  | 738 | +	/* The format for the sysfs directory is <function,sympos> where sympos | 
|---|
|  | 739 | +	 * is the nth occurrence of this symbol in kallsyms for the patched | 
|---|
|  | 740 | +	 * object. If the user selects 0 for old_sympos, then 1 will be used | 
|---|
|  | 741 | +	 * since a unique symbol will be the first occurrence. | 
|---|
|  | 742 | +	 */ | 
|---|
|  | 743 | +	return kobject_add(&func->kobj, &obj->kobj, "%s,%lu", | 
|---|
|  | 744 | +			   func->old_name, | 
|---|
|  | 745 | +			   func->old_sympos ? func->old_sympos : 1); | 
|---|
|  | 746 | +} | 
|---|
|  | 747 | + | 
|---|
|  | 748 | +static int klp_apply_object_relocs(struct klp_patch *patch, | 
|---|
|  | 749 | +				   struct klp_object *obj) | 
|---|
|  | 750 | +{ | 
|---|
|  | 751 | +	int i, ret; | 
|---|
|  | 752 | +	struct klp_modinfo *info = patch->mod->klp_info; | 
|---|
|  | 753 | + | 
|---|
|  | 754 | +	for (i = 1; i < info->hdr.e_shnum; i++) { | 
|---|
|  | 755 | +		Elf_Shdr *sec = info->sechdrs + i; | 
|---|
|  | 756 | + | 
|---|
| 249 | 757 | if (!(sec->sh_flags & SHF_RELA_LIVEPATCH)) | 
|---|
| 250 | 758 | continue; | 
|---|
| 251 | 759 |  | 
|---|
| 252 |  | -		/* | 
|---|
| 253 |  | -		 * Format: .klp.rela.sec_objname.section_name | 
|---|
| 254 |  | -		 * See comment in klp_resolve_symbols() for an explanation | 
|---|
| 255 |  | -		 * of the selected field width value. | 
|---|
| 256 |  | -		 */ | 
|---|
| 257 |  | -		cnt = sscanf(secname, ".klp.rela.%55[^.]", sec_objname); | 
|---|
| 258 |  | -		if (cnt != 1) { | 
|---|
| 259 |  | -			pr_err("section %s has an incorrectly formatted name\n", | 
|---|
| 260 |  | -			       secname); | 
|---|
| 261 |  | -			ret = -EINVAL; | 
|---|
| 262 |  | -			break; | 
|---|
| 263 |  | -		} | 
|---|
| 264 |  | - | 
|---|
| 265 |  | -		if (strcmp(objname, sec_objname)) | 
|---|
| 266 |  | -			continue; | 
|---|
| 267 |  | - | 
|---|
| 268 |  | -		ret = klp_resolve_symbols(sec, pmod); | 
|---|
|  | 760 | +		ret = klp_apply_section_relocs(patch->mod, info->sechdrs, | 
|---|
|  | 761 | +					       info->secstrings, | 
|---|
|  | 762 | +					       patch->mod->core_kallsyms.strtab, | 
|---|
|  | 763 | +					       info->symndx, i, obj->name); | 
|---|
| 269 | 764 | if (ret) | 
|---|
| 270 |  | -			break; | 
|---|
| 271 |  | - | 
|---|
| 272 |  | -		ret = apply_relocate_add(pmod->klp_info->sechdrs, | 
|---|
| 273 |  | -					 pmod->core_kallsyms.strtab, | 
|---|
| 274 |  | -					 pmod->klp_info->symndx, i, pmod); | 
|---|
| 275 |  | -		if (ret) | 
|---|
| 276 |  | -			break; | 
|---|
|  | 765 | +			return ret; | 
|---|
| 277 | 766 | } | 
|---|
| 278 | 767 |  | 
|---|
|  | 768 | +	return 0; | 
|---|
|  | 769 | +} | 
|---|
|  | 770 | + | 
|---|
|  | 771 | +/* parts of the initialization that is done only when the object is loaded */ | 
|---|
|  | 772 | +static int klp_init_object_loaded(struct klp_patch *patch, | 
|---|
|  | 773 | +				  struct klp_object *obj) | 
|---|
|  | 774 | +{ | 
|---|
|  | 775 | +	struct klp_func *func; | 
|---|
|  | 776 | +	int ret; | 
|---|
|  | 777 | + | 
|---|
|  | 778 | +	if (klp_is_module(obj)) { | 
|---|
|  | 779 | +		/* | 
|---|
|  | 780 | +		 * Only write module-specific relocations here | 
|---|
|  | 781 | +		 * (.klp.rela.{module}.*).  vmlinux-specific relocations were | 
|---|
|  | 782 | +		 * written earlier during the initialization of the klp module | 
|---|
|  | 783 | +		 * itself. | 
|---|
|  | 784 | +		 */ | 
|---|
|  | 785 | +		ret = klp_apply_object_relocs(patch, obj); | 
|---|
|  | 786 | +		if (ret) | 
|---|
|  | 787 | +			return ret; | 
|---|
|  | 788 | +	} | 
|---|
|  | 789 | + | 
|---|
|  | 790 | +	klp_for_each_func(obj, func) { | 
|---|
|  | 791 | +		ret = klp_find_object_symbol(obj->name, func->old_name, | 
|---|
|  | 792 | +					     func->old_sympos, | 
|---|
|  | 793 | +					     (unsigned long *)&func->old_func); | 
|---|
|  | 794 | +		if (ret) | 
|---|
|  | 795 | +			return ret; | 
|---|
|  | 796 | + | 
|---|
|  | 797 | +		ret = kallsyms_lookup_size_offset((unsigned long)func->old_func, | 
|---|
|  | 798 | +						  &func->old_size, NULL); | 
|---|
|  | 799 | +		if (!ret) { | 
|---|
|  | 800 | +			pr_err("kallsyms size lookup failed for '%s'\n", | 
|---|
|  | 801 | +			       func->old_name); | 
|---|
|  | 802 | +			return -ENOENT; | 
|---|
|  | 803 | +		} | 
|---|
|  | 804 | + | 
|---|
|  | 805 | +		if (func->nop) | 
|---|
|  | 806 | +			func->new_func = func->old_func; | 
|---|
|  | 807 | + | 
|---|
|  | 808 | +		ret = kallsyms_lookup_size_offset((unsigned long)func->new_func, | 
|---|
|  | 809 | +						  &func->new_size, NULL); | 
|---|
|  | 810 | +		if (!ret) { | 
|---|
|  | 811 | +			pr_err("kallsyms size lookup failed for '%s' replacement\n", | 
|---|
|  | 812 | +			       func->old_name); | 
|---|
|  | 813 | +			return -ENOENT; | 
|---|
|  | 814 | +		} | 
|---|
|  | 815 | +	} | 
|---|
|  | 816 | + | 
|---|
|  | 817 | +	return 0; | 
|---|
|  | 818 | +} | 
|---|
|  | 819 | + | 
|---|
|  | 820 | +static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | 
|---|
|  | 821 | +{ | 
|---|
|  | 822 | +	struct klp_func *func; | 
|---|
|  | 823 | +	int ret; | 
|---|
|  | 824 | +	const char *name; | 
|---|
|  | 825 | + | 
|---|
|  | 826 | +	if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN) | 
|---|
|  | 827 | +		return -EINVAL; | 
|---|
|  | 828 | + | 
|---|
|  | 829 | +	obj->patched = false; | 
|---|
|  | 830 | +	obj->mod = NULL; | 
|---|
|  | 831 | + | 
|---|
|  | 832 | +	klp_find_object_module(obj); | 
|---|
|  | 833 | + | 
|---|
|  | 834 | +	name = klp_is_module(obj) ? obj->name : "vmlinux"; | 
|---|
|  | 835 | +	ret = kobject_add(&obj->kobj, &patch->kobj, "%s", name); | 
|---|
|  | 836 | +	if (ret) | 
|---|
|  | 837 | +		return ret; | 
|---|
|  | 838 | + | 
|---|
|  | 839 | +	klp_for_each_func(obj, func) { | 
|---|
|  | 840 | +		ret = klp_init_func(obj, func); | 
|---|
|  | 841 | +		if (ret) | 
|---|
|  | 842 | +			return ret; | 
|---|
|  | 843 | +	} | 
|---|
|  | 844 | + | 
|---|
|  | 845 | +	if (klp_is_object_loaded(obj)) | 
|---|
|  | 846 | +		ret = klp_init_object_loaded(patch, obj); | 
|---|
|  | 847 | + | 
|---|
| 279 | 848 | return ret; | 
|---|
|  | 849 | +} | 
|---|
|  | 850 | + | 
|---|
|  | 851 | +static void klp_init_func_early(struct klp_object *obj, | 
|---|
|  | 852 | +				struct klp_func *func) | 
|---|
|  | 853 | +{ | 
|---|
|  | 854 | +	kobject_init(&func->kobj, &klp_ktype_func); | 
|---|
|  | 855 | +	list_add_tail(&func->node, &obj->func_list); | 
|---|
|  | 856 | +} | 
|---|
|  | 857 | + | 
|---|
|  | 858 | +static void klp_init_object_early(struct klp_patch *patch, | 
|---|
|  | 859 | +				  struct klp_object *obj) | 
|---|
|  | 860 | +{ | 
|---|
|  | 861 | +	INIT_LIST_HEAD(&obj->func_list); | 
|---|
|  | 862 | +	kobject_init(&obj->kobj, &klp_ktype_object); | 
|---|
|  | 863 | +	list_add_tail(&obj->node, &patch->obj_list); | 
|---|
|  | 864 | +} | 
|---|
|  | 865 | + | 
|---|
|  | 866 | +static int klp_init_patch_early(struct klp_patch *patch) | 
|---|
|  | 867 | +{ | 
|---|
|  | 868 | +	struct klp_object *obj; | 
|---|
|  | 869 | +	struct klp_func *func; | 
|---|
|  | 870 | + | 
|---|
|  | 871 | +	if (!patch->objs) | 
|---|
|  | 872 | +		return -EINVAL; | 
|---|
|  | 873 | + | 
|---|
|  | 874 | +	INIT_LIST_HEAD(&patch->list); | 
|---|
|  | 875 | +	INIT_LIST_HEAD(&patch->obj_list); | 
|---|
|  | 876 | +	kobject_init(&patch->kobj, &klp_ktype_patch); | 
|---|
|  | 877 | +	patch->enabled = false; | 
|---|
|  | 878 | +	patch->forced = false; | 
|---|
|  | 879 | +	INIT_WORK(&patch->free_work, klp_free_patch_work_fn); | 
|---|
|  | 880 | +	init_completion(&patch->finish); | 
|---|
|  | 881 | + | 
|---|
|  | 882 | +	klp_for_each_object_static(patch, obj) { | 
|---|
|  | 883 | +		if (!obj->funcs) | 
|---|
|  | 884 | +			return -EINVAL; | 
|---|
|  | 885 | + | 
|---|
|  | 886 | +		klp_init_object_early(patch, obj); | 
|---|
|  | 887 | + | 
|---|
|  | 888 | +		klp_for_each_func_static(obj, func) { | 
|---|
|  | 889 | +			klp_init_func_early(obj, func); | 
|---|
|  | 890 | +		} | 
|---|
|  | 891 | +	} | 
|---|
|  | 892 | + | 
|---|
|  | 893 | +	if (!try_module_get(patch->mod)) | 
|---|
|  | 894 | +		return -ENODEV; | 
|---|
|  | 895 | + | 
|---|
|  | 896 | +	return 0; | 
|---|
|  | 897 | +} | 
|---|
|  | 898 | + | 
|---|
|  | 899 | +static int klp_init_patch(struct klp_patch *patch) | 
|---|
|  | 900 | +{ | 
|---|
|  | 901 | +	struct klp_object *obj; | 
|---|
|  | 902 | +	int ret; | 
|---|
|  | 903 | + | 
|---|
|  | 904 | +	ret = kobject_add(&patch->kobj, klp_root_kobj, "%s", patch->mod->name); | 
|---|
|  | 905 | +	if (ret) | 
|---|
|  | 906 | +		return ret; | 
|---|
|  | 907 | + | 
|---|
|  | 908 | +	if (patch->replace) { | 
|---|
|  | 909 | +		ret = klp_add_nops(patch); | 
|---|
|  | 910 | +		if (ret) | 
|---|
|  | 911 | +			return ret; | 
|---|
|  | 912 | +	} | 
|---|
|  | 913 | + | 
|---|
|  | 914 | +	klp_for_each_object(patch, obj) { | 
|---|
|  | 915 | +		ret = klp_init_object(patch, obj); | 
|---|
|  | 916 | +		if (ret) | 
|---|
|  | 917 | +			return ret; | 
|---|
|  | 918 | +	} | 
|---|
|  | 919 | + | 
|---|
|  | 920 | +	list_add_tail(&patch->list, &klp_patches); | 
|---|
|  | 921 | + | 
|---|
|  | 922 | +	return 0; | 
|---|
| 280 | 923 | } | 
|---|
| 281 | 924 |  | 
|---|
| 282 | 925 | static int __klp_disable_patch(struct klp_patch *patch) | 
|---|
| .. | .. | 
|---|
| 287 | 930 | return -EINVAL; | 
|---|
| 288 | 931 |  | 
|---|
| 289 | 932 | if (klp_transition_patch) | 
|---|
| 290 |  | -		return -EBUSY; | 
|---|
| 291 |  | - | 
|---|
| 292 |  | -	/* enforce stacking: only the last enabled patch can be disabled */ | 
|---|
| 293 |  | -	if (!list_is_last(&patch->list, &klp_patches) && | 
|---|
| 294 |  | -	    list_next_entry(patch, list)->enabled) | 
|---|
| 295 | 933 | return -EBUSY; | 
|---|
| 296 | 934 |  | 
|---|
| 297 | 935 | klp_init_transition(patch, KLP_UNPATCHED); | 
|---|
| .. | .. | 
|---|
| 310 | 948 | smp_wmb(); | 
|---|
| 311 | 949 |  | 
|---|
| 312 | 950 | klp_start_transition(); | 
|---|
| 313 |  | -	klp_try_complete_transition(); | 
|---|
| 314 | 951 | patch->enabled = false; | 
|---|
|  | 952 | +	klp_try_complete_transition(); | 
|---|
| 315 | 953 |  | 
|---|
| 316 | 954 | return 0; | 
|---|
| 317 | 955 | } | 
|---|
| 318 |  | - | 
|---|
| 319 |  | -/** | 
|---|
| 320 |  | - * klp_disable_patch() - disables a registered patch | 
|---|
| 321 |  | - * @patch:	The registered, enabled patch to be disabled | 
|---|
| 322 |  | - * | 
|---|
| 323 |  | - * Unregisters the patched functions from ftrace. | 
|---|
| 324 |  | - * | 
|---|
| 325 |  | - * Return: 0 on success, otherwise error | 
|---|
| 326 |  | - */ | 
|---|
| 327 |  | -int klp_disable_patch(struct klp_patch *patch) | 
|---|
| 328 |  | -{ | 
|---|
| 329 |  | -	int ret; | 
|---|
| 330 |  | - | 
|---|
| 331 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 332 |  | - | 
|---|
| 333 |  | -	if (!klp_is_patch_registered(patch)) { | 
|---|
| 334 |  | -		ret = -EINVAL; | 
|---|
| 335 |  | -		goto err; | 
|---|
| 336 |  | -	} | 
|---|
| 337 |  | - | 
|---|
| 338 |  | -	if (!patch->enabled) { | 
|---|
| 339 |  | -		ret = -EINVAL; | 
|---|
| 340 |  | -		goto err; | 
|---|
| 341 |  | -	} | 
|---|
| 342 |  | - | 
|---|
| 343 |  | -	ret = __klp_disable_patch(patch); | 
|---|
| 344 |  | - | 
|---|
| 345 |  | -err: | 
|---|
| 346 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 347 |  | -	return ret; | 
|---|
| 348 |  | -} | 
|---|
| 349 |  | -EXPORT_SYMBOL_GPL(klp_disable_patch); | 
|---|
| 350 | 956 |  | 
|---|
| 351 | 957 | static int __klp_enable_patch(struct klp_patch *patch) | 
|---|
| 352 | 958 | { | 
|---|
| .. | .. | 
|---|
| 358 | 964 |  | 
|---|
| 359 | 965 | if (WARN_ON(patch->enabled)) | 
|---|
| 360 | 966 | return -EINVAL; | 
|---|
| 361 |  | - | 
|---|
| 362 |  | -	/* enforce stacking: only the first disabled patch can be enabled */ | 
|---|
| 363 |  | -	if (patch->list.prev != &klp_patches && | 
|---|
| 364 |  | -	    !list_prev_entry(patch, list)->enabled) | 
|---|
| 365 |  | -		return -EBUSY; | 
|---|
| 366 |  | - | 
|---|
| 367 |  | -	/* | 
|---|
| 368 |  | -	 * A reference is taken on the patch module to prevent it from being | 
|---|
| 369 |  | -	 * unloaded. | 
|---|
| 370 |  | -	 */ | 
|---|
| 371 |  | -	if (!try_module_get(patch->mod)) | 
|---|
| 372 |  | -		return -ENODEV; | 
|---|
| 373 | 967 |  | 
|---|
| 374 | 968 | pr_notice("enabling patch '%s'\n", patch->mod->name); | 
|---|
| 375 | 969 |  | 
|---|
| .. | .. | 
|---|
| 404 | 998 | } | 
|---|
| 405 | 999 |  | 
|---|
| 406 | 1000 | klp_start_transition(); | 
|---|
| 407 |  | -	klp_try_complete_transition(); | 
|---|
| 408 | 1001 | patch->enabled = true; | 
|---|
|  | 1002 | +	klp_try_complete_transition(); | 
|---|
| 409 | 1003 |  | 
|---|
| 410 | 1004 | return 0; | 
|---|
| 411 | 1005 | err: | 
|---|
| .. | .. | 
|---|
| 416 | 1010 | } | 
|---|
| 417 | 1011 |  | 
|---|
| 418 | 1012 | /** | 
|---|
| 419 |  | - * klp_enable_patch() - enables a registered patch | 
|---|
| 420 |  | - * @patch:	The registered, disabled patch to be enabled | 
|---|
|  | 1013 | + * klp_enable_patch() - enable the livepatch | 
|---|
|  | 1014 | + * @patch:	patch to be enabled | 
|---|
| 421 | 1015 | * | 
|---|
| 422 |  | - * Performs the needed symbol lookups and code relocations, | 
|---|
| 423 |  | - * then registers the patched functions with ftrace. | 
|---|
|  | 1016 | + * Initializes the data structure associated with the patch, creates the sysfs | 
|---|
|  | 1017 | + * interface, performs the needed symbol lookups and code relocations, | 
|---|
|  | 1018 | + * registers the patched functions with ftrace. | 
|---|
|  | 1019 | + * | 
|---|
|  | 1020 | + * This function is supposed to be called from the livepatch module_init() | 
|---|
|  | 1021 | + * callback. | 
|---|
| 424 | 1022 | * | 
|---|
| 425 | 1023 | * Return: 0 on success, otherwise error | 
|---|
| 426 | 1024 | */ | 
|---|
| .. | .. | 
|---|
| 428 | 1026 | { | 
|---|
| 429 | 1027 | int ret; | 
|---|
| 430 | 1028 |  | 
|---|
| 431 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 432 |  | - | 
|---|
| 433 |  | -	if (!klp_is_patch_registered(patch)) { | 
|---|
| 434 |  | -		ret = -EINVAL; | 
|---|
| 435 |  | -		goto err; | 
|---|
| 436 |  | -	} | 
|---|
| 437 |  | - | 
|---|
| 438 |  | -	ret = __klp_enable_patch(patch); | 
|---|
| 439 |  | - | 
|---|
| 440 |  | -err: | 
|---|
| 441 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 442 |  | -	return ret; | 
|---|
| 443 |  | -} | 
|---|
| 444 |  | -EXPORT_SYMBOL_GPL(klp_enable_patch); | 
|---|
| 445 |  | - | 
|---|
| 446 |  | -/* | 
|---|
| 447 |  | - * Sysfs Interface | 
|---|
| 448 |  | - * | 
|---|
| 449 |  | - * /sys/kernel/livepatch | 
|---|
| 450 |  | - * /sys/kernel/livepatch/<patch> | 
|---|
| 451 |  | - * /sys/kernel/livepatch/<patch>/enabled | 
|---|
| 452 |  | - * /sys/kernel/livepatch/<patch>/transition | 
|---|
| 453 |  | - * /sys/kernel/livepatch/<patch>/signal | 
|---|
| 454 |  | - * /sys/kernel/livepatch/<patch>/force | 
|---|
| 455 |  | - * /sys/kernel/livepatch/<patch>/<object> | 
|---|
| 456 |  | - * /sys/kernel/livepatch/<patch>/<object>/<function,sympos> | 
|---|
| 457 |  | - */ | 
|---|
| 458 |  | - | 
|---|
| 459 |  | -static ssize_t enabled_store(struct kobject *kobj, struct kobj_attribute *attr, | 
|---|
| 460 |  | -			     const char *buf, size_t count) | 
|---|
| 461 |  | -{ | 
|---|
| 462 |  | -	struct klp_patch *patch; | 
|---|
| 463 |  | -	int ret; | 
|---|
| 464 |  | -	bool enabled; | 
|---|
| 465 |  | - | 
|---|
| 466 |  | -	ret = kstrtobool(buf, &enabled); | 
|---|
| 467 |  | -	if (ret) | 
|---|
| 468 |  | -		return ret; | 
|---|
| 469 |  | - | 
|---|
| 470 |  | -	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
| 471 |  | - | 
|---|
| 472 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 473 |  | - | 
|---|
| 474 |  | -	if (!klp_is_patch_registered(patch)) { | 
|---|
| 475 |  | -		/* | 
|---|
| 476 |  | -		 * Module with the patch could either disappear meanwhile or is | 
|---|
| 477 |  | -		 * not properly initialized yet. | 
|---|
| 478 |  | -		 */ | 
|---|
| 479 |  | -		ret = -EINVAL; | 
|---|
| 480 |  | -		goto err; | 
|---|
| 481 |  | -	} | 
|---|
| 482 |  | - | 
|---|
| 483 |  | -	if (patch->enabled == enabled) { | 
|---|
| 484 |  | -		/* already in requested state */ | 
|---|
| 485 |  | -		ret = -EINVAL; | 
|---|
| 486 |  | -		goto err; | 
|---|
| 487 |  | -	} | 
|---|
| 488 |  | - | 
|---|
| 489 |  | -	if (patch == klp_transition_patch) { | 
|---|
| 490 |  | -		klp_reverse_transition(); | 
|---|
| 491 |  | -	} else if (enabled) { | 
|---|
| 492 |  | -		ret = __klp_enable_patch(patch); | 
|---|
| 493 |  | -		if (ret) | 
|---|
| 494 |  | -			goto err; | 
|---|
| 495 |  | -	} else { | 
|---|
| 496 |  | -		ret = __klp_disable_patch(patch); | 
|---|
| 497 |  | -		if (ret) | 
|---|
| 498 |  | -			goto err; | 
|---|
| 499 |  | -	} | 
|---|
| 500 |  | - | 
|---|
| 501 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 502 |  | - | 
|---|
| 503 |  | -	return count; | 
|---|
| 504 |  | - | 
|---|
| 505 |  | -err: | 
|---|
| 506 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 507 |  | -	return ret; | 
|---|
| 508 |  | -} | 
|---|
| 509 |  | - | 
|---|
| 510 |  | -static ssize_t enabled_show(struct kobject *kobj, | 
|---|
| 511 |  | -			    struct kobj_attribute *attr, char *buf) | 
|---|
| 512 |  | -{ | 
|---|
| 513 |  | -	struct klp_patch *patch; | 
|---|
| 514 |  | - | 
|---|
| 515 |  | -	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
| 516 |  | -	return snprintf(buf, PAGE_SIZE-1, "%d\n", patch->enabled); | 
|---|
| 517 |  | -} | 
|---|
| 518 |  | - | 
|---|
| 519 |  | -static ssize_t transition_show(struct kobject *kobj, | 
|---|
| 520 |  | -			       struct kobj_attribute *attr, char *buf) | 
|---|
| 521 |  | -{ | 
|---|
| 522 |  | -	struct klp_patch *patch; | 
|---|
| 523 |  | - | 
|---|
| 524 |  | -	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
| 525 |  | -	return snprintf(buf, PAGE_SIZE-1, "%d\n", | 
|---|
| 526 |  | -			patch == klp_transition_patch); | 
|---|
| 527 |  | -} | 
|---|
| 528 |  | - | 
|---|
| 529 |  | -static ssize_t signal_store(struct kobject *kobj, struct kobj_attribute *attr, | 
|---|
| 530 |  | -			    const char *buf, size_t count) | 
|---|
| 531 |  | -{ | 
|---|
| 532 |  | -	struct klp_patch *patch; | 
|---|
| 533 |  | -	int ret; | 
|---|
| 534 |  | -	bool val; | 
|---|
| 535 |  | - | 
|---|
| 536 |  | -	ret = kstrtobool(buf, &val); | 
|---|
| 537 |  | -	if (ret) | 
|---|
| 538 |  | -		return ret; | 
|---|
| 539 |  | - | 
|---|
| 540 |  | -	if (!val) | 
|---|
| 541 |  | -		return count; | 
|---|
| 542 |  | - | 
|---|
| 543 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 544 |  | - | 
|---|
| 545 |  | -	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
| 546 |  | -	if (patch != klp_transition_patch) { | 
|---|
| 547 |  | -		mutex_unlock(&klp_mutex); | 
|---|
| 548 |  | -		return -EINVAL; | 
|---|
| 549 |  | -	} | 
|---|
| 550 |  | - | 
|---|
| 551 |  | -	klp_send_signals(); | 
|---|
| 552 |  | - | 
|---|
| 553 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 554 |  | - | 
|---|
| 555 |  | -	return count; | 
|---|
| 556 |  | -} | 
|---|
| 557 |  | - | 
|---|
| 558 |  | -static ssize_t force_store(struct kobject *kobj, struct kobj_attribute *attr, | 
|---|
| 559 |  | -			   const char *buf, size_t count) | 
|---|
| 560 |  | -{ | 
|---|
| 561 |  | -	struct klp_patch *patch; | 
|---|
| 562 |  | -	int ret; | 
|---|
| 563 |  | -	bool val; | 
|---|
| 564 |  | - | 
|---|
| 565 |  | -	ret = kstrtobool(buf, &val); | 
|---|
| 566 |  | -	if (ret) | 
|---|
| 567 |  | -		return ret; | 
|---|
| 568 |  | - | 
|---|
| 569 |  | -	if (!val) | 
|---|
| 570 |  | -		return count; | 
|---|
| 571 |  | - | 
|---|
| 572 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 573 |  | - | 
|---|
| 574 |  | -	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
| 575 |  | -	if (patch != klp_transition_patch) { | 
|---|
| 576 |  | -		mutex_unlock(&klp_mutex); | 
|---|
| 577 |  | -		return -EINVAL; | 
|---|
| 578 |  | -	} | 
|---|
| 579 |  | - | 
|---|
| 580 |  | -	klp_force_transition(); | 
|---|
| 581 |  | - | 
|---|
| 582 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 583 |  | - | 
|---|
| 584 |  | -	return count; | 
|---|
| 585 |  | -} | 
|---|
| 586 |  | - | 
|---|
| 587 |  | -static struct kobj_attribute enabled_kobj_attr = __ATTR_RW(enabled); | 
|---|
| 588 |  | -static struct kobj_attribute transition_kobj_attr = __ATTR_RO(transition); | 
|---|
| 589 |  | -static struct kobj_attribute signal_kobj_attr = __ATTR_WO(signal); | 
|---|
| 590 |  | -static struct kobj_attribute force_kobj_attr = __ATTR_WO(force); | 
|---|
| 591 |  | -static struct attribute *klp_patch_attrs[] = { | 
|---|
| 592 |  | -	&enabled_kobj_attr.attr, | 
|---|
| 593 |  | -	&transition_kobj_attr.attr, | 
|---|
| 594 |  | -	&signal_kobj_attr.attr, | 
|---|
| 595 |  | -	&force_kobj_attr.attr, | 
|---|
| 596 |  | -	NULL | 
|---|
| 597 |  | -}; | 
|---|
| 598 |  | - | 
|---|
| 599 |  | -static void klp_kobj_release_patch(struct kobject *kobj) | 
|---|
| 600 |  | -{ | 
|---|
| 601 |  | -	struct klp_patch *patch; | 
|---|
| 602 |  | - | 
|---|
| 603 |  | -	patch = container_of(kobj, struct klp_patch, kobj); | 
|---|
| 604 |  | -	complete(&patch->finish); | 
|---|
| 605 |  | -} | 
|---|
| 606 |  | - | 
|---|
| 607 |  | -static struct kobj_type klp_ktype_patch = { | 
|---|
| 608 |  | -	.release = klp_kobj_release_patch, | 
|---|
| 609 |  | -	.sysfs_ops = &kobj_sysfs_ops, | 
|---|
| 610 |  | -	.default_attrs = klp_patch_attrs, | 
|---|
| 611 |  | -}; | 
|---|
| 612 |  | - | 
|---|
| 613 |  | -static void klp_kobj_release_object(struct kobject *kobj) | 
|---|
| 614 |  | -{ | 
|---|
| 615 |  | -} | 
|---|
| 616 |  | - | 
|---|
| 617 |  | -static struct kobj_type klp_ktype_object = { | 
|---|
| 618 |  | -	.release = klp_kobj_release_object, | 
|---|
| 619 |  | -	.sysfs_ops = &kobj_sysfs_ops, | 
|---|
| 620 |  | -}; | 
|---|
| 621 |  | - | 
|---|
| 622 |  | -static void klp_kobj_release_func(struct kobject *kobj) | 
|---|
| 623 |  | -{ | 
|---|
| 624 |  | -} | 
|---|
| 625 |  | - | 
|---|
| 626 |  | -static struct kobj_type klp_ktype_func = { | 
|---|
| 627 |  | -	.release = klp_kobj_release_func, | 
|---|
| 628 |  | -	.sysfs_ops = &kobj_sysfs_ops, | 
|---|
| 629 |  | -}; | 
|---|
| 630 |  | - | 
|---|
| 631 |  | -/* | 
|---|
| 632 |  | - * Free all functions' kobjects in the array up to some limit. When limit is | 
|---|
| 633 |  | - * NULL, all kobjects are freed. | 
|---|
| 634 |  | - */ | 
|---|
| 635 |  | -static void klp_free_funcs_limited(struct klp_object *obj, | 
|---|
| 636 |  | -				   struct klp_func *limit) | 
|---|
| 637 |  | -{ | 
|---|
| 638 |  | -	struct klp_func *func; | 
|---|
| 639 |  | - | 
|---|
| 640 |  | -	for (func = obj->funcs; func->old_name && func != limit; func++) | 
|---|
| 641 |  | -		kobject_put(&func->kobj); | 
|---|
| 642 |  | -} | 
|---|
| 643 |  | - | 
|---|
| 644 |  | -/* Clean up when a patched object is unloaded */ | 
|---|
| 645 |  | -static void klp_free_object_loaded(struct klp_object *obj) | 
|---|
| 646 |  | -{ | 
|---|
| 647 |  | -	struct klp_func *func; | 
|---|
| 648 |  | - | 
|---|
| 649 |  | -	obj->mod = NULL; | 
|---|
| 650 |  | - | 
|---|
| 651 |  | -	klp_for_each_func(obj, func) | 
|---|
| 652 |  | -		func->old_addr = 0; | 
|---|
| 653 |  | -} | 
|---|
| 654 |  | - | 
|---|
| 655 |  | -/* | 
|---|
| 656 |  | - * Free all objects' kobjects in the array up to some limit. When limit is | 
|---|
| 657 |  | - * NULL, all kobjects are freed. | 
|---|
| 658 |  | - */ | 
|---|
| 659 |  | -static void klp_free_objects_limited(struct klp_patch *patch, | 
|---|
| 660 |  | -				     struct klp_object *limit) | 
|---|
| 661 |  | -{ | 
|---|
| 662 |  | -	struct klp_object *obj; | 
|---|
| 663 |  | - | 
|---|
| 664 |  | -	for (obj = patch->objs; obj->funcs && obj != limit; obj++) { | 
|---|
| 665 |  | -		klp_free_funcs_limited(obj, NULL); | 
|---|
| 666 |  | -		kobject_put(&obj->kobj); | 
|---|
| 667 |  | -	} | 
|---|
| 668 |  | -} | 
|---|
| 669 |  | - | 
|---|
| 670 |  | -static void klp_free_patch(struct klp_patch *patch) | 
|---|
| 671 |  | -{ | 
|---|
| 672 |  | -	klp_free_objects_limited(patch, NULL); | 
|---|
| 673 |  | -	if (!list_empty(&patch->list)) | 
|---|
| 674 |  | -		list_del(&patch->list); | 
|---|
| 675 |  | -} | 
|---|
| 676 |  | - | 
|---|
| 677 |  | -static int klp_init_func(struct klp_object *obj, struct klp_func *func) | 
|---|
| 678 |  | -{ | 
|---|
| 679 |  | -	if (!func->old_name || !func->new_func) | 
|---|
| 680 |  | -		return -EINVAL; | 
|---|
| 681 |  | - | 
|---|
| 682 |  | -	if (strlen(func->old_name) >= KSYM_NAME_LEN) | 
|---|
| 683 |  | -		return -EINVAL; | 
|---|
| 684 |  | - | 
|---|
| 685 |  | -	INIT_LIST_HEAD(&func->stack_node); | 
|---|
| 686 |  | -	func->patched = false; | 
|---|
| 687 |  | -	func->transition = false; | 
|---|
| 688 |  | - | 
|---|
| 689 |  | -	/* The format for the sysfs directory is <function,sympos> where sympos | 
|---|
| 690 |  | -	 * is the nth occurrence of this symbol in kallsyms for the patched | 
|---|
| 691 |  | -	 * object. If the user selects 0 for old_sympos, then 1 will be used | 
|---|
| 692 |  | -	 * since a unique symbol will be the first occurrence. | 
|---|
| 693 |  | -	 */ | 
|---|
| 694 |  | -	return kobject_init_and_add(&func->kobj, &klp_ktype_func, | 
|---|
| 695 |  | -				    &obj->kobj, "%s,%lu", func->old_name, | 
|---|
| 696 |  | -				    func->old_sympos ? func->old_sympos : 1); | 
|---|
| 697 |  | -} | 
|---|
| 698 |  | - | 
|---|
| 699 |  | -/* Arches may override this to finish any remaining arch-specific tasks */ | 
|---|
| 700 |  | -void __weak arch_klp_init_object_loaded(struct klp_patch *patch, | 
|---|
| 701 |  | -					struct klp_object *obj) | 
|---|
| 702 |  | -{ | 
|---|
| 703 |  | -} | 
|---|
| 704 |  | - | 
|---|
| 705 |  | -/* parts of the initialization that is done only when the object is loaded */ | 
|---|
| 706 |  | -static int klp_init_object_loaded(struct klp_patch *patch, | 
|---|
| 707 |  | -				  struct klp_object *obj) | 
|---|
| 708 |  | -{ | 
|---|
| 709 |  | -	struct klp_func *func; | 
|---|
| 710 |  | -	int ret; | 
|---|
| 711 |  | - | 
|---|
| 712 |  | -	mutex_lock(&text_mutex); | 
|---|
| 713 |  | - | 
|---|
| 714 |  | -	module_disable_ro(patch->mod); | 
|---|
| 715 |  | -	ret = klp_write_object_relocations(patch->mod, obj); | 
|---|
| 716 |  | -	if (ret) { | 
|---|
| 717 |  | -		module_enable_ro(patch->mod, true); | 
|---|
| 718 |  | -		mutex_unlock(&text_mutex); | 
|---|
| 719 |  | -		return ret; | 
|---|
| 720 |  | -	} | 
|---|
| 721 |  | - | 
|---|
| 722 |  | -	arch_klp_init_object_loaded(patch, obj); | 
|---|
| 723 |  | -	module_enable_ro(patch->mod, true); | 
|---|
| 724 |  | - | 
|---|
| 725 |  | -	mutex_unlock(&text_mutex); | 
|---|
| 726 |  | - | 
|---|
| 727 |  | -	klp_for_each_func(obj, func) { | 
|---|
| 728 |  | -		ret = klp_find_object_symbol(obj->name, func->old_name, | 
|---|
| 729 |  | -					     func->old_sympos, | 
|---|
| 730 |  | -					     &func->old_addr); | 
|---|
| 731 |  | -		if (ret) | 
|---|
| 732 |  | -			return ret; | 
|---|
| 733 |  | - | 
|---|
| 734 |  | -		ret = kallsyms_lookup_size_offset(func->old_addr, | 
|---|
| 735 |  | -						  &func->old_size, NULL); | 
|---|
| 736 |  | -		if (!ret) { | 
|---|
| 737 |  | -			pr_err("kallsyms size lookup failed for '%s'\n", | 
|---|
| 738 |  | -			       func->old_name); | 
|---|
| 739 |  | -			return -ENOENT; | 
|---|
| 740 |  | -		} | 
|---|
| 741 |  | - | 
|---|
| 742 |  | -		ret = kallsyms_lookup_size_offset((unsigned long)func->new_func, | 
|---|
| 743 |  | -						  &func->new_size, NULL); | 
|---|
| 744 |  | -		if (!ret) { | 
|---|
| 745 |  | -			pr_err("kallsyms size lookup failed for '%s' replacement\n", | 
|---|
| 746 |  | -			       func->old_name); | 
|---|
| 747 |  | -			return -ENOENT; | 
|---|
| 748 |  | -		} | 
|---|
| 749 |  | -	} | 
|---|
| 750 |  | - | 
|---|
| 751 |  | -	return 0; | 
|---|
| 752 |  | -} | 
|---|
| 753 |  | - | 
|---|
| 754 |  | -static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | 
|---|
| 755 |  | -{ | 
|---|
| 756 |  | -	struct klp_func *func; | 
|---|
| 757 |  | -	int ret; | 
|---|
| 758 |  | -	const char *name; | 
|---|
| 759 |  | - | 
|---|
| 760 |  | -	if (!obj->funcs) | 
|---|
| 761 |  | -		return -EINVAL; | 
|---|
| 762 |  | - | 
|---|
| 763 |  | -	if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN) | 
|---|
| 764 |  | -		return -EINVAL; | 
|---|
| 765 |  | - | 
|---|
| 766 |  | -	obj->patched = false; | 
|---|
| 767 |  | -	obj->mod = NULL; | 
|---|
| 768 |  | - | 
|---|
| 769 |  | -	klp_find_object_module(obj); | 
|---|
| 770 |  | - | 
|---|
| 771 |  | -	name = klp_is_module(obj) ? obj->name : "vmlinux"; | 
|---|
| 772 |  | -	ret = kobject_init_and_add(&obj->kobj, &klp_ktype_object, | 
|---|
| 773 |  | -				   &patch->kobj, "%s", name); | 
|---|
| 774 |  | -	if (ret) | 
|---|
| 775 |  | -		return ret; | 
|---|
| 776 |  | - | 
|---|
| 777 |  | -	klp_for_each_func(obj, func) { | 
|---|
| 778 |  | -		ret = klp_init_func(obj, func); | 
|---|
| 779 |  | -		if (ret) | 
|---|
| 780 |  | -			goto free; | 
|---|
| 781 |  | -	} | 
|---|
| 782 |  | - | 
|---|
| 783 |  | -	if (klp_is_object_loaded(obj)) { | 
|---|
| 784 |  | -		ret = klp_init_object_loaded(patch, obj); | 
|---|
| 785 |  | -		if (ret) | 
|---|
| 786 |  | -			goto free; | 
|---|
| 787 |  | -	} | 
|---|
| 788 |  | - | 
|---|
| 789 |  | -	return 0; | 
|---|
| 790 |  | - | 
|---|
| 791 |  | -free: | 
|---|
| 792 |  | -	klp_free_funcs_limited(obj, func); | 
|---|
| 793 |  | -	kobject_put(&obj->kobj); | 
|---|
| 794 |  | -	return ret; | 
|---|
| 795 |  | -} | 
|---|
| 796 |  | - | 
|---|
| 797 |  | -static int klp_init_patch(struct klp_patch *patch) | 
|---|
| 798 |  | -{ | 
|---|
| 799 |  | -	struct klp_object *obj; | 
|---|
| 800 |  | -	int ret; | 
|---|
| 801 |  | - | 
|---|
| 802 |  | -	if (!patch->objs) | 
|---|
| 803 |  | -		return -EINVAL; | 
|---|
| 804 |  | - | 
|---|
| 805 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 806 |  | - | 
|---|
| 807 |  | -	patch->enabled = false; | 
|---|
| 808 |  | -	init_completion(&patch->finish); | 
|---|
| 809 |  | - | 
|---|
| 810 |  | -	ret = kobject_init_and_add(&patch->kobj, &klp_ktype_patch, | 
|---|
| 811 |  | -				   klp_root_kobj, "%s", patch->mod->name); | 
|---|
| 812 |  | -	if (ret) { | 
|---|
| 813 |  | -		mutex_unlock(&klp_mutex); | 
|---|
| 814 |  | -		return ret; | 
|---|
| 815 |  | -	} | 
|---|
| 816 |  | - | 
|---|
| 817 |  | -	klp_for_each_object(patch, obj) { | 
|---|
| 818 |  | -		ret = klp_init_object(patch, obj); | 
|---|
| 819 |  | -		if (ret) | 
|---|
| 820 |  | -			goto free; | 
|---|
| 821 |  | -	} | 
|---|
| 822 |  | - | 
|---|
| 823 |  | -	list_add_tail(&patch->list, &klp_patches); | 
|---|
| 824 |  | - | 
|---|
| 825 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 826 |  | - | 
|---|
| 827 |  | -	return 0; | 
|---|
| 828 |  | - | 
|---|
| 829 |  | -free: | 
|---|
| 830 |  | -	klp_free_objects_limited(patch, obj); | 
|---|
| 831 |  | - | 
|---|
| 832 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 833 |  | - | 
|---|
| 834 |  | -	kobject_put(&patch->kobj); | 
|---|
| 835 |  | -	wait_for_completion(&patch->finish); | 
|---|
| 836 |  | - | 
|---|
| 837 |  | -	return ret; | 
|---|
| 838 |  | -} | 
|---|
| 839 |  | - | 
|---|
| 840 |  | -/** | 
|---|
| 841 |  | - * klp_unregister_patch() - unregisters a patch | 
|---|
| 842 |  | - * @patch:	Disabled patch to be unregistered | 
|---|
| 843 |  | - * | 
|---|
| 844 |  | - * Frees the data structures and removes the sysfs interface. | 
|---|
| 845 |  | - * | 
|---|
| 846 |  | - * Return: 0 on success, otherwise error | 
|---|
| 847 |  | - */ | 
|---|
| 848 |  | -int klp_unregister_patch(struct klp_patch *patch) | 
|---|
| 849 |  | -{ | 
|---|
| 850 |  | -	int ret; | 
|---|
| 851 |  | - | 
|---|
| 852 |  | -	mutex_lock(&klp_mutex); | 
|---|
| 853 |  | - | 
|---|
| 854 |  | -	if (!klp_is_patch_registered(patch)) { | 
|---|
| 855 |  | -		ret = -EINVAL; | 
|---|
| 856 |  | -		goto err; | 
|---|
| 857 |  | -	} | 
|---|
| 858 |  | - | 
|---|
| 859 |  | -	if (patch->enabled) { | 
|---|
| 860 |  | -		ret = -EBUSY; | 
|---|
| 861 |  | -		goto err; | 
|---|
| 862 |  | -	} | 
|---|
| 863 |  | - | 
|---|
| 864 |  | -	klp_free_patch(patch); | 
|---|
| 865 |  | - | 
|---|
| 866 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 867 |  | - | 
|---|
| 868 |  | -	kobject_put(&patch->kobj); | 
|---|
| 869 |  | -	wait_for_completion(&patch->finish); | 
|---|
| 870 |  | - | 
|---|
| 871 |  | -	return 0; | 
|---|
| 872 |  | -err: | 
|---|
| 873 |  | -	mutex_unlock(&klp_mutex); | 
|---|
| 874 |  | -	return ret; | 
|---|
| 875 |  | -} | 
|---|
| 876 |  | -EXPORT_SYMBOL_GPL(klp_unregister_patch); | 
|---|
| 877 |  | - | 
|---|
| 878 |  | -/** | 
|---|
| 879 |  | - * klp_register_patch() - registers a patch | 
|---|
| 880 |  | - * @patch:	Patch to be registered | 
|---|
| 881 |  | - * | 
|---|
| 882 |  | - * Initializes the data structure associated with the patch and | 
|---|
| 883 |  | - * creates the sysfs interface. | 
|---|
| 884 |  | - * | 
|---|
| 885 |  | - * There is no need to take the reference on the patch module here. It is done | 
|---|
| 886 |  | - * later when the patch is enabled. | 
|---|
| 887 |  | - * | 
|---|
| 888 |  | - * Return: 0 on success, otherwise error | 
|---|
| 889 |  | - */ | 
|---|
| 890 |  | -int klp_register_patch(struct klp_patch *patch) | 
|---|
| 891 |  | -{ | 
|---|
| 892 | 1029 | if (!patch || !patch->mod) | 
|---|
| 893 | 1030 | return -EINVAL; | 
|---|
| 894 | 1031 |  | 
|---|
| .. | .. | 
|---|
| 902 | 1039 | return -ENODEV; | 
|---|
| 903 | 1040 |  | 
|---|
| 904 | 1041 | if (!klp_have_reliable_stack()) { | 
|---|
| 905 |  | -		pr_err("This architecture doesn't have support for the livepatch consistency model.\n"); | 
|---|
| 906 |  | -		return -ENOSYS; | 
|---|
|  | 1042 | +		pr_warn("This architecture doesn't have support for the livepatch consistency model.\n"); | 
|---|
|  | 1043 | +		pr_warn("The livepatch transition may never complete.\n"); | 
|---|
| 907 | 1044 | } | 
|---|
| 908 | 1045 |  | 
|---|
| 909 |  | -	return klp_init_patch(patch); | 
|---|
|  | 1046 | +	mutex_lock(&klp_mutex); | 
|---|
|  | 1047 | + | 
|---|
|  | 1048 | +	if (!klp_is_patch_compatible(patch)) { | 
|---|
|  | 1049 | +		pr_err("Livepatch patch (%s) is not compatible with the already installed livepatches.\n", | 
|---|
|  | 1050 | +			patch->mod->name); | 
|---|
|  | 1051 | +		mutex_unlock(&klp_mutex); | 
|---|
|  | 1052 | +		return -EINVAL; | 
|---|
|  | 1053 | +	} | 
|---|
|  | 1054 | + | 
|---|
|  | 1055 | +	ret = klp_init_patch_early(patch); | 
|---|
|  | 1056 | +	if (ret) { | 
|---|
|  | 1057 | +		mutex_unlock(&klp_mutex); | 
|---|
|  | 1058 | +		return ret; | 
|---|
|  | 1059 | +	} | 
|---|
|  | 1060 | + | 
|---|
|  | 1061 | +	ret = klp_init_patch(patch); | 
|---|
|  | 1062 | +	if (ret) | 
|---|
|  | 1063 | +		goto err; | 
|---|
|  | 1064 | + | 
|---|
|  | 1065 | +	ret = __klp_enable_patch(patch); | 
|---|
|  | 1066 | +	if (ret) | 
|---|
|  | 1067 | +		goto err; | 
|---|
|  | 1068 | + | 
|---|
|  | 1069 | +	mutex_unlock(&klp_mutex); | 
|---|
|  | 1070 | + | 
|---|
|  | 1071 | +	return 0; | 
|---|
|  | 1072 | + | 
|---|
|  | 1073 | +err: | 
|---|
|  | 1074 | +	klp_free_patch_start(patch); | 
|---|
|  | 1075 | + | 
|---|
|  | 1076 | +	mutex_unlock(&klp_mutex); | 
|---|
|  | 1077 | + | 
|---|
|  | 1078 | +	klp_free_patch_finish(patch); | 
|---|
|  | 1079 | + | 
|---|
|  | 1080 | +	return ret; | 
|---|
| 910 | 1081 | } | 
|---|
| 911 |  | -EXPORT_SYMBOL_GPL(klp_register_patch); | 
|---|
|  | 1082 | +EXPORT_SYMBOL_GPL(klp_enable_patch); | 
|---|
|  | 1083 | + | 
|---|
|  | 1084 | +/* | 
|---|
|  | 1085 | + * This function unpatches objects from the replaced livepatches. | 
|---|
|  | 1086 | + * | 
|---|
|  | 1087 | + * We could be pretty aggressive here. It is called in the situation where | 
|---|
|  | 1088 | + * these structures are no longer accessed from the ftrace handler. | 
|---|
|  | 1089 | + * All functions are redirected by the klp_transition_patch. They | 
|---|
|  | 1090 | + * use either a new code or they are in the original code because | 
|---|
|  | 1091 | + * of the special nop function patches. | 
|---|
|  | 1092 | + * | 
|---|
|  | 1093 | + * The only exception is when the transition was forced. In this case, | 
|---|
|  | 1094 | + * klp_ftrace_handler() might still see the replaced patch on the stack. | 
|---|
|  | 1095 | + * Fortunately, it is carefully designed to work with removed functions | 
|---|
|  | 1096 | + * thanks to RCU. We only have to keep the patches on the system. Also | 
|---|
|  | 1097 | + * this is handled transparently by patch->module_put. | 
|---|
|  | 1098 | + */ | 
|---|
|  | 1099 | +void klp_unpatch_replaced_patches(struct klp_patch *new_patch) | 
|---|
|  | 1100 | +{ | 
|---|
|  | 1101 | +	struct klp_patch *old_patch; | 
|---|
|  | 1102 | + | 
|---|
|  | 1103 | +	klp_for_each_patch(old_patch) { | 
|---|
|  | 1104 | +		if (old_patch == new_patch) | 
|---|
|  | 1105 | +			return; | 
|---|
|  | 1106 | + | 
|---|
|  | 1107 | +		old_patch->enabled = false; | 
|---|
|  | 1108 | +		klp_unpatch_objects(old_patch); | 
|---|
|  | 1109 | +	} | 
|---|
|  | 1110 | +} | 
|---|
|  | 1111 | + | 
|---|
|  | 1112 | +/* | 
|---|
|  | 1113 | + * This function removes the dynamically allocated 'nop' functions. | 
|---|
|  | 1114 | + * | 
|---|
|  | 1115 | + * We could be pretty aggressive. NOPs do not change the existing | 
|---|
|  | 1116 | + * behavior except for adding unnecessary delay by the ftrace handler. | 
|---|
|  | 1117 | + * | 
|---|
|  | 1118 | + * It is safe even when the transition was forced. The ftrace handler | 
|---|
|  | 1119 | + * will see a valid ops->func_stack entry thanks to RCU. | 
|---|
|  | 1120 | + * | 
|---|
|  | 1121 | + * We could even free the NOPs structures. They must be the last entry | 
|---|
|  | 1122 | + * in ops->func_stack. Therefore unregister_ftrace_function() is called. | 
|---|
|  | 1123 | + * It does the same as klp_synchronize_transition() to make sure that | 
|---|
|  | 1124 | + * nobody is inside the ftrace handler once the operation finishes. | 
|---|
|  | 1125 | + * | 
|---|
|  | 1126 | + * IMPORTANT: It must be called right after removing the replaced patches! | 
|---|
|  | 1127 | + */ | 
|---|
|  | 1128 | +void klp_discard_nops(struct klp_patch *new_patch) | 
|---|
|  | 1129 | +{ | 
|---|
|  | 1130 | +	klp_unpatch_objects_dynamic(klp_transition_patch); | 
|---|
|  | 1131 | +	klp_free_objects_dynamic(klp_transition_patch); | 
|---|
|  | 1132 | +} | 
|---|
| 912 | 1133 |  | 
|---|
| 913 | 1134 | /* | 
|---|
| 914 | 1135 | * Remove parts of patches that touch a given kernel module. The list of | 
|---|
| .. | .. | 
|---|
| 921 | 1142 | struct klp_patch *patch; | 
|---|
| 922 | 1143 | struct klp_object *obj; | 
|---|
| 923 | 1144 |  | 
|---|
| 924 |  | -	list_for_each_entry(patch, &klp_patches, list) { | 
|---|
|  | 1145 | +	klp_for_each_patch(patch) { | 
|---|
| 925 | 1146 | if (patch == limit) | 
|---|
| 926 | 1147 | break; | 
|---|
| 927 | 1148 |  | 
|---|
| .. | .. | 
|---|
| 929 | 1150 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) | 
|---|
| 930 | 1151 | continue; | 
|---|
| 931 | 1152 |  | 
|---|
| 932 |  | -			/* | 
|---|
| 933 |  | -			 * Only unpatch the module if the patch is enabled or | 
|---|
| 934 |  | -			 * is in transition. | 
|---|
| 935 |  | -			 */ | 
|---|
| 936 |  | -			if (patch->enabled || patch == klp_transition_patch) { | 
|---|
|  | 1153 | +			if (patch != klp_transition_patch) | 
|---|
|  | 1154 | +				klp_pre_unpatch_callback(obj); | 
|---|
| 937 | 1155 |  | 
|---|
| 938 |  | -				if (patch != klp_transition_patch) | 
|---|
| 939 |  | -					klp_pre_unpatch_callback(obj); | 
|---|
|  | 1156 | +			pr_notice("reverting patch '%s' on unloading module '%s'\n", | 
|---|
|  | 1157 | +				  patch->mod->name, obj->mod->name); | 
|---|
|  | 1158 | +			klp_unpatch_object(obj); | 
|---|
| 940 | 1159 |  | 
|---|
| 941 |  | -				pr_notice("reverting patch '%s' on unloading module '%s'\n", | 
|---|
| 942 |  | -					  patch->mod->name, obj->mod->name); | 
|---|
| 943 |  | -				klp_unpatch_object(obj); | 
|---|
| 944 |  | - | 
|---|
| 945 |  | -				klp_post_unpatch_callback(obj); | 
|---|
| 946 |  | -			} | 
|---|
|  | 1160 | +			klp_post_unpatch_callback(obj); | 
|---|
| 947 | 1161 |  | 
|---|
| 948 | 1162 | klp_free_object_loaded(obj); | 
|---|
| 949 | 1163 | break; | 
|---|
| .. | .. | 
|---|
| 960 | 1174 | if (WARN_ON(mod->state != MODULE_STATE_COMING)) | 
|---|
| 961 | 1175 | return -EINVAL; | 
|---|
| 962 | 1176 |  | 
|---|
|  | 1177 | +	if (!strcmp(mod->name, "vmlinux")) { | 
|---|
|  | 1178 | +		pr_err("vmlinux.ko: invalid module name"); | 
|---|
|  | 1179 | +		return -EINVAL; | 
|---|
|  | 1180 | +	} | 
|---|
|  | 1181 | + | 
|---|
| 963 | 1182 | mutex_lock(&klp_mutex); | 
|---|
| 964 | 1183 | /* | 
|---|
| 965 | 1184 | * Each module has to know that klp_module_coming() | 
|---|
| .. | .. | 
|---|
| 968 | 1187 | */ | 
|---|
| 969 | 1188 | mod->klp_alive = true; | 
|---|
| 970 | 1189 |  | 
|---|
| 971 |  | -	list_for_each_entry(patch, &klp_patches, list) { | 
|---|
|  | 1190 | +	klp_for_each_patch(patch) { | 
|---|
| 972 | 1191 | klp_for_each_object(patch, obj) { | 
|---|
| 973 | 1192 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) | 
|---|
| 974 | 1193 | continue; | 
|---|
| .. | .. | 
|---|
| 981 | 1200 | patch->mod->name, obj->mod->name, ret); | 
|---|
| 982 | 1201 | goto err; | 
|---|
| 983 | 1202 | } | 
|---|
| 984 |  | - | 
|---|
| 985 |  | -			/* | 
|---|
| 986 |  | -			 * Only patch the module if the patch is enabled or is | 
|---|
| 987 |  | -			 * in transition. | 
|---|
| 988 |  | -			 */ | 
|---|
| 989 |  | -			if (!patch->enabled && patch != klp_transition_patch) | 
|---|
| 990 |  | -				break; | 
|---|
| 991 | 1203 |  | 
|---|
| 992 | 1204 | pr_notice("applying patch '%s' to loading module '%s'\n", | 
|---|
| 993 | 1205 | patch->mod->name, obj->mod->name); | 
|---|
| .. | .. | 
|---|
| 1055 | 1267 |  | 
|---|
| 1056 | 1268 | static int __init klp_init(void) | 
|---|
| 1057 | 1269 | { | 
|---|
| 1058 |  | -	int ret; | 
|---|
| 1059 |  | - | 
|---|
| 1060 |  | -	ret = klp_check_compiler_support(); | 
|---|
| 1061 |  | -	if (ret) { | 
|---|
| 1062 |  | -		pr_info("Your compiler is too old; turning off.\n"); | 
|---|
| 1063 |  | -		return -EINVAL; | 
|---|
| 1064 |  | -	} | 
|---|
| 1065 |  | - | 
|---|
| 1066 | 1270 | klp_root_kobj = kobject_create_and_add("livepatch", kernel_kobj); | 
|---|
| 1067 | 1271 | if (!klp_root_kobj) | 
|---|
| 1068 | 1272 | return -ENOMEM; | 
|---|