All of lore.kernel.org
 help / color / mirror / Atom feed
From: ben-linux@fluff.org (Ben Dooks)
To: linux-arm-kernel@lists.infradead.org
Subject: kernel virtual memory access (from app) does not generate segfault
Date: Tue, 20 Apr 2010 18:09:44 +0100	[thread overview]
Message-ID: <20100420170944.GE2234@trinity.fluff.org> (raw)
In-Reply-To: <20100420142047.GA7398@desktop>

On Tue, Apr 20, 2010 at 10:20:47PM +0800, anfei wrote:
> On Tue, Apr 20, 2010 at 11:27:40AM +0100, Dave P. Martin wrote:
> >  
> > 
> > > -----Original Message-----
> > > From: linux-arm-kernel-bounces at lists.infradead.org 
> > > [mailto:linux-arm-kernel-bounces at lists.infradead.org] On 
> > > Behalf Of Ben Dooks
> > > Sent: 20 April 2010 10:35
> > > To: Sasha Sirotkin
> > > Cc: linux-arm-kernel at lists.infradead.org
> > > Subject: Re: kernel virtual memory access (from app) does not 
> > 
> > [..]
> > 
> > > > For instance, this code generates a segfault allright
> > > >
> > > > int * aa;
> > > > aa = 0xc0000000;
> > > > *aa=42;
> > > >
> > > > However this code does not, instead the process simply 
> > > hangs (and can 
> > > > be
> > > > killed)
> > > >
> > > > void (*func)(void);
> > > > func = 0xc0000000;
> > > > func();
> > > 
> > > Your first example writes to an area, your second is 
> > > execution. IIRC, this version of the ARM architecture equates 
> > > read and execute permission and so you may actually have 
> > > permission to read this area and thus execute code in it.
> > > 
> > > > I stumbled across this by accident. Just curious to 
> > > understand why it 
> > > > happens. Isn't it a bug ?
> > > 
> > > Don't think so, other than you might not want that area to be 
> > > readable by user space?
> > 
> > I tried reading that address (albeit on an old 2.6.28 kernel), and I get a
> > segfault.
> > 
> > Trying to execute in kernel space is the only thing that appears to hang.
> > Attaching to the process in gdb, I observed that pc is always 0xc0000000
> > when the process is stopped.
> > 
> > top accounts most of the CPU time as being consumed in the kernel.
> > 
> > I think what is going on here is that the kernel is catching the expected
> > prefetch abort, but the handler fails to send SIGSEGV to the user process
> > --- the process is resumed with the same pc and we end up in an endless
> > spin.
> > 
> > This only appears to apply to certain address ranges: substituting some
> > other random unmapped address for 0xc0000000 (0x48000000 worked for me), we
> > get the expected segfault.
> > 
> > Does the prefetch abort handler assume that lr >= 0xc0000000 implies the
> > fault came from inside the kernel?  Should it?
> > 
> > arch/arm/mm/fault.c has:
> > 
> > /* 
> > ...
> >  * If the address is in kernel space (>= TASK_SIZE), then we are
> >  * probably faulting in the vmalloc() area.
> > ...
> > */
> > static int __kprobes
> > do_translation_fault(unsigned long addr, unsigned int fsr,
> >                      struct pt_regs *regs)
> > {
> > ...
> >         if (addr < TASK_SIZE)
> >                 return do_page_fault(addr, fsr, regs);
> > 
> > So the common case for userspace prefetch aborts is do_page_fault()
> > 
> > This suggests that the weirdness is caused by something in the remainder of
> > do_translation_fault(), or something it calls.
> > 
> > 
> > The comment preceding do_translation_fault() suggests a possible unsafe
> > assumption which could lead to a security hole... but it really depends on
> > what the handler code is trying to do.  Unfortunately, my understanding has
> > broken down by this point.
> > 
> > Is someone else able to comment on how this code responds to a user fault >=
> > TASK_SIZE?
> > 
> I think something like this is needed:
> 
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index 9d40c34..cd4d15c 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -393,6 +393,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
>  	if (addr < TASK_SIZE)
>  		return do_page_fault(addr, fsr, regs);
>  
> +	if (user_mode(regs) && addr >= TASK_SIZE)
> +		goto bad_area;
> +

technically, addr >= TASK_SIZE was guaranteed by the previous test
on addr. The user_mode(regs) may well be a good idea, although I'm
not sure if we get entered here if the kernel is attempting to access
user-mode memory by forcing unpriveldged accesses.

probably best to get Russell's opinion.

-- 
Ben

Q:      What's a light-year?
A:      One-third less calories than a regular year.

  reply	other threads:[~2010-04-20 17:09 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-20  9:14 kernel virtual memory access (from app) does not generate segfault Sasha Sirotkin
2010-04-20  9:34 ` Ben Dooks
2010-04-20 10:27   ` Dave P. Martin
2010-04-20 14:20     ` anfei
2010-04-20 17:09       ` Ben Dooks [this message]
2010-04-20 19:28         ` Russell King - ARM Linux
2010-04-20 22:31           ` Jamie Lokier
2010-04-20 22:41             ` Russell King - ARM Linux
2010-04-21  0:33               ` Jamie Lokier
2010-04-21 11:17               ` kernel virtual memory access (from app) does not generatesegfault Dave P. Martin
2010-04-21 12:43                 ` anfei
2010-04-21 16:07                   ` Dave P. Martin
2010-04-21 19:16                     ` Jamie Lokier
2010-04-21 19:40                       ` Russell King - ARM Linux
2010-04-21 21:00                         ` Jamie Lokier
2010-04-21 19:36                   ` Russell King - ARM Linux
2010-04-21 19:35                 ` Russell King - ARM Linux
2010-04-21 21:24                   ` Nicolas Pitre
2010-04-21 21:44                     ` Russell King - ARM Linux
2010-04-21 21:54                       ` Russell King - ARM Linux
2010-04-21 22:59                         ` Nicolas Pitre
2010-04-22 10:56                           ` Dave P. Martin
2010-04-22 12:29                             ` anfei
2010-04-22 13:18                               ` Dave P. Martin
2010-04-22 15:59                                 ` Jamie Lokier
2010-04-21 13:11           ` kernel virtual memory access (from app) does not generate segfault anfei
2010-04-21 19:45             ` Jamie Lokier
2010-06-08 13:29             ` anfei
2010-06-08 13:36               ` Russell King - ARM Linux
2010-06-08 14:19                 ` anfei

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=20100420170944.GE2234@trinity.fluff.org \
    --to=ben-linux@fluff.org \
    --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.