Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752672AbcD1OeO (ORCPT ); Thu, 28 Apr 2016 10:34:14 -0400 Received: from mx2.suse.de ([195.135.220.15]:44484 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752207AbcD1OeN (ORCPT ); Thu, 28 Apr 2016 10:34:13 -0400 From: Miroslav Benes To: jpoimboe@redhat.com, jeyu@redhat.com, jikos@kernel.org, pmladek@suse.com Cc: live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Miroslav Benes Subject: [PATCH] klp: make object/func-walking helpers more robust Date: Thu, 28 Apr 2016 16:34:08 +0200 Message-Id: <1461854048-31473-1-git-send-email-mbenes@suse.cz> X-Mailer: git-send-email 2.8.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2065 Lines: 57 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. Signed-off-by: Miroslav Benes --- include/linux/livepatch.h | 6 ++++-- kernel/livepatch/core.c | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index 0933ca47791c..a93a0b23dc8d 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -104,10 +104,12 @@ struct klp_patch { }; #define klp_for_each_object(patch, obj) \ - for (obj = patch->objs; obj->funcs; obj++) + for (obj = patch->objs; obj->funcs || obj->name; obj++) #define klp_for_each_func(obj, func) \ - for (func = obj->funcs; func->old_name; func++) + for (func = obj->funcs; \ + func->old_name || func->new_func || func->old_sympos; \ + func++) int klp_register_patch(struct klp_patch *); int klp_unregister_patch(struct klp_patch *); diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index a19f1954f4ac..5c2bc1052691 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -747,6 +747,9 @@ static void klp_free_patch(struct klp_patch *patch) static int klp_init_func(struct klp_object *obj, struct klp_func *func) { + if (!func->old_name || !func->new_func) + return -EINVAL; + INIT_LIST_HEAD(&func->stack_node); func->state = KLP_DISABLED; -- 2.8.1