On Mon 2018-09-03 18:00:45, Miroslav Benes wrote: > > > -#define klp_for_each_object(patch, obj) \ > > +#define klp_for_each_object_static(patch, obj) \ > > for (obj = patch->objs; obj->funcs || obj->name; obj++) > > > > -#define klp_for_each_func(obj, func) \ > > +#define klp_for_each_object(patch, obj) \ > > + list_for_each_entry(obj, &patch->obj_list, node) > > + > > +#define klp_for_each_func_static(obj, func) \ > > for (func = obj->funcs; \ > > func->old_name || func->new_addr || func->old_sympos; \ > > func++) > > > > +#define klp_for_each_func(obj, func) \ > > + list_for_each_entry(func, &obj->func_list, node) > > + > > int klp_enable_patch(struct klp_patch *); > > > > void arch_klp_init_object_loaded(struct klp_patch *patch, > > diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c > > index 6a47b36a6c9a..7bc23a106b5b 100644 > > --- a/kernel/livepatch/core.c > > +++ b/kernel/livepatch/core.c > > @@ -50,6 +50,21 @@ LIST_HEAD(klp_patches); > > > > static struct kobject *klp_root_kobj; > > > > +static void klp_init_lists(struct klp_patch *patch) > > +{ > > + struct klp_object *obj; > > + struct klp_func *func; > > + > > + INIT_LIST_HEAD(&patch->obj_list); > > + klp_for_each_object_static(patch, obj) { > > + list_add(&obj->node, &patch->obj_list); > > + > > + INIT_LIST_HEAD(&obj->func_list); > > + klp_for_each_func_static(obj, func) > > + list_add(&func->node, &obj->func_list); > > + } > > +} > > + > > static bool klp_is_module(struct klp_object *obj) > > { > > return obj->name; > > @@ -664,6 +679,7 @@ static int klp_init_patch(struct klp_patch *patch) > > patch->module_put = false; > > INIT_LIST_HEAD(&patch->list); > > init_completion(&patch->finish); > > + klp_init_lists(patch); > > This could explode easily if patch->objs is NULL. The check is just below. > > > if (!patch->objs) > > return -EINVAL; > > Here. > > klp_init_lists() calls klp_for_each_object_static() which accesses > obj->name without a check for obj. Great catch! > since the check is already there, could you move klp_init_lists() > call after the check? The same problem is with accessing obj->funcs by klp_for_each_func_static(). I have moved both checks into klp_init_lists(). I made sure that the lists were initialized to be usable with the free functions even in case of error. Best Regards, Petr