arm64: __clear_user: handle exceptions on strb
authorKyle McMartin <kyle@redhat.com>
Wed, 12 Nov 2014 21:07:44 +0000 (21:07 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Thu, 13 Nov 2014 15:21:26 +0000 (15:21 +0000)
commit97fc15436b36ee3956efad83e22a557991f7d19d
tree15caad126a18f7e2db8f4764e3e9c08fde8c29c9
parent287e8c6a41749e5affd6a4faa6a6102ba1594406
arm64: __clear_user: handle exceptions on strb

ARM64 currently doesn't fix up faults on the single-byte (strb) case of
__clear_user... which means that we can cause a nasty kernel panic as an
ordinary user with any multiple PAGE_SIZE+1 read from /dev/zero.
i.e.: dd if=/dev/zero of=foo ibs=1 count=1 (or ibs=65537, etc.)

This is a pretty obscure bug in the general case since we'll only
__do_kernel_fault (since there's no extable entry for pc) if the
mmap_sem is contended. However, with CONFIG_DEBUG_VM enabled, we'll
always fault.

if (!down_read_trylock(&mm->mmap_sem)) {
if (!user_mode(regs) && !search_exception_tables(regs->pc))
goto no_context;
retry:
down_read(&mm->mmap_sem);
} else {
/*
 * The above down_read_trylock() might have succeeded in
 * which
 * case, we'll have missed the might_sleep() from
 * down_read().
 */
might_sleep();
if (!user_mode(regs) && !search_exception_tables(regs->pc))
goto no_context;
}

Fix that by adding an extable entry for the strb instruction, since it
touches user memory, similar to the other stores in __clear_user.

Signed-off-by: Kyle McMartin <kyle@redhat.com>
Reported-by: Miloš Prchlík <mprchlik@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/lib/clear_user.S