Merge "Reland: "Make native bridge libc uninstallable""
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index dd623a5..8084e73 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -149,50 +149,25 @@
_exit(EXIT_FAILURE);
}
-// Force any of the closed stdin, stdout and stderr to be associated with /dev/null.
+// Force any of the stdin/stdout/stderr file descriptors that aren't
+// open to be associated with /dev/null.
static void __nullify_closed_stdio() {
- int dev_null = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
- if (dev_null == -1) {
- // init won't have /dev/null available, but SELinux provides an equivalent.
- dev_null = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR));
- }
- if (dev_null == -1) {
- __early_abort(__LINE__);
- }
-
- // If any of the stdio file descriptors is valid and not associated
- // with /dev/null, dup /dev/null to it.
for (int i = 0; i < 3; i++) {
- // If it is /dev/null already, we are done.
- if (i == dev_null) {
- continue;
- }
+ if (TEMP_FAILURE_RETRY(fcntl(i, F_GETFL)) == -1) {
+ // The only error we allow is that the file descriptor does not exist.
+ if (errno != EBADF) __early_abort(__LINE__);
- // Is this fd already open?
- int status = TEMP_FAILURE_RETRY(fcntl(i, F_GETFL));
- if (status != -1) {
- continue;
- }
-
- // The only error we allow is that the file descriptor does not
- // exist, in which case we dup /dev/null to it.
- if (errno == EBADF) {
- // Try dupping /dev/null to this stdio file descriptor and
- // repeat if there is a signal. Note that any errors in closing
- // the stdio descriptor are lost.
- status = TEMP_FAILURE_RETRY(dup2(dev_null, i));
- if (status == -1) {
+ // This file descriptor wasn't open, so open /dev/null.
+ // init won't have /dev/null available, but SELinux provides an equivalent.
+ // This takes advantage of the fact that open() will take the lowest free
+ // file descriptor, and we're iterating in order from 0, but we'll
+ // double-check we got the right fd anyway...
+ int fd;
+ if (((fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR))) == -1 &&
+ (fd = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR))) == -1) ||
+ fd != i) {
__early_abort(__LINE__);
}
- } else {
- __early_abort(__LINE__);
- }
- }
-
- // If /dev/null is not one of the stdio file descriptors, close it.
- if (dev_null > 2) {
- if (close(dev_null) == -1) {
- __early_abort(__LINE__);
}
}
}
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index 128991b..dbaebb3 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -87,7 +87,7 @@
void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info) {
for (size_t i = 0; i < frame_info.size(); i++) {
const unwindstack::LocalFrameData* info = &frame_info[i];
- unwindstack::MapInfo* map_info = info->map_info;
+ std::shared_ptr<unwindstack::MapInfo> map_info = info->map_info;
std::string line = android::base::StringPrintf(" #%0zd pc %" PAD_PTR " ", i, info->rel_pc);
if (map_info->offset() != 0) {
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 1298df7..7b58f31 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -1528,19 +1528,18 @@
TEST_F(MallocDebugTest, backtrace_full_dump_on_exit) {
pid_t pid;
if ((pid = fork()) == 0) {
+ std::shared_ptr<unwindstack::MapInfo> empty_map;
Init("backtrace=4 backtrace_full backtrace_dump_on_exit");
+ BacktraceUnwindFake(std::vector<unwindstack::LocalFrameData>{
+ {empty_map, 0x1100, 0x100, "fake1", 10}, {empty_map, 0x1200, 0x200, "fake2", 20}});
+ std::shared_ptr<unwindstack::MapInfo> map_info =
+ unwindstack::MapInfo::Create(0x10000, 0x20000, 0, PROT_READ | PROT_EXEC, "/data/fake.so");
+ BacktraceUnwindFake(std::vector<unwindstack::LocalFrameData>{
+ {map_info, 0x1a000, 0xa000, "level1", 0}, {map_info, 0x1b000, 0xb000, "level2", 10}});
BacktraceUnwindFake(
- std::vector<unwindstack::LocalFrameData>{{nullptr, 0x1100, 0x100, "fake1", 10},
- {nullptr, 0x1200, 0x200, "fake2", 20}});
- unwindstack::MapInfo map_info{nullptr, nullptr, 0x10000, 0x20000, 0,
- PROT_READ | PROT_EXEC, "/data/fake.so"};
- BacktraceUnwindFake(
- std::vector<unwindstack::LocalFrameData>{{&map_info, 0x1a000, 0xa000, "level1", 0},
- {&map_info, 0x1b000, 0xb000, "level2", 10}});
- BacktraceUnwindFake(
- std::vector<unwindstack::LocalFrameData>{{nullptr, 0x1a000, 0xa000, "func1", 0},
- {nullptr, 0x1b000, 0xb000, "func2", 10},
- {nullptr, 0x1c000, 0xc000, "", 30}});
+ std::vector<unwindstack::LocalFrameData>{{empty_map, 0x1a000, 0xa000, "func1", 0},
+ {empty_map, 0x1b000, 0xb000, "func2", 10},
+ {empty_map, 0x1c000, 0xc000, "", 30}});
std::vector<void*> pointers;
pointers.push_back(debug_malloc(300));