1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-24 06:04:05 +03:00

basic: add comments about raw_clone() calls not supporting threads/malloc in child

This commit is contained in:
Lennart Poettering 2023-06-22 10:21:32 +02:00
parent c26d7837bb
commit 01ab446c35
2 changed files with 12 additions and 2 deletions

View File

@ -141,6 +141,11 @@ int must_be_root(void);
pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata);
/* 💣 Note that FORK_NEW_USERNS + FORK_NEW_MOUNTNS should not be called in threaded programs, because they
* cause us to use raw_clone() which does not synchronize the glibc malloc() locks, and thus will cause
* deadlocks if the parent uses threads and the child does memory allocations. Hence: if the parent is
* threaded these flags may not be used. These flags cannot be used if the parent uses threads or the child
* uses malloc(). 💣 */
typedef enum ForkFlags {
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
@ -150,13 +155,13 @@ typedef enum ForkFlags {
FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */
FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */
FORK_WAIT = 1 << 7, /* Wait until child exited */
FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace */
FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */
FORK_PRIVATE_TMP = 1 << 10, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */
FORK_RLIMIT_NOFILE_SAFE = 1 << 11, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
FORK_STDOUT_TO_STDERR = 1 << 12, /* Make stdout a copy of stderr */
FORK_FLUSH_STDIO = 1 << 13, /* fflush() stdout (and stderr) before forking */
FORK_NEW_USERNS = 1 << 14, /* Run child in its own user namespace */
FORK_NEW_USERNS = 1 << 14, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
FORK_CLOEXEC_OFF = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
FORK_KEEP_NOTIFY_SOCKET = 1 << 16, /* Unless this specified, $NOTIFY_SOCKET will be unset. */
} ForkFlags;

View File

@ -27,6 +27,11 @@
* Additionally, as this function does not pass the ptid, newtls and ctid parameters to the kernel, flags must not
* contain CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID or CLONE_SETTLS.
*
* WARNING: 💣 this call (just like glibc's own clone() wrapper) will not synchronize on glibc's malloc
* locks, which means they will be in an undefined state in the child if the parent is
* threaded. This means: the parent must either never use threads, or the child cannot use memory
* allocation itself. This is a major pitfall, hence be careful! 💣
*
* Returns: 0 in the child process and the child process id in the parent.
*/
static inline pid_t raw_clone(unsigned long flags) {