From e2cb6559586d4b0d0087c326eac0129fe8661382 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sat, 20 Jun 2020 22:30:12 +0100 Subject: [PATCH] Thorough clean-up following 8270648da1eae77db381b848a47d79b85c206e29. --- src/dnsmasq.c | 53 ++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/dnsmasq.c b/src/dnsmasq.c index e0197af..2306c48 100644 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -1864,31 +1864,30 @@ static void check_dns_listeners(time_t now) else { int i; +#ifdef HAVE_LINUX_NETWORK + /* The child process inherits the netlink socket, + which it never uses, but when the parent (us) + uses it in the future, the answer may go to the + child, resulting in the parent blocking + forever awaiting the result. To avoid this + the child closes the netlink socket, but there's + a nasty race, since the parent may use netlink + before the child has done the close. + + To avoid this, the parent blocks here until a + single byte comes back up the pipe, which + is sent by the child after it has closed the + netlink socket. */ + + unsigned char a; + read_write(pipefd[0], &a, 1, 1); +#endif for (i = 0; i < MAX_PROCS; i++) if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1) { - char a; - (void)a; /* suppress potential unused warning */ - daemon->tcp_pids[i] = p; daemon->tcp_pipes[i] = pipefd[0]; -#ifdef HAVE_LINUX_NETWORK - /* The child process inherits the netlink socket, - which it never uses, but when the parent (us) - uses it in the future, the answer may go to the - child, resulting in the parent blocking - forever awaiting the result. To avoid this - the child closes the netlink socket, but there's - a nasty race, since the parent may use netlink - before the child has done the close. - - To avoid this, the parent blocks here until a - single byte comes back up the pipe, which - is sent by the child after it has closed the - netlink socket. */ - while(retry_send(read(pipefd[0], &a, 1))); -#endif break; } } @@ -1920,16 +1919,16 @@ static void check_dns_listeners(time_t now) terminate the process. */ if (!option_bool(OPT_DEBUG)) { - char a = 0; - (void)a; /* suppress potential unused warning */ +#ifdef HAVE_LINUX_NETWORK + /* See comment above re: netlink socket. */ + unsigned char a = 0; + + close(daemon->netlinkfd); + read_write(pipefd[1], &a, 1, 0); +#endif alarm(CHILD_LIFETIME); close(pipefd[0]); /* close read end in child. */ daemon->pipe_to_parent = pipefd[1]; -#ifdef HAVE_LINUX_NETWORK - /* See comment above re netlink socket. */ - close(daemon->netlinkfd); - while(retry_send(write(pipefd[1], &a, 1))); -#endif } /* start with no upstream connections. */ @@ -1956,8 +1955,10 @@ static void check_dns_listeners(time_t now) shutdown(s->tcpfd, SHUT_RDWR); close(s->tcpfd); } + if (!option_bool(OPT_DEBUG)) { + close(daemon->pipe_to_parent); flush_log(); _exit(0); }