All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.