aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-11-08 13:53:29 +1100
committerStefano Brivio <sbrivio@redhat.com>2024-11-08 08:26:17 +0100
commit14dd70e2b33941f1f7663969574278873c9e3d35 (patch)
treef87bf175430f3a90b29884681d1888462f7a315b
parentd64f25724399fbb4ba9d36eda7e17984a4c6c91c (diff)
downloadpasst-14dd70e2b33941f1f7663969574278873c9e3d35.tar
passt-14dd70e2b33941f1f7663969574278873c9e3d35.tar.gz
passt-14dd70e2b33941f1f7663969574278873c9e3d35.tar.bz2
passt-14dd70e2b33941f1f7663969574278873c9e3d35.tar.lz
passt-14dd70e2b33941f1f7663969574278873c9e3d35.tar.xz
passt-14dd70e2b33941f1f7663969574278873c9e3d35.tar.zst
passt-14dd70e2b33941f1f7663969574278873c9e3d35.zip
linux_dep: Fix CLOSE_RANGE_UNSHARE availability handling
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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--linux_dep.h12
-rw-r--r--util.c16
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 <linux/close_range.h>
-#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");
+ }
+ }
+
}
/**