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=202410 header.b=dXpxQ3nJ; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 12A455A061C for ; Fri, 08 Nov 2024 03:53:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202410; t=1731034409; bh=4IlDwGk1fn9KAwDwQw9O3N8gdfnabeKtb6A5c5BSycI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dXpxQ3nJ2NLeZ71eQVOWEOZAGaNeuP5WM/b1pyqowMWy2a8xJbLckqCYWcIUvgpim /0+stVvNr901C0qg63E1GlsXUpyVFABxz6HnN1Fw9yaBgnB+d5AQAHRmz0EfcN50CS mrxrQ2ZLE1aGyqUvJ0JIZMY8QrvOX5iXsFENb6kRNEvneD2TlcclSfawcG/XigQXy9 uRcx78mUoZfZ5klZQpbfo/R4/kxNt7+gwbr8Eiircgyc2lAjIK3vfR6Zae0MIH3wg7 QF779X7+qc0M3BVVcC97KKzdrvKdk19NHIAl9eFgfE/RmaxHPgw4EmYzF7/cDph/mV JhN5yEz8lqBIA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4Xl3RF3h9rz4x7X; Fri, 8 Nov 2024 13:53:29 +1100 (AEDT) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v2 3/4] linux_dep: Fix CLOSE_RANGE_UNSHARE availability handling Date: Fri, 8 Nov 2024 13:53:29 +1100 Message-ID: <20241108025330.3161314-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241108025330.3161314-1-david@gibson.dropbear.id.au> References: <20241108025330.3161314-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: B4VXDHQUZTAYQRED7QY7EY7JH6VNYXRM X-Message-ID-Hash: B4VXDHQUZTAYQRED7QY7EY7JH6VNYXRM 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 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: If CLOSE_RANGE_UNSHARE isn't defined, we define a fallback version of close_range() which is a (successful) no-op. This is broken in several ways: * It doesn't actually fix compile if using old kernel headers, because the caller of close_range() still directly uses CLOSE_RANGE_UNSHARE unprotected by ifdefs * Even if it did fix the compile, it means inconsistent behaviour between a compile time failure to find the value (we silently don't close files) and a runtime failure (we die with an error from close_range()) * Silently not closing the files we intend to close for security reasons is probably not a good idea in any case We don't want to simply error if close_range() or CLOSE_RANGE_UNSHARE isn't available, because that would require running on kernel >= 5.9. On the other hand there's not really any other way to flush all possible fds leaked by the parent (close() in a loop takes over a minute). So in this case print a warning and carry on. As bonus this fixes a cppcheck error I see with some different options I'm looking to apply in future. Signed-off-by: David Gibson --- linux_dep.h | 12 ++++-------- util.c | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/linux_dep.h b/linux_dep.h index 3a41e42..240f50a 100644 --- a/linux_dep.h +++ b/linux_dep.h @@ -127,22 +127,18 @@ struct tcp_info_linux { #include -#ifdef CLOSE_RANGE_UNSHARE /* Linux kernel >= 5.9 */ /* glibc < 2.34 and musl as of 1.2.5 need these */ #ifndef SYS_close_range #define SYS_close_range 436 #endif +#ifndef CLOSE_RANGE_UNSHARE /* Linux kernel < 5.9 */ +#define CLOSE_RANGE_UNSHARE (1U << 1) +#endif + __attribute__ ((weak)) /* cppcheck-suppress funcArgNamesDifferent */ int close_range(unsigned int first, unsigned int last, int flags) { return syscall(SYS_close_range, first, last, flags); } -#else -/* No reasonable fallback option */ -/* cppcheck-suppress funcArgNamesDifferent */ -int close_range(unsigned int first, unsigned int last, int flags) { - return 0; -} -#endif #endif /* LINUX_DEP_H */ diff --git a/util.c b/util.c index 913f34b..126dedb 100644 --- a/util.c +++ b/util.c @@ -738,8 +738,20 @@ void close_open_files(int argc, char **argv) rc = close_range(fd + 1, ~0U, CLOSE_RANGE_UNSHARE); } - if (rc) - die_perror("Failed to close files leaked by parent"); + if (rc) { + if (errno == ENOSYS || errno == EINVAL) { + /* This probably means close_range() or the + * CLOSE_RANGE_UNSHARE flag is not supported by the + * kernel. Not much we can do here except carry on and + * hope for the best. + */ + warn( +"Can't use close_range() to ensure no files leaked by parent"); + } else { + die_perror("Failed to close files leaked by parent"); + } + } + } /** -- 2.47.0