diff options
author | Maciej Żenczykowski <maze@google.com> | 2022-01-21 11:19:55 -0800 |
---|---|---|
committer | Maciej Żenczykowski <maze@google.com> | 2022-04-29 13:42:50 -0700 |
commit | 436980d31c99bdee3c794e26e662e885eba928d6 (patch) | |
tree | 95dfe3ef3c0613b9e6974a160f71512938cb9435 | |
parent | 06b249fc75b4f554b52198b94737a5aabe30ddb0 (diff) | |
download | bionic-436980d31c99bdee3c794e26e662e885eba928d6.tar.gz |
allowlist new Linux close_range() system call, use it in posix_spawn()
Linux kernel's close_range() system call (currently) allows:
close() unshare() fcntl(F_SETFD, FD_CLOEXEC)
to be performed on ranges of fds.
All 3 of these are already allowed by seccomp bpf:
as such this doesn't allow you to do anything you can't already do.
We can't add close_range() properly to bionic because we'd need to
fiddle about with ltp and it's too late to add new T API anyway,
so let's just make the direct syscall() call.
We'll add proper support in U.
See also:
https://man7.org/linux/man-pages/man2/close_range.2.html
Test: TreeHugger
Bug: 229913920
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I85586d544fc23bed6aee59f00bdb79ee7a8150d1
Merged-In: I85586d544fc23bed6aee59f00bdb79ee7a8150d1
-rw-r--r-- | libc/SECCOMP_ALLOWLIST_COMMON.TXT | 2 | ||||
-rw-r--r-- | libc/bionic/spawn.cpp | 5 |
2 files changed, 7 insertions, 0 deletions
diff --git a/libc/SECCOMP_ALLOWLIST_COMMON.TXT b/libc/SECCOMP_ALLOWLIST_COMMON.TXT index 6650d7e32..c440f9b74 100644 --- a/libc/SECCOMP_ALLOWLIST_COMMON.TXT +++ b/libc/SECCOMP_ALLOWLIST_COMMON.TXT @@ -74,3 +74,5 @@ int futex_time64(int*, int, int, const timespec64*, int*, int) lp32 int sched_rr_get_interval_time64(pid_t, timespec64*) lp32 # Since Linux 5.4, not in glibc. Probed for and conditionally used by ART. int userfaultfd(int) all +# Since Linux 5.9, used by POSIX_SPAWN_CLOEXEC_DEFAULT +int close_range(unsigned int, unsigned int, int) all diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp index 314a05669..59f763138 100644 --- a/libc/bionic/spawn.cpp +++ b/libc/bionic/spawn.cpp @@ -30,10 +30,12 @@ #include <errno.h> #include <fcntl.h> +#include <linux/close_range.h> #include <signal.h> #include <stdlib.h> #include <string.h> #include <sys/resource.h> +#include <sys/syscall.h> #include <unistd.h> #include <android/fdsan.h> @@ -49,6 +51,9 @@ static int set_cloexec(int i) { // mark all open fds except stdin/out/err as close-on-exec static int cloexec_except_stdioe() { + // requires 5.11+ or ACK 5.10-T kernel, otherwise returns ENOSYS or EINVAL + if (!syscall(SYS_close_range, 3, ~0U, CLOSE_RANGE_CLOEXEC)) return 0; + // unfortunately getrlimit can lie: // - both soft and hard limits can be lowered to 0, with fds still open, so it can underestimate // - in practice it usually is some really large value (like 32K or more) |