Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250321170417.2959-1-Kenji.Mouri@outlook.com>
Date: Sat, 22 Mar 2025 01:04:16 +0800
From: MouriNaruto <mourinaruto@...il.com>
To: musl@...ts.openwall.com
Cc: MouriNaruto <Kenji.Mouri@...look.com>
Subject: [PATCH] workaround the issue that pthread_getattr_np won't return in FreeBSD Linuxulator

Some notes from Kenji Mouri (MouriNaruto) about this workaround:

I tried to use musl-based userspace in FreeBSD's Linuxulator, I found some
Node.js based app will hung at startup. I did some investigations and finally
found that caused by the mremap loop in the musl's pthread_getattr_np. I read
the FreeBSD's Linuxulator source code, it seems mremap in FreeBSD's Linuxulator
in won't support expand the size.

With Edward Tomasz Napierala (https://wiki.freebsd.org/EdwardTomaszNapierala)'s
suggestion, choose to use RLIMIT_STACK _in addition_ to the current measurement
can workaround the issue without doing much modifications.

Consider that getrlimit may failed, so I think we should use __default_stacksize
when getrlimit failed.

I have tested this commit in my FreeBSD environment with Visual Studio Code
Remote SSH server which requires the FreeBSD's Linuxulator.
---
 src/thread/pthread_getattr_np.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/thread/pthread_getattr_np.c b/src/thread/pthread_getattr_np.c
index 2881831f..54b1ba34 100644
--- a/src/thread/pthread_getattr_np.c
+++ b/src/thread/pthread_getattr_np.c
@@ -2,6 +2,7 @@
 #include "pthread_impl.h"
 #include "libc.h"
 #include <sys/mman.h>
+#include <sys/resource.h>
 
 int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
 {
@@ -12,11 +13,19 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
 		a->_a_stackaddr = (uintptr_t)t->stack;
 		a->_a_stacksize = t->stack_size;
 	} else {
+		struct rlimit rl_stack = {0};
+		/* get the current stack limit to workaround the issue */
+		/* that mremap loop won't stop in FreeBSD Linuxulator */
+		if (getrlimit(RLIMIT_STACK, &rl_stack) != 0) {
+			/* use default stack size if getrlimit fails */
+			rl_stack.rlim_cur = __default_stacksize;
+			rl_stack.rlim_max = __default_stacksize;
+		}
 		char *p = (void *)libc.auxv;
 		size_t l = PAGE_SIZE;
 		p += -(uintptr_t)p & PAGE_SIZE-1;
 		a->_a_stackaddr = (uintptr_t)p;
-		while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
+		while (l <= rl_stack.rlim_cur && mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
 			l += PAGE_SIZE;
 		a->_a_stacksize = l;
 	}
-- 
2.47.2

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.