Merge "fcntl: remove some duplication, fix a bug."
diff --git a/linker/linker.cpp b/linker/linker.cpp
index c10e9f6..6246f8c 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -39,6 +39,7 @@
#include <sys/vfs.h>
#include <unistd.h>
+#include <iterator>
#include <new>
#include <string>
#include <unordered_map>
@@ -2484,11 +2485,12 @@
return false;
}
- auto sonames = android::base::Split(shared_lib_sonames, ":");
- std::unordered_set<std::string> sonames_set(sonames.begin(), sonames.end());
+ std::vector<std::string> sonames = android::base::Split(shared_lib_sonames, ":");
+ std::unordered_set<std::string> sonames_set(std::make_move_iterator(sonames.begin()),
+ std::make_move_iterator(sonames.end()));
ProtectedDataGuard guard;
- namespace_from->add_linked_namespace(namespace_to, sonames_set, false);
+ namespace_from->add_linked_namespace(namespace_to, std::move(sonames_set), false);
return true;
}
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 6817901..671e0b5 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -41,11 +41,11 @@
struct android_namespace_link_t {
public:
android_namespace_link_t(android_namespace_t* linked_namespace,
- const std::unordered_set<std::string>& shared_lib_sonames,
+ std::unordered_set<std::string> shared_lib_sonames,
bool allow_all_shared_libs)
- : linked_namespace_(linked_namespace), shared_lib_sonames_(shared_lib_sonames),
- allow_all_shared_libs_(allow_all_shared_libs)
- {}
+ : linked_namespace_(linked_namespace),
+ shared_lib_sonames_(std::move(shared_lib_sonames)),
+ allow_all_shared_libs_(allow_all_shared_libs) {}
android_namespace_t* linked_namespace() const {
return linked_namespace_;
@@ -127,10 +127,10 @@
return linked_namespaces_;
}
void add_linked_namespace(android_namespace_t* linked_namespace,
- const std::unordered_set<std::string>& shared_lib_sonames,
+ std::unordered_set<std::string> shared_lib_sonames,
bool allow_all_shared_libs) {
- linked_namespaces_.push_back(
- android_namespace_link_t(linked_namespace, shared_lib_sonames, allow_all_shared_libs));
+ linked_namespaces_.emplace_back(linked_namespace, std::move(shared_lib_sonames),
+ allow_all_shared_libs);
}
void add_soinfo(soinfo* si) {
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 0c9a2e0..8ae2257 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -1661,6 +1661,7 @@
},
},
header_libs: ["bionic_libc_platform_headers"],
+ cflags: ["-fexceptions"],
}
cc_test {
@@ -1676,6 +1677,7 @@
},
},
header_libs: ["bionic_libc_platform_headers"],
+ cflags: ["-fexceptions"],
}
cc_genrule {
diff --git a/tests/libs/stack_tagging_helper.cpp b/tests/libs/stack_tagging_helper.cpp
index a239dc1..d29844d 100644
--- a/tests/libs/stack_tagging_helper.cpp
+++ b/tests/libs/stack_tagging_helper.cpp
@@ -260,6 +260,81 @@
CHECK(memtag_stack);
}
+static uintptr_t GetTag(void* addr) {
+ return reinterpret_cast<uintptr_t>(addr) & (0xFULL << 56);
+}
+
+static uintptr_t GetTag(volatile void* addr) {
+ return GetTag(const_cast<void*>(addr));
+}
+
+static volatile char* throw_frame;
+static volatile char* skip_frame3_frame;
+volatile char *x;
+
+__attribute__((noinline)) void throws() {
+ // Prevent optimization.
+ if (getpid() == 0) return;
+ throw_frame = reinterpret_cast<char*>(__builtin_frame_address(0));
+ throw "error";
+}
+
+__attribute__((noinline)) void maybe_throws() {
+ // These are all unique sizes so in case of a failure, we can see which ones
+ // are not untagged from the tag dump.
+ volatile char y[5 * 16]= {};
+ x = y;
+ // Make sure y is tagged.
+ CHECK(GetTag(&y) != GetTag(__builtin_frame_address(0)));
+ throws();
+}
+
+__attribute__((noinline, no_sanitize("memtag"))) void skip_frame() {
+ volatile char y[6*16] = {};
+ x = y;
+ // Make sure y is not tagged.
+ CHECK(GetTag(&y) == GetTag(__builtin_frame_address(0)));
+ maybe_throws();
+}
+
+__attribute__((noinline)) void skip_frame2() {
+ volatile char y[7*16] = {};
+ x = y;
+ // Make sure y is tagged.
+ CHECK(GetTag(&y) != GetTag(__builtin_frame_address(0)));
+ skip_frame();
+}
+
+__attribute__((noinline, no_sanitize("memtag"))) void skip_frame3() {
+ volatile char y[8*16] = {};
+ x = y;
+ skip_frame3_frame = reinterpret_cast<char*>(__builtin_frame_address(0));
+ // Make sure y is not tagged.
+ CHECK(GetTag(&y) == GetTag(__builtin_frame_address(0)));
+ skip_frame2();
+}
+
+void test_exception_cleanup() {
+ // This is here for debugging purposes, if something goes wrong we can
+ // verify that this placeholder did not get untagged.
+ volatile char placeholder[16*16] = {};
+ x = placeholder;
+ try {
+ skip_frame3();
+ } catch (const char* e) {
+ }
+ if (throw_frame >= skip_frame3_frame) {
+ fprintf(stderr, "invalid throw frame");
+ exit(1);
+ }
+ for (char* b = const_cast<char*>(throw_frame); b < skip_frame3_frame; ++b) {
+ if (mte_get_tag(b) != b) {
+ fprintf(stderr, "invalid tag at %p", b);
+ exit(1);
+ }
+ }
+}
+
int main(int argc, char** argv) {
if (argc < 2) {
printf("nothing to do\n");
@@ -296,6 +371,11 @@
return 0;
}
+ if (strcmp(argv[1], "exception_cleanup") == 0) {
+ test_exception_cleanup();
+ return 0;
+ }
+
printf("unrecognized command: %s\n", argv[1]);
return 1;
}
diff --git a/tests/memtag_stack_test.cpp b/tests/memtag_stack_test.cpp
index 84ee8d1..97084ec 100644
--- a/tests/memtag_stack_test.cpp
+++ b/tests/memtag_stack_test.cpp
@@ -44,13 +44,13 @@
#endif
}
-INSTANTIATE_TEST_SUITE_P(, MemtagStackTest,
- testing::Combine(testing::Values("vfork_execve", "vfork_execl",
- "vfork_exit", "longjmp",
- "longjmp_sigaltstack", "android_mallopt"),
- testing::Bool()),
- [](const ::testing::TestParamInfo<MemtagStackTest::ParamType>& info) {
- std::string s = std::get<0>(info.param);
- if (std::get<1>(info.param)) s += "_static";
- return s;
- });
+INSTANTIATE_TEST_SUITE_P(
+ , MemtagStackTest,
+ testing::Combine(testing::Values("vfork_execve", "vfork_execl", "vfork_exit", "longjmp",
+ "longjmp_sigaltstack", "android_mallopt", "exception_cleanup"),
+ testing::Bool()),
+ [](const ::testing::TestParamInfo<MemtagStackTest::ParamType>& info) {
+ std::string s = std::get<0>(info.param);
+ if (std::get<1>(info.param)) s += "_static";
+ return s;
+ });