Skip to content

Commit f7fb1cb

Browse files
liu-song-6opsiff
authored andcommitted
livepatch: Match old_sympos 0 and 1 in klp_find_func()
[ Upstream commit 139560e ] When there is only one function of the same name, old_sympos of 0 and 1 are logically identical. Match them in klp_find_func(). This is to avoid a corner case with different toolchain behavior. In this specific issue, two versions of kpatch-build were used to build livepatch for the same kernel. One assigns old_sympos == 0 for unique local functions, the other assigns old_sympos == 1 for unique local functions. Both versions work fine by themselves. (PS: This behavior change was introduced in a downstream version of kpatch-build. This change does not exist in upstream kpatch-build.) However, during livepatch upgrade (with the replace flag set) from a patch built with one version of kpatch-build to the same fix built with the other version of kpatch-build, livepatching fails with errors like: [ 14.218706] sysfs: cannot create duplicate filename 'xxx/somefunc,1' ... [ 14.219466] Call Trace: [ 14.219468] <TASK> [ 14.219469] dump_stack_lvl+0x47/0x60 [ 14.219474] sysfs_warn_dup.cold+0x17/0x27 [ 14.219476] sysfs_create_dir_ns+0x95/0xb0 [ 14.219479] kobject_add_internal+0x9e/0x260 [ 14.219483] kobject_add+0x68/0x80 [ 14.219485] ? kstrdup+0x3c/0xa0 [ 14.219486] klp_enable_patch+0x320/0x830 [ 14.219488] patch_init+0x443/0x1000 [ccc_0_6] [ 14.219491] ? 0xffffffffa05eb000 [ 14.219492] do_one_initcall+0x2e/0x190 [ 14.219494] do_init_module+0x67/0x270 [ 14.219496] init_module_from_file+0x75/0xa0 [ 14.219499] idempotent_init_module+0x15a/0x240 [ 14.219501] __x64_sys_finit_module+0x61/0xc0 [ 14.219503] do_syscall_64+0x5b/0x160 [ 14.219505] entry_SYSCALL_64_after_hwframe+0x4b/0x53 [ 14.219507] RIP: 0033:0x7f545a4bd96d ... [ 14.219516] kobject: kobject_add_internal failed for somefunc,1 with -EEXIST, don't try to register things with the same name ... This happens because klp_find_func() thinks somefunc with old_sympos==0 is not the same as somefunc with old_sympos==1, and klp_add_object_nops adds another xxx/func,1 to the list of functions to patch. Signed-off-by: Song Liu <song@kernel.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> [pmladek@suse.com: Fixed some typos.] Reviewed-by: Petr Mladek <pmladek@suse.com> Tested-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit c9266cafb2772d7ff3adae699b86b2e12d6d4d5f) Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
1 parent a23d9de commit f7fb1cb

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

kernel/livepatch/core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,14 @@ static struct klp_func *klp_find_func(struct klp_object *obj,
8888
struct klp_func *func;
8989

9090
klp_for_each_func(obj, func) {
91+
/*
92+
* Besides identical old_sympos, also consider old_sympos
93+
* of 0 and 1 are identical.
94+
*/
9195
if ((strcmp(old_func->old_name, func->old_name) == 0) &&
92-
(old_func->old_sympos == func->old_sympos)) {
96+
((old_func->old_sympos == func->old_sympos) ||
97+
(old_func->old_sympos == 0 && func->old_sympos == 1) ||
98+
(old_func->old_sympos == 1 && func->old_sympos == 0))) {
9399
return func;
94100
}
95101
}

0 commit comments

Comments
 (0)