mirror of
https://passt.top/passt
synced 2024-12-22 05:35:23 +00:00
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>
This commit is contained in:
parent
d64f257243
commit
14dd70e2b3
12
linux_dep.h
12
linux_dep.h
@ -127,22 +127,18 @@ struct tcp_info_linux {
|
|||||||
|
|
||||||
#include <linux/close_range.h>
|
#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 */
|
/* glibc < 2.34 and musl as of 1.2.5 need these */
|
||||||
#ifndef SYS_close_range
|
#ifndef SYS_close_range
|
||||||
#define SYS_close_range 436
|
#define SYS_close_range 436
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CLOSE_RANGE_UNSHARE /* Linux kernel < 5.9 */
|
||||||
|
#define CLOSE_RANGE_UNSHARE (1U << 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
__attribute__ ((weak))
|
__attribute__ ((weak))
|
||||||
/* cppcheck-suppress funcArgNamesDifferent */
|
/* cppcheck-suppress funcArgNamesDifferent */
|
||||||
int close_range(unsigned int first, unsigned int last, int flags) {
|
int close_range(unsigned int first, unsigned int last, int flags) {
|
||||||
return syscall(SYS_close_range, first, last, 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 */
|
#endif /* LINUX_DEP_H */
|
||||||
|
14
util.c
14
util.c
@ -738,9 +738,21 @@ void close_open_files(int argc, char **argv)
|
|||||||
rc = close_range(fd + 1, ~0U, CLOSE_RANGE_UNSHARE);
|
rc = close_range(fd + 1, ~0U, CLOSE_RANGE_UNSHARE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc)
|
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");
|
die_perror("Failed to close files leaked by parent");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snprintf_check() - snprintf() wrapper, checking for truncation and errors
|
* snprintf_check() - snprintf() wrapper, checking for truncation and errors
|
||||||
|
Loading…
Reference in New Issue
Block a user