Skip to content

Commit 5aaf1ab

Browse files
pmladekJiri Kosina
authored andcommitted
livepatch: Correctly call klp_post_unpatch_callback() in error paths
The post_unpatch_enabled flag in struct klp_callbacks is set when a pre-patch callback successfully executes, indicating that we need to call a corresponding post-unpatch callback when the patch is reverted. This is true for ordinary patch disable as well as the error paths of klp_patch_object() callers. As currently coded, we inadvertently execute the post-patch callback twice in klp_module_coming() when klp_patch_object() fails: - We explicitly call klp_post_unpatch_callback() for the failed object - We call it again for the same object (and all the others) via klp_cleanup_module_patches_limited() We should clear the flag in klp_post_unpatch_callback() to make sure that the callback is not called twice. It makes the API more safe. (We could have removed the callback from the former error path as it would be covered by the latter call, but I think that is is cleaner to clear the post_unpatch_enabled after its invoked. For example, someone might later decide to call the callback only when obj->patched flag is set.) There is another mistake in the error path of klp_coming_module() in which it skips the post-unpatch callback for the klp_transition_patch. However, the pre-patch callback was called even for this patch, so be sure to make the corresponding callbacks for all patches. Finally, I used this opportunity to make klp_pre_patch_callback() more readable. [[email protected]: incorporate changelog wording changes proposed by Joe Lawrence] Signed-off-by: Petr Mladek <[email protected]> Acked-by: Joe Lawrence <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent af02679 commit 5aaf1ab

File tree

2 files changed

+6
-6
lines changed

2 files changed

+6
-6
lines changed

kernel/livepatch/core.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -894,9 +894,7 @@ int klp_module_coming(struct module *mod)
894894
pr_warn("failed to apply patch '%s' to module '%s' (%d)\n",
895895
patch->mod->name, obj->mod->name, ret);
896896

897-
if (patch != klp_transition_patch)
898-
klp_post_unpatch_callback(obj);
899-
897+
klp_post_unpatch_callback(obj);
900898
goto err;
901899
}
902900

kernel/livepatch/core.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ static inline bool klp_is_object_loaded(struct klp_object *obj)
1212

1313
static inline int klp_pre_patch_callback(struct klp_object *obj)
1414
{
15-
int ret;
15+
int ret = 0;
1616

17-
ret = (obj->callbacks.pre_patch) ?
18-
(*obj->callbacks.pre_patch)(obj) : 0;
17+
if (obj->callbacks.pre_patch)
18+
ret = (*obj->callbacks.pre_patch)(obj);
1919

2020
obj->callbacks.post_unpatch_enabled = !ret;
2121

@@ -39,6 +39,8 @@ static inline void klp_post_unpatch_callback(struct klp_object *obj)
3939
if (obj->callbacks.post_unpatch_enabled &&
4040
obj->callbacks.post_unpatch)
4141
(*obj->callbacks.post_unpatch)(obj);
42+
43+
obj->callbacks.post_unpatch_enabled = false;
4244
}
4345

4446
#endif /* _LIVEPATCH_CORE_H */

0 commit comments

Comments
 (0)