From fbfa40fe4d0426b3de23abc2fac73f2422f5be40 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Jun 2026 11:21:59 +1000 Subject: [PATCH] vfs: port 37dbb263's operator-path mknod FIFO/socket fallback Linear-rebase counterpart of the round-2 merge resolution: 37dbb263 fixed do_mknod_at()'s operator branch in syscall.c (deleted on this branch) to fall back to mkfifoat() for a FIFO and EOPNOTSUPP for a nested socket when mknodat() can't make a special file on the BSDs/macOS/Solaris. Re-express it in the VFS_OPERATOR_PATH branch of vfs__mknod_secure() in vfs/mknod.c, mirroring the secure-relpath branch already in that function. Tree is byte-identical to the validated round-2 merge result. --- vfs/mknod.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vfs/mknod.c b/vfs/mknod.c index d4d14e0d..a6ffbfa3 100644 --- a/vfs/mknod.c +++ b/vfs/mknod.c @@ -126,6 +126,19 @@ static int vfs__mknod_secure(const char *pathname, mode_t mode, dev_t dev, int f if (dfd < 0) return -1; ret = mknodat(dfd, bname, mode, dev); + if (ret < 0) { + /* mknodat() can't make a FIFO/socket on the BSDs/macOS/ + * Solaris (EINVAL); retry race-safely on the held dirfd, + * mirroring the secure-relpath path below. Without this a + * FIFO backup to an operator --backup-dir fails there. */ +#ifdef HAVE_MKFIFOAT + if (S_ISFIFO(mode)) + ret = mkfifoat(dfd, bname, mode); + else +#endif + if (S_ISSOCK(mode)) + errno = EOPNOTSUPP; /* no dirfd-relative socket bind */ + } e = errno; close(dfd); errno = e;