All of lore.kernel.org
 help / color / mirror / Atom feed
From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] arm64: kprobe: make page to RO mode when allocate it
Date: Mon, 29 Oct 2018 17:02:26 +0000	[thread overview]
Message-ID: <20181029170226.GA16739@arm.com> (raw)
In-Reply-To: <CAK8P3a0oSn8Z6wJT1X2si8+A2wttkh7EjqD_MZYt4+L5a_XKLg@mail.gmail.com>

On Mon, Oct 29, 2018 at 01:11:24PM +0100, Arnd Bergmann wrote:
> On 10/29/18, Will Deacon <will.deacon@arm.com> wrote:
> > On Mon, Oct 15, 2018 at 01:16:00PM +0200, Anders Roxell wrote:
> 
> >> -static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
> >> +void *alloc_insn_page(void)
> >>  {
> >> -	void *addrs[1];
> >> -	u32 insns[1];
> >> +	void *page;
> >>
> >> -	addrs[0] = (void *)addr;
> >> -	insns[0] = (u32)opcode;
> >> +	page = vmalloc_exec(PAGE_SIZE);
> >> +	if (page)
> >> +		set_memory_ro((unsigned long)page & PAGE_MASK, 1);
> >
> > This looks a bit strange to me -- you're allocating PAGE_SIZE bytes so
> > that we can adjust the permissions, yet we can't guarantee that page is
> > actually page-aligned and therefore end up explicitly masking down.
> >
> > In which case allocating an entire page isn't actually helping us, and
> > we could end up racing with somebody else changing permission on the
> > same page afaict.
> >
> > I think we need to ensure we really have an entire page, perhaps using
> > vmap() instead? Or have I missed some subtle detail here?
> 
> I'm fairly sure that vmalloc() and vmalloc_exec() is guaranteed to be page
> aligned everywhere. The documentation is a bit vague here, but I'm
> still confident enough that we can make that assumption based on
> 
> /**
>  *      vmalloc_exec  -  allocate virtually contiguous, executable memory
>  *      @size:          allocation size
>  *
>  *      Kernel-internal function to allocate enough pages to cover @size
>  *      the page level allocator and map them into contiguous and
>  *      executable kernel virtual space.
>  *
>  *      For tight control over page level allocator and protection flags
>  *      use __vmalloc() instead.
>  */
> void *vmalloc_exec(unsigned long size)

FWIW, I did a bit of digging and I agree with your conclusion. vmalloc()
allocations end up getting installed in map_vm_area() via
__vmalloc_area_node(), which allocates things a page at a time.

So we can simplify this patch to drop the masking when calling
set_memory_ro().

Will

WARNING: multiple messages have this Message-ID (diff)
From: Will Deacon <will.deacon@arm.com>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Anders Roxell <anders.roxell@linaro.org>,
	catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Laura Abbott <labbott@redhat.com>
Subject: Re: [PATCH] arm64: kprobe: make page to RO mode when allocate it
Date: Mon, 29 Oct 2018 17:02:26 +0000	[thread overview]
Message-ID: <20181029170226.GA16739@arm.com> (raw)
In-Reply-To: <CAK8P3a0oSn8Z6wJT1X2si8+A2wttkh7EjqD_MZYt4+L5a_XKLg@mail.gmail.com>

On Mon, Oct 29, 2018 at 01:11:24PM +0100, Arnd Bergmann wrote:
> On 10/29/18, Will Deacon <will.deacon@arm.com> wrote:
> > On Mon, Oct 15, 2018 at 01:16:00PM +0200, Anders Roxell wrote:
> 
> >> -static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
> >> +void *alloc_insn_page(void)
> >>  {
> >> -	void *addrs[1];
> >> -	u32 insns[1];
> >> +	void *page;
> >>
> >> -	addrs[0] = (void *)addr;
> >> -	insns[0] = (u32)opcode;
> >> +	page = vmalloc_exec(PAGE_SIZE);
> >> +	if (page)
> >> +		set_memory_ro((unsigned long)page & PAGE_MASK, 1);
> >
> > This looks a bit strange to me -- you're allocating PAGE_SIZE bytes so
> > that we can adjust the permissions, yet we can't guarantee that page is
> > actually page-aligned and therefore end up explicitly masking down.
> >
> > In which case allocating an entire page isn't actually helping us, and
> > we could end up racing with somebody else changing permission on the
> > same page afaict.
> >
> > I think we need to ensure we really have an entire page, perhaps using
> > vmap() instead? Or have I missed some subtle detail here?
> 
> I'm fairly sure that vmalloc() and vmalloc_exec() is guaranteed to be page
> aligned everywhere. The documentation is a bit vague here, but I'm
> still confident enough that we can make that assumption based on
> 
> /**
>  *      vmalloc_exec  -  allocate virtually contiguous, executable memory
>  *      @size:          allocation size
>  *
>  *      Kernel-internal function to allocate enough pages to cover @size
>  *      the page level allocator and map them into contiguous and
>  *      executable kernel virtual space.
>  *
>  *      For tight control over page level allocator and protection flags
>  *      use __vmalloc() instead.
>  */
> void *vmalloc_exec(unsigned long size)

FWIW, I did a bit of digging and I agree with your conclusion. vmalloc()
allocations end up getting installed in map_vm_area() via
__vmalloc_area_node(), which allocates things a page at a time.

So we can simplify this patch to drop the masking when calling
set_memory_ro().

Will

  reply	other threads:[~2018-10-29 17:02 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-15 11:16 [PATCH] arm64: kprobe: make page to RO mode when allocate it Anders Roxell
2018-10-15 11:16 ` Anders Roxell
2018-10-15 11:22 ` Ard Biesheuvel
2018-10-15 11:22   ` Ard Biesheuvel
2018-10-15 12:27   ` Masami Hiramatsu
2018-10-15 12:27     ` Masami Hiramatsu
2018-10-22 10:56 ` Laura Abbott
2018-10-22 10:56   ` Laura Abbott
2018-10-29 12:04 ` Will Deacon
2018-10-29 12:04   ` Will Deacon
2018-10-29 12:11   ` Arnd Bergmann
2018-10-29 12:11     ` Arnd Bergmann
2018-10-29 17:02     ` Will Deacon [this message]
2018-10-29 17:02       ` Will Deacon

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=20181029170226.GA16739@arm.com \
    --to=will.deacon@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /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.