Commit 5c553d8d authored by Zheng Yejian's avatar Zheng Yejian Committed by Zheng Zengkai
Browse files

livepatch/core: Validate function old_name before 'klp_init_object_loaded'

Offering: HULK
hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4WBFN



--------------------------------

Refer to following procedure:
  klp_init_object
    klp_init_object_loaded
      klp_find_object_symbol <-- 1. oops happened when old_name is NULL!!!
    klp_init_func  <-- 2. currently old_name is first time check here

This problem was introduced in commit 7834e94c ("livepatch/arm64:
Fix func size less than limit") which exchange order of 'klp_init_func'
and 'klp_init_object_loaded' then cause old_name being used before check.

We move these checks before 'klp_init_object_loaded' and add several
logs to tell why check failed.

Fixes: 7834e94c ("livepatch/arm64: Fix func size less than limit")
Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
Reviewed-by: default avatarCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 042bf6a8
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -953,19 +953,6 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func)
	int ret;
#endif

	if (!func->old_name)
		return -EINVAL;

	/*
	 * NOPs get the address later. The patched module must be loaded,
	 * see klp_init_object_loaded().
	 */
	if (!func->new_func && !func->nop)
		return -EINVAL;

	if (strlen(func->old_name) >= KSYM_NAME_LEN)
		return -EINVAL;

	INIT_LIST_HEAD(&func->stack_node);
	func->patched = false;

@@ -1082,6 +1069,24 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)

	if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN)
		return -EINVAL;
	klp_for_each_func(obj, func) {
		if (!func->old_name) {
			pr_err("old name is invalid\n");
			return -EINVAL;
		}
		/*
		 * NOPs get the address later. The patched module must be loaded,
		 * see klp_init_object_loaded().
		 */
		if (!func->new_func && !func->nop) {
			pr_err("new_func is invalid\n");
			return -EINVAL;
		}
		if (strlen(func->old_name) >= KSYM_NAME_LEN) {
			pr_err("function old name is too long\n");
			return -EINVAL;
		}
	}

	obj->patched = false;
	obj->mod = NULL;