Merge "Fix the MapWithLoopDevice"
diff --git a/code_coverage/seccomp_policy/code_coverage.arm.policy b/code_coverage/seccomp_policy/code_coverage.arm.policy
index b80910f..3589379 100644
--- a/code_coverage/seccomp_policy/code_coverage.arm.policy
+++ b/code_coverage/seccomp_policy/code_coverage.arm.policy
@@ -1,4 +1,5 @@
close: 1
+fchmod: 1
mkdirat: 1
msync: 1
munmap: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.arm64.policy b/code_coverage/seccomp_policy/code_coverage.arm64.policy
index 7040ea2..fdb4d1e 100644
--- a/code_coverage/seccomp_policy/code_coverage.arm64.policy
+++ b/code_coverage/seccomp_policy/code_coverage.arm64.policy
@@ -1,4 +1,5 @@
close: 1
+fchmod: 1
mkdirat: 1
msync: 1
munmap: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.policy.def b/code_coverage/seccomp_policy/code_coverage.policy.def
index 599c4a4..b6a4c6d 100644
--- a/code_coverage/seccomp_policy/code_coverage.policy.def
+++ b/code_coverage/seccomp_policy/code_coverage.policy.def
@@ -13,6 +13,9 @@
// 2nd-Nth: uses mmap() to update in place
close: 1
+// fchmod allowed to set libprofile-clang-extras, which wraps `open` calls, to
+// set correct permission for coverage files.
+fchmod: 1
mkdirat: 1
msync: 1
munmap: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.x86.policy b/code_coverage/seccomp_policy/code_coverage.x86.policy
index f8e0cc0..145d3a3 100644
--- a/code_coverage/seccomp_policy/code_coverage.x86.policy
+++ b/code_coverage/seccomp_policy/code_coverage.x86.policy
@@ -1,4 +1,5 @@
close: 1
+fchmod: 1
mkdirat: 1
msync: 1
munmap: 1
diff --git a/code_coverage/seccomp_policy/code_coverage.x86_64.policy b/code_coverage/seccomp_policy/code_coverage.x86_64.policy
index dcf2f9a..11c8075 100644
--- a/code_coverage/seccomp_policy/code_coverage.x86_64.policy
+++ b/code_coverage/seccomp_policy/code_coverage.x86_64.policy
@@ -1,4 +1,5 @@
close: 1
+fchmod: 1
mkdirat: 1
msync: 1
munmap: 1
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 7938a61..45e555f 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -16,6 +16,7 @@
#include <err.h>
#include <fcntl.h>
+#include <malloc.h>
#include <stdlib.h>
#include <sys/capability.h>
#include <sys/mman.h>
@@ -32,7 +33,6 @@
#include <android/fdsan.h>
#include <android/set_abort_message.h>
-#include <bionic/malloc.h>
#include <bionic/mte.h>
#include <bionic/reserved_signals.h>
@@ -385,8 +385,7 @@
#if defined(__aarch64__)
static void SetTagCheckingLevelSync() {
- HeapTaggingLevel heap_tagging_level = M_HEAP_TAGGING_LEVEL_SYNC;
- if (!android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &heap_tagging_level, sizeof(heap_tagging_level))) {
+ if (mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, M_HEAP_TAGGING_LEVEL_SYNC) == 0) {
abort();
}
}
diff --git a/fastboot/fastboot.bash b/fastboot/fastboot.bash
index 406e8b8..f5a3384 100644
--- a/fastboot/fastboot.bash
+++ b/fastboot/fastboot.bash
@@ -109,7 +109,7 @@
cur="${COMP_WORDS[COMP_CWORD]}"
if [[ $i -eq $COMP_CWORD ]]; then
- partitions="boot bootloader dtbo modem odm odm_dlkm oem product radio recovery system vbmeta vendor vendor_dlkm"
+ partitions="boot bootloader dtbo modem odm odm_dlkm oem product pvmfw radio recovery system vbmeta vendor vendor_dlkm"
COMPREPLY=( $(compgen -W "$partitions" -- $cur) )
else
_fastboot_util_complete_local_file "${cur}" '!*.img'
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 62f6ac7..f7edf8e 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -147,6 +147,7 @@
{ "odm", "odm.img", "odm.sig", "odm", true, ImageType::Normal },
{ "odm_dlkm", "odm_dlkm.img", "odm_dlkm.sig", "odm_dlkm", true, ImageType::Normal },
{ "product", "product.img", "product.sig", "product", true, ImageType::Normal },
+ { "pvmfw", "pvmfw.img", "pvmfw.sig", "pvmfw", true, ImageType::BootCritical },
{ "recovery", "recovery.img", "recovery.sig", "recovery", true, ImageType::BootCritical },
{ "super", "super.img", "super.sig", "super", true, ImageType::Extra },
{ "system", "system.img", "system.sig", "system", false, ImageType::Normal },
diff --git a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
index 7aef086..ff0047e 100644
--- a/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
+++ b/fs_mgr/libsnapshot/include_test/libsnapshot/test_helpers.h
@@ -51,8 +51,8 @@
extern std::unique_ptr<SnapshotManager> sm;
extern class TestDeviceInfo* test_device;
extern std::string fake_super;
-static constexpr uint64_t kSuperSize = 16_MiB + 4_KiB;
-static constexpr uint64_t kGroupSize = 16_MiB;
+static constexpr uint64_t kSuperSize = 32_MiB + 4_KiB;
+static constexpr uint64_t kGroupSize = 32_MiB;
// Redirect requests for "super" to our fake super partition.
class TestPartitionOpener final : public android::fs_mgr::PartitionOpener {
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index f0646fc..21b720e 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -676,6 +676,8 @@
}
}
+ bool compression_enabled = false;
+
uint64_t total_cow_file_size = 0;
DmTargetSnapshot::Status initial_target_values = {};
for (const auto& snapshot : snapshots) {
@@ -692,6 +694,8 @@
return false;
}
total_cow_file_size += snapshot_status.cow_file_size();
+
+ compression_enabled |= snapshot_status.compression_enabled();
}
if (cow_file_size) {
@@ -703,6 +707,7 @@
initial_status.set_sectors_allocated(initial_target_values.sectors_allocated);
initial_status.set_total_sectors(initial_target_values.total_sectors);
initial_status.set_metadata_sectors(initial_target_values.metadata_sectors);
+ initial_status.set_compression_enabled(compression_enabled);
// Point of no return - mark that we're starting a merge. From now on every
// snapshot must be a merge target.
@@ -1405,7 +1410,7 @@
return false;
}
- CHECK(base_sectors == target.spec.length);
+ CHECK(base_sectors <= target.spec.length);
if (!snapuserd_client_->AttachDmUser(misc_name)) {
// This error is unrecoverable. We cannot proceed because reads to
@@ -2285,9 +2290,15 @@
}
bool SnapshotManager::WriteUpdateState(LockedFile* lock, UpdateState state) {
- SnapshotUpdateStatus status = {};
+ SnapshotUpdateStatus status;
status.set_state(state);
- status.set_compression_enabled(IsCompressionEnabled());
+
+ // If we're transitioning between two valid states (eg, we're not beginning
+ // or ending an OTA), then make sure to propagate the compression bit.
+ if (!(state == UpdateState::Initiated || state == UpdateState::None)) {
+ SnapshotUpdateStatus old_status = ReadSnapshotUpdateStatus(lock);
+ status.set_compression_enabled(old_status.compression_enabled());
+ }
return WriteSnapshotUpdateStatus(lock, status);
}
@@ -2477,6 +2488,12 @@
auto lock = LockExclusive();
if (!lock) return Return::Error();
+ auto update_state = ReadUpdateState(lock.get());
+ if (update_state != UpdateState::Initiated) {
+ LOG(ERROR) << "Cannot create update snapshots in state " << update_state;
+ return Return::Error();
+ }
+
// TODO(b/134949511): remove this check. Right now, with overlayfs mounted, the scratch
// partition takes up a big chunk of space in super, causing COW images to be created on
// retrofit Virtual A/B devices.
@@ -2571,6 +2588,14 @@
return Return::Error();
}
+ SnapshotUpdateStatus status = {};
+ status.set_state(update_state);
+ status.set_compression_enabled(cow_creator.compression_enabled);
+ if (!WriteSnapshotUpdateStatus(lock.get(), status)) {
+ LOG(ERROR) << "Unable to write new update state";
+ return Return::Error();
+ }
+
created_devices.Release();
LOG(INFO) << "Successfully created all snapshots for target slot " << target_suffix;
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index bb44425..80a6074 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -854,15 +854,15 @@
group_->add_partition_names("prd");
sys_ = manifest_.add_partitions();
sys_->set_partition_name("sys");
- sys_->set_estimate_cow_size(6_MiB);
+ sys_->set_estimate_cow_size(2_MiB);
SetSize(sys_, 3_MiB);
vnd_ = manifest_.add_partitions();
vnd_->set_partition_name("vnd");
- vnd_->set_estimate_cow_size(6_MiB);
+ vnd_->set_estimate_cow_size(2_MiB);
SetSize(vnd_, 3_MiB);
prd_ = manifest_.add_partitions();
prd_->set_partition_name("prd");
- prd_->set_estimate_cow_size(6_MiB);
+ prd_->set_estimate_cow_size(2_MiB);
SetSize(prd_, 3_MiB);
// Initialize source partition metadata using |manifest_|.
@@ -1050,11 +1050,17 @@
ASSERT_TRUE(sm->UnmapUpdateSnapshot(name));
}
- // Grow all partitions.
+ // Grow all partitions. Set |prd| large enough that |sys| and |vnd|'s COWs
+ // fit in super, but not |prd|.
constexpr uint64_t partition_size = 3788_KiB;
SetSize(sys_, partition_size);
SetSize(vnd_, partition_size);
- SetSize(prd_, partition_size);
+ SetSize(prd_, 18_MiB);
+
+ // Make sure |prd| does not fit in super at all. On VABC, this means we
+ // fake an extra large COW for |vnd| to fill up super.
+ vnd_->set_estimate_cow_size(30_MiB);
+ prd_->set_estimate_cow_size(30_MiB);
AddOperationForPartitions();
@@ -1066,11 +1072,7 @@
auto tgt = MetadataBuilder::New(*opener_, "super", 1);
ASSERT_NE(tgt, nullptr);
ASSERT_NE(nullptr, tgt->FindPartition("sys_b-cow"));
- if (IsCompressionEnabled()) {
- ASSERT_EQ(nullptr, tgt->FindPartition("vnd_b-cow"));
- } else {
- ASSERT_NE(nullptr, tgt->FindPartition("vnd_b-cow"));
- }
+ ASSERT_NE(nullptr, tgt->FindPartition("vnd_b-cow"));
ASSERT_EQ(nullptr, tgt->FindPartition("prd_b-cow"));
// Write some data to target partitions.
@@ -1104,6 +1106,7 @@
// Initiate the merge and wait for it to be completed.
ASSERT_TRUE(init->InitiateMerge());
+ ASSERT_EQ(init->IsSnapuserdRequired(), IsCompressionEnabled());
ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
// Check that the target partitions have the same content after the merge.
@@ -1128,6 +1131,7 @@
SetSize(sys_, 4_MiB); // grows
SetSize(vnd_, 2_MiB); // shrinks
// prd_b is unchanged
+ ASSERT_TRUE(sm->BeginUpdate());
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
ASSERT_EQ(4_MiB, GetSnapshotSize("sys_b").value_or(0));
}
@@ -1137,6 +1141,7 @@
TEST_F(SnapshotUpdateTest, CowPartitionDoNotTakeOldPartitions) {
SetSize(sys_, 2_MiB); // shrinks
// vnd_b and prd_b are unchanged.
+ ASSERT_TRUE(sm->BeginUpdate());
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
auto tgt = MetadataBuilder::New(*opener_, "super", 1);
@@ -1260,6 +1265,11 @@
// Test that at the second update, old COW partition spaces are reclaimed.
TEST_F(SnapshotUpdateTest, ReclaimCow) {
+ // Make sure VABC cows are small enough that they fit in fake_super.
+ sys_->set_estimate_cow_size(64_KiB);
+ vnd_->set_estimate_cow_size(64_KiB);
+ prd_->set_estimate_cow_size(64_KiB);
+
// Execute the first update.
ASSERT_TRUE(sm->BeginUpdate());
ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
@@ -1376,9 +1386,13 @@
TEST_F(SnapshotUpdateTest, MergeCannotRemoveCow) {
// Make source partitions as big as possible to force COW image to be created.
- SetSize(sys_, 5_MiB);
- SetSize(vnd_, 5_MiB);
- SetSize(prd_, 5_MiB);
+ SetSize(sys_, 10_MiB);
+ SetSize(vnd_, 10_MiB);
+ SetSize(prd_, 10_MiB);
+ sys_->set_estimate_cow_size(12_MiB);
+ vnd_->set_estimate_cow_size(12_MiB);
+ prd_->set_estimate_cow_size(12_MiB);
+
src_ = MetadataBuilder::New(*opener_, "super", 0);
ASSERT_NE(src_, nullptr);
src_->RemoveGroupAndPartitions(group_->name() + "_a");
@@ -1676,6 +1690,8 @@
SetSize(sys_, partition_size);
AddOperation(sys_, data_size);
+ sys_->set_estimate_cow_size(partition_size + data_size);
+
// Set hastree extents.
sys_->mutable_hash_tree_data_extent()->set_start_block(0);
sys_->mutable_hash_tree_data_extent()->set_num_blocks(data_size / block_size);
@@ -1716,6 +1732,10 @@
// Test for overflow bit after update
TEST_F(SnapshotUpdateTest, Overflow) {
+ if (IsCompressionEnabled()) {
+ GTEST_SKIP() << "No overflow bit set for userspace COWs";
+ }
+
const auto actual_write_size = GetSize(sys_);
const auto declared_write_size = actual_write_size - 1_MiB;
@@ -1743,12 +1763,15 @@
auto userdata = std::make_unique<LowSpaceUserdata>();
ASSERT_TRUE(userdata->Init(kMaxFree));
- // Grow all partitions to 5_MiB, total 15_MiB. This requires 15 MiB of CoW space. After
- // using the empty space in super (< 1 MiB), it uses at least 14 MiB of /userdata space.
- constexpr uint64_t partition_size = 5_MiB;
+ // Grow all partitions to 10_MiB, total 30_MiB. This requires 30 MiB of CoW space. After
+ // using the empty space in super (< 1 MiB), it uses 30 MiB of /userdata space.
+ constexpr uint64_t partition_size = 10_MiB;
SetSize(sys_, partition_size);
SetSize(vnd_, partition_size);
SetSize(prd_, partition_size);
+ sys_->set_estimate_cow_size(partition_size);
+ vnd_->set_estimate_cow_size(partition_size);
+ prd_->set_estimate_cow_size(partition_size);
AddOperationForPartitions();
@@ -1758,7 +1781,7 @@
ASSERT_FALSE(res);
ASSERT_EQ(Return::ErrorCode::NO_SPACE, res.error_code());
ASSERT_GE(res.required_size(), 14_MiB);
- ASSERT_LT(res.required_size(), 15_MiB);
+ ASSERT_LT(res.required_size(), 40_MiB);
}
class AutoKill final {
diff --git a/gatekeeperd/Android.bp b/gatekeeperd/Android.bp
index 27a6452..2d9a820 100644
--- a/gatekeeperd/Android.bp
+++ b/gatekeeperd/Android.bp
@@ -28,6 +28,7 @@
shared_libs: [
"libbinder",
+ "libbinder_ndk",
"libgatekeeper",
"libgsi",
"liblog",
@@ -40,6 +41,8 @@
"libhidlbase",
"android.hardware.gatekeeper@1.0",
"libgatekeeper_aidl",
+ "android.hardware.security.keymint-unstable-ndk_platform",
+ "android.security.authorization-ndk_platform",
],
static_libs: ["libscrypt_static"],
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index b982dbc..941f8c2 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -19,42 +19,45 @@
#include <android/service/gatekeeper/BnGateKeeperService.h>
#include <gatekeeper/GateKeeperResponse.h>
+#include <endian.h>
#include <errno.h>
#include <fcntl.h>
-#include <inttypes.h>
-#include <stdint.h>
#include <unistd.h>
#include <memory>
-#include <android/security/keystore/IKeystoreService.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/security/keystore/IKeystoreService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
-#include <gatekeeper/password_handle.h> // for password_handle_t
-#include <hardware/gatekeeper.h>
+#include <gatekeeper/password_handle.h> // for password_handle_t
#include <hardware/hw_auth_token.h>
-#include <keystore/keystore.h> // For error code
#include <keystore/keystore_return_types.h>
#include <libgsi/libgsi.h>
#include <log/log.h>
-#include <utils/Log.h>
#include <utils/String16.h>
-#include <hidl/HidlSupport.h>
+#include <aidl/android/hardware/security/keymint/HardwareAuthToken.h>
+#include <aidl/android/security/authorization/IKeystoreAuthorization.h>
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+#include <hidl/HidlSupport.h>
using android::sp;
-using android::hardware::gatekeeper::V1_0::IGatekeeper;
-using android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
-using android::hardware::gatekeeper::V1_0::GatekeeperResponse;
using android::hardware::Return;
+using android::hardware::gatekeeper::V1_0::GatekeeperResponse;
+using android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
+using android::hardware::gatekeeper::V1_0::IGatekeeper;
using ::android::binder::Status;
using ::android::service::gatekeeper::BnGateKeeperService;
using GKResponse = ::android::service::gatekeeper::GateKeeperResponse;
using GKResponseCode = ::android::service::gatekeeper::ResponseCode;
+using ::aidl::android::hardware::security::keymint::HardwareAuthenticatorType;
+using ::aidl::android::hardware::security::keymint::HardwareAuthToken;
+using ::aidl::android::security::authorization::IKeystoreAuthorization;
namespace android {
@@ -62,7 +65,7 @@
static const String16 DUMP_PERMISSION("android.permission.DUMP");
class GateKeeperProxy : public BnGateKeeperService {
-public:
+ public:
GateKeeperProxy() {
clear_state_if_needed_done = false;
hw_device = IGatekeeper::getService();
@@ -73,8 +76,7 @@
}
}
- virtual ~GateKeeperProxy() {
- }
+ virtual ~GateKeeperProxy() {}
void store_sid(uint32_t userId, uint64_t sid) {
char filename[21];
@@ -96,7 +98,7 @@
if (mark_cold_boot() && !is_running_gsi) {
ALOGI("cold boot: clearing state");
if (hw_device) {
- hw_device->deleteAllUsers([](const GatekeeperResponse &){});
+ hw_device->deleteAllUsers([](const GatekeeperResponse&) {});
}
}
@@ -104,7 +106,7 @@
}
bool mark_cold_boot() {
- const char *filename = ".coldboot";
+ const char* filename = ".coldboot";
if (access(filename, F_OK) == -1) {
int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
if (fd < 0) {
@@ -299,7 +301,36 @@
if (gkResponse->response_code() == GKResponseCode::OK) {
if (gkResponse->payload().size() != 0) {
+ // try to connect to IKeystoreAuthorization AIDL service first.
+ AIBinder* authzAIBinder =
+ AServiceManager_checkService("android.security.authorization");
+ ::ndk::SpAIBinder authzBinder(authzAIBinder);
+ auto authzService = IKeystoreAuthorization::fromBinder(authzBinder);
+ if (authzService) {
+ if (gkResponse->payload().size() != sizeof(hw_auth_token_t)) {
+ LOG(ERROR) << "Incorrect size of AuthToken payload.";
+ return GK_ERROR;
+ }
+
+ const hw_auth_token_t* hwAuthToken =
+ reinterpret_cast<const hw_auth_token_t*>(gkResponse->payload().data());
+ HardwareAuthToken authToken;
+
+ authToken.timestamp.milliSeconds = betoh64(hwAuthToken->timestamp);
+ authToken.challenge = hwAuthToken->challenge;
+ authToken.authenticatorId = hwAuthToken->authenticator_id;
+ authToken.authenticatorType = static_cast<HardwareAuthenticatorType>(
+ betoh32(hwAuthToken->authenticator_type));
+ authToken.mac.assign(&hwAuthToken->hmac[0], &hwAuthToken->hmac[32]);
+ auto result = authzService->addAuthToken(authToken);
+ if (!result.isOk()) {
+ LOG(ERROR) << "Failure in sending AuthToken to AuthorizationService.";
+ return GK_ERROR;
+ }
+ AIBinder_decStrong(authzAIBinder);
+ }
sp<IServiceManager> sm = defaultServiceManager();
+
sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
sp<security::keystore::IKeystoreService> service =
interface_cast<security::keystore::IKeystoreService>(binder);
@@ -310,9 +341,12 @@
if (!binder_result.isOk() ||
!keystore::KeyStoreServiceReturnCode(result).isOk()) {
LOG(ERROR) << "Failure sending auth token to KeyStore: " << result;
+ return GK_ERROR;
}
} else {
- LOG(ERROR) << "Cannot deliver auth token. Unable to communicate with Keystore.";
+ LOG(ERROR) << "Cannot deliver auth token. Unable to communicate with "
+ "Keystore.";
+ return GK_ERROR;
}
}
@@ -366,23 +400,23 @@
}
if (hw_device == NULL) {
- const char *result = "Device not available";
+ const char* result = "Device not available";
write(fd, result, strlen(result) + 1);
} else {
- const char *result = "OK";
+ const char* result = "OK";
write(fd, result, strlen(result) + 1);
}
return OK;
}
-private:
+ private:
sp<IGatekeeper> hw_device;
bool clear_state_if_needed_done;
bool is_running_gsi;
};
-}// namespace android
+} // namespace android
int main(int argc, char* argv[]) {
ALOGI("Starting gatekeeperd...");
diff --git a/healthd/Android.bp b/healthd/Android.bp
index b3de9c4..251a45b 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -62,29 +62,6 @@
srcs: [
"HealthServiceDefault.cpp",
],
-
- overrides: [
- "healthd",
- ]
-}
-
-cc_binary {
- name: "healthd",
- defaults: ["android.hardware.health@2.0-service_defaults"],
-
- init_rc: ["healthd.rc"],
- srcs: [
- "HealthServiceHealthd.cpp",
- ],
- local_include_dirs: ["include"],
-
- shared_libs: [
- "android.hardware.health@1.0",
- ],
-
- vintf_fragments: [
- "manifest_healthd.xml"
- ],
}
cc_library_static {
diff --git a/healthd/HealthServiceHealthd.cpp b/healthd/HealthServiceHealthd.cpp
deleted file mode 100644
index 5fd2597..0000000
--- a/healthd/HealthServiceHealthd.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "healthd"
-#include <android-base/logging.h>
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <android/hardware/health/1.0/types.h>
-#include <hal_conversion.h>
-#include <health2/service.h>
-#include <healthd/healthd.h>
-#include <hidl/HidlTransportSupport.h>
-
-using android::OK;
-using android::NAME_NOT_FOUND;
-using android::hardware::health::V1_0::HealthConfig;
-using android::hardware::health::V1_0::HealthInfo;
-using android::hardware::health::V1_0::Result;
-using android::hardware::health::V1_0::hal_conversion::convertFromHealthConfig;
-using android::hardware::health::V1_0::hal_conversion::convertToHealthConfig;
-using android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;
-using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
-
-using IHealthLegacy = android::hardware::health::V1_0::IHealth;
-
-static android::sp<IHealthLegacy> gHealth_1_0;
-
-static int healthd_board_get_energy_counter(int64_t* energy) {
- if (gHealth_1_0 == nullptr) {
- return NAME_NOT_FOUND;
- }
-
- Result result = Result::NOT_SUPPORTED;
- gHealth_1_0->energyCounter([energy, &result](Result ret, int64_t energyOut) {
- result = ret;
- *energy = energyOut;
- });
-
- return result == Result::SUCCESS ? OK : NAME_NOT_FOUND;
-}
-
-void healthd_board_init(struct healthd_config* config) {
- gHealth_1_0 = IHealthLegacy::getService();
-
- if (gHealth_1_0 == nullptr) {
- return;
- }
-
- HealthConfig halConfig{};
- convertToHealthConfig(config, halConfig);
- gHealth_1_0->init(halConfig, [config](const auto& halConfigOut) {
- convertFromHealthConfig(halConfigOut, config);
- // always redirect energy counter queries
- config->energyCounter = healthd_board_get_energy_counter;
- });
- LOG(INFO) << LOG_TAG << ": redirecting calls to 1.0 health HAL";
-}
-
-// TODO(b/68724651): Move this function into healthd_mode_service_2_0_battery_update
-// with logthis returned.
-int healthd_board_battery_update(struct android::BatteryProperties* props) {
- int logthis = 0;
-
- if (gHealth_1_0 == nullptr) {
- return logthis;
- }
-
- HealthInfo info;
- convertToHealthInfo(props, info);
- gHealth_1_0->update(info, [props, &logthis](int32_t ret, const auto& infoOut) {
- logthis = ret;
- convertFromHealthInfo(infoOut, props);
- });
-
- return logthis;
-}
-
-int main() {
- return health_service_main("backup");
-}
diff --git a/healthd/manifest_healthd.xml b/healthd/manifest_healthd.xml
deleted file mode 100644
index 097a7d8..0000000
--- a/healthd/manifest_healthd.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="framework">
- <hal>
- <name>android.hardware.health</name>
- <transport>hwbinder</transport>
- <version>2.0</version>
- <interface>
- <name>IHealth</name>
- <instance>backup</instance>
- </interface>
- </hal>
-</manifest>
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 64d4edc..ce67386 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -890,6 +890,69 @@
}
}
+// If the ro.product.cpu.abilist* properties have not been explicitly
+// set, derive them from ro.${partition}.product.cpu.abilist* properties.
+static void property_initialize_ro_cpu_abilist() {
+ // From high to low priority.
+ const char* kAbilistSources[] = {
+ "product",
+ "odm",
+ "vendor",
+ "system",
+ };
+ const std::string EMPTY = "";
+ const char* kAbilistProp = "ro.product.cpu.abilist";
+ const char* kAbilist32Prop = "ro.product.cpu.abilist32";
+ const char* kAbilist64Prop = "ro.product.cpu.abilist64";
+
+ // If the properties are defined explicitly, just use them.
+ if (GetProperty(kAbilistProp, EMPTY) != EMPTY) {
+ return;
+ }
+
+ // Find the first source defining these properties by order.
+ std::string abilist32_prop_val;
+ std::string abilist64_prop_val;
+ for (const auto& source : kAbilistSources) {
+ const auto abilist32_prop = std::string("ro.") + source + ".product.cpu.abilist32";
+ const auto abilist64_prop = std::string("ro.") + source + ".product.cpu.abilist64";
+ abilist32_prop_val = GetProperty(abilist32_prop, EMPTY);
+ abilist64_prop_val = GetProperty(abilist64_prop, EMPTY);
+ // The properties could be empty on 32-bit-only or 64-bit-only devices,
+ // but we cannot identify a property is empty or undefined by GetProperty().
+ // So, we assume both of these 2 properties are empty as undefined.
+ if (abilist32_prop_val != EMPTY || abilist64_prop_val != EMPTY) {
+ break;
+ }
+ }
+
+ // Merge ABI lists for ro.product.cpu.abilist
+ auto abilist_prop_val = abilist64_prop_val;
+ if (abilist32_prop_val != EMPTY) {
+ if (abilist_prop_val != EMPTY) {
+ abilist_prop_val += ",";
+ }
+ abilist_prop_val += abilist32_prop_val;
+ }
+
+ // Set these properties
+ const std::pair<const char*, const std::string&> set_prop_list[] = {
+ {kAbilistProp, abilist_prop_val},
+ {kAbilist32Prop, abilist32_prop_val},
+ {kAbilist64Prop, abilist64_prop_val},
+ };
+ for (const auto& [prop, prop_val] : set_prop_list) {
+ LOG(INFO) << "Setting property '" << prop << "' to '" << prop_val << "'";
+
+ std::string error;
+ uint32_t res = PropertySet(prop, prop_val, &error);
+ if (res != PROP_SUCCESS) {
+ LOG(ERROR) << "Error setting property '" << prop << "': err=" << res << " (" << error
+ << ")";
+ }
+ }
+}
+
void PropertyLoadBootDefaults() {
// We read the properties and their values into a map, in order to always allow properties
// loaded in the later property files to override the properties in loaded in the earlier
@@ -972,6 +1035,7 @@
property_initialize_ro_product_props();
property_derive_build_fingerprint();
+ property_initialize_ro_cpu_abilist();
update_sys_usb_config();
}
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index cf809f1..d46aeab 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -210,9 +210,6 @@
"uevent.cpp",
],
},
- bionic: {
- header_libs: ["bionic_libc_platform_headers"],
- },
android_arm: {
sanitize: {
diff --git a/libcutils/memory.cpp b/libcutils/memory.cpp
index f526520..5a410c2 100644
--- a/libcutils/memory.cpp
+++ b/libcutils/memory.cpp
@@ -18,19 +18,18 @@
#include <log/log.h>
-#ifdef __BIONIC__
-#include <bionic/malloc.h>
+#if !defined(__APPLE__)
+#include <malloc.h>
#endif
void process_disable_memory_mitigations() {
bool success = false;
#ifdef __BIONIC__
- // TODO(b/158870657) is fixed and scudo is used globally, we can assert when an
- // an error is returned.
-
- success = android_mallopt(M_DISABLE_MEMORY_MITIGATIONS, nullptr, 0);
+ success = mallopt(M_BIONIC_DISABLE_MEMORY_MITIGATIONS, 0);
#endif
+ // TODO: if b/158870657 is fixed and scudo is used globally,
+ // we can assert on failure rather than just log.
if (success) {
ALOGI("Disabled memory mitigations for process.");
} else {
diff --git a/libprocessgroup/cgroup_map.cpp b/libprocessgroup/cgroup_map.cpp
index b82b0ab..5ca0967 100644
--- a/libprocessgroup/cgroup_map.cpp
+++ b/libprocessgroup/cgroup_map.cpp
@@ -71,7 +71,7 @@
if (!HasValue()) return false;
if (state_ == UNKNOWN) {
- if (ACgroupController_getFlags != nullptr) {
+ if (__builtin_available(android 30, *)) {
uint32_t flags = ACgroupController_getFlags(controller_);
state_ = (flags & CGROUPRC_CONTROLLER_FLAG_MOUNTED) != 0 ? USABLE : MISSING;
} else {
@@ -172,7 +172,7 @@
auto controller_count = ACgroupFile_getControllerCount();
for (uint32_t i = 0; i < controller_count; ++i) {
const ACgroupController* controller = ACgroupFile_getController(i);
- if (ACgroupController_getFlags != nullptr) {
+ if (__builtin_available(android 30, *)) {
LOG(INFO) << "\t" << ACgroupController_getName(controller) << " ver "
<< ACgroupController_getVersion(controller) << " path "
<< ACgroupController_getPath(controller) << " flags "
diff --git a/libprocessgroup/cgrouprc/include/android/cgrouprc.h b/libprocessgroup/cgrouprc/include/android/cgrouprc.h
index 7e74432..9a79954 100644
--- a/libprocessgroup/cgrouprc/include/android/cgrouprc.h
+++ b/libprocessgroup/cgrouprc/include/android/cgrouprc.h
@@ -28,8 +28,6 @@
struct ACgroupController;
typedef struct ACgroupController ACgroupController;
-#if __ANDROID_API__ >= __ANDROID_API_Q__
-
// ACgroupFile
/**
@@ -71,8 +69,6 @@
#define CGROUPRC_CONTROLLER_FLAG_MOUNTED 0x1
#define CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION 0x2
-#if __ANDROID_API__ >= __ANDROID_API_R__
-
/**
* Returns the flags bitmask of the given controller.
* If the given controller is null, return 0.
@@ -80,8 +76,6 @@
__attribute__((warn_unused_result, weak)) uint32_t ACgroupController_getFlags(
const ACgroupController*) __INTRODUCED_IN(30);
-#endif
-
/**
* Returns the name of the given controller.
* If the given controller is null, return nullptr.
@@ -97,5 +91,3 @@
__INTRODUCED_IN(29);
__END_DECLS
-
-#endif
diff --git a/libsync/include/ndk/sync.h b/libsync/include/ndk/sync.h
index 2a59e35..38ccb68 100644
--- a/libsync/include/ndk/sync.h
+++ b/libsync/include/ndk/sync.h
@@ -33,8 +33,6 @@
__BEGIN_DECLS
-#if __ANDROID_API__ >= 26
-
/* Fences indicate the status of an asynchronous task. They are initially
* in unsignaled state (0), and make a one-time transition to either signaled
* (1) or error (< 0) state. A sync file is a collection of one or more fences;
@@ -101,8 +99,6 @@
*/
void sync_file_info_free(struct sync_file_info* info) __INTRODUCED_IN(26);
-#endif /* __ANDROID_API__ >= 26 */
-
__END_DECLS
#endif /* ANDROID_SYNC_H */
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 049301d..19c00f9 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -856,13 +856,6 @@
wait_for_prop apexd.status activated
perform_apex_config
- # Lock the fs-verity keyring, so no more keys can be added
- exec -- /system/bin/fsverity_init --lock
-
- # After apexes are mounted, tell keymaster early boot has ended, so it will
- # stop allowing use of early-boot keys
- exec - system system -- /system/bin/vdc keymaster earlyBootEnded
-
# Special-case /data/media/obb per b/64566063
mkdir /data/media 0770 media_rw media_rw encryption=None
exec - media_rw media_rw -- /system/bin/chattr +F /data/media
@@ -872,15 +865,22 @@
init_user0
+ # Set SELinux security contexts on upgrade or policy update.
+ restorecon --recursive --skip-ce /data
+
+ # After apexes are mounted, tell keymaster early boot has ended, so it will
+ # stop allowing use of early-boot keys
+ exec - system system -- /system/bin/vdc keymaster earlyBootEnded
+
+ # Lock the fs-verity keyring, so no more keys can be added
+ exec -- /system/bin/fsverity_init --lock
+
# Allow apexd to snapshot and restore device encrypted apex data in the case
# of a rollback. This should be done immediately after DE_user data keys
# are loaded. APEXes should not access this data until this has been
# completed and apexd.status becomes "ready".
exec_start apexd-snapshotde
- # Set SELinux security contexts on upgrade or policy update.
- restorecon --recursive --skip-ce /data
-
# Check any timezone data in /data is newer than the copy in the time zone data
# module, delete if not.
exec - system system -- /system/bin/tzdatacheck /apex/com.android.tzdata/etc/tz /data/misc/zoneinfo
diff --git a/trusty/confirmationui/fuzz/fuzz.cpp b/trusty/confirmationui/fuzz/fuzz.cpp
index 9d3008b..df2517c 100644
--- a/trusty/confirmationui/fuzz/fuzz.cpp
+++ b/trusty/confirmationui/fuzz/fuzz.cpp
@@ -14,10 +14,7 @@
* limitations under the License.
*/
-#undef NDEBUG
-
-#include <assert.h>
-#include <log/log.h>
+#include <iostream>
#include <stdlib.h>
#include <trusty/coverage/coverage.h>
#include <trusty/fuzz/counters.h>
@@ -30,6 +27,7 @@
#define TIPC_DEV "/dev/trusty-ipc-dev0"
#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
+#define CONFIRMATIONUI_MODULE_NAME "confirmationui.syms.elf"
/* ConfirmationUI TA's UUID is 7dee2364-c036-425b-b086-df0f6c233c1b */
static struct uuid confirmationui_uuid = {
@@ -48,11 +46,14 @@
uint8_t payload[];
};
-static CoverageRecord record(TIPC_DEV, &confirmationui_uuid);
+static CoverageRecord record(TIPC_DEV, &confirmationui_uuid, CONFIRMATIONUI_MODULE_NAME);
extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
auto ret = record.Open();
- assert(ret.ok());
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
return 0;
}
diff --git a/trusty/coverage/Android.bp b/trusty/coverage/Android.bp
index 6038d44..daa6f03 100644
--- a/trusty/coverage/Android.bp
+++ b/trusty/coverage/Android.bp
@@ -28,6 +28,7 @@
shared_libs: [
"libbase",
"liblog",
+ "libdmabufheap",
],
}
@@ -43,6 +44,7 @@
shared_libs: [
"libbase",
"liblog",
+ "libdmabufheap",
],
require_root: true,
}
diff --git a/trusty/coverage/coverage.cpp b/trusty/coverage/coverage.cpp
index f383dd1..5eccdc5 100644
--- a/trusty/coverage/coverage.cpp
+++ b/trusty/coverage/coverage.cpp
@@ -16,10 +16,12 @@
#define LOG_TAG "coverage"
+#include <BufferAllocator/BufferAllocator.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <assert.h>
+#include <log/log.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/uio.h>
@@ -37,6 +39,8 @@
using android::base::ErrnoError;
using android::base::Error;
using std::string;
+using std::to_string;
+using std::unique_ptr;
static inline uintptr_t RoundPageUp(uintptr_t val) {
return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
@@ -46,12 +50,29 @@
: tipc_dev_(std::move(tipc_dev)),
coverage_srv_fd_(-1),
uuid_(*uuid),
+ sancov_filename_(),
+ record_len_(0),
+ shm_(NULL),
+ shm_len_(0) {}
+
+CoverageRecord::CoverageRecord(string tipc_dev, struct uuid* uuid, string module_name)
+ : tipc_dev_(std::move(tipc_dev)),
+ coverage_srv_fd_(-1),
+ uuid_(*uuid),
+ sancov_filename_(module_name + "." + to_string(getpid()) + ".sancov"),
record_len_(0),
shm_(NULL),
shm_len_(0) {}
CoverageRecord::~CoverageRecord() {
if (shm_) {
+ if (sancov_filename_) {
+ auto res = SaveSancovFile(*sancov_filename_);
+ if (!res.ok()) {
+ ALOGE("Could not write sancov file for module: %s\n", sancov_filename_->c_str());
+ }
+ }
+
munmap((void*)shm_, shm_len_);
}
}
@@ -114,24 +135,23 @@
record_len_ = resp.open_args.record_len;
shm_len_ = RoundPageUp(record_len_);
- fd = memfd_create("trusty-coverage", 0);
+ BufferAllocator allocator;
+
+ fd = allocator.Alloc("system", shm_len_);
if (fd < 0) {
- return ErrnoError() << "failed to create memfd: ";
+ return ErrnoError() << "failed to create dmabuf of size " << shm_len_
+ << " err code: " << fd;
}
- unique_fd memfd(fd);
+ unique_fd dma_buf(fd);
- if (ftruncate(memfd, shm_len_) < 0) {
- return ErrnoError() << "failed to resize memfd: ";
- }
-
- void* shm = mmap(0, shm_len_, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0);
+ void* shm = mmap(0, shm_len_, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
if (shm == MAP_FAILED) {
return ErrnoError() << "failed to map memfd: ";
}
req.hdr.cmd = COVERAGE_CLIENT_CMD_SHARE_RECORD;
req.share_record_args.shm_len = shm_len_;
- ret = Rpc(&req, memfd, &resp);
+ ret = Rpc(&req, dma_buf, &resp);
if (!ret.ok()) {
return Error() << "failed to send shared memory: ";
}
diff --git a/trusty/coverage/include/trusty/coverage/coverage.h b/trusty/coverage/include/trusty/coverage/coverage.h
index b6d46eb..5da68da 100644
--- a/trusty/coverage/include/trusty/coverage/coverage.h
+++ b/trusty/coverage/include/trusty/coverage/coverage.h
@@ -16,6 +16,7 @@
#pragma once
+#include <optional>
#include <string>
#include <android-base/result.h>
@@ -32,7 +33,18 @@
class CoverageRecord {
public:
+ /**
+ * Create a coverage record interface. Coverage will not be written to a
+ * sancov output file on completion.
+ */
CoverageRecord(std::string tipc_dev, struct uuid* uuid);
+
+ /**
+ * Create a coverage record interface. On destruction, write this coverage
+ * to the given sancov filename.
+ */
+ CoverageRecord(std::string tipc_dev, struct uuid* uuid, std::string module_name);
+
~CoverageRecord();
Result<void> Open();
void ResetFullRecord();
@@ -58,6 +70,7 @@
std::string tipc_dev_;
unique_fd coverage_srv_fd_;
struct uuid uuid_;
+ std::optional<std::string> sancov_filename_;
size_t record_len_;
volatile void* shm_;
size_t shm_len_;
diff --git a/trusty/fuzz/counters.cpp b/trusty/fuzz/counters.cpp
index 8c79475..1e863ac 100644
--- a/trusty/fuzz/counters.cpp
+++ b/trusty/fuzz/counters.cpp
@@ -21,6 +21,7 @@
#include <trusty/fuzz/counters.h>
#include <android-base/logging.h>
+#include <log/log.h>
#include <trusty/coverage/coverage.h>
#include <trusty/coverage/tipc.h>
@@ -32,7 +33,8 @@
* We don't know how many counters the coverage record will contain. So, eyeball
* the size of this section.
*/
-__attribute__((section("__libfuzzer_extra_counters"))) volatile uint8_t counters[PAGE_SIZE];
+static const size_t kMaxNumCounters = 0x4000;
+__attribute__((section("__libfuzzer_extra_counters"))) volatile uint8_t counters[kMaxNumCounters];
namespace android {
namespace trusty {
@@ -62,8 +64,16 @@
volatile uint8_t* end = NULL;
record_->GetRawCounts(&begin, &end);
+ if (!begin || !end) {
+ ALOGE("Could not get raw counts from coverage record\n");
+ return;
+ }
size_t num_counters = end - begin;
+ if (num_counters > kMaxNumCounters) {
+ ALOGE("Too many counters (%zu) to fit in the extra counters section!\n", num_counters);
+ num_counters = kMaxNumCounters;
+ }
for (size_t i = 0; i < num_counters; i++) {
*(counters + i) = *(begin + i);
}
diff --git a/trusty/fuzz/test/fuzz.cpp b/trusty/fuzz/test/fuzz.cpp
index 28bb3f7..e7913db 100644
--- a/trusty/fuzz/test/fuzz.cpp
+++ b/trusty/fuzz/test/fuzz.cpp
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-#undef NDEBUG
-
-#include <assert.h>
-#include <log/log.h>
#include <stdlib.h>
#include <trusty/coverage/coverage.h>
#include <trusty/fuzz/counters.h>
#include <trusty/fuzz/utils.h>
#include <unistd.h>
+#include <iostream>
using android::trusty::coverage::CoverageRecord;
using android::trusty::fuzz::ExtraCounters;
@@ -43,7 +40,10 @@
extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
auto ret = record.Open();
- assert(ret.ok());
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
return 0;
}
diff --git a/trusty/gatekeeper/fuzz/fuzz.cpp b/trusty/gatekeeper/fuzz/fuzz.cpp
index c0e8abb..7bfd7d1 100644
--- a/trusty/gatekeeper/fuzz/fuzz.cpp
+++ b/trusty/gatekeeper/fuzz/fuzz.cpp
@@ -14,15 +14,12 @@
* limitations under the License.
*/
-#undef NDEBUG
-
-#include <assert.h>
-#include <log/log.h>
#include <stdlib.h>
#include <trusty/coverage/coverage.h>
#include <trusty/fuzz/counters.h>
#include <trusty/fuzz/utils.h>
#include <unistd.h>
+#include <iostream>
using android::trusty::coverage::CoverageRecord;
using android::trusty::fuzz::ExtraCounters;
@@ -30,6 +27,7 @@
#define TIPC_DEV "/dev/trusty-ipc-dev0"
#define GATEKEEPER_PORT "com.android.trusty.gatekeeper"
+#define GATEKEEPER_MODULE_NAME "gatekeeper.syms.elf"
/* Gatekeeper TA's UUID is 38ba0cdc-df0e-11e4-9869-233fb6ae4795 */
static struct uuid gatekeeper_uuid = {
@@ -39,11 +37,14 @@
{0x98, 0x69, 0x23, 0x3f, 0xb6, 0xae, 0x47, 0x95},
};
-static CoverageRecord record(TIPC_DEV, &gatekeeper_uuid);
+static CoverageRecord record(TIPC_DEV, &gatekeeper_uuid, GATEKEEPER_MODULE_NAME);
extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
auto ret = record.Open();
- assert(ret.ok());
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
return 0;
}
diff --git a/trusty/keymaster/fuzz/Android.bp b/trusty/keymaster/fuzz/Android.bp
new file mode 100644
index 0000000..da9f9ec
--- /dev/null
+++ b/trusty/keymaster/fuzz/Android.bp
@@ -0,0 +1,19 @@
+// 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.
+
+cc_fuzz {
+ name: "trusty_keymaster_fuzzer",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: ["fuzz.cpp"],
+}
diff --git a/trusty/keymaster/fuzz/fuzz.cpp b/trusty/keymaster/fuzz/fuzz.cpp
new file mode 100644
index 0000000..4ac97bb
--- /dev/null
+++ b/trusty/keymaster/fuzz/fuzz.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <trusty/coverage/coverage.h>
+#include <trusty/fuzz/counters.h>
+#include <trusty/fuzz/utils.h>
+#include <unistd.h>
+#include <iostream>
+
+using android::trusty::coverage::CoverageRecord;
+using android::trusty::fuzz::ExtraCounters;
+using android::trusty::fuzz::TrustyApp;
+
+#define TIPC_DEV "/dev/trusty-ipc-dev0"
+#define KEYMASTER_PORT "com.android.trusty.keymaster"
+#define KEYMASTER_MODULE_FILENAME "keymaster.syms.elf"
+
+/* Keymaster TA's UUID is 5f902ace-5e5c-4cd8-ae54-87b88c22ddaf */
+static struct uuid keymaster_uuid = {
+ 0x5f902ace,
+ 0x5e5c,
+ 0x4cd8,
+ {0xae, 0x54, 0x87, 0xb8, 0x8c, 0x22, 0xdd, 0xaf},
+};
+
+static CoverageRecord record(TIPC_DEV, &keymaster_uuid, KEYMASTER_MODULE_FILENAME);
+
+extern "C" int LLVMFuzzerInitialize(int* /* argc */, char*** /* argv */) {
+ auto ret = record.Open();
+ if (!ret.ok()) {
+ std::cerr << ret.error() << std::endl;
+ exit(-1);
+ }
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static uint8_t buf[TIPC_MAX_MSG_SIZE];
+
+ ExtraCounters counters(&record);
+ counters.Reset();
+
+ android::trusty::fuzz::TrustyApp ta(TIPC_DEV, KEYMASTER_PORT);
+ auto ret = ta.Connect();
+ if (!ret.ok()) {
+ android::trusty::fuzz::Abort();
+ }
+
+ /* Send message to test server */
+ ret = ta.Write(data, size);
+ if (!ret.ok()) {
+ return -1;
+ }
+
+ /* Read message from test server */
+ ret = ta.Read(&buf, sizeof(buf));
+ if (!ret.ok()) {
+ return -1;
+ }
+
+ return 0;
+}