aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-30 05:06:18 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-30 05:06:18 +0000
commit9d496e6c34fa8419f09260975f3d2cea69db4d50 (patch)
tree95dfe3ef3c0613b9e6974a160f71512938cb9435
parent0530ce23079d10201e3c487ae02367d382a3a345 (diff)
parent24d11c5ad8f19b74723b36a04226628d9c5bc606 (diff)
downloadbionic-9d496e6c34fa8419f09260975f3d2cea69db4d50.tar.gz
Snap for 8521661 from 24d11c5ad8f19b74723b36a04226628d9c5bc606 to tm-qpr1-release
Change-Id: I993ba0ad9d8555d17b84a2381cd6071ed23ad31b
-rw-r--r--libc/SECCOMP_ALLOWLIST_COMMON.TXT2
-rw-r--r--libc/bionic/spawn.cpp5
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)