From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202606 header.b=X9qpwJwV; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 01A885A0626 for ; Fri, 17 Jul 2026 07:46:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202606; t=1784267197; bh=OZCzkSO8pXm1kJokXQwDbUw2qvhasvtvZKSM8NMWwTs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X9qpwJwVuYkHsDyVfZgDB6sxiXop66CbJ+G1sCCtb4eVS1orCul8LXiX5ky48cq5C ByWAZo+IDc7MhBleUZro7DNeSJVIyNfEqFYfzVFNaOmm6C+0oYb7Kz6tf7YJB7s9S9 JPdhYB+tX+hq2Hp2ZXz2sctMb1ES0yUhwj0log8w7xJpdTmESFYWJrajP3OPi118Wp 8v5G8gNhxS/lZYM/xxcqZI/9E4e9Ch9/ipScQ6BnThuGziVbyeXcha3XS4ilbfkMrW n+8lqIYrxu/15BKuKwpK7SsLB+ASAp83IhklKIpDKXnIdFZSG1Mq2xrQiY3/doRdRT 4vMkifn1eeaRA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4h1f6j0nK0z4wCP; Fri, 17 Jul 2026 15:46:37 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 5/6] isolation: Move --fd descriptor to a number of our choosing Date: Fri, 17 Jul 2026 15:46:33 +1000 Message-ID: <20260717054634.1293553-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260717054634.1293553-1-david@gibson.dropbear.id.au> References: <20260717054634.1293553-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 4XNGJ2OWDCB6WGJ5N2QITFWDIIA3FGZ5 X-Message-ID-Hash: 4XNGJ2OWDCB6WGJ5N2QITFWDIIA3FGZ5 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson , Alyssa Ross X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Some users of passt pass an fd for the tap interface in, with the --fd parameter, rather than having passt open it itself. This requires some slightly fiddly logic in isolate_fds() so we don't close() it along with any other file descriptors leaked into us by the parent. More importantly, this is broken if the passed fd is 0, 1 or 2, since in that case we will assume it's a standard stream and close it in __daemon(). We explicitly disallow 1 or 2 in conf_tap_fd(), but 0 has been permitted since aa1cc8922 ("conf: allow --fd 0"). It looks like the use case of the contributor of that patch didn't involve daemonizing passt. To fix this more robustly, use dup2() to move to the passed fd to 3. This removes the possibility of mixing it up with a standard stream, and as a bonus makes the close_range() logic much simpler. With isolate_fds() made safe for --fd 1 and --fd 2, we can remove the logic excluding those from conf_fd_tap(). Cc: Alyssa Ross Signed-off-by: David Gibson --- conf.c | 4 +--- isolation.c | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/conf.c b/conf.c index df204d13..0fcba5cf 100644 --- a/conf.c +++ b/conf.c @@ -1177,9 +1177,7 @@ int conf_tap_fd(int argc, char **argv) return -1; p = fdarg; - if (!parse_unsigned(&p, 0, &val) || !parse_eoi(p) || - val > INT_MAX || - (val != STDIN_FILENO && val <= STDERR_FILENO)) + if (!parse_unsigned(&p, 0, &val) || !parse_eoi(p) || val > INT_MAX) die("Invalid --fd: %s", fdarg); return val; diff --git a/isolation.c b/isolation.c index 725a72bb..94cbe7f8 100644 --- a/isolation.c +++ b/isolation.c @@ -248,7 +248,6 @@ void isolate_initial(void) drop_caps_ep_except(keep); } - /* * isolate_fds() - Close leaked files, but not --fd, stdin, stdout, stderr * @argc: Argument count @@ -256,27 +255,26 @@ void isolate_initial(void) * * Should: * - close all open files except for standard streams and the one from --fd + * - move the --fd descriptor out of the range 0-2 * - * Return: fd number from --fd, or -1 if not specified + * Return: new fd number for descriptor from --fd, or -1 if not specified */ int isolate_fds(int argc, char **argv) { - int fd, rc; + int fd, close_from = STDERR_FILENO + 1; fd = conf_tap_fd(argc, argv); - if (fd == -1) { - rc = close_range(STDERR_FILENO + 1, ~0U, CLOSE_RANGE_UNSHARE); - } else if (fd == STDERR_FILENO + 1) { /* Still a single range */ - rc = close_range(STDERR_FILENO + 2, ~0U, CLOSE_RANGE_UNSHARE); - } else { - rc = close_range(STDERR_FILENO + 1, fd - 1, - CLOSE_RANGE_UNSHARE); - if (!rc) - rc = close_range(fd + 1, ~0U, CLOSE_RANGE_UNSHARE); + if (fd >= 0) { + /* Move the passed fd to a more convenient location */ + if (fd != close_from && + (dup2(fd, close_from) != close_from || + close(fd))) + die_perror("Could not move --fd descriptor"); + fd = close_from++; } - if (rc) { + if (close_range(close_from, ~0U, CLOSE_RANGE_UNSHARE)) { if (errno == ENOSYS || errno == EINVAL) { /* This probably means close_range() or the * CLOSE_RANGE_UNSHARE flag is not supported by the -- 2.55.0