From: "Dmitry V. Levin" <ldv@altlinux.org>
To: Sergei Trofimovich <slyfox@gentoo.org>,
Matt Turner <mattst88@gmail.com>,
Richard Henderson <rth@twiddle.net>,
Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: linux-alpha@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] alpha: fix page fault handling for r16-r18 targets
Date: Mon, 31 Dec 2018 04:45:15 +0300 [thread overview]
Message-ID: <20181231014515.GA13296@altlinux.org> (raw)
In-Reply-To: <20181230202312.7239-1-slyfox@gentoo.org>
[-- Attachment #1: Type: text/plain, Size: 4812 bytes --]
Hi,
On Sun, Dec 30, 2018 at 08:23:12PM +0000, Sergei Trofimovich wrote:
> Fix page fault handling code to fixup r16-r18 registers.
> Before the patch code had off-by-two registers bug.
> This bug caused overwriting of ps,pc,gp registers instead
> of fixing intended r16,r17,r18 (see `struct pt_regs`).
>
> More details:
>
> Initially Dmitry noticed a kernel bug as a failure
> on strace test suite. Test passes unmapped userspace
> pointer to io_submit:
>
> ```c
> #include <err.h>
> #include <unistd.h>
> #include <sys/mman.h>
> #include <asm/unistd.h>
> int main(void)
> {
> unsigned long ctx = 0;
> if (syscall(__NR_io_setup, 1, &ctx))
> err(1, "io_setup");
> const size_t page_size = sysconf(_SC_PAGESIZE);
> const size_t size = page_size * 2;
> void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
> MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
> if (MAP_FAILED == ptr)
> err(1, "mmap(%zu)", size);
> if (munmap(ptr, size))
> err(1, "munmap");
> syscall(__NR_io_submit, ctx, 1, ptr + page_size);
> syscall(__NR_io_destroy, ctx);
> return 0;
> }
> ```
>
> Running this test causes kernel to crash when handling page fault:
>
> ```
> Unable to handle kernel paging request at virtual address ffffffffffff9468
> CPU 3
> aio(26027): Oops 0
> pc = [<fffffc00004eddf8>] ra = [<fffffc00004edd5c>] ps = 0000 Not tainted
> pc is at sys_io_submit+0x108/0x200
> ra is at sys_io_submit+0x6c/0x200
> v0 = fffffc00c58e6300 t0 = fffffffffffffff2 t1 = 000002000025e000
> t2 = fffffc01f159fef8 t3 = fffffc0001009640 t4 = fffffc0000e0f6e0
> t5 = 0000020001002e9e t6 = 4c41564e49452031 t7 = fffffc01f159c000
> s0 = 0000000000000002 s1 = 000002000025e000 s2 = 0000000000000000
> s3 = 0000000000000000 s4 = 0000000000000000 s5 = fffffffffffffff2
> s6 = fffffc00c58e6300
> a0 = fffffc00c58e6300 a1 = 0000000000000000 a2 = 000002000025e000
> a3 = 00000200001ac260 a4 = 00000200001ac1e8 a5 = 0000000000000001
> t8 = 0000000000000008 t9 = 000000011f8bce30 t10= 00000200001ac440
> t11= 0000000000000000 pv = fffffc00006fd320 at = 0000000000000000
> gp = 0000000000000000 sp = 00000000265fd174
> Disabling lock debugging due to kernel taint
> Trace:
> [<fffffc0000311404>] entSys+0xa4/0xc0
> ```
>
> Here `gp` has invalid value. `gp is s overwritten by a fixup for the
> following page fault handler in `io_submit` syscall handler:
>
> ```
> __se_sys_io_submit
> ...
> ldq a1,0(t1)
> bne t0,4280 <__se_sys_io_submit+0x180>
> ```
>
> After a page fault `t0` should contain -EFALUT and `a1` is 0.
> Instead `gp` was overwritten in place of `a1`.
>
> This happens due to a off-by-two bug in `dpf_reg()` for `r16-r18`
> (aka `a0-a2`).
>
> I think the bug went unnoticed for a long time as `gp` is one
> of scratch registers. Any kernel function call would re-calculate `gp`.
Thanks, that's impressive!
According to the history git, the off-by-two bug was introduced in linux
2.1.32 when trap_a{0,1,2} fields were inserted into struct pt_regs on
alpha without an appropriate dpf_reg() update.
Before 2.1.32 (back to 2.1.7 when dpf_reg() was introduced)
there was another off-by-one bug in dpf_reg(): r16 was written
into struct pt_regs.r17.
In other words, the bug is quite old indeed.
You can add
Reported-and-reviewed-by: "Dmitry V. Levin" <ldv@altlinux.org>
Cc: stable@vger.kernel.org # v2.1.32+
> CC: Dmitry V. Levin <gentoo.dl@altlinux.org>
This is a technical address, please remove it.
> CC: Richard Henderson <rth@twiddle.net>
> CC: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> CC: Matt Turner <mattst88@gmail.com>
> CC: linux-alpha@vger.kernel.org
> CC: linux-kernel@vger.kernel.org
> Reported-by: Dmitry V. Levin
> Bug: https://bugs.gentoo.org/672040
> Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
> ---
> arch/alpha/mm/fault.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
> index d73dc473fbb9..188fc9256baf 100644
> --- a/arch/alpha/mm/fault.c
> +++ b/arch/alpha/mm/fault.c
> @@ -78,7 +78,7 @@ __load_new_mm_context(struct mm_struct *next_mm)
> /* Macro for exception fixup code to access integer registers. */
> #define dpf_reg(r) \
> (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \
> - (r) <= 18 ? (r)+8 : (r)-10])
> + (r) <= 18 ? (r)+10 : (r)-10])
>
> asmlinkage void
> do_page_fault(unsigned long address, unsigned long mmcsr,
> --
> 2.20.1
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
next prev parent reply other threads:[~2018-12-31 1:45 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-30 20:23 [PATCH] alpha: fix page fault handling for r16-r18 targets Sergei Trofimovich
2018-12-31 1:45 ` Dmitry V. Levin [this message]
2018-12-31 11:53 ` [PATCH v2] " Sergei Trofimovich
2019-01-22 7:36 ` Matt Turner
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=20181231014515.GA13296@altlinux.org \
--to=ldv@altlinux.org \
--cc=ink@jurassic.park.msu.ru \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mattst88@gmail.com \
--cc=rth@twiddle.net \
--cc=slyfox@gentoo.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.