Merge "Match 'Access denied finding property' log severity to SELinux"
diff --git a/benchmarks/linker_relocation/Android.bp b/benchmarks/linker_relocation/Android.bp
index b41d093..b78eb8e 100644
--- a/benchmarks/linker_relocation/Android.bp
+++ b/benchmarks/linker_relocation/Android.bp
@@ -32,7 +32,6 @@
name: "linker_reloc_bench_headers",
defaults: ["bionic_spawn_benchmark_targets"],
export_include_dirs: ["include"],
- bazel_module: { bp2build_available: true },
}
// TODO: This benchmark doesn't work with TradeFed/atest because it doesn't copy its test libraries
diff --git a/libc/Android.bp b/libc/Android.bp
index df8871a..4084b96 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -21,7 +21,6 @@
}
libc_common_src_files = [
- "async_safe/async_safe_log.cpp",
"bionic/ether_aton.c",
"bionic/ether_ntoa.c",
"bionic/exit.cpp",
@@ -1291,7 +1290,6 @@
cmd: "$(location :bionic-gensyscalls) arm $(in) > $(out)",
bazel_module: {
bp2build_available: true,
- label: "//bionic/libc:syscalls-arm.S"
}
}
@@ -1303,7 +1301,6 @@
cmd: "$(location :bionic-gensyscalls) arm64 $(in) > $(out)",
bazel_module: {
bp2build_available: true,
- label: "//bionic/libc:syscalls-arm64.S"
},
}
@@ -1315,7 +1312,6 @@
cmd: "$(location :bionic-gensyscalls) x86 $(in) > $(out)",
bazel_module: {
bp2build_available: true,
- label: "//bionic/libc:syscalls-x86.S"
},
}
@@ -1327,7 +1323,6 @@
cmd: "$(location :bionic-gensyscalls) x86_64 $(in) > $(out)",
bazel_module: {
bp2build_available: true,
- label: "//bionic/libc:syscalls-x86_64.S"
},
}
@@ -1420,6 +1415,7 @@
whole_static_libs: [
"gwp_asan",
"libarm-optimized-routines-string",
+ "libasync_safe",
"libc_bionic_ndk",
"libc_bootstrap",
"libc_fortify",
@@ -1451,6 +1447,7 @@
whole_static_libs: [
"libarm-optimized-routines-string",
+ "libasync_safe",
"libc_bionic",
"libc_bionic_ndk",
"libc_bootstrap",
@@ -2112,23 +2109,12 @@
}
cc_object {
- name: "crtbegin_so1",
+ name: "crtbegin_so",
local_include_dirs: ["include"],
srcs: ["arch-common/bionic/crtbegin_so.c"],
defaults: ["crt_so_defaults"],
-
- bazel_module: {
- bp2build_available: true,
- },
-}
-
-cc_object {
- name: "crtbegin_so",
-
- defaults: ["crt_so_defaults"],
objs: [
- "crtbegin_so1",
"crtbrand",
],
@@ -2137,7 +2123,10 @@
cc_object {
name: "crtend_so",
- local_include_dirs: ["include"],
+ local_include_dirs: [
+ "include",
+ "private", // crtend_so.S depends on private/bionic_asm_arm64.h
+ ],
srcs: ["arch-common/bionic/crtend_so.S"],
defaults: ["crt_so_defaults"],
@@ -2146,24 +2135,15 @@
}
cc_object {
- name: "crtbegin_static1",
+ name: "crtbegin_static",
+
local_include_dirs: [
"include",
"bionic", // crtbegin.c includes bionic/libc_init_common.h
],
+
srcs: ["arch-common/bionic/crtbegin.c"],
- defaults: ["crt_defaults"],
- // When using libc.a, we're using the latest library regardless of target API level.
- min_sdk_version: "current",
-
- bazel_module: { bp2build_available: true },
-}
-
-cc_object {
- name: "crtbegin_static",
-
objs: [
- "crtbegin_static1",
"crtbrand",
],
defaults: ["crt_defaults"],
@@ -2174,22 +2154,14 @@
}
cc_object {
- name: "crtbegin_dynamic1",
+ name: "crtbegin_dynamic",
+
local_include_dirs: [
"include",
"bionic", // crtbegin.c includes bionic/libc_init_common.h
],
srcs: ["arch-common/bionic/crtbegin.c"],
- defaults: ["crt_defaults"],
-
- bazel_module: { bp2build_available: true },
-}
-
-cc_object {
- name: "crtbegin_dynamic",
-
objs: [
- "crtbegin_dynamic1",
"crtbrand",
],
target: {
@@ -2209,7 +2181,10 @@
// We rename crtend.o to crtend_android.o to avoid a
// name clash between gcc and bionic.
name: "crtend_android",
- local_include_dirs: ["include"],
+ local_include_dirs: [
+ "include",
+ "private", // crtend.S depends on private/bionic_asm_arm64.h
+ ],
srcs: ["arch-common/bionic/crtend.S"],
defaults: ["crt_defaults"],
@@ -2224,6 +2199,7 @@
srcs: ["arch-arm64/bionic/note_memtag_heap_async.S"],
}
},
+ sdk_version: "minimum",
defaults: ["crt_defaults"],
}
@@ -2235,6 +2211,7 @@
srcs: ["arch-arm64/bionic/note_memtag_heap_sync.S"],
}
},
+ sdk_version: "minimum",
defaults: ["crt_defaults"],
}
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index f2b6638..62878378 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -89,6 +89,3 @@
#include "__dso_handle.h"
#include "atexit.h"
#include "pthread_atfork.h"
-#ifdef __i386__
-# include "../../arch-x86/bionic/__stack_chk_fail_local.h"
-#endif
diff --git a/libc/arch-common/bionic/crtbegin_so.c b/libc/arch-common/bionic/crtbegin_so.c
index cf369cc..2f3b118 100644
--- a/libc/arch-common/bionic/crtbegin_so.c
+++ b/libc/arch-common/bionic/crtbegin_so.c
@@ -73,6 +73,3 @@
# include "atexit.h"
#endif
#include "pthread_atfork.h"
-#ifdef __i386__
-# include "../../arch-x86/bionic/__stack_chk_fail_local.h"
-#endif
diff --git a/libc/arch-x86/bionic/__stack_chk_fail_local.h b/libc/arch-x86/bionic/__stack_chk_fail_local.h
deleted file mode 100644
index 0b0fd7f..0000000
--- a/libc/arch-x86/bionic/__stack_chk_fail_local.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-
-/*
- __stack_chk_fail routine is runtime part of stack protector compiler
- feature. It's implemented in libc and represents die routine when stack
- corruption is detected.
-
- Calls are generated by compiler and injected into user functions when
- -fstack-protector* options are used.
-
- __stack_chk_fail_local is wrapper for __stack_chk_fail. Compiler generates
- wrapper calls instead for PIC code only and only on IA32 for optimization
- purpose (see gcc/config/i386/i386.c). Wrapper body is always included into
- executable or library. This is the idea of optimization.
-
- Glibc is doing this via libc_nonshared.a which is linked automatically
- everytime with libc.so. In bionic we have to bring it within crtfiles
- because libc.so is real library and not a link script like libc.so at glibc.
-
- For x86_64 or non-PIC code compiler always generates __stack_chk_fail calls.
-*/
-
-#ifdef __i386__
-extern void __stack_chk_fail();
-
-__LIBC_HIDDEN__ void __stack_chk_fail_local() {
- __stack_chk_fail();
-}
-#endif
diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp
index 2e05d7a..e4a5837 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -57,5 +57,4 @@
"//apex_available:platform",
"com.android.runtime",
],
- bazel_module: { bp2build_available: true },
}
diff --git a/libc/bionic/scandir.cpp b/libc/bionic/scandir.cpp
index 6a7e368..f528286 100644
--- a/libc/bionic/scandir.cpp
+++ b/libc/bionic/scandir.cpp
@@ -16,8 +16,9 @@
#include <dirent.h>
-#include <fcntl.h>
+#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -32,10 +33,8 @@
}
~ScandirResult() {
- while (size_ > 0) {
- free(names_[--size_]);
- }
- free(names_);
+ // We always call release(), so this can't happen.
+ if (names_ != nullptr) __assert(__FILE__, __LINE__, "missing call to release()");
}
size_t size() {
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index b1bd713..2556d11 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -281,10 +281,12 @@
*/
# define __call_bypassing_fortify(fn) (&fn)
/*
- * Because clang-FORTIFY uses overloads, we can't mark functions as `extern
- * inline` without making them available externally.
+ * Because clang-FORTIFY uses overloads, we can't mark functions as `extern inline` without making
+ * them available externally. FORTIFY'ed functions try to be as close to possible as 'invisible';
+ * having stack protectors detracts from that (b/182948263).
*/
-# define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline __VERSIONER_FORTIFY_INLINE
+# define __BIONIC_FORTIFY_INLINE static __inline__ __attribute__((no_stack_protector)) \
+ __always_inline __VERSIONER_FORTIFY_INLINE
/*
* We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
* for variadic functions because compilers cannot inline them.
diff --git a/libc/kernel/README.md b/libc/kernel/README.md
index 6db08d6..5f1c81d 100644
--- a/libc/kernel/README.md
+++ b/libc/kernel/README.md
@@ -17,11 +17,23 @@
Description of the directories involved in generating the parsed kernel headers:
- * `external/kernel-headers/original/`
- Contains the uapi kernel headers found in the android kernel. Note this
+ * `external/kernel-headers/original/uapi/`
+ Contains the uapi kernel headers found in the Android kernel. Note this
also includes the header files that are generated by building the kernel
sources.
+ * `external/kernel-headers/original/scsi/`
+ Contains copies of the kernel scsi header files. These where never
+ made into uapi files, but some user space code expects that these
+ headers are available.
+
+ * `external/kernel-headers/modified/scsi/`
+ Contains hand-modified versions of a few files from `original/scsi/`
+ that removes the kernel specific code from these files so they can
+ be used as uapi headers. The tools to process the kernel headers will
+ warn if any scsi header files have changed and require new versions
+ to be hand-modified.
+
* `bionic/libc/kernel/uapi/`
Contains the cleaned kernel headers and mirrors the directory structure
in `external/kernel-headers/original/uapi/`.
@@ -33,7 +45,7 @@
The tools to get/parse the headers:
* `tools/generate_uapi_headers.sh`
- Checks out the android kernel and generates all uapi header files.
+ Checks out the Android kernel and generates all uapi header files.
copies all the changed files into external/kernel-headers.
* `tools/clean_header.py`
@@ -60,19 +72,25 @@
kernel_src> git clone https://android.googlesource.com/kernel/common/ -b android-mainline
```
-For now, there are no tags, take the top of tree version. To find the
-version of the linux stable kernel headers the mainline source code is
-tracking, read the uapi/linux/version.h that is generated.
+The Android mainline kernel source has tags that indicate the kernel
+version to which they correspond. The format of a tag is
+android-mainline-XXX, where XXX is the kernel version. For example,
+android-mainline-5.10 corresponds to linux stable kernel 5.10. To check out
+a particular tag:
```
- kernel_src> cd linux-stable
- kernel_src/linux-stable> git checkout tags/vXXX
+ kernel_src> cd common
+ kernel_src/common> git checkout tags/android-mainline-XXX
```
+It is expected that a kernel update should only be performed on a valid tag.
+For testing purposes, it is possible that you can use the top of tree
+version, but never use that as the basis for importing new kernel headers.
+
Before running the command to import the headers, make sure that you have
done a lunch TARGET. The script uses a variable set by the lunch command
to determine which directory to use as the destination directory.
-After running lunch, run this command to import the headers into the android
+After running lunch, run this command to import the headers into the Android
source tree if there is a kernel source tree already checked out:
```
bionic/libc/kernel/tools/generate_uapi_headers.sh --use-kernel-dir kernel_src
diff --git a/libc/tools/Android.bp b/libc/tools/Android.bp
index 575a31a..116b853 100644
--- a/libc/tools/Android.bp
+++ b/libc/tools/Android.bp
@@ -11,7 +11,6 @@
filegroup {
name: "bionic-gensyscalls",
srcs: ["gensyscalls.py"],
- bazel_module: { bp2build_available: true },
}
// Generate the C++ policy sources for app and system seccomp-bpf filters.
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 898bc43..fd56274 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -31,9 +31,12 @@
#include <array>
#include <mutex>
+#include <thread>
+#include <utility>
#include <vector>
#include <android/fdsan.h>
+#include <android/set_abort_message.h>
#include <bionic/fdtrack.h>
#include <android-base/no_destructor.h>
@@ -48,6 +51,7 @@
};
extern "C" void fdtrack_dump();
+extern "C" void fdtrack_dump_fatal();
using fdtrack_callback_t = bool (*)(int fd, const char* const* function_names,
const uint64_t* function_offsets, size_t count, void* arg);
@@ -74,7 +78,17 @@
entry.backtrace.reserve(kStackDepth);
}
- signal(BIONIC_SIGNAL_FDTRACK, [](int) { fdtrack_dump(); });
+ struct sigaction sa = {};
+ sa.sa_sigaction = [](int, siginfo_t* siginfo, void*) {
+ if (siginfo->si_code == SI_QUEUE && siginfo->si_int == 1) {
+ fdtrack_dump_fatal();
+ } else {
+ fdtrack_dump();
+ }
+ };
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ sigaction(BIONIC_SIGNAL_FDTRACK, &sa, nullptr);
+
if (Unwinder().Init()) {
android_fdtrack_hook_t expected = nullptr;
installed = android_fdtrack_compare_exchange_hook(&expected, &fd_hook);
@@ -156,16 +170,47 @@
android_fdtrack_set_enabled(prev);
}
-void fdtrack_dump() {
+static size_t hash_stack(const char* const* function_names, const uint64_t* function_offsets,
+ size_t stack_depth) {
+ size_t hash = 0;
+ for (size_t i = 0; i < stack_depth; ++i) {
+ // To future maintainers: if a libc++ update ever makes this invalid, replace this with +.
+ hash = std::__hash_combine(hash, std::hash<std::string_view>()(function_names[i]));
+ hash = std::__hash_combine(hash, std::hash<uint64_t>()(function_offsets[i]));
+ }
+ return hash;
+}
+
+static void fdtrack_dump_impl(bool fatal) {
if (!installed) {
async_safe_format_log(ANDROID_LOG_INFO, "fdtrack", "fdtrack not installed");
} else {
async_safe_format_log(ANDROID_LOG_INFO, "fdtrack", "fdtrack dumping...");
}
+ // If we're aborting, identify the most common stack in the hopes that it's the culprit,
+ // and emit that in the abort message so crash reporting can separate different fd leaks out.
+ // This is horrible and quadratic, but we need to avoid allocation since this can happen in
+ // response to a signal generated asynchronously. We're only going to dump 1k fds by default,
+ // and we're about to blow up the entire system, so this isn't too expensive.
+ struct StackInfo {
+ size_t hash = 0;
+ size_t count = 0;
+
+ size_t stack_depth = 0;
+ const char* function_names[kStackDepth - kStackFrameSkip];
+ uint64_t function_offsets[kStackDepth - kStackFrameSkip];
+ };
+ struct StackList {
+ size_t count = 0;
+ std::array<StackInfo, 128> data;
+ };
+ static StackList stacks;
+
fdtrack_iterate(
- [](int fd, const char* const* function_names, const uint64_t* function_offsets, size_t count,
- void*) {
+ [](int fd, const char* const* function_names, const uint64_t* function_offsets,
+ size_t stack_depth, void* stacks_ptr) {
+ auto stacks = static_cast<StackList*>(stacks_ptr);
uint64_t fdsan_owner = android_fdsan_get_owner_tag(fd);
if (fdsan_owner != 0) {
async_safe_format_log(ANDROID_LOG_INFO, "fdtrack", "fd %d: (owner = 0x%" PRIx64 ")", fd,
@@ -174,12 +219,81 @@
async_safe_format_log(ANDROID_LOG_INFO, "fdtrack", "fd %d: (unowned)", fd);
}
- for (size_t i = 0; i < count; ++i) {
+ for (size_t i = 0; i < stack_depth; ++i) {
async_safe_format_log(ANDROID_LOG_INFO, "fdtrack", " %zu: %s+%" PRIu64, i,
function_names[i], function_offsets[i]);
}
+ if (stacks) {
+ size_t hash = hash_stack(function_names, function_offsets, stack_depth);
+ bool found_stack = false;
+ for (size_t i = 0; i < stacks->count; ++i) {
+ if (stacks->data[i].hash == hash) {
+ ++stacks->data[i].count;
+ found_stack = true;
+ break;
+ }
+ }
+
+ if (!found_stack) {
+ if (stacks->count < stacks->data.size()) {
+ auto& stack = stacks->data[stacks->count++];
+ stack.hash = hash;
+ stack.count = 1;
+ stack.stack_depth = stack_depth;
+ for (size_t i = 0; i < stack_depth; ++i) {
+ stack.function_names[i] = function_names[i];
+ stack.function_offsets[i] = function_offsets[i];
+ }
+ }
+ }
+ }
+
return true;
},
- nullptr);
+ fatal ? &stacks : nullptr);
+
+ if (fatal) {
+ // Find the most common stack.
+ size_t max = 0;
+ StackInfo* stack = nullptr;
+ for (size_t i = 0; i < stacks.count; ++i) {
+ if (stacks.data[i].count > max) {
+ stack = &stacks.data[i];
+ max = stack->count;
+ }
+ }
+
+ static char buf[1024];
+
+ if (!stack) {
+ async_safe_format_buffer(buf, sizeof(buf),
+ "aborting due to fd leak: failed to find most common stack");
+ } else {
+ char* p = buf;
+ p += async_safe_format_buffer(buf, sizeof(buf),
+ "aborting due to fd leak: most common stack =\n");
+
+ for (size_t i = 0; i < stack->stack_depth; ++i) {
+ ssize_t bytes_left = buf + sizeof(buf) - p;
+ if (bytes_left > 0) {
+ p += async_safe_format_buffer(p, buf + sizeof(buf) - p, " %zu: %s+%" PRIu64 "\n", i,
+ stack->function_names[i], stack->function_offsets[i]);
+ }
+ }
+ }
+
+ android_set_abort_message(buf);
+
+ // Abort on a different thread to avoid ART dumping runtime stacks.
+ std::thread([]() { abort(); }).join();
+ }
+}
+
+void fdtrack_dump() {
+ fdtrack_dump_impl(false);
+}
+
+void fdtrack_dump_fatal() {
+ fdtrack_dump_impl(true);
}
diff --git a/libfdtrack/libfdtrack.map.txt b/libfdtrack/libfdtrack.map.txt
index 7a23954..6c4015c 100644
--- a/libfdtrack/libfdtrack.map.txt
+++ b/libfdtrack/libfdtrack.map.txt
@@ -1,6 +1,7 @@
LIBFDTRACK {
global:
fdtrack_dump;
+ fdtrack_dump_fatal;
fdtrack_iterate;
local:
*;
diff --git a/linker/Android.bp b/linker/Android.bp
index dd376da..3370f28 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -68,6 +68,9 @@
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
+
+ // b/182338959
+ bazel_module: { bp2build_available: false },
}
// ========================================================
diff --git a/tools/Android.bp b/tools/Android.bp
index 5a54fe4..dcd2a7d 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -18,5 +18,4 @@
filegroup {
name: "bionic-generate-version-script",
srcs: ["generate-version-script.py"],
- bazel_module: { bp2build_available: true },
}