Received: by 10.223.185.116 with SMTP id b49csp1023197wrg; Wed, 21 Feb 2018 10:44:16 -0800 (PST) X-Google-Smtp-Source: AH8x2278YV3QHKfCVKGABqDp3jtsis4pP2i+EvaJreGiNDZ3byop6z/2QhNRyYvVYm9SIg0cjDgT X-Received: by 10.98.77.66 with SMTP id a63mr2068533pfb.112.1519238656552; Wed, 21 Feb 2018 10:44:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519238656; cv=none; d=google.com; s=arc-20160816; b=Q4GBcJtf590VwxnHaSFGvEyZTSChqqGFyXAeCmp6FyJLgVcTZ7TuXKAKBlbKu97k8b di0yPrNemPF/ektpoVR5UneuUU5zd5cgdyO//hA6IkQ07IbIJlk1jI5MWpMItJSD+ca/ 2vxrp/ZpR1E8d8bLd8AVEgo2JM9qzbiOqc6CpLUQcnaT/dtyXzIxQirqGtSxGsoqukox 51QwUOt+YUWEyw09DYx+TzGjAna8rM7k8Vvrlw3wMNwgZlkOGop+MKunC51a4SocCIF+ 3YshwA9OtaXZmDhHIegszr+lI+aaFPd7CZxtZu4VYLMsAYXLTZFt+S3IgRpmCkM+zeaU KnWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=VbVd459xIwCeAuaHo1CSfeom8+LdDq8BpZxHpSKcRhQ=; b=hEr9xYJ/8iVp9BlmYV1Iz8oq929KYJVIfiu1bvXhSh6OgtF8hxdLnJk+Na2eqN3GYU YQkDeA6l3JUgEBeTaMgOwTYptffvbl3Dq22eQIa1ovI+ttSgNLWB5vhu1TlDPCaI6qFo ocKpQkJqRAbnvFJj4iCU7zIU2Fcse5d5HNBzIsSgJ0bfxuYW8+CznTEI9jXbW8NoPUNQ SKLUaDc9kcpl+SwPdDLA0CRyF97LYuTcDhjXLmPR5F9QLPKfHFsxIEj8NEst+frxPiUy VjcDUTHk6Dcq52IwlY8yqSfpWtiw91qz2uvnuCcq14ZTQCjk53hxogMdUb1H592PkANX SR/w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v2si11196582pgf.530.2018.02.21.10.44.02; Wed, 21 Feb 2018 10:44:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936832AbeBUN3z (ORCPT + 99 others); Wed, 21 Feb 2018 08:29:55 -0500 Received: from mx2.suse.de ([195.135.220.15]:49114 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934599AbeBUN3u (ORCPT ); Wed, 21 Feb 2018 08:29:50 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 0B4E7AC87; Wed, 21 Feb 2018 13:29:49 +0000 (UTC) From: Petr Mladek To: Jiri Kosina , Josh Poimboeuf , Miroslav Benes Cc: Jason Baron , Joe Lawrence , Jessica Yu , Evgenii Shatokhin , live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Petr Mladek Subject: [PATCH v8 7/8] livepatch: Correctly handle atomic replace for not yet loaded modules Date: Wed, 21 Feb 2018 14:29:13 +0100 Message-Id: <20180221132914.4809-8-pmladek@suse.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180221132914.4809-1-pmladek@suse.com> References: <20180221132914.4809-1-pmladek@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The atomic replace feature uses dynamically allocated struct klp_func to handle functions that will not longer be patched. These structures are of the type KLP_FUNC_NOP. They cause the ftrace handler to jump to the original code. But the address of the original code is not known until the patched module is loaded. This patch allows the late initialization. Also it adds a sanity check into the ftrace handler. Alternative solution would be to do not set the address at all. The ftrace handler could just return to the original code when NOP struct klp_func is used. But this would require another changes. For example, in the stack checking. Note that NOP structures might be available even when the patch is being disabled. This would happen when the patch enable transition is reverted. Signed-off-by: Petr Mladek --- kernel/livepatch/core.c | 16 ++++++++++++++-- kernel/livepatch/patch.c | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index ad508a86b2f9..da1438d47d83 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -945,8 +945,12 @@ static void klp_free_object_loaded(struct klp_object *obj) obj->mod = NULL; - klp_for_each_func(obj, func) + klp_for_each_func(obj, func) { func->old_addr = 0; + + if (klp_is_func_type(func, KLP_FUNC_NOP)) + func->new_func = NULL; + } } /* @@ -984,7 +988,12 @@ 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) + if (!func->old_name) + return -EINVAL; + + /* NOPs do not know the address until the patched module is loaded. */ + if (!func->new_func && + (!klp_is_func_type(func, KLP_FUNC_NOP) || klp_is_object_loaded(obj))) return -EINVAL; INIT_LIST_HEAD(&func->stack_node); @@ -1039,6 +1048,9 @@ static int klp_init_object_loaded(struct klp_patch *patch, return -ENOENT; } + if (klp_is_func_type(func, KLP_FUNC_NOP)) + func->new_func = (void *)func->old_addr; + ret = kallsyms_lookup_size_offset((unsigned long)func->new_func, &func->new_size, NULL); if (!ret) { diff --git a/kernel/livepatch/patch.c b/kernel/livepatch/patch.c index 54b3c379bb0f..1f5c3eea9ee1 100644 --- a/kernel/livepatch/patch.c +++ b/kernel/livepatch/patch.c @@ -118,7 +118,12 @@ static void notrace klp_ftrace_handler(unsigned long ip, } } + /* Survive ugly mistakes, for example, when handling NOPs. */ + if (WARN_ON_ONCE(!func->new_func)) + goto unlock; + klp_arch_set_pc(regs, (unsigned long)func->new_func); + unlock: preempt_enable_notrace(); } -- 2.13.6