--- /dev/null
+
+# HG changeset patch
+# User Gian-Carlo Pascutto <gcp@mozilla.com>
+# Date 1628058287 0
+# Node ID 7f9b9624c400dc847dc0053ebe35fbe63353a3d2
+# Parent 958aef401f3c27231c426fc6e00024b0741470a6
+Bug 1721326 - Allow dynamic PTHREAD_STACK_MIN. r=glandium, a=RyanVM
+
+https://phabricator.services.mozilla.com/D120708
+
+Differential Revision: https://phabricator.services.mozilla.com/D120972
+
+diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp
+--- a/js/xpconnect/src/XPCJSContext.cpp
++++ b/js/xpconnect/src/XPCJSContext.cpp
+@@ -81,23 +81,20 @@
+ # include <algorithm>
+ # include <windows.h>
+ #endif
+
+ using namespace mozilla;
+ using namespace xpc;
+ using namespace JS;
+
+-// The watchdog thread loop is pretty trivial, and should not require much stack
+-// space to do its job. So only give it 32KiB or the platform minimum.
++// We will clamp to reasonable values if this isn't set.
+ #if !defined(PTHREAD_STACK_MIN)
+ # define PTHREAD_STACK_MIN 0
+ #endif
+-static constexpr size_t kWatchdogStackSize =
+- PTHREAD_STACK_MIN < 32 * 1024 ? 32 * 1024 : PTHREAD_STACK_MIN;
+
+ static void WatchdogMain(void* arg);
+ class Watchdog;
+ class WatchdogManager;
+ class MOZ_RAII AutoLockWatchdog final {
+ Watchdog* const mWatchdog;
+
+ public:
+@@ -154,22 +151,29 @@ class Watchdog {
+ // extra pages if we can avoid it.
+ nsCOMPtr<nsIDebug2> dbg = do_GetService("@mozilla.org/xpcom/debug;1");
+ Unused << dbg;
+ }
+
+ {
+ AutoLockWatchdog lock(this);
+
++ // The watchdog thread loop is pretty trivial, and should not
++ // require much stack space to do its job. So only give it 32KiB
++ // or the platform minimum. On modern Linux libc this might resolve to
++ // a runtime call.
++ size_t watchdogStackSize = PTHREAD_STACK_MIN;
++ watchdogStackSize = std::max<size_t>(32 * 1024, watchdogStackSize);
++
+ // Gecko uses thread private for accounting and has to clean up at thread
+ // exit. Therefore, even though we don't have a return value from the
+ // watchdog, we need to join it on shutdown.
+ mThread = PR_CreateThread(PR_USER_THREAD, WatchdogMain, this,
+ PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+- PR_JOINABLE_THREAD, kWatchdogStackSize);
++ PR_JOINABLE_THREAD, watchdogStackSize);
+ if (!mThread) {
+ MOZ_CRASH("PR_CreateThread failed!");
+ }
+
+ // WatchdogMain acquires the lock and then asserts mInitialized. So
+ // make sure to set mInitialized before releasing the lock here so
+ // that it's atomic with the creation of the thread.
+ mInitialized = true;
+
+
+# HG changeset patch
+# User stransky <stransky@redhat.com>
+# Date 1628058287 0
+# Node ID 600365d8b24068e8105773830270cf86478aa487
+# Parent 7f9b9624c400dc847dc0053ebe35fbe63353a3d2
+Bug 1721326 - Use small stack for DoClone(). r=jld, a=RyanVM
+
+Patch author is Florian Weimer <fweimer 'at' redhat.com>
+
+Differential Revision: https://phabricator.services.mozilla.com/D120709
+
+diff --git a/security/sandbox/linux/launch/SandboxLaunch.cpp b/security/sandbox/linux/launch/SandboxLaunch.cpp
+--- a/security/sandbox/linux/launch/SandboxLaunch.cpp
++++ b/security/sandbox/linux/launch/SandboxLaunch.cpp
+@@ -504,18 +504,17 @@ static int CloneCallee(void* aPtr) {
+ // stack, not switch stacks.
+ //
+ // Valgrind would disapprove of using clone() without CLONE_VM;
+ // Chromium uses the raw syscall as a workaround in that case, but
+ // we don't currently support sandboxing under valgrind.
+ MOZ_NEVER_INLINE MOZ_ASAN_BLACKLIST static pid_t DoClone(int aFlags,
+ jmp_buf* aCtx) {
+ static constexpr size_t kStackAlignment = 16;
+- uint8_t miniStack[PTHREAD_STACK_MIN]
+- __attribute__((aligned(kStackAlignment)));
++ uint8_t miniStack[4096] __attribute__((aligned(kStackAlignment)));
+ #ifdef __hppa__
+ void* stackPtr = miniStack;
+ #else
+ void* stackPtr = ArrayEnd(miniStack);
+ #endif
+ return clone(CloneCallee, stackPtr, aFlags, aCtx);
+ }
+
+@@ -526,23 +525,29 @@ MOZ_NEVER_INLINE MOZ_ASAN_BLACKLIST stat
+ static pid_t ForkWithFlags(int aFlags) {
+ // Don't allow flags that would share the address space, or
+ // require clone() arguments we're not passing:
+ static const int kBadFlags = CLONE_VM | CLONE_VFORK | CLONE_SETTLS |
+ CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
+ CLONE_CHILD_CLEARTID;
+ MOZ_RELEASE_ASSERT((aFlags & kBadFlags) == 0);
+
++ // Block signals due to small stack in DoClone.
++ sigset_t oldSigs;
++ BlockAllSignals(&oldSigs);
++
++ int ret = 0;
+ jmp_buf ctx;
+ if (setjmp(ctx) == 0) {
+ // In the parent and just called setjmp:
+- return DoClone(aFlags | SIGCHLD, &ctx);
++ ret = DoClone(aFlags | SIGCHLD, &ctx);
+ }
++ RestoreSignals(&oldSigs);
+ // In the child and have longjmp'ed:
+- return 0;
++ return ret;
+ }
+
+ static bool WriteStringToFile(const char* aPath, const char* aStr,
+ const size_t aLen) {
+ int fd = open(aPath, O_WRONLY);
+ if (fd < 0) {
+ return false;
+ }
+