Merge "Add TEST_MAPPING for system/core/rootdir/etc"
diff --git a/fs_mgr/libfs_avb/Android.bp b/fs_mgr/libfs_avb/Android.bp
index 3e93265..a3c76ab 100644
--- a/fs_mgr/libfs_avb/Android.bp
+++ b/fs_mgr/libfs_avb/Android.bp
@@ -24,6 +24,8 @@
"avb_ops.cpp",
"avb_util.cpp",
"fs_avb.cpp",
+ "fs_avb_util.cpp",
+ "types.cpp",
"util.cpp",
],
static_libs: [
@@ -98,6 +100,7 @@
srcs: [
"tests/basic_test.cpp",
"tests/fs_avb_test.cpp",
+ "tests/fs_avb_util_test.cpp",
],
}
@@ -115,3 +118,26 @@
"tests/util_test.cpp",
],
}
+
+cc_test {
+ name: "libfs_avb_device_test",
+ test_suites: ["device-tests"],
+ static_libs: [
+ "libavb",
+ "libdm",
+ "libfs_avb",
+ "libfstab",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcrypto",
+ ],
+ srcs: [
+ "tests/fs_avb_device_test.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+}
diff --git a/fs_mgr/libfs_avb/avb_ops.h b/fs_mgr/libfs_avb/avb_ops.h
index c0f12aa..a849d94 100644
--- a/fs_mgr/libfs_avb/avb_ops.h
+++ b/fs_mgr/libfs_avb/avb_ops.h
@@ -27,7 +27,7 @@
#include <string>
#include <vector>
-#include <fs_avb/fs_avb.h>
+#include <fs_avb/types.h>
#include <libavb/libavb.h>
namespace android {
diff --git a/fs_mgr/libfs_avb/avb_util.cpp b/fs_mgr/libfs_avb/avb_util.cpp
index 08f87b4..fa9080e 100644
--- a/fs_mgr/libfs_avb/avb_util.cpp
+++ b/fs_mgr/libfs_avb/avb_util.cpp
@@ -34,56 +34,11 @@
namespace android {
namespace fs_mgr {
-// Helper functions to print enum class VBMetaVerifyResult.
-const char* VBMetaVerifyResultToString(VBMetaVerifyResult result) {
- // clang-format off
- static const char* const name[] = {
- "ResultSuccess",
- "ResultError",
- "ResultErrorVerification",
- "ResultUnknown",
- };
- // clang-format on
-
- uint32_t index = static_cast<uint32_t>(result);
- uint32_t unknown_index = sizeof(name) / sizeof(char*) - 1;
- if (index >= unknown_index) {
- index = unknown_index;
- }
-
- return name[index];
-}
-
-std::ostream& operator<<(std::ostream& os, VBMetaVerifyResult result) {
- os << VBMetaVerifyResultToString(result);
- return os;
-}
-
-// class VBMetaData
-// ----------------
-std::unique_ptr<AvbVBMetaImageHeader> VBMetaData::GetVBMetaHeader(bool update_vbmeta_size) {
- auto vbmeta_header = std::make_unique<AvbVBMetaImageHeader>();
-
- if (!vbmeta_header) return nullptr;
-
- /* Byteswap the header. */
- avb_vbmeta_image_header_to_host_byte_order((AvbVBMetaImageHeader*)vbmeta_ptr_.get(),
- vbmeta_header.get());
- if (update_vbmeta_size) {
- vbmeta_size_ = sizeof(AvbVBMetaImageHeader) +
- vbmeta_header->authentication_data_block_size +
- vbmeta_header->auxiliary_data_block_size;
- }
-
- return vbmeta_header;
-}
-
// Constructs dm-verity arguments for sending DM_TABLE_LOAD ioctl to kernel.
// See the following link for more details:
// https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity
-bool ConstructVerityTable(const AvbHashtreeDescriptor& hashtree_desc, const std::string& salt,
- const std::string& root_digest, const std::string& blk_device,
- android::dm::DmTable* table) {
+bool ConstructVerityTable(const FsAvbHashtreeDescriptor& hashtree_desc,
+ const std::string& blk_device, android::dm::DmTable* table) {
// Loads androidboot.veritymode from kernel cmdline.
std::string verity_mode;
if (!fs_mgr_get_boot_config("veritymode", &verity_mode)) {
@@ -104,12 +59,12 @@
std::ostringstream hash_algorithm;
hash_algorithm << hashtree_desc.hash_algorithm;
- android::dm::DmTargetVerity target(0, hashtree_desc.image_size / 512,
- hashtree_desc.dm_verity_version, blk_device, blk_device,
- hashtree_desc.data_block_size, hashtree_desc.hash_block_size,
- hashtree_desc.image_size / hashtree_desc.data_block_size,
- hashtree_desc.tree_offset / hashtree_desc.hash_block_size,
- hash_algorithm.str(), root_digest, salt);
+ android::dm::DmTargetVerity target(
+ 0, hashtree_desc.image_size / 512, hashtree_desc.dm_verity_version, blk_device,
+ blk_device, hashtree_desc.data_block_size, hashtree_desc.hash_block_size,
+ hashtree_desc.image_size / hashtree_desc.data_block_size,
+ hashtree_desc.tree_offset / hashtree_desc.hash_block_size, hash_algorithm.str(),
+ hashtree_desc.root_digest, hashtree_desc.salt);
if (hashtree_desc.fec_size > 0) {
target.UseFec(blk_device, hashtree_desc.fec_num_roots,
hashtree_desc.fec_offset / hashtree_desc.data_block_size,
@@ -126,12 +81,10 @@
return table->AddTarget(std::make_unique<android::dm::DmTargetVerity>(target));
}
-bool HashtreeDmVeritySetup(FstabEntry* fstab_entry, const AvbHashtreeDescriptor& hashtree_desc,
- const std::string& salt, const std::string& root_digest,
+bool HashtreeDmVeritySetup(FstabEntry* fstab_entry, const FsAvbHashtreeDescriptor& hashtree_desc,
bool wait_for_verity_dev) {
android::dm::DmTable table;
- if (!ConstructVerityTable(hashtree_desc, salt, root_digest, fstab_entry->blk_device, &table) ||
- !table.valid()) {
+ if (!ConstructVerityTable(hashtree_desc, fstab_entry->blk_device, &table) || !table.valid()) {
LERROR << "Failed to construct verity table.";
return false;
}
@@ -164,12 +117,11 @@
return true;
}
-std::unique_ptr<AvbHashtreeDescriptor> GetHashtreeDescriptor(
- const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images,
- std::string* out_salt, std::string* out_digest) {
+std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
+ const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images) {
bool found = false;
const uint8_t* desc_partition_name;
- auto hashtree_desc = std::make_unique<AvbHashtreeDescriptor>();
+ auto hashtree_desc = std::make_unique<FsAvbHashtreeDescriptor>();
for (const auto& vbmeta : vbmeta_images) {
size_t num_descriptors;
@@ -209,15 +161,17 @@
}
if (!found) {
- LERROR << "Partition descriptor not found: " << partition_name.c_str();
+ LERROR << "Hashtree descriptor not found: " << partition_name;
return nullptr;
}
+ hashtree_desc->partition_name = partition_name;
+
const uint8_t* desc_salt = desc_partition_name + hashtree_desc->partition_name_len;
- *out_salt = BytesToHex(desc_salt, hashtree_desc->salt_len);
+ hashtree_desc->salt = BytesToHex(desc_salt, hashtree_desc->salt_len);
const uint8_t* desc_digest = desc_salt + hashtree_desc->salt_len;
- *out_digest = BytesToHex(desc_digest, hashtree_desc->root_digest_len);
+ hashtree_desc->root_digest = BytesToHex(desc_digest, hashtree_desc->root_digest_len);
return hashtree_desc;
}
@@ -235,18 +189,15 @@
return false;
}
- std::string salt;
- std::string root_digest;
- std::unique_ptr<AvbHashtreeDescriptor> hashtree_descriptor =
- GetHashtreeDescriptor(partition_name, vbmeta_images, &salt, &root_digest);
+ std::unique_ptr<FsAvbHashtreeDescriptor> hashtree_descriptor =
+ GetHashtreeDescriptor(partition_name, vbmeta_images);
if (!hashtree_descriptor) {
return false;
}
// Converts HASHTREE descriptor to verity table to load into kernel.
// When success, the new device path will be returned, e.g., /dev/block/dm-2.
- return HashtreeDmVeritySetup(fstab_entry, *hashtree_descriptor, salt, root_digest,
- wait_for_verity_dev);
+ return HashtreeDmVeritySetup(fstab_entry, *hashtree_descriptor, wait_for_verity_dev);
}
// Converts a AVB partition_name (without A/B suffix) to a device partition name.
@@ -420,6 +371,10 @@
uint64_t vbmeta_size = VBMetaData::kMaxVBMetaSize;
bool is_vbmeta_partition = StartsWith(partition_name, "vbmeta");
+ if (out_verify_result) {
+ *out_verify_result = VBMetaVerifyResult::kError;
+ }
+
if (!is_vbmeta_partition) {
std::unique_ptr<AvbFooter> footer = GetAvbFooter(fd);
if (!footer) {
@@ -445,7 +400,10 @@
auto verify_result =
VerifyVBMetaSignature(*vbmeta, expected_public_key_blob, out_public_key_data);
- if (out_verify_result != nullptr) *out_verify_result = verify_result;
+
+ if (out_verify_result != nullptr) {
+ *out_verify_result = verify_result;
+ }
if (verify_result == VBMetaVerifyResult::kSuccess ||
verify_result == VBMetaVerifyResult::kErrorVerification) {
@@ -508,6 +466,10 @@
const std::string& expected_public_key_blob, bool allow_verification_error,
bool rollback_protection, bool is_chained_vbmeta, std::string* out_public_key_data,
bool* out_verification_disabled, VBMetaVerifyResult* out_verify_result) {
+ if (out_verify_result) {
+ *out_verify_result = VBMetaVerifyResult::kError;
+ }
+
// Ensures the device path (might be a symlink created by init) is ready to access.
if (!WaitForFile(image_path, 1s)) {
PERROR << "No such path: " << image_path;
diff --git a/fs_mgr/libfs_avb/avb_util.h b/fs_mgr/libfs_avb/avb_util.h
index 4b54e27..9babd88 100644
--- a/fs_mgr/libfs_avb/avb_util.h
+++ b/fs_mgr/libfs_avb/avb_util.h
@@ -24,19 +24,11 @@
#include <libavb/libavb.h>
#include <libdm/dm.h>
-#include "fs_avb/fs_avb.h"
+#include "fs_avb/types.h"
namespace android {
namespace fs_mgr {
-enum class VBMetaVerifyResult {
- kSuccess = 0,
- kError = 1,
- kErrorVerification = 2,
-};
-
-std::ostream& operator<<(std::ostream& os, VBMetaVerifyResult);
-
struct ChainInfo {
std::string partition_name;
std::string public_key_blob;
@@ -46,16 +38,13 @@
};
// AvbHashtreeDescriptor to dm-verity table setup.
-std::unique_ptr<AvbHashtreeDescriptor> GetHashtreeDescriptor(
- const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images,
- std::string* out_salt, std::string* out_digest);
+std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
+ const std::string& partition_name, const std::vector<VBMetaData>& vbmeta_images);
-bool ConstructVerityTable(const AvbHashtreeDescriptor& hashtree_desc, const std::string& salt,
- const std::string& root_digest, const std::string& blk_device,
- android::dm::DmTable* table);
+bool ConstructVerityTable(const FsAvbHashtreeDescriptor& hashtree_desc,
+ const std::string& blk_device, android::dm::DmTable* table);
-bool HashtreeDmVeritySetup(FstabEntry* fstab_entry, const AvbHashtreeDescriptor& hashtree_desc,
- const std::string& salt, const std::string& root_digest,
+bool HashtreeDmVeritySetup(FstabEntry* fstab_entry, const FsAvbHashtreeDescriptor& hashtree_desc,
bool wait_for_verity_dev);
// Searches a Avb hashtree descriptor in vbmeta_images for fstab_entry, to enable dm-verity.
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp
index 1af3b33..938e149 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -76,33 +76,6 @@
return std::make_pair(digest, total_size);
}
-// Helper functions to dump enum class AvbHandleStatus.
-const char* AvbHandleStatusToString(AvbHandleStatus status) {
- // clang-format off
- static const char* const name[] = {
- "Success",
- "Uninitialized",
- "HashtreeDisabled",
- "VerificationDisabled",
- "VerificationError",
- "Unknown",
- };
- // clang-format on
-
- uint32_t index = static_cast<uint32_t>(status);
- uint32_t unknown_index = sizeof(name) / sizeof(char*) - 1;
- if (index >= unknown_index) {
- index = unknown_index;
- }
-
- return name[index];
-}
-
-std::ostream& operator<<(std::ostream& os, AvbHandleStatus status) {
- os << AvbHandleStatusToString(status);
- return os;
-}
-
// class AvbVerifier
// -----------------
// Reads the following values from kernel cmdline and provides the
diff --git a/fs_mgr/libfs_avb/fs_avb_util.cpp b/fs_mgr/libfs_avb/fs_avb_util.cpp
new file mode 100644
index 0000000..f82f83d
--- /dev/null
+++ b/fs_mgr/libfs_avb/fs_avb_util.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 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 "fs_avb/fs_avb_util.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/strings.h>
+#include <fstab/fstab.h>
+#include <libavb/libavb.h>
+#include <libdm/dm.h>
+
+#include "avb_util.h"
+#include "util.h"
+
+namespace android {
+namespace fs_mgr {
+
+// Given a FstabEntry, loads and verifies the vbmeta, to extract the Avb Hashtree descriptor.
+std::unique_ptr<VBMetaData> LoadAndVerifyVbmeta(const FstabEntry& fstab_entry,
+ const std::string& expected_public_key_blob,
+ std::string* out_public_key_data,
+ std::string* out_avb_partition_name,
+ VBMetaVerifyResult* out_verify_result) {
+ // Derives partition_name from blk_device to query the corresponding AVB HASHTREE descriptor
+ // to setup dm-verity. The partition_names in AVB descriptors are without A/B suffix.
+ std::string avb_partition_name = DeriveAvbPartitionName(fstab_entry, fs_mgr_get_slot_suffix(),
+ fs_mgr_get_other_slot_suffix());
+ if (out_avb_partition_name) {
+ *out_avb_partition_name = avb_partition_name;
+ }
+
+ // Updates fstab_entry->blk_device from <partition> to /dev/block/dm-<N> if
+ // it's a logical partition.
+ std::string device_path = fstab_entry.blk_device;
+ if (fstab_entry.fs_mgr_flags.logical &&
+ !android::base::StartsWith(fstab_entry.blk_device, "/")) {
+ dm::DeviceMapper& dm = dm::DeviceMapper::Instance();
+ if (!dm.GetDmDevicePathByName(fstab_entry.blk_device, &device_path)) {
+ LERROR << "Failed to resolve logical device path for: " << fstab_entry.blk_device;
+ return nullptr;
+ }
+ }
+
+ return LoadAndVerifyVbmetaByPath(device_path, avb_partition_name, expected_public_key_blob,
+ true /* allow_verification_error */,
+ false /* rollback_protection */, false /* is_chained_vbmeta */,
+ out_public_key_data, nullptr /* out_verification_disabled */,
+ out_verify_result);
+}
+
+// Given a path, loads and verifies the vbmeta, to extract the Avb Hashtree descriptor.
+std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
+ const std::string& avb_partition_name, VBMetaData&& vbmeta) {
+ if (!vbmeta.size()) return nullptr;
+
+ std::vector<VBMetaData> vbmeta_images;
+ vbmeta_images.emplace_back(std::move(vbmeta));
+ return GetHashtreeDescriptor(avb_partition_name, vbmeta_images);
+}
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
index d4e3a6e..d026722 100644
--- a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
+++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
@@ -21,32 +21,13 @@
#include <string>
#include <vector>
+#include <fs_avb/types.h>
#include <fstab/fstab.h>
#include <libavb/libavb.h>
namespace android {
namespace fs_mgr {
-enum class AvbHashtreeResult {
- kSuccess = 0,
- kFail,
- kDisabled,
-};
-
-enum class HashAlgorithm {
- kInvalid = 0,
- kSHA256 = 1,
- kSHA512 = 2,
-};
-
-enum class AvbHandleStatus {
- kSuccess = 0,
- kUninitialized = 1,
- kHashtreeDisabled = 2,
- kVerificationDisabled = 3,
- kVerificationError = 4,
-};
-
struct VBMetaInfo {
std::string digest;
HashAlgorithm hash_algorithm;
@@ -58,51 +39,6 @@
: digest(std::move(digest_value)), hash_algorithm(algorithm), total_size(size) {}
};
-class VBMetaData {
- public:
- // Constructors
- VBMetaData() : vbmeta_ptr_(nullptr), vbmeta_size_(0){};
-
- VBMetaData(const uint8_t* data, size_t size, const std::string& partition_name)
- : vbmeta_ptr_(new (std::nothrow) uint8_t[size]),
- vbmeta_size_(size),
- partition_name_(partition_name) {
- // The ownership of data is NOT transferred, i.e., the caller still
- // needs to release the memory as we make a copy here.
- memcpy(vbmeta_ptr_.get(), data, size * sizeof(uint8_t));
- }
-
- explicit VBMetaData(size_t size, const std::string& partition_name)
- : vbmeta_ptr_(new (std::nothrow) uint8_t[size]),
- vbmeta_size_(size),
- partition_name_(partition_name) {}
-
- // Extracts vbmeta header from the vbmeta buffer, set update_vbmeta_size to
- // true to update vbmeta_size_ to the actual size with valid content.
- std::unique_ptr<AvbVBMetaImageHeader> GetVBMetaHeader(bool update_vbmeta_size = false);
-
- // Sets the vbmeta_path where we load the vbmeta data. Could be a partition or a file.
- // e.g.,
- // - /dev/block/by-name/system_a
- // - /path/to/system_other.img.
- void set_vbmeta_path(std::string vbmeta_path) { vbmeta_path_ = std::move(vbmeta_path); }
-
- // Get methods for each data member.
- const std::string& partition() const { return partition_name_; }
- const std::string& vbmeta_path() const { return vbmeta_path_; }
- uint8_t* data() const { return vbmeta_ptr_.get(); }
- const size_t& size() const { return vbmeta_size_; }
-
- // Maximum size of a vbmeta data - 64 KiB.
- static const size_t kMaxVBMetaSize = 64 * 1024;
-
- private:
- std::unique_ptr<uint8_t[]> vbmeta_ptr_;
- size_t vbmeta_size_;
- std::string partition_name_;
- std::string vbmeta_path_;
-};
-
class FsManagerAvbOps;
class AvbHandle;
diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h
new file mode 100644
index 0000000..ec8badb
--- /dev/null
+++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb_util.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <fs_avb/types.h>
+#include <fstab/fstab.h>
+#include <libavb/libavb.h>
+
+namespace android {
+namespace fs_mgr {
+
+// Given a FstabEntry, loads and verifies the vbmeta.
+std::unique_ptr<VBMetaData> LoadAndVerifyVbmeta(const FstabEntry& fstab_entry,
+ const std::string& expected_public_key_blob,
+ std::string* out_public_key_data,
+ std::string* out_avb_partition_name,
+ VBMetaVerifyResult* out_verify_result);
+
+// Gets the hashtree descriptor for avb_partition_name from the vbmeta.
+std::unique_ptr<FsAvbHashtreeDescriptor> GetHashtreeDescriptor(
+ const std::string& avb_partition_name, VBMetaData&& vbmeta);
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/libfs_avb/include/fs_avb/types.h b/fs_mgr/libfs_avb/include/fs_avb/types.h
new file mode 100644
index 0000000..bd638e6
--- /dev/null
+++ b/fs_mgr/libfs_avb/include/fs_avb/types.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <cstring>
+#include <memory>
+#include <ostream>
+
+#include <libavb/libavb.h>
+
+namespace android {
+namespace fs_mgr {
+
+enum class VBMetaVerifyResult {
+ kSuccess = 0,
+ kError = 1,
+ kErrorVerification = 2,
+};
+
+std::ostream& operator<<(std::ostream& os, VBMetaVerifyResult);
+
+enum class AvbHashtreeResult {
+ kSuccess = 0,
+ kFail,
+ kDisabled,
+};
+
+enum class HashAlgorithm {
+ kInvalid = 0,
+ kSHA256 = 1,
+ kSHA512 = 2,
+};
+
+enum class AvbHandleStatus {
+ kSuccess = 0,
+ kUninitialized = 1,
+ kHashtreeDisabled = 2,
+ kVerificationDisabled = 3,
+ kVerificationError = 4,
+};
+
+std::ostream& operator<<(std::ostream& os, AvbHandleStatus status);
+
+struct FsAvbHashtreeDescriptor : AvbHashtreeDescriptor {
+ std::string partition_name;
+ std::string salt;
+ std::string root_digest;
+};
+
+class VBMetaData {
+ public:
+ // Constructors
+ VBMetaData() : vbmeta_ptr_(nullptr), vbmeta_size_(0){};
+
+ VBMetaData(const uint8_t* data, size_t size, const std::string& partition_name)
+ : vbmeta_ptr_(new (std::nothrow) uint8_t[size]),
+ vbmeta_size_(size),
+ partition_name_(partition_name) {
+ // The ownership of data is NOT transferred, i.e., the caller still
+ // needs to release the memory as we make a copy here.
+ std::memcpy(vbmeta_ptr_.get(), data, size * sizeof(uint8_t));
+ }
+
+ explicit VBMetaData(size_t size, const std::string& partition_name)
+ : vbmeta_ptr_(new (std::nothrow) uint8_t[size]),
+ vbmeta_size_(size),
+ partition_name_(partition_name) {}
+
+ // Extracts vbmeta header from the vbmeta buffer, set update_vbmeta_size to
+ // true to update vbmeta_size_ to the actual size with valid content.
+ std::unique_ptr<AvbVBMetaImageHeader> GetVBMetaHeader(bool update_vbmeta_size = false);
+
+ // Sets the vbmeta_path where we load the vbmeta data. Could be a partition or a file.
+ // e.g.,
+ // - /dev/block/by-name/system_a
+ // - /path/to/system_other.img.
+ void set_vbmeta_path(std::string vbmeta_path) { vbmeta_path_ = std::move(vbmeta_path); }
+
+ // Get methods for each data member.
+ const std::string& partition() const { return partition_name_; }
+ const std::string& vbmeta_path() const { return vbmeta_path_; }
+ uint8_t* data() const { return vbmeta_ptr_.get(); }
+ const size_t& size() const { return vbmeta_size_; }
+
+ // Maximum size of a vbmeta data - 64 KiB.
+ static const size_t kMaxVBMetaSize = 64 * 1024;
+
+ private:
+ std::unique_ptr<uint8_t[]> vbmeta_ptr_;
+ size_t vbmeta_size_;
+ std::string partition_name_;
+ std::string vbmeta_path_;
+};
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/fs_mgr/libfs_avb/run_tests.sh b/fs_mgr/libfs_avb/run_tests.sh
new file mode 100755
index 0000000..5d2ce3d
--- /dev/null
+++ b/fs_mgr/libfs_avb/run_tests.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# Run host tests
+atest libfs_avb_test # Tests public libfs_avb APIs.
+atest libfs_avb_internal_test # Tests libfs_avb private APIs.
+
+# Run device tests
+atest libfs_avb_device_test # Test public libfs_avb APIs on a device.
diff --git a/fs_mgr/libfs_avb/tests/fs_avb_device_test.cpp b/fs_mgr/libfs_avb/tests/fs_avb_device_test.cpp
new file mode 100644
index 0000000..fc4eb5f
--- /dev/null
+++ b/fs_mgr/libfs_avb/tests/fs_avb_device_test.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 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 <android-base/properties.h>
+#include <fs_avb/fs_avb_util.h>
+#include <fstab/fstab.h>
+#include <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+using android::fs_mgr::Fstab;
+using android::fs_mgr::FstabEntry;
+using android::fs_mgr::VBMetaData;
+using android::fs_mgr::VBMetaVerifyResult;
+
+namespace fs_avb_device_test {
+
+// system vbmeta might not be at the end of /system when dynamic partition is
+// enabled. Therefore, disable it by default.
+TEST(PublicFsAvbDeviceTest, DISABLED_LoadAndVerifyVbmeta_SystemVbmeta) {
+ Fstab fstab;
+ EXPECT_TRUE(ReadDefaultFstab(&fstab));
+
+ FstabEntry* system_entry = GetEntryForMountPoint(&fstab, "/system");
+ EXPECT_NE(nullptr, system_entry);
+
+ std::string out_public_key_data;
+ std::string out_avb_partition_name;
+ VBMetaVerifyResult out_verify_result;
+ std::unique_ptr<VBMetaData> vbmeta =
+ LoadAndVerifyVbmeta(*system_entry, "" /* expected_public_key_blob */,
+ &out_public_key_data, &out_avb_partition_name, &out_verify_result);
+
+ EXPECT_NE(nullptr, vbmeta);
+ EXPECT_EQ(VBMetaVerifyResult::kSuccess, out_verify_result);
+ EXPECT_EQ("system", out_avb_partition_name);
+ EXPECT_NE("", out_public_key_data);
+}
+
+TEST(PublicFsAvbDeviceTest, GetHashtreeDescriptor_SystemOther) {
+ // Non-A/B device doesn't have system_other partition.
+ if (fs_mgr_get_slot_suffix() == "") return;
+
+ // Skip running this test if system_other is a logical partition.
+ // Note that system_other is still a physical partition on "retrofit" devices.
+ if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
+ !android::base::GetBoolProperty("ro.boot.dynamic_partitions_retrofit", false)) {
+ return;
+ }
+
+ Fstab fstab;
+ EXPECT_TRUE(ReadFstabFromFile("/system/etc/fstab.postinstall", &fstab));
+
+ // It should have two lines in the fstab, the first for logical system_other,
+ // the other for physical system_other.
+ EXPECT_EQ(2UL, fstab.size());
+
+ // Use the 2nd fstab entry, which is for physical system_other partition.
+ FstabEntry* system_other = &fstab[1];
+ EXPECT_NE(nullptr, system_other);
+
+ std::string out_public_key_data;
+ std::string out_avb_partition_name;
+ VBMetaVerifyResult out_verify_result;
+ std::unique_ptr<VBMetaData> system_other_vbmeta =
+ LoadAndVerifyVbmeta(*system_other, "" /* expected_public_key_blob */,
+ &out_public_key_data, &out_avb_partition_name, &out_verify_result);
+
+ EXPECT_NE(nullptr, system_other_vbmeta);
+ EXPECT_EQ(VBMetaVerifyResult::kSuccess, out_verify_result);
+ EXPECT_EQ("system_other", out_avb_partition_name);
+ EXPECT_NE("", out_public_key_data);
+
+ auto hashtree_desc =
+ GetHashtreeDescriptor(out_avb_partition_name, std::move(*system_other_vbmeta));
+ EXPECT_NE(nullptr, hashtree_desc);
+}
+
+} // namespace fs_avb_device_test
diff --git a/fs_mgr/libfs_avb/tests/fs_avb_test_util.h b/fs_mgr/libfs_avb/tests/fs_avb_test_util.h
index 2e46644..ab1980b 100644
--- a/fs_mgr/libfs_avb/tests/fs_avb_test_util.h
+++ b/fs_mgr/libfs_avb/tests/fs_avb_test_util.h
@@ -29,7 +29,7 @@
#include <android-base/unique_fd.h>
#include <base/files/file_path.h>
#include <base/strings/stringprintf.h>
-#include <fs_avb/fs_avb.h>
+#include <fs_avb/types.h>
#include <gtest/gtest.h>
// Utility macro to run the command expressed by the printf()-style string
diff --git a/fs_mgr/libfs_avb/tests/fs_avb_util_test.cpp b/fs_mgr/libfs_avb/tests/fs_avb_util_test.cpp
new file mode 100644
index 0000000..7c34009
--- /dev/null
+++ b/fs_mgr/libfs_avb/tests/fs_avb_util_test.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2019 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 <fs_avb/fs_avb_util.h>
+
+#include "fs_avb_test_util.h"
+
+namespace fs_avb_host_test {
+
+class PublicFsAvbUtilTest : public BaseFsAvbTest {
+ public:
+ PublicFsAvbUtilTest(){};
+
+ protected:
+ ~PublicFsAvbUtilTest(){};
+};
+
+TEST_F(PublicFsAvbUtilTest, GetHashtreeDescriptor) {
+ // Generates a raw system_other.img, use a smaller size to speed-up unit test.
+ const size_t system_image_size = 10 * 1024 * 1024;
+ const size_t system_partition_size = 15 * 1024 * 1024;
+ base::FilePath system_path = GenerateImage("system.img", system_image_size);
+
+ // Adds AVB Hashtree Footer.
+ AddAvbFooter(system_path, "hashtree", "system", system_partition_size, "SHA512_RSA4096", 20,
+ data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
+ "--internal_release_string \"unit test\"");
+
+ auto system_vbmeta = ExtractAndLoadVBMetaData(system_path, "system-vbmeta.img");
+
+ auto hashtree_desc =
+ GetHashtreeDescriptor("system" /* avb_partition_name */, std::move(system_vbmeta));
+ EXPECT_NE(nullptr, hashtree_desc);
+
+ // Checks the returned hashtree_desc matches the following info returned by avbtool.
+ EXPECT_EQ(
+ "Footer version: 1.0\n"
+ "Image size: 15728640 bytes\n"
+ "Original image size: 10485760 bytes\n"
+ "VBMeta offset: 10661888\n"
+ "VBMeta size: 2112 bytes\n"
+ "--\n"
+ "Minimum libavb version: 1.0\n"
+ "Header Block: 256 bytes\n"
+ "Authentication Block: 576 bytes\n"
+ "Auxiliary Block: 1280 bytes\n"
+ "Algorithm: SHA512_RSA4096\n"
+ "Rollback Index: 20\n"
+ "Flags: 0\n"
+ "Release String: 'unit test'\n"
+ "Descriptors:\n"
+ " Hashtree descriptor:\n"
+ " Version of dm-verity: 1\n"
+ " Image Size: 10485760 bytes\n"
+ " Tree Offset: 10485760\n"
+ " Tree Size: 86016 bytes\n"
+ " Data Block Size: 4096 bytes\n"
+ " Hash Block Size: 4096 bytes\n"
+ " FEC num roots: 2\n"
+ " FEC offset: 10571776\n"
+ " FEC size: 90112 bytes\n"
+ " Hash Algorithm: sha1\n"
+ " Partition Name: system\n"
+ " Salt: d00df00d\n"
+ " Root Digest: a3d5dd307341393d85de356c384ff543ec1ed81b\n"
+ " Flags: 0\n",
+ InfoImage(system_path));
+
+ EXPECT_EQ(1UL, hashtree_desc->dm_verity_version);
+ EXPECT_EQ(10485760UL, hashtree_desc->image_size);
+ EXPECT_EQ(10485760UL, hashtree_desc->tree_offset);
+ EXPECT_EQ(86016UL, hashtree_desc->tree_size);
+ EXPECT_EQ(4096UL, hashtree_desc->data_block_size);
+ EXPECT_EQ(4096UL, hashtree_desc->hash_block_size);
+ EXPECT_EQ(2UL, hashtree_desc->fec_num_roots);
+ EXPECT_EQ(10571776UL, hashtree_desc->fec_offset);
+ EXPECT_EQ(90112UL, hashtree_desc->fec_size);
+ EXPECT_EQ(std::string("sha1"),
+ std::string(reinterpret_cast<const char*>(hashtree_desc->hash_algorithm)));
+ EXPECT_EQ(std::string("system").length(), hashtree_desc->partition_name_len);
+ EXPECT_EQ(hashtree_desc->partition_name, "system");
+ EXPECT_EQ(hashtree_desc->salt, "d00df00d");
+ EXPECT_EQ(hashtree_desc->root_digest, "a3d5dd307341393d85de356c384ff543ec1ed81b");
+
+ // Checks it's null if partition name doesn't match.
+ EXPECT_EQ(nullptr, GetHashtreeDescriptor("system_not_exist" /* avb_partition_name */,
+ std::move(system_vbmeta)));
+}
+
+TEST_F(PublicFsAvbUtilTest, GetHashtreeDescriptor_NotFound) {
+ // Generates a raw boot.img
+ const size_t image_size = 5 * 1024 * 1024;
+ const size_t partition_size = 10 * 1024 * 1024;
+ base::FilePath boot_path = GenerateImage("boot.img", image_size);
+ // Appends AVB Hash Footer.
+ AddAvbFooter(boot_path, "hash", "boot", partition_size, "SHA256_RSA4096", 10,
+ data_dir_.Append("testkey_rsa4096.pem"), "d00df00d",
+ "--internal_release_string \"unit test\"");
+ // Extracts boot vbmeta from boot.img into boot-vbmeta.img.
+ auto boot_vbmeta = ExtractAndLoadVBMetaData(boot_path, "boot-vbmeta.img");
+
+ auto hashtree_desc =
+ GetHashtreeDescriptor("boot" /* avb_partition_name */, std::move(boot_vbmeta));
+ EXPECT_EQ(nullptr, hashtree_desc);
+}
+
+} // namespace fs_avb_host_test
diff --git a/fs_mgr/libfs_avb/types.cpp b/fs_mgr/libfs_avb/types.cpp
new file mode 100644
index 0000000..3c277f3
--- /dev/null
+++ b/fs_mgr/libfs_avb/types.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2019 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 "fs_avb/types.h"
+
+namespace android {
+namespace fs_mgr {
+
+// Helper functions to print enum class VBMetaVerifyResult.
+const char* VBMetaVerifyResultToString(VBMetaVerifyResult result) {
+ // clang-format off
+ static const char* const name[] = {
+ "ResultSuccess",
+ "ResultError",
+ "ResultErrorVerification",
+ "ResultUnknown",
+ };
+ // clang-format on
+
+ uint32_t index = static_cast<uint32_t>(result);
+ uint32_t unknown_index = sizeof(name) / sizeof(char*) - 1;
+ if (index >= unknown_index) {
+ index = unknown_index;
+ }
+
+ return name[index];
+}
+
+std::ostream& operator<<(std::ostream& os, VBMetaVerifyResult result) {
+ os << VBMetaVerifyResultToString(result);
+ return os;
+}
+
+// Helper functions to dump enum class AvbHandleStatus.
+const char* AvbHandleStatusToString(AvbHandleStatus status) {
+ // clang-format off
+ static const char* const name[] = {
+ "Success",
+ "Uninitialized",
+ "HashtreeDisabled",
+ "VerificationDisabled",
+ "VerificationError",
+ "Unknown",
+ };
+ // clang-format on
+
+ uint32_t index = static_cast<uint32_t>(status);
+ uint32_t unknown_index = sizeof(name) / sizeof(char*) - 1;
+ if (index >= unknown_index) {
+ index = unknown_index;
+ }
+
+ return name[index];
+}
+
+std::ostream& operator<<(std::ostream& os, AvbHandleStatus status) {
+ os << AvbHandleStatusToString(status);
+ return os;
+}
+
+// class VBMetaData
+// ----------------
+std::unique_ptr<AvbVBMetaImageHeader> VBMetaData::GetVBMetaHeader(bool update_vbmeta_size) {
+ auto vbmeta_header = std::make_unique<AvbVBMetaImageHeader>();
+
+ if (!vbmeta_header) return nullptr;
+
+ /* Byteswap the header. */
+ avb_vbmeta_image_header_to_host_byte_order((AvbVBMetaImageHeader*)vbmeta_ptr_.get(),
+ vbmeta_header.get());
+ if (update_vbmeta_size) {
+ vbmeta_size_ = sizeof(AvbVBMetaImageHeader) +
+ vbmeta_header->authentication_data_block_size +
+ vbmeta_header->auxiliary_data_block_size;
+ }
+
+ return vbmeta_header;
+}
+
+} // namespace fs_mgr
+} // namespace android
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
index 2f0af4a..b7ba782 100644
--- a/liblog/logd_reader.cpp
+++ b/liblog/logd_reader.cpp
@@ -100,148 +100,29 @@
return -EBADF;
}
-/* Private copy of ../libcutils/socket_local_client.c prevent library loops */
+// Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
+// O_CLOEXEC is always set.
+static int socket_local_client(const std::string& name, int type) {
+ sockaddr_un addr = {.sun_family = AF_LOCAL};
-#if defined(_WIN32)
-
-LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId, int type) {
- errno = ENOSYS;
- return -ENOSYS;
-}
-
-#else /* !_WIN32 */
-
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-/* Private copy of ../libcutils/socket_local.h prevent library loops */
-#define FILESYSTEM_SOCKET_PREFIX "/tmp/"
-#define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"
-/* End of ../libcutils/socket_local.h */
-
-#define LISTEN_BACKLOG 4
-
-/* Documented in header file. */
-LIBLOG_WEAK int socket_make_sockaddr_un(const char* name, int namespaceId,
- struct sockaddr_un* p_addr, socklen_t* alen) {
- memset(p_addr, 0, sizeof(*p_addr));
- size_t namelen;
-
- switch (namespaceId) {
- case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
-#if defined(__linux__)
- namelen = strlen(name);
-
- /* Test with length +1 for the *initial* '\0'. */
- if ((namelen + 1) > sizeof(p_addr->sun_path)) {
- goto error;
- }
-
- /*
- * Note: The path in this case is *not* supposed to be
- * '\0'-terminated. ("man 7 unix" for the gory details.)
- */
-
- p_addr->sun_path[0] = 0;
- memcpy(p_addr->sun_path + 1, name, namelen);
-#else
- /* this OS doesn't have the Linux abstract namespace */
-
- namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
- /* unix_path_max appears to be missing on linux */
- if (namelen > sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
- goto error;
- }
-
- strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
- strcat(p_addr->sun_path, name);
-#endif
- break;
-
- case ANDROID_SOCKET_NAMESPACE_RESERVED:
- namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
- /* unix_path_max appears to be missing on linux */
- if (namelen > sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
- goto error;
- }
-
- strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
- strcat(p_addr->sun_path, name);
- break;
-
- case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
- namelen = strlen(name);
- /* unix_path_max appears to be missing on linux */
- if (namelen > sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
- goto error;
- }
-
- strcpy(p_addr->sun_path, name);
- break;
-
- default:
- /* invalid namespace id */
- return -1;
+ std::string path = "/dev/socket/" + name;
+ if (path.size() + 1 > sizeof(addr.sun_path)) {
+ return -1;
}
+ strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
- p_addr->sun_family = AF_LOCAL;
- *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
- return 0;
-error:
- return -1;
-}
-
-/**
- * connect to peer named "name" on fd
- * returns same fd or -1 on error.
- * fd is not closed on error. that's your job.
- *
- * Used by AndroidSocketImpl
- */
-LIBLOG_WEAK int socket_local_client_connect(int fd, const char* name, int namespaceId,
- int type __unused) {
- struct sockaddr_un addr;
- socklen_t alen;
- int err;
-
- err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
-
- if (err < 0) {
- goto error;
- }
-
- if (connect(fd, (struct sockaddr*)&addr, alen) < 0) {
- goto error;
- }
-
- return fd;
-
-error:
- return -1;
-}
-
-/**
- * connect to peer named "name"
- * returns fd or -1 on error
- */
-LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId, int type) {
- int s;
-
- s = socket(AF_LOCAL, type, 0);
- if (s < 0) return -1;
-
- if (0 > socket_local_client_connect(s, name, namespaceId, type)) {
- close(s);
+ int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0);
+ if (fd == 0) {
return -1;
}
- return s;
-}
+ if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
+ close(fd);
+ return -1;
+ }
-#endif /* !_WIN32 */
-/* End of ../libcutils/socket_local_client.c */
+ return fd;
+}
/* worker for sending the command to the logger */
static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg, char* buf,
@@ -250,7 +131,7 @@
size_t len;
char* cp;
int errno_save = 0;
- int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+ int sock = socket_local_client("logd", SOCK_STREAM);
if (sock < 0) {
return sock;
}
@@ -460,10 +341,10 @@
return sock;
}
- sock = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
+ sock = socket_local_client("logdr", SOCK_SEQPACKET);
if (sock == 0) {
/* Guarantee not file descriptor zero */
- int newsock = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
+ int newsock = socket_local_client("logdr", SOCK_SEQPACKET);
close(sock);
sock = newsock;
}
diff --git a/liblog/tests/Android.bp b/liblog/tests/Android.bp
index 4ab2acb..50755ce 100644
--- a/liblog/tests/Android.bp
+++ b/liblog/tests/Android.bp
@@ -31,6 +31,7 @@
shared_libs: [
"libm",
"libbase",
+ "libcutils",
],
static_libs: ["liblog"],
srcs: ["liblog_benchmark.cpp"],
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
index 6d78ed6..3534eb8 100644
--- a/liblog/tests/libc_test.cpp
+++ b/liblog/tests/libc_test.cpp
@@ -23,7 +23,7 @@
#ifdef __ANDROID__
#ifndef NO_PSTORE
FILE* fp;
- ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "a")));
+ ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "ae")));
static const char message[] = "libc.__pstore_append\n";
ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp));
int fflushReturn = fflush(fp);
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index c8ac321..7d11ccf 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -172,7 +172,7 @@
* Measure the time it takes to submit the android logging data to pstore
*/
static void BM_pmsg_short(benchmark::State& state) {
- int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
if (pstore_fd < 0) {
state.SkipWithError("/dev/pmsg0");
return;
@@ -248,7 +248,7 @@
* best case aligned single block.
*/
static void BM_pmsg_short_aligned(benchmark::State& state) {
- int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
if (pstore_fd < 0) {
state.SkipWithError("/dev/pmsg0");
return;
@@ -323,7 +323,7 @@
* best case aligned single block.
*/
static void BM_pmsg_short_unaligned1(benchmark::State& state) {
- int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
if (pstore_fd < 0) {
state.SkipWithError("/dev/pmsg0");
return;
@@ -398,7 +398,7 @@
* best case aligned single block.
*/
static void BM_pmsg_long_aligned(benchmark::State& state) {
- int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
if (pstore_fd < 0) {
state.SkipWithError("/dev/pmsg0");
return;
@@ -471,7 +471,7 @@
* best case aligned single block.
*/
static void BM_pmsg_long_unaligned1(benchmark::State& state) {
- int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));
+ int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
if (pstore_fd < 0) {
state.SkipWithError("/dev/pmsg0");
return;
@@ -949,8 +949,8 @@
// Must be functionally identical to liblog internal __send_log_msg.
static void send_to_control(char* buf, size_t len) {
- int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
- SOCK_STREAM);
+ int sock =
+ socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM | SOCK_CLOEXEC);
if (sock < 0) return;
size_t writeLen = strlen(buf) + 1;
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 83f0fa9..1f87b3e 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -93,7 +93,7 @@
static std::string popenToString(const std::string& command) {
std::string ret;
- FILE* fp = popen(command.c_str(), "r");
+ FILE* fp = popen(command.c_str(), "re");
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = "";
pclose(fp);
@@ -645,7 +645,7 @@
char buffer[512];
snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
- FILE* fp = fopen(buffer, "r");
+ FILE* fp = fopen(buffer, "re");
if (!fp) {
return;
}
diff --git a/liblog/tests/log_radio_test.cpp b/liblog/tests/log_radio_test.cpp
index f202c67..fa1255e 100644
--- a/liblog/tests/log_radio_test.cpp
+++ b/liblog/tests/log_radio_test.cpp
@@ -91,7 +91,7 @@
"logcat -b radio --pid=%u -d -s"
" TEST__RLOGV TEST__RLOGD TEST__RLOGI TEST__RLOGW TEST__RLOGE",
(unsigned)getpid());
- FILE* fp = popen(buf.c_str(), "r");
+ FILE* fp = popen(buf.c_str(), "re");
int count = 0;
int count_false = 0;
if (fp) {
diff --git a/liblog/tests/log_system_test.cpp b/liblog/tests/log_system_test.cpp
index 0656c0b..13f026d 100644
--- a/liblog/tests/log_system_test.cpp
+++ b/liblog/tests/log_system_test.cpp
@@ -91,7 +91,7 @@
"logcat -b system --pid=%u -d -s"
" TEST__SLOGV TEST__SLOGD TEST__SLOGI TEST__SLOGW TEST__SLOGE",
(unsigned)getpid());
- FILE* fp = popen(buf.c_str(), "r");
+ FILE* fp = popen(buf.c_str(), "re");
int count = 0;
int count_false = 0;
if (fp) {
diff --git a/libmeminfo/libdmabufinfo/tools/Android.bp b/libmeminfo/libdmabufinfo/tools/Android.bp
index 0af3c48..224b68e 100644
--- a/libmeminfo/libdmabufinfo/tools/Android.bp
+++ b/libmeminfo/libdmabufinfo/tools/Android.bp
@@ -26,5 +26,5 @@
static_libs: [
"libdmabufinfo",
],
- soc_specific: true,
+ product_specific: true,
}
\ No newline at end of file
diff --git a/lmkd/include/lmkd.h b/lmkd/include/lmkd.h
index e72d159..59377dd 100644
--- a/lmkd/include/lmkd.h
+++ b/lmkd/include/lmkd.h
@@ -50,7 +50,7 @@
typedef int LMKD_CTRL_PACKET[CTRL_PACKET_MAX_SIZE / sizeof(int)];
/* Get LMKD packet command */
-inline enum lmk_cmd lmkd_pack_get_cmd(LMKD_CTRL_PACKET pack) {
+static inline enum lmk_cmd lmkd_pack_get_cmd(LMKD_CTRL_PACKET pack) {
return (enum lmk_cmd)ntohl(pack[0]);
}
@@ -64,8 +64,8 @@
* For LMK_TARGET packet get target_idx-th payload.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline void lmkd_pack_get_target(LMKD_CTRL_PACKET packet,
- int target_idx, struct lmk_target *target) {
+static inline void lmkd_pack_get_target(LMKD_CTRL_PACKET packet, int target_idx,
+ struct lmk_target* target) {
target->minfree = ntohl(packet[target_idx * 2 + 1]);
target->oom_adj_score = ntohl(packet[target_idx * 2 + 2]);
}
@@ -74,9 +74,8 @@
* Prepare LMK_TARGET packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet,
- struct lmk_target *targets,
- size_t target_cnt) {
+static inline size_t lmkd_pack_set_target(LMKD_CTRL_PACKET packet, struct lmk_target* targets,
+ size_t target_cnt) {
int idx = 0;
packet[idx++] = htonl(LMK_TARGET);
while (target_cnt) {
@@ -99,8 +98,7 @@
* For LMK_PROCPRIO packet get its payload.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet,
- struct lmk_procprio *params) {
+static inline void lmkd_pack_get_procprio(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) {
params->pid = (pid_t)ntohl(packet[1]);
params->uid = (uid_t)ntohl(packet[2]);
params->oomadj = ntohl(packet[3]);
@@ -110,8 +108,7 @@
* Prepare LMK_PROCPRIO packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline size_t lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet,
- struct lmk_procprio *params) {
+static inline size_t lmkd_pack_set_procprio(LMKD_CTRL_PACKET packet, struct lmk_procprio* params) {
packet[0] = htonl(LMK_PROCPRIO);
packet[1] = htonl(params->pid);
packet[2] = htonl(params->uid);
@@ -128,8 +125,8 @@
* For LMK_PROCREMOVE packet get its payload.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline void lmkd_pack_get_procremove(LMKD_CTRL_PACKET packet,
- struct lmk_procremove *params) {
+static inline void lmkd_pack_get_procremove(LMKD_CTRL_PACKET packet,
+ struct lmk_procremove* params) {
params->pid = (pid_t)ntohl(packet[1]);
}
@@ -137,8 +134,8 @@
* Prepare LMK_PROCREMOVE packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline size_t lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet,
- struct lmk_procprio *params) {
+static inline size_t lmkd_pack_set_procremove(LMKD_CTRL_PACKET packet,
+ struct lmk_procprio* params) {
packet[0] = htonl(LMK_PROCREMOVE);
packet[1] = htonl(params->pid);
return 2 * sizeof(int);
@@ -148,7 +145,7 @@
* Prepare LMK_PROCPURGE packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline size_t lmkd_pack_set_procpurge(LMKD_CTRL_PACKET packet) {
+static inline size_t lmkd_pack_set_procpurge(LMKD_CTRL_PACKET packet) {
packet[0] = htonl(LMK_PROCPURGE);
return sizeof(int);
}
@@ -163,8 +160,8 @@
* For LMK_GETKILLCNT packet get its payload.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline void lmkd_pack_get_getkillcnt(LMKD_CTRL_PACKET packet,
- struct lmk_getkillcnt *params) {
+static inline void lmkd_pack_get_getkillcnt(LMKD_CTRL_PACKET packet,
+ struct lmk_getkillcnt* params) {
params->min_oomadj = ntohl(packet[1]);
params->max_oomadj = ntohl(packet[2]);
}
@@ -173,8 +170,8 @@
* Prepare LMK_GETKILLCNT packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline size_t lmkd_pack_set_getkillcnt(LMKD_CTRL_PACKET packet,
- struct lmk_getkillcnt *params) {
+static inline size_t lmkd_pack_set_getkillcnt(LMKD_CTRL_PACKET packet,
+ struct lmk_getkillcnt* params) {
packet[0] = htonl(LMK_GETKILLCNT);
packet[1] = htonl(params->min_oomadj);
packet[2] = htonl(params->max_oomadj);
@@ -185,7 +182,7 @@
* Prepare LMK_GETKILLCNT reply packet and return packet size in bytes.
* Warning: no checks performed, caller should ensure valid parameters.
*/
-inline size_t lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet, int kill_cnt) {
+static inline size_t lmkd_pack_set_getkillcnt_repl(LMKD_CTRL_PACKET packet, int kill_cnt) {
packet[0] = htonl(LMK_GETKILLCNT);
packet[1] = htonl(kill_cnt);
return 2 * sizeof(int);
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index cbbc710..123fdd7 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -42,6 +42,23 @@
LOCAL_POST_INSTALL_CMD = mkdir -p $(TARGET_OUT)/usr && rm -rf $(TARGET_OUT)/usr/icu
LOCAL_POST_INSTALL_CMD += ; ln -sf /apex/com.android.runtime/etc/icu $(TARGET_OUT)/usr/icu
+# TODO(b/124106384): Clean up compat symlinks for ART binaries.
+ART_BINARIES= \
+ dalvikvm32 \
+ dalvikvm64 \
+ dex2oat \
+ dexdiag \
+ dexdump \
+ dexlist \
+ dexoptanalyzer \
+ oatdump \
+ profman \
+
+$(foreach b,$(ART_BINARIES), \
+ $(eval LOCAL_POST_INSTALL_CMD += \
+ ; ln -sf /apex/com.android.runtime/bin/$(b) $(TARGET_OUT)/bin/$(b)) \
+)
+
# End of runtime APEX compatibilty.
include $(BUILD_PREBUILT)
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 2a44ae4..df9abbd 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -20,13 +20,17 @@
dir.vendor = /data/benchmarktest/vendor
dir.vendor = /data/benchmarktest64/vendor
+dir.unrestricted = /data/nativetest/unrestricted
+dir.unrestricted = /data/nativetest64/unrestricted
+
+# TODO(b/123864775): Ensure tests are run from /data/nativetest{,64} or (if
+# necessary) the unrestricted subdirs above. Then clean this up.
+dir.unrestricted = /data/local/tmp
+
dir.system = /data/nativetest
dir.system = /data/nativetest64
dir.system = /data/benchmarktest
dir.system = /data/benchmarktest64
-# TODO(b/123864775): Ensure tests are run from one of the directories above and
-# remove this.
-dir.system = /data/local/tmp
dir.postinstall = /postinstall
@@ -409,6 +413,7 @@
# Keep in sync with ld.config.txt in the com.android.runtime APEX.
namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
namespace.runtime.links = system
# TODO(b/119867084): Restrict to Bionic dlopen dependencies and PALette library
# when it exists.
@@ -477,6 +482,111 @@
namespace.system.link.runtime.shared_libs += libnativehelper.so
namespace.system.link.runtime.shared_libs += libnativeloader.so
+
+###############################################################################
+# Namespace config for native tests that need access to both system and vendor
+# libraries. This replicates the default linker config (done by
+# init_default_namespace_no_config in bionic/linker/linker.cpp), except that it
+# includes the requisite namespace setup for APEXes.
+###############################################################################
+[unrestricted]
+additional.namespaces = runtime,media,conscrypt,resolv
+
+namespace.default.search.paths = /system/${LIB}
+namespace.default.search.paths += /odm/${LIB}
+namespace.default.search.paths += /vendor/${LIB}
+
+namespace.default.asan.search.paths = /data/asan/system/${LIB}
+namespace.default.asan.search.paths += /system/${LIB}
+namespace.default.asan.search.paths += /data/asan/odm/${LIB}
+namespace.default.asan.search.paths += /odm/${LIB}
+namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
+namespace.default.asan.search.paths += /vendor/${LIB}
+
+# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+namespace.default.links = runtime,resolv
+namespace.default.visible = true
+
+namespace.default.link.runtime.shared_libs = libart.so:libartd.so
+namespace.default.link.runtime.shared_libs += libdexfile_external.so
+namespace.default.link.runtime.shared_libs += libnativebridge.so
+namespace.default.link.runtime.shared_libs += libnativehelper.so
+namespace.default.link.runtime.shared_libs += libnativeloader.so
+namespace.default.link.runtime.shared_libs += libandroidicu.so
+
+# TODO(b/122876336): Remove libpac.so once it's migrated to Webview
+namespace.default.link.runtime.shared_libs += libpac.so
+
+namespace.default.link.resolv.shared_libs = libnetd_resolv.so
+
+###############################################################################
+# "runtime" APEX namespace
+#
+# This namespace exposes externally accessible libraries from the Runtime APEX.
+###############################################################################
+namespace.runtime.isolated = true
+namespace.runtime.visible = true
+
+# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+namespace.runtime.links = default
+# TODO(b/119867084): Restrict to Bionic dlopen dependencies and PALette library
+# when it exists.
+namespace.runtime.link.default.allow_all_shared_libs = true
+
+###############################################################################
+# "media" APEX namespace
+#
+# This namespace is for libraries within the media APEX.
+###############################################################################
+namespace.media.isolated = true
+namespace.media.visible = true
+
+namespace.media.search.paths = /apex/com.android.media/${LIB}
+namespace.media.asan.search.paths = /apex/com.android.media/${LIB}
+
+namespace.media.links = default
+namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
+namespace.media.link.default.shared_libs += libandroid.so
+namespace.media.link.default.shared_libs += libbinder_ndk.so
+namespace.media.link.default.shared_libs += libmediametrics.so
+namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+
+###############################################################################
+# "conscrypt" APEX namespace
+#
+# This namespace is for libraries within the conscrypt APEX.
+###############################################################################
+namespace.conscrypt.isolated = true
+namespace.conscrypt.visible = true
+
+# Keep in sync with ld.config.txt in the com.android.runtime APEX.
+namespace.conscrypt.search.paths = /apex/com.android.conscrypt/${LIB}
+namespace.conscrypt.asan.search.paths = /apex/com.android.conscrypt/${LIB}
+namespace.conscrypt.links = runtime,default
+namespace.conscrypt.link.runtime.shared_libs = libjavacore.so
+namespace.conscrypt.link.default.shared_libs = libc.so
+namespace.conscrypt.link.default.shared_libs += libm.so
+namespace.conscrypt.link.default.shared_libs += libdl.so
+
+###############################################################################
+# "resolv" APEX namespace
+#
+# This namespace is for libraries within the resolv APEX.
+###############################################################################
+namespace.resolv.isolated = true
+namespace.resolv.visible = true
+
+namespace.resolv.search.paths = /apex/com.android.resolv/${LIB}
+namespace.resolv.asan.search.paths = /apex/com.android.resolv/${LIB}
+namespace.resolv.links = default
+namespace.resolv.link.default.shared_libs = libc.so
+namespace.resolv.link.default.shared_libs += libm.so
+namespace.resolv.link.default.shared_libs += libdl.so
+namespace.resolv.link.default.shared_libs += libbinder_ndk.so
+
+
###############################################################################
# Namespace config for binaries under /postinstall.
# Only default namespace is defined and default has no directories
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 23b4e7d..3c97a49 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -350,6 +350,7 @@
# Keep in sync with ld.config.txt in the com.android.runtime APEX.
namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# TODO(b/119867084): Restrict to Bionic dlopen dependencies and PALette library
# when it exists.