From: Chris J Arges <chris.j.arges@canonical.com>
To: Miroslav Benes <mbenes@suse.cz>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>,
Jiri Kosina <jikos@kernel.org>,
jeyu@redhat.com, eugene.shatokhin@rosalab.ru,
live-patching@vger.kernel.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
pmladek@suse.cz
Subject: Re: Bug with paravirt ops and livepatches
Date: Wed, 6 Apr 2016 11:38:21 +0100 [thread overview]
Message-ID: <20160406103821.GA4968@canonical.com> (raw)
In-Reply-To: <alpine.LNX.2.00.1604061103390.27016@pobox.suse.cz>
On Wed, Apr 06, 2016 at 11:09:04AM +0200, Miroslav Benes wrote:
> On Wed, 6 Apr 2016, Chris J Arges wrote:
>
> > On Tue, Apr 05, 2016 at 03:07:13PM +0200, Miroslav Benes wrote:
> > > On Mon, 4 Apr 2016, Josh Poimboeuf wrote:
> > >
> > > > So I think this doesn't fix the problem. Dynamic relocations are
> > > > applied to the "patch module", whereas the above code deals with the
> > > > initialization order of the "patched module". This distinction
> > > > originally confused me as well, until Jessica set me straight.
> > > >
> > > > Let me try to illustrate the problem with an example. Imagine you have
> > > > a patch module P which applies a patch to module M. P replaces M's
> > > > function F with a new function F', which uses paravirt ops.
> > > >
> > > > 1) Patch P is loaded before module M. P's new function F' has an
> > > > instruction which is patched by apply_paravirt(), even though the
> > > > patch hasn't been applied yet.
> > > >
> > > > 2) Module M is loaded. Before applying the patch, livepatch tries to
> > > > apply a klp_reloc to the instruction in F' which was already patched
> > > > by apply_paravirt() in step 1. This results in undefined behavior
> > > > because it tries to patch the original instruction but instead
> > > > patches the new paravirt instruction.
> > > >
> > > > So the above patch makes no difference because the paravirt module
> > > > loading order doesn't really matter.
> > >
> > > Hi,
> > >
> > > we are trying really hard to understand the actual culprit here and as it
> > > is quite confusing I have several questions/comments...
> > >
> > > 1. can you provide dynrela sections of the patch module from
> > > https://github.com/dynup/kpatch/issues/580? What is interesting is that
> > > kvm_arch_vm_ioctl() function contains rela records only for trivial (==
> > > exported) symbols from the first look. The problem should be there only if
> > > you want to patch a function which reference some paravirt_ops unexported
> > > symbol. For that symbol dynrela should be created.
> > >
> > > 2. I am almost 100 percent sure that the second problem Chris mentions in
> > > github post is something different. If he patches only kvm_arch_vm_ioctl()
> > > so that it calls his exported __kvm_arch_vm_ioctl() duplicate there is no
> > > problem. Because it is a trivial livepatching case. There are no dynrelas
> > > and no alternatives in the patch module. The crash is suspicious and we
> > > have a problem somewhere. Chris, can you please provide more info about
> > > that? That is how exactly you used kallsyms_lookup_name() and so on...
> > >
> >
> > Miroslav,
> >
> > In my original comment I was trying to see if this was a kpatch-build specific
> > issue and that's why I tried to reproduce using just a simple out of tree built
> > livepatch module. For this case I copied kvm_arch_vm_ioctl into
> > __kvm_arch_vm_ioctl (to simplify patching). I then built and installed this
> > base kernel and kvm.ko module. However, for the crashing and non-crashing
> > cases I used two slightly different base kernels and livepatch code.
> >
> > I just re-tested this using the latest livepatch.git/for-next code and have the
> > following:
> >
> > This crashes if I use kallsyms_lookup_name to find the __kvm_arch_vm_ioctl
> > symbol and then call it from my livepatch:
> > http://people.canonical.com/~arges/livepatch_issue/livepatch_kvm_arch_vm_ioctl.crashes/
> >
> > This works if I export __kvm_arch_vm_ioctl in the base kernel, and in the
> > livepatch just call it directly:
> > http://people.canonical.com/~arges/livepatch_issue/livepatch_kvm_arch_vm_ioctl.works/
> >
> > Where livepatch.c is the livepatch and kernel.patch is the base kernel patch for
> > both directories.
>
> Thank you, Chris.
>
> First (before to reproduce it) I have to ask one thing. What is the order
> of module loading? Do you first load kvm.ko and then livepatch or the
> opposite.
>
I just tested this experimentally, in both cases kvm and kvm_intel was loaded
before the livepatch module was inserted. The bug is triggered only when I
actually start the VM and only when using my kallsyms_lookup_name hack.
> It does not matter in the first case where the function is exported.
> Because of it there would be a dependency of the modules so once you load
> livepatch module kvm.ko is loaded before it. This is the only way to do
> it. Undefined symbols of livepatch module are thus easily resolved.
>
> The situation differs in the second case though. You use
> kallsyms_lookup_name to circumvent dynrela for __kvm_arch_vm_ioctl (it is
> not exported now). So when you load livepatch module kallsyms_lookup_name
> would in fact fail and the kernel would then crash. Although the bug would
> be different (NULL pointer dereference) and I guess you are aware of that
> because you have a printk there. But just to make sure...
>
> Thanks
> Miroslav
I think this approach needs more thought and my code has bug(s).
--chris
next prev parent reply other threads:[~2016-04-06 10:38 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-29 12:05 Bug with paravirt ops and livepatches Chris J Arges
2016-03-29 13:01 ` Miroslav Benes
2016-03-29 13:05 ` Jiri Kosina
2016-04-01 15:01 ` Jiri Kosina
2016-04-01 15:46 ` Miroslav Benes
2016-04-01 16:01 ` Chris J Arges
2016-04-01 19:07 ` Chris J Arges
2016-04-01 19:35 ` Jiri Kosina
2016-04-04 16:14 ` Josh Poimboeuf
2016-04-04 17:58 ` Jessica Yu
2016-04-05 13:07 ` Miroslav Benes
2016-04-05 13:53 ` Evgenii Shatokhin
2016-04-05 14:24 ` Josh Poimboeuf
2016-04-05 19:19 ` Jessica Yu
2016-04-06 8:30 ` Miroslav Benes
2016-04-06 8:43 ` Miroslav Benes
2016-04-06 9:09 ` Miroslav Benes
2016-04-06 17:23 ` Jessica Yu
2016-04-06 16:55 ` Jessica Yu
2016-04-05 23:27 ` Chris J Arges
2016-04-06 9:09 ` Miroslav Benes
2016-04-06 10:38 ` Chris J Arges [this message]
2016-04-06 12:09 ` Miroslav Benes
2016-04-06 13:48 ` Chris J Arges
2016-04-06 14:17 ` Miroslav Benes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160406103821.GA4968@canonical.com \
--to=chris.j.arges@canonical.com \
--cc=eugene.shatokhin@rosalab.ru \
--cc=jeyu@redhat.com \
--cc=jikos@kernel.org \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=live-patching@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=pmladek@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox