Merge "seccomp: Generate the policy files at compile time"
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
deleted file mode 120000
index 328d3eb..0000000
--- a/android-changes-for-ndk-developers.md
+++ /dev/null
@@ -1 +0,0 @@
-docs/android-changes-for-ndk-developers.md
\ No newline at end of file
diff --git a/docs/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
similarity index 100%
rename from docs/android-changes-for-ndk-developers.md
rename to android-changes-for-ndk-developers.md
diff --git a/docs/libc_assembler.md b/docs/libc_assembler.md
index 151f265..44c0036 100644
--- a/docs/libc_assembler.md
+++ b/docs/libc_assembler.md
@@ -18,15 +18,15 @@
Benchmark 64 bit memcmp:
- /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --bionic_xml=string.xml memcmp
+ /data/benchmarktest64/bionic-benchmarks/bionic-benchmarks --bionic_xml=string.xml --benchmark_filter=memcmp
Benchmark 32 bit memcmp:
- /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --bionic_xml=string.xml memcmp
+ /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --bionic_xml=string.xml --benchmark_filter=memcmp
Locking to a specific cpu:
- /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --bionic_cpu=2 --bionic_xml=string.xml memcmp
+ /data/benchmarktest/bionic-benchmarks/bionic-benchmarks --bionic_cpu=2 --bionic_xml=string.xml --benchmark_filter=memcmp
## Performance
The bionic benchmarks are used to verify the performance of changes to
@@ -56,7 +56,7 @@
command to work, you need to change directory to one of the above
directories.
- bionic-benchmarks --bionic_xml=suites/string.xml memcmp
+ bionic-benchmarks --bionic_xml=string.xml --benchmark_filter=memcmp
The last argument is the name of the one function that you want to
benchmark.
@@ -102,6 +102,22 @@
always a good idea to rerun the suite a couple of times to verify that
there isn't a high variation in the numbers.
+If you want to verify a single benchmark result, you can run a single test
+using a command like this:
+
+ bionic-benchmarks --bionic_xml=string.xml --benchmark_filter=BM_string_memcmp/1/1/0
+
+Where the argument to the filter argument is the name of the benchmark from
+the output. Sometimes this filter can still match multiple benchmarks, to
+guarantee that you only run the single benchmark, you can execute the benchmark
+like so:
+
+ bionic-benchmarks --bionic_xml=string.xml --benchmark_filter=BM_string_memcmp/1/1/0$
+
+NOTE: It is assumed that these commands are executed in adb as the shell user
+on device. If you are trying to run this using adb directly from a host
+machine, you might need to escape the special shell characters such as **$**.
+
## Testing
Run the bionic tests to verify that the new routines are valid. However,
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index a56d77a..43d8831 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -50,10 +50,65 @@
static constexpr const char* kFdsanPropertyName = "debug.fdsan";
+template<size_t inline_fds>
+FdEntry* FdTableImpl<inline_fds>::at(size_t idx) {
+ if (idx < inline_fds) {
+ return &entries[idx];
+ }
+
+ // Try to create the overflow table ourselves.
+ FdTableOverflow* local_overflow = atomic_load(&overflow);
+ if (__predict_false(!local_overflow)) {
+ struct rlimit rlim = { .rlim_max = 32768 };
+ getrlimit(RLIMIT_NOFILE, &rlim);
+ rlim_t max = rlim.rlim_max;
+
+ if (max == RLIM_INFINITY) {
+ // This isn't actually possible (the kernel has a hard limit), but just
+ // in case...
+ max = 32768;
+ }
+
+ if (idx > max) {
+ // This can happen if an fd is created and then the rlimit is lowered.
+ // In this case, just return nullptr and ignore the fd.
+ return nullptr;
+ }
+
+ size_t required_count = max - inline_fds;
+ size_t required_size = sizeof(FdTableOverflow) + required_count * sizeof(FdEntry);
+ size_t aligned_size = __BIONIC_ALIGN(required_size, PAGE_SIZE);
+ size_t aligned_count = (aligned_size - sizeof(FdTableOverflow)) / sizeof(FdEntry);
+
+ void* allocation =
+ mmap(nullptr, aligned_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (allocation == MAP_FAILED) {
+ async_safe_fatal("fdsan: mmap failed: %s", strerror(errno));
+ }
+
+ FdTableOverflow* new_overflow = reinterpret_cast<FdTableOverflow*>(allocation);
+ new_overflow->len = aligned_count;
+
+ if (atomic_compare_exchange_strong(&overflow, &local_overflow, new_overflow)) {
+ local_overflow = new_overflow;
+ } else {
+ // Someone beat us to it. Deallocate and use theirs.
+ munmap(allocation, aligned_size);
+ }
+ }
+
+ size_t offset = idx - inline_fds;
+ if (local_overflow->len < offset) {
+ return nullptr;
+ }
+ return &local_overflow->entries[offset];
+}
+
void __libc_init_fdsan() {
+ constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE;
const prop_info* pi = __system_property_find(kFdsanPropertyName);
if (!pi) {
- android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
+ android_fdsan_set_error_level(default_level);
return;
}
__system_property_read_callback(
@@ -70,13 +125,13 @@
async_safe_format_log(ANDROID_LOG_ERROR, "libc",
"debug.fdsan set to unknown value '%s', disabling", value);
}
- android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
+ android_fdsan_set_error_level(default_level);
}
},
nullptr);
}
-static FdTable<128>* GetFdTable() {
+static FdTable* GetFdTable() {
if (!__libc_shared_globals) {
return nullptr;
}
@@ -84,6 +139,11 @@
return &__libc_shared_globals->fd_table;
}
+// Exposed to the platform to allow crash_dump to print out the fd table.
+extern "C" void* android_fdsan_get_fd_table() {
+ return GetFdTable();
+}
+
static FdEntry* GetFdEntry(int fd) {
if (fd < 0) {
return nullptr;
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 23ee3f3..6d39812 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1661,6 +1661,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index eadf70d..1cf48b1 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1379,6 +1379,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 12e657f..135206e 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1687,6 +1687,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index c7fe2c6..a330a45 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1502,6 +1502,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index eadf70d..1cf48b1 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1379,6 +1379,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index f6d1871..7a2fe9a 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1501,6 +1501,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index eadf70d..1cf48b1 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1379,6 +1379,7 @@
__system_property_area_init;
__system_property_set_filename;
__system_property_update;
+ android_fdsan_get_fd_table;
android_net_res_stats_get_info_for_net;
android_net_res_stats_aggregate;
android_net_res_stats_get_usable_servers;
diff --git a/libc/private/bionic_fdsan.h b/libc/private/bionic_fdsan.h
index b93260b..de14cf8 100644
--- a/libc/private/bionic_fdsan.h
+++ b/libc/private/bionic_fdsan.h
@@ -38,8 +38,6 @@
#include <sys/resource.h>
#include <sys/user.h>
-#include <async_safe/log.h>
-
struct FdEntry {
_Atomic(uint64_t) close_tag;
};
@@ -50,62 +48,14 @@
};
template <size_t inline_fds>
-struct FdTable {
+struct FdTableImpl {
+ uint32_t version; // currently 0, and hopefully it'll stay that way.
_Atomic(android_fdsan_error_level) error_level;
FdEntry entries[inline_fds];
_Atomic(FdTableOverflow*) overflow;
- FdEntry* at(size_t idx) {
- if (idx < inline_fds) {
- return &entries[idx];
- }
-
- // Try to create the overflow table ourselves.
- FdTableOverflow* local_overflow = atomic_load(&overflow);
- if (__predict_false(!local_overflow)) {
- struct rlimit rlim = { .rlim_max = 32768 };
- getrlimit(RLIMIT_NOFILE, &rlim);
- rlim_t max = rlim.rlim_max;
-
- if (max == RLIM_INFINITY) {
- // This isn't actually possible (the kernel has a hard limit), but just
- // in case...
- max = 32768;
- }
-
- if (idx > max) {
- // This can happen if an fd is created and then the rlimit is lowered.
- // In this case, just return nullptr and ignore the fd.
- return nullptr;
- }
-
- size_t required_count = max - inline_fds;
- size_t required_size = sizeof(FdTableOverflow) + required_count * sizeof(FdEntry);
- size_t aligned_size = __BIONIC_ALIGN(required_size, PAGE_SIZE);
- size_t aligned_count = (aligned_size - sizeof(FdTableOverflow)) / sizeof(FdEntry);
-
- void* allocation =
- mmap(nullptr, aligned_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (allocation == MAP_FAILED) {
- async_safe_fatal("fdsan: mmap failed: %s", strerror(errno));
- }
-
- FdTableOverflow* new_overflow = reinterpret_cast<FdTableOverflow*>(allocation);
- new_overflow->len = aligned_count;
-
- if (atomic_compare_exchange_strong(&overflow, &local_overflow, new_overflow)) {
- local_overflow = new_overflow;
- } else {
- // Someone beat us to it. Deallocate and use theirs.
- munmap(allocation, aligned_size);
- }
- }
-
- size_t offset = idx - inline_fds;
- if (local_overflow->len < offset) {
- return nullptr;
- }
- return &local_overflow->entries[offset];
- }
+ FdEntry* at(size_t idx);
};
+
+using FdTable = FdTableImpl<128>;
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index e569209..eee33c9 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -46,7 +46,7 @@
// Globals shared between the dynamic linker and libc.so.
struct libc_shared_globals {
- FdTable<128> fd_table;
+ FdTable fd_table;
};
__LIBC_HIDDEN__ extern libc_shared_globals* __libc_shared_globals;
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 050157b..71fdd27 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -1178,8 +1178,6 @@
}
FILE* popen(const char* cmd, const char* mode) {
- bool close_on_exec = (strchr(mode, 'e') != nullptr);
-
// Was the request for a socketpair or just a pipe?
int fds[2];
bool bidirectional = false;
@@ -1231,8 +1229,6 @@
FILE* fp = fdopen(fds[parent], mode);
if (fp == nullptr) return __popen_fail(fds);
- // The caller didn't ask for their pipe to be O_CLOEXEC, so flip it back now the child has forked.
- if (!close_on_exec) fcntl(fds[parent], F_SETFD, 0);
close(fds[child]);
_EXT(fp)->_popen_pid = pid;