Merge changes from topic "snapuserd-gflags"
* changes:
snapuserd: Add a no-socket mode.
snapuserd: Use gflags for arguments.
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index d7067ca..2f1b693 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -370,14 +370,12 @@
return "SEGV_ADIDERR";
case SEGV_ADIPERR:
return "SEGV_ADIPERR";
-#if defined(ANDROID_EXPERIMENTAL_MTE)
case SEGV_MTEAERR:
return "SEGV_MTEAERR";
case SEGV_MTESERR:
return "SEGV_MTESERR";
-#endif
}
- static_assert(NSIGSEGV == SEGV_ADIPERR, "missing SEGV_* si_code");
+ static_assert(NSIGSEGV == SEGV_MTESERR, "missing SEGV_* si_code");
break;
case SIGSYS:
switch (si->si_code) {
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 6948dd1..f0adbea 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -24,6 +24,7 @@
],
shared_libs: [
"libbase",
+ "libchrome",
"libcutils",
"liblog",
],
@@ -44,7 +45,6 @@
"libz",
],
header_libs: [
- "libchrome",
"libfiemap_headers",
"libstorage_literals_headers",
"libupdate_engine_headers",
@@ -351,6 +351,7 @@
static_libs: [
"libbase",
"libbrotli",
+ "libchrome",
"libcrypto_static",
"libcutils",
"libext2_uuid",
@@ -367,7 +368,6 @@
"libz",
],
header_libs: [
- "libchrome",
"libfiemap_headers",
"libstorage_literals_headers",
"libupdate_engine_headers",
diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp
index 3fbc5f3..c15a05b 100644
--- a/fs_mgr/libsnapshot/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/cow_reader.cpp
@@ -222,8 +222,6 @@
LOG(ERROR) << "ops checksum does not match";
return false;
}
- } else {
- LOG(INFO) << "No COW Footer, recovered data";
}
ops_ = ops_buffer;
diff --git a/init/firmware_handler_test.cpp b/init/firmware_handler_test.cpp
index 7bb603c..5124a6f 100644
--- a/init/firmware_handler_test.cpp
+++ b/init/firmware_handler_test.cpp
@@ -79,6 +79,8 @@
}
int HandleAbort(int argc, char** argv) {
+ // Since this is an expected failure, disable debuggerd to not generate a tombstone.
+ signal(SIGABRT, SIG_DFL);
abort();
return 0;
}
diff --git a/init/init_test.cpp b/init/init_test.cpp
index fa65740..8550ec8 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -17,6 +17,7 @@
#include <functional>
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/properties.h>
#include <gtest/gtest.h>
@@ -268,6 +269,17 @@
ASSERT_EQ(1u, parser.parse_error_count());
}
+class TestCaseLogger : public ::testing::EmptyTestEventListener {
+ void OnTestStart(const ::testing::TestInfo& test_info) override {
+#ifdef __ANDROID__
+ LOG(INFO) << "===== " << test_info.test_suite_name() << "::" << test_info.name() << " ("
+ << test_info.file() << ":" << test_info.line() << ")";
+#else
+ UNUSED(test_info);
+#endif
+ }
+};
+
} // namespace init
} // namespace android
@@ -284,5 +296,6 @@
}
testing::InitGoogleTest(&argc, argv);
+ testing::UnitTest::GetInstance()->listeners().Append(new android::init::TestCaseLogger());
return RUN_ALL_TESTS();
}
diff --git a/init/subcontext_test.cpp b/init/subcontext_test.cpp
index ee765a7..da1f455 100644
--- a/init/subcontext_test.cpp
+++ b/init/subcontext_test.cpp
@@ -202,6 +202,8 @@
// For RecoverAfterAbort
auto do_cause_log_fatal = [](const BuiltinArguments& args) -> Result<void> {
+ // Since this is an expected failure, disable debuggerd to not generate a tombstone.
+ signal(SIGABRT, SIG_DFL);
return Error() << std::string(4097, 'f');
};
auto do_generate_sane_error = [](const BuiltinArguments& args) -> Result<void> {
diff --git a/libappfuse/tests/FuseAppLoopTest.cc b/libappfuse/tests/FuseAppLoopTest.cc
index 98e3665..ea98ae2 100644
--- a/libappfuse/tests/FuseAppLoopTest.cc
+++ b/libappfuse/tests/FuseAppLoopTest.cc
@@ -167,7 +167,7 @@
EXPECT_EQ(0u, response_.entry_out.attr.gid);
EXPECT_EQ(0u, response_.entry_out.attr.rdev);
EXPECT_EQ(0u, response_.entry_out.attr.blksize);
- EXPECT_EQ(0u, response_.entry_out.attr.padding);
+ EXPECT_EQ(0u, response_.entry_out.attr.flags);
}
TEST_F(FuseAppLoopTest, LookUp_InvalidName) {
@@ -226,7 +226,7 @@
EXPECT_EQ(0u, response_.attr_out.attr.gid);
EXPECT_EQ(0u, response_.attr_out.attr.rdev);
EXPECT_EQ(0u, response_.attr_out.attr.blksize);
- EXPECT_EQ(0u, response_.attr_out.attr.padding);
+ EXPECT_EQ(0u, response_.attr_out.attr.flags);
}
TEST_F(FuseAppLoopTest, GetAttr_Root) {
@@ -259,7 +259,7 @@
EXPECT_EQ(0u, response_.attr_out.attr.gid);
EXPECT_EQ(0u, response_.attr_out.attr.rdev);
EXPECT_EQ(0u, response_.attr_out.attr.blksize);
- EXPECT_EQ(0u, response_.attr_out.attr.padding);
+ EXPECT_EQ(0u, response_.attr_out.attr.flags);
}
TEST_F(FuseAppLoopTest, Open) {
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 42229bd..1147315 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -46,7 +46,8 @@
/dev/vndbinder 0666 root root
/dev/pmsg0 0222 root log
-/dev/dma_heap/system 0666 system system
+/dev/dma_heap/system 0444 system system
+/dev/dma_heap/system-uncached 0444 system system
# kms driver for drm based gpu
/dev/dri/* 0666 root graphics
diff --git a/trusty/coverage/Android.bp b/trusty/coverage/Android.bp
index a4adf81..3d2caa6 100644
--- a/trusty/coverage/Android.bp
+++ b/trusty/coverage/Android.bp
@@ -42,4 +42,5 @@
"libbase",
"liblog",
],
+ require_root: true,
}
diff --git a/trusty/coverage/coverage.cpp b/trusty/coverage/coverage.cpp
index 1162f42..9413ce3 100644
--- a/trusty/coverage/coverage.cpp
+++ b/trusty/coverage/coverage.cpp
@@ -16,12 +16,15 @@
#define LOG_TAG "coverage"
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <assert.h>
+#include <stdio.h>
#include <sys/mman.h>
#include <sys/uio.h>
#include <trusty/coverage/coverage.h>
+#include <trusty/coverage/record.h>
#include <trusty/coverage/tipc.h>
#include <trusty/tipc.h>
@@ -137,12 +140,59 @@
return {};
}
-void CoverageRecord::Reset() {
- for (size_t i = 0; i < shm_len_; i++) {
+void CoverageRecord::ResetFullRecord() {
+ auto header_region = GetRegionBounds(COV_START);
+ if (!header_region) {
+ // If the header cannot be parsed, we can't reset the proper region yet.
+ return;
+ }
+
+ for (size_t i = header_region->second; i < shm_len_; i++) {
*((volatile uint8_t*)shm_ + i) = 0;
}
}
+void CoverageRecord::ResetCounts() {
+ volatile uint8_t* begin = nullptr;
+ volatile uint8_t* end = nullptr;
+ GetRawCounts(&begin, &end);
+
+ for (volatile uint8_t* x = begin; x < end; x++) {
+ *x = 0;
+ }
+}
+
+void CoverageRecord::ResetPCs() {
+ volatile uintptr_t* begin = nullptr;
+ volatile uintptr_t* end = nullptr;
+ GetRawPCs(&begin, &end);
+
+ for (volatile uintptr_t* x = begin; x < end; x++) {
+ *x = 0;
+ }
+}
+
+Result<std::pair<size_t, size_t>> CoverageRecord::GetRegionBounds(uint32_t region_type) {
+ assert(shm_);
+
+ auto header = (volatile struct coverage_record_header*)shm_;
+
+ if (header->type != COV_START) {
+ return Error() << "Header not yet valid";
+ }
+
+ for (++header; header->type != COV_TOTAL_LENGTH; ++header) {
+ if (header->type == region_type) {
+ // Coverage record must end with a COV_TOTAL_LENGTH header entry, so
+ // it is always safe to read the next entry since we don't iterate
+ // over the COV_TOTAL_LENGTH entry.
+ return {{header->offset, (header + 1)->offset}};
+ }
+ }
+
+ return Error() << "Could not find coverage region type: " << region_type;
+}
+
void CoverageRecord::GetRawData(volatile void** begin, volatile void** end) {
assert(shm_);
@@ -150,7 +200,35 @@
*end = (uint8_t*)(*begin) + record_len_;
}
-uint64_t CoverageRecord::CountEdges() {
+void CoverageRecord::GetRawCounts(volatile uint8_t** begin, volatile uint8_t** end) {
+ auto region = GetRegionBounds(COV_8BIT_COUNTERS);
+ if (!region) {
+ *begin = 0;
+ *end = 0;
+ return;
+ }
+
+ assert(region->second <= record_len_);
+
+ *begin = (volatile uint8_t*)shm_ + region->first;
+ *end = (volatile uint8_t*)shm_ + region->second;
+}
+
+void CoverageRecord::GetRawPCs(volatile uintptr_t** begin, volatile uintptr_t** end) {
+ auto region = GetRegionBounds(COV_INSTR_PCS);
+ if (!region) {
+ *begin = 0;
+ *end = 0;
+ return;
+ }
+
+ assert(region->second <= record_len_);
+
+ *begin = (volatile uintptr_t*)((volatile uint8_t*)shm_ + region->first);
+ *end = (volatile uintptr_t*)((volatile uint8_t*)shm_ + region->second);
+}
+
+uint64_t CoverageRecord::TotalEdgeCounts() {
assert(shm_);
uint64_t counter = 0;
@@ -158,7 +236,7 @@
volatile uint8_t* begin = NULL;
volatile uint8_t* end = NULL;
- GetRawData((volatile void**)&begin, (volatile void**)&end);
+ GetRawCounts(&begin, &end);
for (volatile uint8_t* x = begin; x < end; x++) {
counter += *x;
@@ -167,6 +245,35 @@
return counter;
}
+Result<void> CoverageRecord::SaveSancovFile(const std::string& filename) {
+ android::base::unique_fd output_fd(TEMP_FAILURE_RETRY(creat(filename.c_str(), 00644)));
+ if (!output_fd.ok()) {
+ return ErrnoError() << "Could not open sancov file";
+ }
+
+ uint64_t magic;
+ if (sizeof(uintptr_t) == 8) {
+ magic = 0xC0BFFFFFFFFFFF64;
+ } else if (sizeof(uintptr_t) == 4) {
+ magic = 0xC0BFFFFFFFFFFF32;
+ }
+ WriteFully(output_fd, &magic, sizeof(magic));
+
+ volatile uintptr_t* begin = nullptr;
+ volatile uintptr_t* end = nullptr;
+
+ GetRawPCs(&begin, &end);
+
+ for (volatile uintptr_t* pc_ptr = begin; pc_ptr < end; pc_ptr++) {
+ uintptr_t pc = *pc_ptr;
+ if (pc) {
+ WriteFully(output_fd, &pc, sizeof(pc));
+ }
+ }
+
+ return {};
+}
+
} // namespace coverage
} // namespace trusty
} // namespace android
diff --git a/trusty/coverage/coverage_test.cpp b/trusty/coverage/coverage_test.cpp
index d8df7a4..c1efca6 100644
--- a/trusty/coverage/coverage_test.cpp
+++ b/trusty/coverage/coverage_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include <gtest/gtest.h>
#include <trusty/coverage/coverage.h>
#include <trusty/tipc.h>
@@ -27,6 +28,7 @@
#define TIPC_DEV "/dev/trusty-ipc-dev0"
#define TEST_SRV_PORT "com.android.trusty.sancov.test.srv"
+#define TEST_SRV_MODULE "srv.syms.elf"
namespace android {
namespace trusty {
@@ -54,8 +56,8 @@
};
TEST_F(CoverageTest, CoverageReset) {
- record_->Reset();
- auto counter = record_->CountEdges();
+ record_->ResetFullRecord();
+ auto counter = record_->TotalEdgeCounts();
ASSERT_EQ(counter, 0);
}
@@ -69,7 +71,7 @@
for (size_t i = 1; i < sizeof(magic) * 8; i++) {
/* Reset coverage */
- record_->Reset();
+ record_->ResetCounts();
/* Send message to test server */
uint32_t msg = magic & ~(mask << i);
@@ -81,10 +83,15 @@
ASSERT_EQ(rc, sizeof(msg));
/* Count number of non-unique blocks executed */
- auto counter = record_->CountEdges();
+ auto counter = record_->TotalEdgeCounts();
/* Each consecutive input should exercise more or same blocks */
ASSERT_GE(counter, high_watermark);
high_watermark = counter;
+
+ auto sancov_filename = android::base::StringPrintf(
+ "/data/local/tmp/" TEST_SRV_MODULE ".%d.sancov", getpid());
+ auto res = record_->SaveSancovFile(sancov_filename);
+ ASSERT_TRUE(res.ok());
}
ASSERT_GT(high_watermark, 0);
diff --git a/trusty/coverage/include/trusty/coverage/coverage.h b/trusty/coverage/include/trusty/coverage/coverage.h
index b61b959..b6d46eb 100644
--- a/trusty/coverage/include/trusty/coverage/coverage.h
+++ b/trusty/coverage/include/trusty/coverage/coverage.h
@@ -35,13 +35,26 @@
CoverageRecord(std::string tipc_dev, struct uuid* uuid);
~CoverageRecord();
Result<void> Open();
- void Reset();
+ void ResetFullRecord();
+ void ResetCounts();
+ void ResetPCs();
void GetRawData(volatile void** begin, volatile void** end);
- uint64_t CountEdges();
+ void GetRawCounts(volatile uint8_t** begin, volatile uint8_t** end);
+ void GetRawPCs(volatile uintptr_t** begin, volatile uintptr_t** end);
+ uint64_t TotalEdgeCounts();
+
+ /**
+ * Save the current set of observed PCs to the given filename.
+ * The resulting .sancov file can be parsed via the LLVM sancov tool to see
+ * coverage statistics and visualize coverage.
+ */
+ Result<void> SaveSancovFile(const std::string& filename);
private:
Result<void> Rpc(coverage_client_req* req, int req_fd, coverage_client_resp* resp);
+ Result<std::pair<size_t, size_t>> GetRegionBounds(uint32_t region_type);
+
std::string tipc_dev_;
unique_fd coverage_srv_fd_;
struct uuid uuid_;
diff --git a/trusty/coverage/include/trusty/coverage/record.h b/trusty/coverage/include/trusty/coverage/record.h
new file mode 100644
index 0000000..bfe06f3
--- /dev/null
+++ b/trusty/coverage/include/trusty/coverage/record.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file needs to be kept in-sync with its counterpart on Trusty side:
+ * trusty/user/base/lib/coverage/common/include/lib/coverage/common/record.h */
+
+#pragma once
+
+#include <stdint.h>
+
+/**
+ * enum coverage_record_type - Coverage region header type
+ * @COV_START: Magic header start marker
+ * @COV_8BIT_COUNTERS: 8bit counter for each instrumentation point
+ * @COV_INSTR_PCS: Pointer length offset of each instrumentation point from the
+ * start of the binary
+ * @COV_TOTAL_LENGTH: Total length of the entire coverage record, must be the
+ * last header item.
+ *
+ * Describes the type of a region of the coverage record. See &struct
+ * coverage_record_header.
+ */
+enum coverage_record_type {
+ COV_START = 0x434f5652,
+ COV_8BIT_COUNTERS = 1,
+ COV_INSTR_PCS = 2,
+ COV_TOTAL_LENGTH = 0,
+};
+
+/**
+ * struct coverage_record_header - Header entry describing a region of the
+ * coverage record.
+ * @type: type of the region, must be one of @enum coverage_record_type
+ * @offset: offset from the beginning of the header to the start of the region
+ *
+ * Coverage records start with a header which is a list of struct
+ * coverage_record_header, beginning with an entry with type COV_START and
+ * terminated with an entry with type COV_TOTAL_LENGTH. Each of these header
+ * entries corresponds to a region of the record, with the offset indicating the
+ * offset of the start of that region from the beginning of the record (i.e. the
+ * beginning of the header). Each record type and offset is 32-bit field with
+ * native endianness. The first header item must be COV_START with a 0 offset.
+ * The COV_START entry should be initialized when the coverage header is
+ * complete and ready for consumption by the client, because coverage record
+ * initialization happens asynchronously. The final header item,
+ * COV_TOTAL_LENGTH, which must always be present, indicates the total length of
+ * the coverage record, including the header.
+ *
+ * Coverage regions should be contiguous, so the end of one region is the start
+ * of the next, and the coverage header must be in the same order as the regions
+ * in the record body. Thus we can compute the length of a region by subtracting
+ * the region's offset from the offset of the next header item.
+ */
+struct coverage_record_header {
+ uint32_t type;
+ uint32_t offset;
+};
diff --git a/trusty/fuzz/Android.bp b/trusty/fuzz/Android.bp
index 22d834d..4df77af 100644
--- a/trusty/fuzz/Android.bp
+++ b/trusty/fuzz/Android.bp
@@ -39,10 +39,10 @@
export_include_dirs: ["include"],
static_libs: [
"libFuzzer",
+ "libtrusty_test",
],
shared_libs: [
"libtrusty_coverage",
- "libtrusty_test",
"libbase",
"liblog",
],
diff --git a/trusty/fuzz/counters.cpp b/trusty/fuzz/counters.cpp
index 3fc9f48..8c79475 100644
--- a/trusty/fuzz/counters.cpp
+++ b/trusty/fuzz/counters.cpp
@@ -42,9 +42,9 @@
assert(fuzzer::ExtraCountersBegin());
assert(fuzzer::ExtraCountersEnd());
- uint8_t* begin = NULL;
- uint8_t* end = NULL;
- record_->GetRawData((volatile void**)&begin, (volatile void**)&end);
+ volatile uint8_t* begin = NULL;
+ volatile uint8_t* end = NULL;
+ record_->GetRawCounts(&begin, &end);
assert(end - begin <= sizeof(counters));
}
@@ -53,7 +53,7 @@
}
void ExtraCounters::Reset() {
- record_->Reset();
+ record_->ResetCounts();
fuzzer::ClearExtraCounters();
}
@@ -61,7 +61,7 @@
volatile uint8_t* begin = NULL;
volatile uint8_t* end = NULL;
- record_->GetRawData((volatile void**)&begin, (volatile void**)&end);
+ record_->GetRawCounts(&begin, &end);
size_t num_counters = end - begin;
for (size_t i = 0; i < num_counters; i++) {
diff --git a/trusty/keymaster/set_attestation_key/set_attestation_key.cpp b/trusty/keymaster/set_attestation_key/set_attestation_key.cpp
index 6f74833..df6b0f8 100644
--- a/trusty/keymaster/set_attestation_key/set_attestation_key.cpp
+++ b/trusty/keymaster/set_attestation_key/set_attestation_key.cpp
@@ -70,7 +70,7 @@
}
struct SetAttestationKeyRequest : public keymaster::KeymasterMessage {
- explicit SetAttestationKeyRequest(int32_t ver = keymaster::MAX_MESSAGE_VERSION)
+ explicit SetAttestationKeyRequest(int32_t ver = keymaster::kDefaultMessageVersion)
: KeymasterMessage(ver) {}
size_t SerializedSize() const override { return sizeof(uint32_t) + key_data.SerializedSize(); }
@@ -88,7 +88,7 @@
};
struct KeymasterNoResponse : public keymaster::KeymasterResponse {
- explicit KeymasterNoResponse(int32_t ver = keymaster::MAX_MESSAGE_VERSION)
+ explicit KeymasterNoResponse(int32_t ver = keymaster::kDefaultMessageVersion)
: keymaster::KeymasterResponse(ver) {}
size_t NonErrorSerializedSize() const override { return 0; }
@@ -99,7 +99,7 @@
struct SetAttestationKeyResponse : public KeymasterNoResponse {};
struct ClearAttestationCertChainRequest : public keymaster::KeymasterMessage {
- explicit ClearAttestationCertChainRequest(int32_t ver = keymaster::MAX_MESSAGE_VERSION)
+ explicit ClearAttestationCertChainRequest(int32_t ver = keymaster::kDefaultMessageVersion)
: KeymasterMessage(ver) {}
size_t SerializedSize() const override { return sizeof(uint32_t); }