Re: [PATCH v12 07/12] livepatch: Use lists to manage patches, objects and functions

From: Miroslav Benes
Date: Mon Sep 03 2018 - 12:00:51 EST



> -#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. One could argue that it is a
responsibility of the user not to do such a silly thing, but since the
check is already there, could you move klp_init_lists() call after the
check?

Regards,
Miroslav