[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHk-=whkEXGOCEZFO2vAZ9rDd8uW8MJwFNYg9KXaC_vZVso6iA@mail.gmail.com>
Date: Wed, 24 Jan 2024 14:10:54 -0800
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: Xi Ruoyao <xry111@...111.site>
Cc: Andreas Schwab <schwab@...e.de>, Ben Hutchings <ben@...adent.org.uk>, linux-mips@...r.kernel.org,
linux-kernel@...r.kernel.org, Jiaxun Yang <jiaxun.yang@...goat.com>,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>, libc-alpha@...rceware.org
Subject: Re: Strange EFAULT on mips64el returned by syscall when another
thread is forking
On Wed, 24 Jan 2024 at 13:54, Linus Torvalds
<torvalds@...ux-foundation.org> wrote:
>
>
> And I think the "fails with any integer in [1, 8)" is because the MIPS
> "copy_from_user()" code is likely doing something special for those
> small copies.
Lcopy_bytes_checklen\@: does COPY_BYTE(0) for the first access, which is
#define COPY_BYTE(N) \
LOADB(t0, N(src), .Ll_exc\@); \
SUB len, len, 1; \
beqz len, .Ldone\@; \
STOREB(t0, N(dst), .Ls_exc_p1\@)
so yeah, for 'copy_to_user()" (which is what that "read (fd, buf, 7)"
will do, we have that user space write ("STOREB()") in the branch
delay slot of the length test.
So that matches.
And it only fails when
(a) you're unlucky, and that stack buffer
char buf[16] = {};
happens to be just under the last page that has been accessed, so
you get a page fault
(b) you hit a mmap_sem already being locked, presumably because
another thread is doing that fork().
Anyway, I'm pretty sure this is the bug, now some MIPS person just
needs to fix the MIPS version of "instruction_pointer()" to do what
"exception_epc()" already does.
Linus
Powered by blists - more mailing lists