Path: blob/main/dns/dnsmasq/files/patch-src_util.c
16461 views
commit 15841f187d2b208a6113d4e2d479d3af4275bb1c1Author: Simon Kelley <simon@thekelleys.org.uk>2Date: Sun Jun 22 23:04:36 2025 +010034Fix issue with fast file-descriptor close on *BSD.56This fixes a problem introduced in 8a5fe8ce6bb6c2bd81f237a0f4a2583722ffbd1c78On BSD, fdescfs is normally mounted at /dev/fd. However9if it is NOT mounted, devfs creates a directory at /dev/fd10which contains (only) the file descriptors 0,1 and 2.1112Under these conditions, opendir() will succeed, and13if we proceed we will fail to close extant14file descriptors which should be closed.1516Check that there is a filesystem mounted at /dev/fd17by checking that the device changes between /dev/fd18and /dev. If if doesn't, fall back to the dumb path.1920Thanks to Roman Bogorodskiy for spotting the problem21and helping with diagnosis.2223--- src/util.c.orig 2025-03-14 15:09:35 UTC24+++ src/util.c25@@ -34,6 +34,10 @@26#include <sys/utsname.h>27#endif2829+#ifdef HAVE_BSD_NETWORK30+#include <libgen.h>31+#endif32+33/* SURF random number generator */3435static u32 seed[32];36@@ -831,9 +835,34 @@ void close_fds(long max_fd, int spare1, int spare2, in37#endif3839#ifdef FDESCFS40- DIR *d;41+ DIR *d = NULL;4243- if ((d = opendir(FDESCFS)))44+# ifdef HAVE_BSD_NETWORK45+ dev_t dirdev = 0;46+ char fdescfs[] = FDESCFS; /* string must be writable */47+ struct stat statbuf;48+49+ /* On BSD, fdescfs is normally mounted at /dev/fd. However50+ if it is NOT mounted, devfs creates a directory at /dev/fd51+ which contains (only) the file descriptors 0,1 and 2.52+53+ Under these conditions, opendir() will succeed, and54+ if we proceed we will fail to close extant55+ file descriptors which should be closed.56+57+ Check that there is a filesystem mounted at /dev/fd58+ by checking that the device changes between /dev/fd59+ and /dev. If if doesn't, fall back to the dumb path. */60+61+ if (stat(fdescfs, &statbuf) != -1)62+ dirdev = statbuf.st_dev;63+64+ if (stat(dirname(fdescfs), &statbuf) != -1 &&65+ dirdev != statbuf.st_dev)66+# endif67+ d = opendir(FDESCFS);68+69+ if (d)70{71struct dirent *de;72737475