lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <41f026468cc70abad5e6500657953f5ef575ac81.camel@xry111.site>
Date: Thu, 25 Jan 2024 06:42:17 +0800
From: Xi Ruoyao <xry111@...111.site>
To: Linus Torvalds <torvalds@...ux-foundation.org>
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, 2024-01-24 at 14:10 -0800, Linus Torvalds wrote:
> 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().

So I added a stupid hack:

diff --git a/mm/memory.c b/mm/memory.c
index 7e1f4849463a..e663eb517bbf 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -92,6 +92,12 @@
 #include "internal.h"
 #include "swap.h"
 
+#ifdef __mips__
+#include "asm/branch.h"
+#undef instruction_pointer
+#define instruction_pointer(x) exception_epc(x)
+#endif
+
 #if defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) && !defined(CONFIG_COMPILE_TEST)
 #warning Unfortunate NUMA and NUMA Balancing config, growing page-frame for last_cpupid.
 #endif

and it indeed "solved" the problem.

> 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.

Agree.

-- 
Xi Ruoyao <xry111@...111.site>
School of Aerospace Science and Technology, Xidian University

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ