Skip to content

Commit b6dc978

Browse files
committed
subprocess-posix: avoid using mmap
1 parent 2f6617d commit b6dc978

1 file changed

Lines changed: 26 additions & 17 deletions

File tree

osdep/subprocess-posix.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ extern char **environ;
3434

3535
#if HAVE_CLONE
3636
#include <sched.h>
37-
#include <sys/mman.h>
3837
#endif
3938

4039
#ifdef SIGRTMAX
@@ -95,25 +94,27 @@ struct child_args {
9594
const char *path;
9695
struct mp_subprocess_opts *opts;
9796
int *src_fds;
97+
void *child_stack;
9898
int pipe_end;
9999
bool detach;
100100
};
101101

102102
static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *opts,
103-
int src_fds[], bool detach);
103+
int src_fds[], bool detach, void *stacks[]);
104104

105105
static int child_main(void* args)
106106
{
107107
struct child_args *child_args = args;
108108
const char *path = child_args->path;
109109
struct mp_subprocess_opts *opts = child_args->opts;
110110
int *src_fds = child_args->src_fds;
111+
void *child_stack = child_args->child_stack;
111112
int *pipe_end = &child_args->pipe_end;
112113
bool detach = child_args->detach;
113114

114115
if (detach) {
115116
setsid();
116-
if (!spawn_process_inner(path, opts, src_fds, false))
117+
if (!spawn_process_inner(path, opts, src_fds, false, &child_stack))
117118
goto child_failed;
118119
return 0;
119120
}
@@ -148,7 +149,7 @@ static int child_main(void* args)
148149
}
149150

150151
static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *opts,
151-
int src_fds[], bool detach)
152+
int src_fds[], bool detach, void *stacks[])
152153
{
153154
pid_t fres = 0;
154155
int r;
@@ -157,21 +158,15 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
157158
.path = path,
158159
.opts = opts,
159160
.src_fds = src_fds,
161+
.child_stack = stacks[1],
160162
.pipe_end = 0,
161163
.detach = detach,
162164
};
163165

164-
#if HAVE_CLONE || HAVE_RFORK
165-
const size_t stack_size = 0x8000;
166-
void* stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
167-
if (stack == MAP_FAILED)
168-
goto done;
169-
#endif
170-
171166
#if HAVE_RFORK
172-
fres = rfork_thread(RFSPAWN, (int8_t*)stack + stack_size, child_main, &child_args);
167+
fres = rfork_thread(RFSPAWN, stacks[0], child_main, &child_args);
173168
#elif HAVE_CLONE
174-
fres = clone(child_main, (int8_t*)stack + stack_size, CLONE_VM | CLONE_VFORK | SIGCHLD, &child_args);
169+
fres = clone(child_main, stacks[0], CLONE_VM | CLONE_VFORK | SIGCHLD, &child_args);
175170
#else
176171
int p[2] = {-1, -1};
177172
// We setup a communication pipe to signal failure. Since the child calls
@@ -219,9 +214,7 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
219214
}
220215

221216
done:
222-
#if HAVE_CLONE || HAVE_RFORK
223-
munmap(stack, stack_size);
224-
#else
217+
#if !HAVE_CLONE && !HAVE_RFORK
225218
SAFE_CLOSE(p[0]);
226219
SAFE_CLOSE(p[1]);
227220
#endif
@@ -234,19 +227,35 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
234227
static pid_t spawn_process(const char *path, struct mp_subprocess_opts *opts,
235228
int src_fds[])
236229
{
230+
bool detach = opts->detach;
231+
void *stacks[2];
232+
233+
#if HAVE_CLONE || HAVE_RFORK
234+
// pre-allocate stacks so we can be async-signal-safe in spawn_process_inner()
235+
const size_t stack_size = 0x8000;
236+
void *ctx = talloc_new(NULL);
237+
// stack should be aligned to 16 bytes, which is guaranteed by malloc
238+
stacks[0] = (int8_t*)talloc_size(ctx, stack_size) + stack_size;
239+
if (detach) stacks[1] = (int8_t*)talloc_size(ctx, stack_size) + stack_size;
240+
#endif
241+
237242
#if !HAVE_RFORK
238243
sigset_t sigmask, oldmask;
239244

240245
sigfillset(&sigmask);
241246
pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
242247
#endif
243248

244-
pid_t fres = spawn_process_inner(path, opts, src_fds, opts->detach);
249+
pid_t fres = spawn_process_inner(path, opts, src_fds, detach, stacks);
245250

246251
#if !HAVE_RFORK
247252
pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
248253
#endif
249254

255+
#if HAVE_CLONE || HAVE_RFORK
256+
talloc_free(ctx);
257+
#endif
258+
250259
return fres;
251260
}
252261

0 commit comments

Comments
 (0)