NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-amd64/54052: bump STACK_ALIGNBYTES for COMPAT_LINUX



>Number:         54052
>Category:       port-amd64
>Synopsis:       bump STACK_ALIGNBYTES for COMPAT_LINUX
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-amd64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 11 05:50:00 +0000 2019
>Originator:     Rin Okuyama
>Release:        HEAD
>Organization:
Department of Physics, Meiji University
>Environment:
NetBSD kobrpd02 8.99.35 NetBSD 8.99.35 (AMD64) #0: Sun Mar 10 22:31:53 JST 2019  rin@latipes:/build/src/sys/arch/amd64/compile/AMD64 amd64
>Description:
Linux binaries with glibc >= 2.23 randomly crashes in dynamic linker.
By bisectioning, the cause turns out to be this commit

https://github.molgen.mpg.de/git-mirror/glibc/commit/38d22f9f48a84b441c5777aff103f5b980243b5f

where -mno-sse flag is removed for ld.so. Due to SSE instructions,
Linux binaries now requires stack is aligned in 16-byte boundary.

Bump STACK_ALIGNBYTES for amd64 to (16 - 1) fixes problems.

Note that there's no similar problem for i386.
>How-To-Repeat:
Mount Linux userland with glibc >= 2.23 into /emul/linux.
(e.g., Fedora 24 and 29 uses glibc 2.23 and 2.28, respectively.)

Then, dynamic-link binaries receives SIGSEGV randomly in
/emul/linux/lib64/ld-linux-x86-64.so.2.

The following are objdump near address which causes SIGSEGV:

    c224:       66 0f ef c0             pxor   %xmm0,%xmm0
--> c228:       0f 29 45 90             movaps %xmm0,-0x70(%rbp)
    c22c:       0f 29 45 a0             movaps %xmm0,-0x60(%rbp)
    c230:       0f 29 45 b0             movaps %xmm0,-0x50(%rbp)
    c234:       0f 29 45 c0             movaps %xmm0,-0x40(%rbp)

movaps is a SSE instruction, for which destination address should be
aligned to 16-byte boundary. This code is generated from code segment
something like:

---
	struct {
		long l[2];
		int i[2];
	} s[2] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
	...
---

Linux binaries now requires stack is aligned to 16-byte boundary.
Bumping STACK_ALIGN from __ALIGNBYTES = (8 - 1) to (16 - 1) fixes the
problem.

For i386, GCC does not generate SSE instructions for that code
even if -msse is specified.
>Fix:
Index: sys/arch/amd64/include/param.h
===================================================================
RCS file: /home/netbsd/src/sys/arch/amd64/include/param.h,v
retrieving revision 1.29
diff -p -u -r1.29 param.h
--- sys/arch/amd64/include/param.h	11 Feb 2019 14:59:32 -0000	1.29
+++ sys/arch/amd64/include/param.h	10 Mar 2019 13:12:11 -0000
@@ -23,6 +23,8 @@
 
 #define ALIGNED_POINTER(p,t)	1
 
+#define STACK_ALIGNBYTES	(16 - 1)	/* COMPAT_LINUX */
+
 #define ALIGNBYTES32		(sizeof(int) - 1)
 #define ALIGN32(p)		(((u_long)(p) + ALIGNBYTES32) &~ALIGNBYTES32)
 



Home | Main Index | Thread Index | Old Index