FBSD: Use ucontext for FreeBSD 10+ on amd64 91/13691/5
authorAndrew Deason <adeason@dson.org>
Sun, 14 Jul 2019 22:31:30 +0000 (17:31 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Mon, 26 Aug 2019 00:00:29 +0000 (20:00 -0400)
Currently, running any LWP program on recent FreeBSD on amd64 causes
(or can cause) a SIGBUS very quickly. This is possibly because our
stack management code in LWP only ensures our stacks are 4 or 8-byte
aligned in most cases (except DARWIN, which gets 16-byte-aligned
stacks), according to the value of STACK_ALIGN. The amd64 ABI mandates
that stacks be 16-byte-aligned, and some function calls assume that
this is followed, causing a SIGBUS when it is not. FreeBSD on amd64
currently uses process.amd64.s for its savecontext() implementation,
which does not do any checking or fixup of the stack alignment.

This behavior has been observed on amd64 with FreeBSD 11 specifically,
but it probably happens on any FreeBSD release when using clang.
FreeBSD switched to clang as the default compiler with FreeBSD 10, so
this probably occurs with FreeBSD 10 and newer.

We could perhaps try to fix this by changing our stack management
code, but we can also avoid most of this nonsense by just using
ucontext instead of our custom assembly code. So, do that, by setting
USE_UCONTEXT for FreeBSD 10+. Also enable the same 'stackvar'-based
workaround in savecontext() as Linux uses, since otherwise 'topstack'
appears to always be NULL, and triggers our stack overflow checks.

Note that while LWP use is deprecated, as of this commit many small
utilities (like 'fs') are still linked to LWP, and so are unusable
without a fix like this.

Change-Id: Ie8e928bd71e7f6e9c0fb1379259c55527b6ccdf3
Reviewed-on: https://gerrit.openafs.org/13691
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: Benjamin Kaduk <kaduk@mit.edu>

src/config/param.amd64_fbsd_100.h
src/config/param.amd64_fbsd_101.h
src/config/param.amd64_fbsd_102.h
src/config/param.amd64_fbsd_103.h
src/config/param.amd64_fbsd_104.h
src/config/param.amd64_fbsd_110.h
src/config/param.amd64_fbsd_111.h
src/config/param.amd64_fbsd_112.h
src/config/param.amd64_fbsd_120.h
src/lwp/Makefile.in
src/lwp/process.c

index 7a8a265..3b38a43 100644 (file)
@@ -79,4 +79,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index d092cd9..7ca16ca 100644 (file)
@@ -82,4 +82,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index 6aad21d..424fb33 100644 (file)
@@ -85,4 +85,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index b768999..5121e6d 100644 (file)
@@ -88,4 +88,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index 26950fa..05d0305 100644 (file)
@@ -91,4 +91,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index 2e896a8..72b371a 100644 (file)
@@ -82,4 +82,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index 7c3af71..167314e 100644 (file)
@@ -94,4 +94,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index f7d9e9b..254b2bd 100644 (file)
@@ -97,4 +97,6 @@
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index 2398c50..2179a81 100644 (file)
 
 #endif /* !defined(UKERNEL) */
 
+#define USE_UCONTEXT
+
 #endif /* AFS_PARAM_H */
index 46561f1..6fe5396 100644 (file)
@@ -130,6 +130,8 @@ process.o   : process.default.s process.i386.s process.amd64.s process.c lwp.o
                ${CCOBJ} -DIGNORE_STDS_H -E -I${srcdir} -I${TOP_INCDIR} process.S > process.s ; \
                ${AS} process.s -o process.o ;  \
                $(RM) -f process.s process.S ;;\
+       amd64_fbsd_1??) \
+               $(AFS_CCRULE_NOQ) -c ${srcdir}/process.c;; \
        amd64_*bsd*) \
                cp ${srcdir}/process.amd64.s process.S ; \
                ${CCOBJ} -DIGNORE_STDS_H -E -I${srcdir} -I${TOP_INCDIR} process.S > process.s ; \
index 45520ef..9540571 100644 (file)
@@ -26,23 +26,27 @@ extern char PRE_Block;              /* used in lwp.c and process.s */
 
 #if defined(USE_UCONTEXT) && defined(HAVE_UCONTEXT_H)
 
+# if defined(AFS_LINUX20_ENV) || defined(AFS_XBSD_ENV)
+#  define AFS_UCONTEXT_NOSTACK
+# endif
+
 afs_int32
 savecontext(void (*ep) (void), struct lwp_context *savearea, char *newsp)
 {
-#if defined(AFS_LINUX20_ENV)
+# ifdef AFS_UCONTEXT_NOSTACK
     /* getcontext does not export stack info */
     int stackvar;
-#endif
+# endif
 
     PRE_Block = 1;
 
     savearea->state = 0;
     getcontext(&savearea->ucontext);
-#if defined(AFS_LINUX20_ENV)
+# ifdef AFS_UCONTEXT_NOSTACK
     savearea->topstack = (char *)&stackvar;
-#else
+# else
     savearea->topstack = savearea->ucontext.uc_stack.ss_sp;
-#endif
+# endif
     switch (savearea->state) {
     case 0:
        if (newsp) {