Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751657AbdILWWv (ORCPT ); Tue, 12 Sep 2017 18:22:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52194 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751017AbdILWWs (ORCPT ); Tue, 12 Sep 2017 18:22:48 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7A0164E028 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=jpoimboe@redhat.com Date: Tue, 12 Sep 2017 17:22:45 -0500 From: Josh Poimboeuf To: Joe Lawrence Cc: Miroslav Benes , live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Jessica Yu , Jiri Kosina , Petr Mladek , Chris J Arges Subject: Re: [PATCH v5 1/3] livepatch: add (un)patch callbacks Message-ID: <20170912222245.bzvwzef27ul77xqm@treble> References: <1504191233-2642-1-git-send-email-joe.lawrence@redhat.com> <1504191233-2642-2-git-send-email-joe.lawrence@redhat.com> <20170912220544.zdgh65o4aqmd5ni4@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20170912220544.zdgh65o4aqmd5ni4@redhat.com> User-Agent: Mutt/1.6.0.1 (2016-04-01) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 12 Sep 2017 22:22:48 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3381 Lines: 89 On Tue, Sep 12, 2017 at 06:05:44PM -0400, Joe Lawrence wrote: > On Tue, Sep 12, 2017 at 11:48:48AM -0400, Joe Lawrence wrote: > > On 09/12/2017 04:53 AM, Miroslav Benes wrote: > > >> @@ -871,13 +882,27 @@ int klp_module_coming(struct module *mod) > > >> pr_notice("applying patch '%s' to loading module '%s'\n", > > >> patch->mod->name, obj->mod->name); > > >> > > >> + ret = klp_pre_patch_callback(obj); > > >> + if (ret) { > > >> + pr_warn("pre-patch callback failed for object '%s'\n", > > >> + obj->name); > > >> + goto err; > > >> + } > > > > > > There is a problem here. We cycle through all enabled patches (or > > > klp_transition_patch) and call klp_pre_patch_callback() everytime an > > > enabled patch contains a patch for a coming module. Now, it can easily > > > happen that klp_pre_patch_callback() fails. And not the first one from the > > > first relevant patch, but the next one. In that case we need to call > > > klp_post_unpatch_callback() for all already processed relevant patches in > > > the error path. > > > > Good test case, if I understand you correctly: > > > > - Load target modules mod1 and mod2 > > - Load a livepatch that targets mod1 and mod2 > > - pre-patch succeeds for mod1 > > - pre-patch fails for mod2 > > > > and then we should: > > > > - NOT run post-patch or pre/post-unpatch handlers for mod2 > > - NOT run post-patch or pre-unpatch handlers for mod1 > > - do run post-unpatch handler for mod1 > > - Refuse to load the livepatch > > > > Does that sound right? > > Erm, probably not... > > > > Unfortunately, we need to do the same for klp_patch_object() below, > > > because there is the same problem and we missed it. > > > > > >> + > > >> ret = klp_patch_object(obj); > > >> if (ret) { > > >> pr_warn("failed to apply patch '%s' to module '%s' (%d)\n", > > >> patch->mod->name, obj->mod->name, ret); > > >> + > > >> + if (patch != klp_transition_patch) > > >> + klp_post_unpatch_callback(obj); > > >> + > > >> goto err; > > > > > > Here. > > > > > > Could you do it as a part of the patch set (or send it separately), > > > please? > > I've re-read this a few times, and I think I might have been originally > off-base with what I thought you were concerned about. But I think I > grok it now: the problem you pointed out arises because > klp_module_coming() iterates like so: > > for each klp_patch > for each kobj in klp_patch > > which means that we may have made pre-patch callbacks and patched a > given kobj for an earlier klp_patch that now fails for a later > klp_patch. > > What should be the defined behavior in this case? I would expect that > we need to unpatch all similar kobjs across klp_patches which have > already been successfully patched. In turn, their post-unpatch > callbacks should be invoked. > > If that's true, maybe this would make a better follow-on patch. The rabbit hole seems to be getting deeper, is it really worth it? I'd rather we just make the pre-patch handler return void and be done with it, as Joe originally proposed. So far, allowing the pre-patch handler to halt patching is a purely theoretical feature, nobody even knows if we need it yet, and whether it's worth the pain. So I'd vote to just simplify this mess and let whoever wants the feature try to implement it :-) -- Josh