Merge "rust: Visibility exports for bindgen"
diff --git a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
index 762aebb..f850b94 100644
--- a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
+++ b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
@@ -17,6 +17,7 @@
#include <memory>
#include <optional>
#include <string>
+#include <unordered_map>
#include <unordered_set>
#include <android-base/file.h>
@@ -165,27 +166,25 @@
android::dm::IDeviceMapper& impl_;
};
-class SnapshotTestPropertyFetcher : public android::fs_mgr::testing::MockPropertyFetcher {
+class SnapshotTestPropertyFetcher : public android::fs_mgr::IPropertyFetcher {
public:
- SnapshotTestPropertyFetcher(const std::string& slot_suffix) {
- using testing::Return;
- ON_CALL(*this, GetProperty("ro.boot.slot_suffix", _)).WillByDefault(Return(slot_suffix));
- ON_CALL(*this, GetBoolProperty("ro.boot.dynamic_partitions", _))
- .WillByDefault(Return(true));
- ON_CALL(*this, GetBoolProperty("ro.boot.dynamic_partitions_retrofit", _))
- .WillByDefault(Return(false));
- ON_CALL(*this, GetBoolProperty("ro.virtual_ab.enabled", _)).WillByDefault(Return(true));
- }
+ explicit SnapshotTestPropertyFetcher(const std::string& slot_suffix,
+ std::unordered_map<std::string, std::string>&& props = {});
+
+ std::string GetProperty(const std::string& key, const std::string& defaultValue) override;
+ bool GetBoolProperty(const std::string& key, bool defaultValue) override;
static void SetUp(const std::string& slot_suffix = "_a") { Reset(slot_suffix); }
-
static void TearDown() { Reset("_a"); }
private:
static void Reset(const std::string& slot_suffix) {
IPropertyFetcher::OverrideForTesting(
- std::make_unique<NiceMock<SnapshotTestPropertyFetcher>>(slot_suffix));
+ std::make_unique<SnapshotTestPropertyFetcher>(slot_suffix));
}
+
+ private:
+ std::unordered_map<std::string, std::string> properties_;
};
// Helper for error-spam-free cleanup.
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index d242e60..91f31b0 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -53,9 +53,11 @@
#include <libsnapshot/mock_device_info.h>
#include <libsnapshot/mock_snapshot.h>
-DEFINE_string(force_config, "", "Force testing mode (dmsnap, vab, vabc) ignoring device config.");
+DEFINE_string(force_mode, "",
+ "Force testing older modes (vab-legacy, vabc-legacy) ignoring device config.");
DEFINE_string(force_iouring_disable, "",
"Force testing mode (iouring_disabled) - disable io_uring");
+DEFINE_string(compression_method, "gz", "Default compression algorithm.");
namespace android {
namespace snapshot {
@@ -90,7 +92,6 @@
std::unique_ptr<SnapshotManager> sm;
TestDeviceInfo* test_device = nullptr;
std::string fake_super;
-bool gIsSnapuserdRequired;
void MountMetadata();
@@ -108,7 +109,7 @@
void SetUp() override {
SKIP_IF_NON_VIRTUAL_AB();
- SnapshotTestPropertyFetcher::SetUp();
+ SetupProperties();
InitializeState();
CleanupTestArtifacts();
FormatFakeSuper();
@@ -116,6 +117,38 @@
ASSERT_TRUE(sm->BeginUpdate());
}
+ void SetupProperties() {
+ std::unordered_map<std::string, std::string> properties;
+
+ ASSERT_TRUE(android::base::SetProperty("snapuserd.test.dm.snapshots", "0"))
+ << "Failed to disable property: virtual_ab.userspace.snapshots.enabled";
+ ASSERT_TRUE(android::base::SetProperty("snapuserd.test.io_uring.force_disable", "0"))
+ << "Failed to set property: snapuserd.test.io_uring.disabled";
+
+ if (FLAGS_force_mode == "vabc-legacy") {
+ ASSERT_TRUE(android::base::SetProperty("snapuserd.test.dm.snapshots", "1"))
+ << "Failed to disable property: virtual_ab.userspace.snapshots.enabled";
+ properties["ro.virtual_ab.compression.enabled"] = "true";
+ properties["ro.virtual_ab.userspace.snapshots.enabled"] = "false";
+ } else if (FLAGS_force_mode == "vab-legacy") {
+ properties["ro.virtual_ab.compression.enabled"] = "false";
+ properties["ro.virtual_ab.userspace.snapshots.enabled"] = "false";
+ }
+
+ if (FLAGS_force_iouring_disable == "iouring_disabled") {
+ ASSERT_TRUE(android::base::SetProperty("snapuserd.test.io_uring.force_disable", "1"))
+ << "Failed to set property: snapuserd.test.io_uring.disabled";
+ properties["ro.virtual_ab.io_uring.enabled"] = "false";
+ }
+
+ auto fetcher = std::make_unique<SnapshotTestPropertyFetcher>("_a", std::move(properties));
+ IPropertyFetcher::OverrideForTesting(std::move(fetcher));
+
+ if (GetLegacyCompressionEnabledProperty() || CanUseUserspaceSnapshots()) {
+ snapuserd_required_ = true;
+ }
+ }
+
void TearDown() override {
RETURN_IF_NON_VIRTUAL_AB();
@@ -358,8 +391,11 @@
DeltaArchiveManifest manifest;
auto dynamic_partition_metadata = manifest.mutable_dynamic_partition_metadata();
- dynamic_partition_metadata->set_vabc_enabled(gIsSnapuserdRequired);
+ dynamic_partition_metadata->set_vabc_enabled(snapuserd_required_);
dynamic_partition_metadata->set_cow_version(android::snapshot::kCowVersionMajor);
+ if (snapuserd_required_) {
+ dynamic_partition_metadata->set_vabc_compression_param(FLAGS_compression_method);
+ }
auto group = dynamic_partition_metadata->add_groups();
group->set_name("group");
@@ -397,7 +433,7 @@
if (!res) {
return res;
}
- } else if (!gIsSnapuserdRequired) {
+ } else if (!snapuserd_required_) {
std::string ignore;
if (!MapUpdateSnapshot("test_partition_b", &ignore)) {
return AssertionFailure() << "Failed to map test_partition_b";
@@ -450,15 +486,16 @@
std::unique_ptr<SnapshotManager::LockedFile> lock_;
android::fiemap::IImageManager* image_manager_ = nullptr;
std::string fake_super_;
+ bool snapuserd_required_ = false;
};
TEST_F(SnapshotTest, CreateSnapshot) {
ASSERT_TRUE(AcquireLock());
PartitionCowCreator cow_creator;
- cow_creator.using_snapuserd = gIsSnapuserdRequired;
+ cow_creator.using_snapuserd = snapuserd_required_;
if (cow_creator.using_snapuserd) {
- cow_creator.compression_algorithm = "gz";
+ cow_creator.compression_algorithm = FLAGS_compression_method;
} else {
cow_creator.compression_algorithm = "none";
}
@@ -497,7 +534,7 @@
ASSERT_TRUE(AcquireLock());
PartitionCowCreator cow_creator;
- cow_creator.using_snapuserd = gIsSnapuserdRequired;
+ cow_creator.using_snapuserd = snapuserd_required_;
static const uint64_t kDeviceSize = 1024 * 1024;
SnapshotStatus status;
@@ -624,10 +661,10 @@
SnapshotStatus status;
ASSERT_TRUE(init->ReadSnapshotStatus(lock_.get(), "test_partition_b", &status));
ASSERT_EQ(status.state(), SnapshotState::CREATED);
- if (gIsSnapuserdRequired) {
- ASSERT_EQ(status.compression_algorithm(), "gz");
+ if (snapuserd_required_) {
+ ASSERT_EQ(status.compression_algorithm(), FLAGS_compression_method);
} else {
- ASSERT_EQ(status.compression_algorithm(), "none");
+ ASSERT_EQ(status.compression_algorithm(), "");
}
DeviceMapper::TargetInfo target;
@@ -898,8 +935,11 @@
opener_ = std::make_unique<TestPartitionOpener>(fake_super);
auto dynamic_partition_metadata = manifest_.mutable_dynamic_partition_metadata();
- dynamic_partition_metadata->set_vabc_enabled(gIsSnapuserdRequired);
+ dynamic_partition_metadata->set_vabc_enabled(snapuserd_required_);
dynamic_partition_metadata->set_cow_version(android::snapshot::kCowVersionMajor);
+ if (snapuserd_required_) {
+ dynamic_partition_metadata->set_vabc_compression_param(FLAGS_compression_method);
+ }
// Create a fake update package metadata.
// Not using full name "system", "vendor", "product" because these names collide with the
@@ -1031,7 +1071,7 @@
}
AssertionResult MapOneUpdateSnapshot(const std::string& name) {
- if (gIsSnapuserdRequired) {
+ if (snapuserd_required_) {
std::unique_ptr<ISnapshotWriter> writer;
return MapUpdateSnapshot(name, &writer);
} else {
@@ -1052,7 +1092,7 @@
AssertionResult WriteSnapshotAndHash(PartitionUpdate* partition) {
std::string name = partition->partition_name() + "_b";
- if (gIsSnapuserdRequired) {
+ if (snapuserd_required_) {
std::unique_ptr<ISnapshotWriter> writer;
auto res = MapUpdateSnapshot(name, &writer);
if (!res) {
@@ -1254,7 +1294,7 @@
// Initiate the merge and wait for it to be completed.
ASSERT_TRUE(init->InitiateMerge());
- ASSERT_EQ(init->IsSnapuserdRequired(), gIsSnapuserdRequired);
+ ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
{
// We should have started in SECOND_PHASE since nothing shrinks.
ASSERT_TRUE(AcquireLock());
@@ -1281,7 +1321,7 @@
}
TEST_F(SnapshotUpdateTest, DuplicateOps) {
- if (!gIsSnapuserdRequired) {
+ if (!snapuserd_required_) {
GTEST_SKIP() << "snapuserd-only test";
}
@@ -1323,7 +1363,7 @@
// Test that shrinking and growing partitions at the same time is handled
// correctly in VABC.
TEST_F(SnapshotUpdateTest, SpaceSwapUpdate) {
- if (!gIsSnapuserdRequired) {
+ if (!snapuserd_required_) {
// b/179111359
GTEST_SKIP() << "Skipping snapuserd test";
}
@@ -1386,7 +1426,7 @@
// Initiate the merge and wait for it to be completed.
ASSERT_TRUE(init->InitiateMerge());
- ASSERT_EQ(init->IsSnapuserdRequired(), gIsSnapuserdRequired);
+ ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
{
// Check that the merge phase is FIRST_PHASE until at least one call
// to ProcessUpdateState() occurs.
@@ -1440,7 +1480,7 @@
// Test that a transient merge consistency check failure can resume properly.
TEST_F(SnapshotUpdateTest, ConsistencyCheckResume) {
- if (!gIsSnapuserdRequired) {
+ if (!snapuserd_required_) {
// b/179111359
GTEST_SKIP() << "Skipping snapuserd test";
}
@@ -1494,7 +1534,7 @@
// Initiate the merge and wait for it to be completed.
ASSERT_TRUE(init->InitiateMerge());
- ASSERT_EQ(init->IsSnapuserdRequired(), gIsSnapuserdRequired);
+ ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
{
// Check that the merge phase is FIRST_PHASE until at least one call
// to ProcessUpdateState() occurs.
@@ -2098,8 +2138,8 @@
ASSERT_TRUE(AcquireLock());
PartitionCowCreator cow_creator = {
- .using_snapuserd = gIsSnapuserdRequired,
- .compression_algorithm = gIsSnapuserdRequired ? "gz" : "",
+ .using_snapuserd = snapuserd_required_,
+ .compression_algorithm = snapuserd_required_ ? FLAGS_compression_method : "",
};
SnapshotStatus status;
status.set_name("sys_a");
@@ -2195,7 +2235,7 @@
// Test for overflow bit after update
TEST_F(SnapshotUpdateTest, Overflow) {
- if (gIsSnapuserdRequired) {
+ if (snapuserd_required_) {
GTEST_SKIP() << "No overflow bit set for snapuserd COWs";
}
@@ -2330,7 +2370,7 @@
};
TEST_F(SnapshotUpdateTest, DaemonTransition) {
- if (!gIsSnapuserdRequired) {
+ if (!snapuserd_required_) {
GTEST_SKIP() << "Skipping snapuserd test";
}
@@ -2761,21 +2801,17 @@
}
}
-void SetGlobalConfigOptions() {
- if (FLAGS_force_config == "dmsnap") {
- ASSERT_TRUE(android::base::SetProperty("snapuserd.test.dm.snapshots", "1"))
- << "Failed to disable property: virtual_ab.userspace.snapshots.enabled";
+void KillSnapuserd() {
+ auto status = android::base::GetProperty("init.svc.snapuserd", "stopped");
+ if (status == "stopped") {
+ return;
}
-
- if (FLAGS_force_iouring_disable == "iouring_disabled") {
- ASSERT_TRUE(android::base::SetProperty("snapuserd.test.io_uring.force_disable", "1"))
- << "Failed to disable property: snapuserd.test.io_uring.disabled";
+ auto snapuserd_client = SnapuserdClient::Connect(kSnapuserdSocket, 5s);
+ if (!snapuserd_client) {
+ return;
}
-
- if (FLAGS_force_config != "dmsnap" &&
- (GetLegacyCompressionEnabledProperty() || CanUseUserspaceSnapshots())) {
- gIsSnapuserdRequired = true;
- }
+ snapuserd_client->DetachSnapuserd();
+ snapuserd_client->CloseConnection();
}
} // namespace snapshot
@@ -2788,23 +2824,20 @@
android::base::SetProperty("ctl.stop", "snapuserd");
- std::unordered_set<std::string> configs = {"", "dmsnap", "vab", "vabc"};
- if (configs.count(FLAGS_force_config) == 0) {
+ std::unordered_set<std::string> modes = {"", "vab-legacy", "vabc-legacy"};
+ if (modes.count(FLAGS_force_mode) == 0) {
std::cerr << "Unexpected force_config argument\n";
return 1;
}
- android::snapshot::SetGlobalConfigOptions();
+ // This is necessary if the configuration we're testing doesn't match the device.
+ android::snapshot::KillSnapuserd();
int ret = RUN_ALL_TESTS();
- if (FLAGS_force_config == "dmsnap") {
- android::base::SetProperty("snapuserd.test.dm.snapshots", "0");
- }
+ android::base::SetProperty("snapuserd.test.dm.snapshots", "0");
+ android::base::SetProperty("snapuserd.test.io_uring.force_disable", "0");
- if (FLAGS_force_iouring_disable == "iouring_disabled") {
- android::base::SetProperty("snapuserd.test.io_uring.force_disable", "0");
- }
-
+ android::snapshot::KillSnapuserd();
return ret;
}
diff --git a/fs_mgr/libsnapshot/test_helpers.cpp b/fs_mgr/libsnapshot/test_helpers.cpp
index 3e889a0..b05123a 100644
--- a/fs_mgr/libsnapshot/test_helpers.cpp
+++ b/fs_mgr/libsnapshot/test_helpers.cpp
@@ -18,10 +18,12 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/parsebool.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
+#include <liblp/property_fetcher.h>
#include <openssl/sha.h>
#include <payload_consumer/file_descriptor.h>
@@ -278,5 +280,38 @@
return android::base::GetBoolProperty("ro.virtual_ab.enabled", false);
}
+SnapshotTestPropertyFetcher::SnapshotTestPropertyFetcher(
+ const std::string& slot_suffix, std::unordered_map<std::string, std::string>&& props)
+ : properties_(std::move(props)) {
+ properties_["ro.boot.slot_suffix"] = slot_suffix;
+ properties_["ro.boot.dynamic_partitions"] = "true";
+ properties_["ro.boot.dynamic_partitions_retrofit"] = "false";
+ properties_["ro.virtual_ab.enabled"] = "true";
+}
+
+std::string SnapshotTestPropertyFetcher::GetProperty(const std::string& key,
+ const std::string& defaultValue) {
+ auto iter = properties_.find(key);
+ if (iter == properties_.end()) {
+ return android::base::GetProperty(key, defaultValue);
+ }
+ return iter->second;
+}
+
+bool SnapshotTestPropertyFetcher::GetBoolProperty(const std::string& key, bool defaultValue) {
+ auto iter = properties_.find(key);
+ if (iter == properties_.end()) {
+ return android::base::GetBoolProperty(key, defaultValue);
+ }
+ switch (android::base::ParseBool(iter->second)) {
+ case android::base::ParseBoolResult::kTrue:
+ return true;
+ case android::base::ParseBoolResult::kFalse:
+ return false;
+ default:
+ return defaultValue;
+ }
+}
+
} // namespace snapshot
} // namespace android
diff --git a/fs_mgr/libsnapshot/utility.cpp b/fs_mgr/libsnapshot/utility.cpp
index 08207be..0a1be0d 100644
--- a/fs_mgr/libsnapshot/utility.cpp
+++ b/fs_mgr/libsnapshot/utility.cpp
@@ -26,6 +26,7 @@
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <fs_mgr/roots.h>
+#include <liblp/property_fetcher.h>
using android::dm::kSectorSize;
using android::fiemap::FiemapStatus;
@@ -33,6 +34,7 @@
using android::fs_mgr::EnsurePathUnmounted;
using android::fs_mgr::Fstab;
using android::fs_mgr::GetEntryForPath;
+using android::fs_mgr::IPropertyFetcher;
using android::fs_mgr::MetadataBuilder;
using android::fs_mgr::Partition;
using android::fs_mgr::ReadDefaultFstab;
@@ -185,11 +187,13 @@
}
bool GetLegacyCompressionEnabledProperty() {
- return android::base::GetBoolProperty("ro.virtual_ab.compression.enabled", false);
+ auto fetcher = IPropertyFetcher::GetInstance();
+ return fetcher->GetBoolProperty("ro.virtual_ab.compression.enabled", false);
}
bool GetUserspaceSnapshotsEnabledProperty() {
- return android::base::GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
+ auto fetcher = IPropertyFetcher::GetInstance();
+ return fetcher->GetBoolProperty("ro.virtual_ab.userspace.snapshots.enabled", false);
}
bool CanUseUserspaceSnapshots() {
@@ -197,9 +201,11 @@
return false;
}
+ auto fetcher = IPropertyFetcher::GetInstance();
+
const std::string UNKNOWN = "unknown";
const std::string vendor_release =
- android::base::GetProperty("ro.vendor.build.version.release_or_codename", UNKNOWN);
+ fetcher->GetProperty("ro.vendor.build.version.release_or_codename", UNKNOWN);
// No user-space snapshots if vendor partition is on Android 12
if (vendor_release.find("12") != std::string::npos) {
@@ -217,11 +223,13 @@
}
bool GetIouringEnabledProperty() {
- return android::base::GetBoolProperty("ro.virtual_ab.io_uring.enabled", false);
+ auto fetcher = IPropertyFetcher::GetInstance();
+ return fetcher->GetBoolProperty("ro.virtual_ab.io_uring.enabled", false);
}
bool GetXorCompressionEnabledProperty() {
- return android::base::GetBoolProperty("ro.virtual_ab.compression.xor.enabled", false);
+ auto fetcher = IPropertyFetcher::GetInstance();
+ return fetcher->GetBoolProperty("ro.virtual_ab.compression.xor.enabled", false);
}
std::string GetOtherPartitionName(const std::string& name) {
@@ -233,7 +241,8 @@
}
bool IsDmSnapshotTestingEnabled() {
- return android::base::GetBoolProperty("snapuserd.test.dm.snapshots", false);
+ auto fetcher = IPropertyFetcher::GetInstance();
+ return fetcher->GetBoolProperty("snapuserd.test.dm.snapshots", false);
}
} // namespace snapshot
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index 40b6bf0..ed5b2a9 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -149,6 +149,29 @@
// Same for weak counts.
#define BAD_WEAK(c) ((c) == 0 || ((c) & (~MAX_COUNT)) != 0)
+// name kept because prebuilts used to use it from inlining sp<> code
+void sp_report_stack_pointer() { LOG_ALWAYS_FATAL("RefBase used with stack pointer argument"); }
+
+// Check whether address is definitely on the calling stack. We actually check whether it is on
+// the same 4K page as the frame pointer.
+//
+// Assumptions:
+// - Pages are never smaller than 4K (MIN_PAGE_SIZE)
+// - Malloced memory never shares a page with a stack.
+//
+// It does not appear safe to broaden this check to include adjacent pages; apparently this code
+// is used in environments where there may not be a guard page below (at higher addresses than)
+// the bottom of the stack.
+static void check_not_on_stack(const void* ptr) {
+ static constexpr int MIN_PAGE_SIZE = 0x1000; // 4K. Safer than including sys/user.h.
+ static constexpr uintptr_t MIN_PAGE_MASK = ~static_cast<uintptr_t>(MIN_PAGE_SIZE - 1);
+ uintptr_t my_frame_address =
+ reinterpret_cast<uintptr_t>(__builtin_frame_address(0 /* this frame */));
+ if (((reinterpret_cast<uintptr_t>(ptr) ^ my_frame_address) & MIN_PAGE_MASK) == 0) {
+ sp_report_stack_pointer();
+ }
+}
+
// ---------------------------------------------------------------------------
class RefBase::weakref_impl : public RefBase::weakref_type
@@ -432,6 +455,8 @@
return;
}
+ check_not_on_stack(this);
+
int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
// A decStrong() must still happen after us.
ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);
@@ -772,6 +797,8 @@
void RefBase::extendObjectLifetime(int32_t mode)
{
+ check_not_on_stack(this);
+
// Must be happens-before ordered with respect to construction or any
// operation that could destroy the object.
mRefs->mFlags.fetch_or(mode, std::memory_order_relaxed);
diff --git a/libutils/RefBase_test.cpp b/libutils/RefBase_test.cpp
index b89779d..aed3b9b 100644
--- a/libutils/RefBase_test.cpp
+++ b/libutils/RefBase_test.cpp
@@ -275,6 +275,11 @@
EXPECT_FALSE(isDeleted);
}
+TEST(RefBase, StackOwnershipDeath) {
+ bool isDeleted;
+ EXPECT_DEATH({ Foo foo(&isDeleted); foo.incStrong(nullptr); }, "");
+}
+
// Set up a situation in which we race with visit2AndRremove() to delete
// 2 strong references. Bar destructor checks that there are no early
// deletions and prior updates are visible to destructor.
diff --git a/libutils/StrongPointer.cpp b/libutils/StrongPointer.cpp
index ef46723..ba52502 100644
--- a/libutils/StrongPointer.cpp
+++ b/libutils/StrongPointer.cpp
@@ -21,7 +21,4 @@
namespace android {
void sp_report_race() { LOG_ALWAYS_FATAL("sp<> assignment detected data race"); }
-
-void sp_report_stack_pointer() { LOG_ALWAYS_FATAL("sp<> constructed with stack pointer argument"); }
-
}
diff --git a/libutils/include/utils/StrongPointer.h b/libutils/include/utils/StrongPointer.h
index bb1941b..54aa691 100644
--- a/libutils/include/utils/StrongPointer.h
+++ b/libutils/include/utils/StrongPointer.h
@@ -120,7 +120,6 @@
template<typename Y> friend class sp;
template<typename Y> friend class wp;
void set_pointer(T* ptr);
- static inline void check_not_on_stack(const void* ptr);
T* m_ptr;
};
@@ -185,32 +184,10 @@
// For code size reasons, we do not want these inlined or templated.
void sp_report_race();
-void sp_report_stack_pointer();
// ---------------------------------------------------------------------------
// No user serviceable parts below here.
-// Check whether address is definitely on the calling stack. We actually check whether it is on
-// the same 4K page as the frame pointer.
-//
-// Assumptions:
-// - Pages are never smaller than 4K (MIN_PAGE_SIZE)
-// - Malloced memory never shares a page with a stack.
-//
-// It does not appear safe to broaden this check to include adjacent pages; apparently this code
-// is used in environments where there may not be a guard page below (at higher addresses than)
-// the bottom of the stack.
-template <typename T>
-void sp<T>::check_not_on_stack(const void* ptr) {
- static constexpr int MIN_PAGE_SIZE = 0x1000; // 4K. Safer than including sys/user.h.
- static constexpr uintptr_t MIN_PAGE_MASK = ~static_cast<uintptr_t>(MIN_PAGE_SIZE - 1);
- uintptr_t my_frame_address =
- reinterpret_cast<uintptr_t>(__builtin_frame_address(0 /* this frame */));
- if (((reinterpret_cast<uintptr_t>(ptr) ^ my_frame_address) & MIN_PAGE_MASK) == 0) {
- sp_report_stack_pointer();
- }
-}
-
// TODO: Ideally we should find a way to increment the reference count before running the
// constructor, so that generating an sp<> to this in the constructor is no longer dangerous.
template <typename T>
@@ -219,14 +196,13 @@
T* t = new T(std::forward<Args>(args)...);
sp<T> result;
result.m_ptr = t;
- t->incStrong(t); // bypass check_not_on_stack for heap allocation
+ t->incStrong(t);
return result;
}
template <typename T>
sp<T> sp<T>::fromExisting(T* other) {
if (other) {
- check_not_on_stack(other);
other->incStrongRequireStrong(other);
sp<T> result;
result.m_ptr = other;
@@ -240,7 +216,6 @@
sp<T>::sp(T* other)
: m_ptr(other) {
if (other) {
- check_not_on_stack(other);
other->incStrong(this);
}
}
@@ -249,7 +224,6 @@
template <typename U>
sp<T>::sp(U* other) : m_ptr(other) {
if (other) {
- check_not_on_stack(other);
(static_cast<T*>(other))->incStrong(this);
}
}
@@ -258,7 +232,6 @@
sp<T>& sp<T>::operator=(T* other) {
T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
if (other) {
- check_not_on_stack(other);
other->incStrong(this);
}
if (oldPtr) oldPtr->decStrong(this);
diff --git a/trusty/OWNERS b/trusty/OWNERS
index 5c4e03a..61b97c6 100644
--- a/trusty/OWNERS
+++ b/trusty/OWNERS
@@ -1,9 +1,11 @@
armellel@google.com
arve@android.com
+danielangell@google.com
gmar@google.com
marcone@google.com
mmaurer@google.com
ncbray@google.com
swillden@google.com
+thurston@google.com
trong@google.com
wenhaowang@google.com
diff --git a/trusty/metrics/metrics_test.cpp b/trusty/metrics/metrics_test.cpp
index 9897950..0c6db7f 100644
--- a/trusty/metrics/metrics_test.cpp
+++ b/trusty/metrics/metrics_test.cpp
@@ -61,6 +61,18 @@
virtual void SetUp() override {
auto ret = Open();
ASSERT_TRUE(ret.ok()) << ret.error();
+
+ /* Drain events (if any) and reset state */
+ DrainEvents();
+ crashed_app_.clear();
+ event_drop_count_ = 0;
+ }
+
+ void DrainEvents() {
+ while (WaitForEvent(1000 /* 1 second timeout */).ok()) {
+ auto ret = HandleEvent();
+ ASSERT_TRUE(ret.ok()) << ret.error();
+ }
}
void WaitForAndHandleEvent() {
@@ -79,6 +91,9 @@
TriggerCrash();
WaitForAndHandleEvent();
+ /* Check that no event was dropped. */
+ ASSERT_EQ(event_drop_count_, 0);
+
/* Check that correct TA crashed. */
ASSERT_EQ(crashed_app_, "36f5b435-5bd3-4526-8b76-200e3a7e79f3:crasher");
}
@@ -110,6 +125,9 @@
auto ret = HandleEvent();
ASSERT_TRUE(ret.ok()) << ret.error();
+ /* Check that no event was dropped. */
+ ASSERT_EQ(event_drop_count_, 0);
+
/* Check that correct TA crashed. */
ASSERT_EQ(crashed_app_, "36f5b435-5bd3-4526-8b76-200e3a7e79f3:crasher");
}