aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiroslav Benes <mbenes@suse.cz>2016-04-28 10:34:08 -0400
committerJiri Kosina <jkosina@suse.cz>2016-04-29 18:04:08 -0400
commitf09d90864eb7cc00cadbbfd083b4eff84c167981 (patch)
tree67671556a815610742c7680e4c7a32bd25bf4740
parent0f49fc95b86fc77b867d643e2d38bc9f28035ed4 (diff)
livepatch: make object/func-walking helpers more robust
Current object-walking helper checks the presence of obj->funcs to determine the end of objs array in klp_object structure. This is somewhat fragile because one can easily forget about funcs definition during livepatch creation. In such a case the livepatch module is successfully loaded and all objects after the incorrect one are omitted. This is very confusing. Let's make the helper more robust and check also for the other external member, name. Thus the helper correctly stops on an empty item of the array. We need to have a check for obj->funcs in klp_init_object() to make it work. The same applies to a func-walking helper. As a benefit we'll check for new_func member definition during the livepatch initialization. There is no such check anywhere in the code now. [jkosina@suse.cz: fix shortlog] Signed-off-by: Miroslav Benes <mbenes@suse.cz> Acked-by: Josh Poimboeuf <jpoimboe@redhat.com> Acked-by: Jessica Yu <jeyu@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--include/linux/livepatch.h6
-rw-r--r--kernel/livepatch/core.c3
2 files changed, 7 insertions, 2 deletions
diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h
index bd830d590465..90843ccb7852 100644
--- a/include/linux/livepatch.h
+++ b/include/linux/livepatch.h
@@ -124,10 +124,12 @@ struct klp_patch {
124}; 124};
125 125
126#define klp_for_each_object(patch, obj) \ 126#define klp_for_each_object(patch, obj) \
127 for (obj = patch->objs; obj->funcs; obj++) 127 for (obj = patch->objs; obj->funcs || obj->name; obj++)
128 128
129#define klp_for_each_func(obj, func) \ 129#define klp_for_each_func(obj, func) \
130 for (func = obj->funcs; func->old_name; func++) 130 for (func = obj->funcs; \
131 func->old_name || func->new_func || func->old_sympos; \
132 func++)
131 133
132int klp_register_patch(struct klp_patch *); 134int klp_register_patch(struct klp_patch *);
133int klp_unregister_patch(struct klp_patch *); 135int klp_unregister_patch(struct klp_patch *);
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index d68fbf63b083..ddef649a2914 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -683,6 +683,9 @@ static void klp_free_patch(struct klp_patch *patch)
683 683
684static int klp_init_func(struct klp_object *obj, struct klp_func *func) 684static int klp_init_func(struct klp_object *obj, struct klp_func *func)
685{ 685{
686 if (!func->old_name || !func->new_func)
687 return -EINVAL;
688
686 INIT_LIST_HEAD(&func->stack_node); 689 INIT_LIST_HEAD(&func->stack_node);
687 func->state = KLP_DISABLED; 690 func->state = KLP_DISABLED;
688 691