]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: hard-fail creating threads before fork()
authorDavid Lamparter <equinox@opensourcerouting.org>
Thu, 22 Apr 2021 10:10:27 +0000 (12:10 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Thu, 22 Apr 2021 11:25:38 +0000 (13:25 +0200)
Creating any threads before we fork() into the background (if `-d` is
given) is an extremely dangerous footgun;  the threads are created in
the parent and terminated when that exits.

This is extra dangerous because while testing, you'd often run the
daemon in foreground without `-d`, and everything works as expected.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/frr_pthread.c
lib/libfrr.c
lib/libfrr.h

index 03359f4d18ea1e1913feeff80bb08a969468be1a..898fe98aada9f712e25dcb3df7b917779f2883ac 100644 (file)
@@ -28,6 +28,7 @@
 #include "memory.h"
 #include "linklist.h"
 #include "zlog.h"
+#include "libfrr.h"
 #include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread");
@@ -162,6 +163,8 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr)
        int ret;
        sigset_t oldsigs, blocksigs;
 
+       assert(frr_is_after_fork || !"trying to start thread before fork()");
+
        /* Ensure we never handle signals on a background thread by blocking
         * everything here (new thread inherits signal mask)
         */
index 38f994bdfc316a416e8f6dfaafcdaae4d8b1209f..970e82c0649c050abaf44c6b7cac61a6e0ae8584 100644 (file)
@@ -70,6 +70,8 @@ static char dbfile_default[512];
 #endif
 static char vtypath_default[512];
 
+/* cleared in frr_preinit(), then re-set after daemonizing */
+bool frr_is_after_fork = true;
 bool debug_memstats_at_exit = false;
 static bool nodetach_term, nodetach_daemon;
 static uint64_t startup_fds;
@@ -308,6 +310,7 @@ void frr_init_vtydir(void)
 void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv)
 {
        di = daemon;
+       frr_is_after_fork = false;
 
        /* basename(), opencoded. */
        char *p = strrchr(argv[0], '/');
@@ -990,6 +993,8 @@ void frr_config_fork(void)
        if (di->daemon_mode || di->terminal)
                frr_daemonize();
 
+       frr_is_after_fork = true;
+
        if (!di->pid_file)
                di->pid_file = pidfile_default;
        pid_output(di->pid_file);
index 47ded8f313f49715be5f369045790a36e7c6d378..3dc5d7af81db4c30fb4c04bfc53c4757cadfa3b6 100644 (file)
@@ -172,6 +172,8 @@ extern const char frr_scriptdir[];
 
 extern char frr_protoname[];
 extern char frr_protonameinst[];
+/* always set in the spot where we *would* fork even if we don't do so */
+extern bool frr_is_after_fork;
 
 extern bool debug_memstats_at_exit;