Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162678671
D57955.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D57955.diff
View Options
diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c
--- a/lib/libc/gen/posix_spawn.c
+++ b/lib/libc/gen/posix_spawn.c
@@ -28,6 +28,7 @@
#include "namespace.h"
#include <sys/param.h>
+#include <sys/mman.h>
#include <sys/procctl.h>
#include <sys/procdesc.h>
#include <sys/queue.h>
@@ -231,19 +232,7 @@
volatile int error;
};
-#define PSPAWN_STACK_ALIGNMENT 16
-#define PSPAWN_STACK_ALIGNBYTES (PSPAWN_STACK_ALIGNMENT - 1)
-#define PSPAWN_STACK_ALIGN(sz) \
- (((sz) + PSPAWN_STACK_ALIGNBYTES) & ~PSPAWN_STACK_ALIGNBYTES)
-
-/*
- * Below we'll assume that _RFORK_THREAD_STACK_SIZE is appropriately aligned for
- * the posix_spawn() case where we do not end up calling execvpe and won't ever
- * try to allocate space on the stack for argv[].
- */
#define _RFORK_THREAD_STACK_SIZE 4096
-_Static_assert((_RFORK_THREAD_STACK_SIZE % PSPAWN_STACK_ALIGNMENT) == 0,
- "Inappropriate stack size alignment");
static int
_posix_spawn_thr(void *data)
@@ -285,11 +274,13 @@
pid_t p;
int pfd;
bool do_pfd;
- char *stack;
- size_t stacksz;
+ char *guard, *stack;
+ size_t stacksz, pagesz;
#if defined(__i386__) || defined(__amd64__)
stacksz = _RFORK_THREAD_STACK_SIZE;
+ pagesz = getpagesize();
+
if (use_env_path) {
size_t cnt;
@@ -304,24 +295,21 @@
for (cnt = 0; argv[cnt] != NULL; ++cnt)
;
stacksz += MAX(3, cnt + 2) * sizeof(char *);
- stacksz = PSPAWN_STACK_ALIGN(stacksz);
}
- /*
- * aligned_alloc is not safe to use here, because we can't guarantee
- * that aligned_alloc and free will be provided by the same
- * implementation. We've actively hit at least one application that
- * will provide its own malloc/free but not aligned_alloc leading to
- * a free by the wrong allocator.
- */
- stack = malloc(stacksz);
- if (stack == NULL)
+ stacksz = round_page(stacksz);
+ guard = mmap(NULL, stacksz + pagesz, 0, MAP_GUARD, -1, 0);
+ if (guard == MAP_FAILED)
return (ENOMEM);
- stacksz = (((uintptr_t)stack + stacksz) & ~PSPAWN_STACK_ALIGNBYTES) -
- (uintptr_t)stack;
+ stack = mmap(guard + pagesz, stacksz, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);
+ if (stack == MAP_FAILED) {
+ munmap(guard, stacksz + pagesz);
+ return (ENOMEM);
+ }
#else
- stack = NULL;
- stacksz = 0;
+ guard = stack = NULL;
+ pagesz = stacksz = 0;
#endif
psa.path = path;
psa.fa = fa;
@@ -362,7 +350,8 @@
p = rfork_thread(RFSPAWN, stack + stacksz, _posix_spawn_thr,
&psa);
}
- free(stack);
+ if (stack != NULL)
+ munmap(guard, stacksz + pagesz);
/*
* The above block should leave us in a state where we've either
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 16, 4:21 PM (8 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34526135
Default Alt Text
D57955.diff (2 KB)
Attached To
Mode
D57955: posix_spawn(): create a guard page below the stack for rfork_thread
Attached
Detach File
Event Timeline
Log In to Comment