diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-11-05 12:35:27 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-11-05 12:35:27 +0000 |
commit | 072c490777eebd75c0fdb415e31ab0a485a3ff5d (patch) | |
tree | cd762306a7599ab655b83cc4642415d5d2535923 | |
parent | 6a9029542ce465b65f12221bdb6c9b74cec3252f (diff) | |
parent | 3d56a0b774ec0306652e614550730431d773ef37 (diff) | |
download | extras-072c490777eebd75c0fdb415e31ab0a485a3ff5d.tar.gz |
Snap for 5988121 from 3d56a0b774ec0306652e614550730431d773ef37 to qt-aml-networking-release
Change-Id: Ia843446f9faf09b97c52d162235c5f29b25dac62
l--------- | libfscrypt/.clang-format | 1 | ||||
-rw-r--r-- | libfscrypt/fscrypt.cpp | 269 | ||||
-rw-r--r-- | libfscrypt/include/fscrypt/fscrypt.h | 40 | ||||
-rw-r--r-- | libfscrypt/tests/Android.bp | 33 | ||||
-rw-r--r-- | libfscrypt/tests/fscrypt_test.cpp | 138 | ||||
-rw-r--r-- | libperfmgr/tools/ConfigVerifier.cc | 17 | ||||
-rw-r--r-- | simpleperf/JITDebugReader.cpp | 18 | ||||
-rw-r--r-- | simpleperf/cmd_record_test.cpp | 23 | ||||
-rw-r--r-- | simpleperf/command.cpp | 5 | ||||
-rw-r--r-- | simpleperf/event_selection_set.cpp | 5 |
10 files changed, 421 insertions, 128 deletions
diff --git a/libfscrypt/.clang-format b/libfscrypt/.clang-format new file mode 120000 index 00000000..973b2fab --- /dev/null +++ b/libfscrypt/.clang-format @@ -0,0 +1 @@ +../../../build/soong/scripts/system-clang-format
\ No newline at end of file diff --git a/libfscrypt/fscrypt.cpp b/libfscrypt/fscrypt.cpp index 66a43200..b76f0b17 100644 --- a/libfscrypt/fscrypt.cpp +++ b/libfscrypt/fscrypt.cpp @@ -18,6 +18,7 @@ #include <android-base/file.h> #include <android-base/logging.h> +#include <android-base/strings.h> #include <android-base/unique_fd.h> #include <asm/ioctl.h> #include <cutils/properties.h> @@ -32,6 +33,10 @@ #include <utils/misc.h> #include <array> +#include <string> +#include <vector> + +using namespace std::string_literals; // TODO: switch to <linux/fscrypt.h> once it's in Bionic #ifndef FSCRYPT_POLICY_V1 @@ -67,7 +72,45 @@ struct fscrypt_policy_v2 { #define HEX_LOOKUP "0123456789abcdef" -#define MAX_KEY_REF_SIZE_HEX (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1) +struct ModeLookupEntry { + std::string name; + int id; +}; + +static const auto contents_modes = std::vector<ModeLookupEntry>{ + {"aes-256-xts"s, FS_ENCRYPTION_MODE_AES_256_XTS}, + {"software"s, FS_ENCRYPTION_MODE_AES_256_XTS}, + {"adiantum"s, FS_ENCRYPTION_MODE_ADIANTUM}, + {"ice"s, FS_ENCRYPTION_MODE_PRIVATE}, +}; + +static const auto filenames_modes = std::vector<ModeLookupEntry>{ + {"aes-256-cts"s, FS_ENCRYPTION_MODE_AES_256_CTS}, + {"aes-256-heh"s, FS_ENCRYPTION_MODE_AES_256_HEH}, + {"adiantum"s, FS_ENCRYPTION_MODE_ADIANTUM}, +}; + +static bool LookupModeByName(const std::vector<struct ModeLookupEntry>& modes, + const std::string& name, int* result) { + for (const auto& e : modes) { + if (e.name == name) { + *result = e.id; + return true; + } + } + return false; +} + +static bool LookupModeById(const std::vector<struct ModeLookupEntry>& modes, int id, + std::string* result) { + for (const auto& e : modes) { + if (e.id == id) { + *result = e.name; + return true; + } + } + return false; +} bool fscrypt_is_native() { char value[PROPERTY_VALUE_MAX]; @@ -75,6 +118,9 @@ bool fscrypt_is_native() { return !strcmp(value, "file"); } +namespace android { +namespace fscrypt { + static void log_ls(const char* dirname) { std::array<const char*, 3> argv = {"ls", "-laZ", dirname}; int status = 0; @@ -96,17 +142,85 @@ static void log_ls(const char* dirname) { } } -static void keyrefstring(const char* key_raw_ref, size_t key_raw_ref_length, char* hex) { - size_t j = 0; - for (size_t i = 0; i < key_raw_ref_length; i++) { - hex[j++] = HEX_LOOKUP[(key_raw_ref[i] & 0xF0) >> 4]; - hex[j++] = HEX_LOOKUP[key_raw_ref[i] & 0x0F]; +void BytesToHex(const std::string& bytes, std::string* hex) { + hex->clear(); + for (char c : bytes) { + *hex += HEX_LOOKUP[(c & 0xF0) >> 4]; + *hex += HEX_LOOKUP[c & 0x0F]; } - hex[j] = '\0'; } -static uint8_t fscrypt_get_policy_flags(int filenames_encryption_mode, int policy_version) { - uint8_t flags = 0; +static bool fscrypt_is_encrypted(int fd) { + fscrypt_policy_v1 policy; + + // success => encrypted with v1 policy + // EINVAL => encrypted with v2 policy + // ENODATA => not encrypted + return ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) == 0 || errno == EINVAL; +} + +bool OptionsToString(const EncryptionOptions& options, std::string* options_string) { + std::string contents_mode, filenames_mode; + if (!LookupModeById(contents_modes, options.contents_mode, &contents_mode)) { + return false; + } + if (!LookupModeById(filenames_modes, options.filenames_mode, &filenames_mode)) { + return false; + } + *options_string = contents_mode + ":" + filenames_mode + ":v" + std::to_string(options.version); + if ((options.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64)) { + *options_string += "+inlinecrypt_optimized"; + } + EncryptionOptions options_check; + if (!ParseOptions(*options_string, &options_check)) { + LOG(ERROR) << "Internal error serializing options as string: " << *options_string; + return false; + } + if (memcmp(&options, &options_check, sizeof(options_check)) != 0) { + LOG(ERROR) << "Internal error serializing options as string, round trip failed: " + << *options_string; + return false; + } + return true; +} + +bool ParseOptions(const std::string& options_string, EncryptionOptions* options) { + memset(options, '\0', sizeof(*options)); + auto parts = android::base::Split(options_string, ":"); + if (parts.size() < 1 || parts.size() > 3) { + return false; + } + if (!LookupModeByName(contents_modes, parts[0], &options->contents_mode)) { + LOG(ERROR) << "Invalid file contents encryption mode: " << parts[0]; + return false; + } + if (parts.size() >= 2) { + if (!LookupModeByName(filenames_modes, parts[1], &options->filenames_mode)) { + LOG(ERROR) << "Invalid file names encryption mode: " << parts[1]; + return false; + } + } else if (options->contents_mode == FS_ENCRYPTION_MODE_ADIANTUM) { + options->filenames_mode = FS_ENCRYPTION_MODE_ADIANTUM; + } else { + options->filenames_mode = FS_ENCRYPTION_MODE_AES_256_CTS; + } + options->version = 1; + options->flags = 0; + if (parts.size() >= 3) { + auto flags = android::base::Split(parts[2], "+"); + for (const auto& flag : flags) { + if (flag == "v1") { + options->version = 1; + } else if (flag == "v2") { + options->version = 2; + } else if (flag == "inlinecrypt_optimized") { + options->flags |= FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64; + } else { + LOG(ERROR) << "Unknown flag: " << flag; + return false; + } + } + } // In the original setting of v1 policies and AES-256-CTS we used 4-byte // padding of filenames, so we have to retain that for compatibility. @@ -114,105 +228,77 @@ static uint8_t fscrypt_get_policy_flags(int filenames_encryption_mode, int polic // For everything else, use 16-byte padding. This is more secure (it helps // hide the length of filenames), and it makes the inputs evenly divisible // into cipher blocks which is more efficient for encryption and decryption. - if (policy_version == 1 && filenames_encryption_mode == FS_ENCRYPTION_MODE_AES_256_CTS) { - flags |= FS_POLICY_FLAGS_PAD_4; + if (options->version == 1 && options->filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS) { + options->flags |= FS_POLICY_FLAGS_PAD_4; } else { - flags |= FS_POLICY_FLAGS_PAD_16; + options->flags |= FS_POLICY_FLAGS_PAD_16; } // Use DIRECT_KEY for Adiantum, since it's much more efficient but just as // secure since Android doesn't reuse the same master key for multiple // encryption modes. - if (filenames_encryption_mode == FS_ENCRYPTION_MODE_ADIANTUM) { - flags |= FS_POLICY_FLAG_DIRECT_KEY; + if (options->filenames_mode == FS_ENCRYPTION_MODE_ADIANTUM) { + options->flags |= FS_POLICY_FLAG_DIRECT_KEY; } - - return flags; + return true; } -static bool fscrypt_is_encrypted(int fd) { - fscrypt_policy_v1 policy; - - // success => encrypted with v1 policy - // EINVAL => encrypted with v2 policy - // ENODATA => not encrypted - return ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) == 0 || errno == EINVAL; +static std::string PolicyDebugString(const EncryptionPolicy& policy) { + std::stringstream ss; + std::string ref_hex; + BytesToHex(policy.key_raw_ref, &ref_hex); + ss << ref_hex; + ss << " v" << policy.options.version; + ss << " modes " << policy.options.contents_mode << "/" << policy.options.filenames_mode; + ss << std::hex << " flags 0x" << policy.options.flags; + return ss.str(); } -int fscrypt_policy_ensure(const char* directory, const char* key_raw_ref, size_t key_raw_ref_length, - const char* contents_encryption_mode, - const char* filenames_encryption_mode, int policy_version) { - int contents_mode = 0; - int filenames_mode = 0; - - if (!strcmp(contents_encryption_mode, "software") || - !strcmp(contents_encryption_mode, "aes-256-xts")) { - contents_mode = FS_ENCRYPTION_MODE_AES_256_XTS; - } else if (!strcmp(contents_encryption_mode, "adiantum")) { - contents_mode = FS_ENCRYPTION_MODE_ADIANTUM; - } else if (!strcmp(contents_encryption_mode, "ice")) { - contents_mode = FS_ENCRYPTION_MODE_PRIVATE; - } else { - LOG(ERROR) << "Invalid file contents encryption mode: " - << contents_encryption_mode; - return -1; - } - - if (!strcmp(filenames_encryption_mode, "aes-256-cts")) { - filenames_mode = FS_ENCRYPTION_MODE_AES_256_CTS; - } else if (!strcmp(filenames_encryption_mode, "aes-256-heh")) { - filenames_mode = FS_ENCRYPTION_MODE_AES_256_HEH; - } else if (!strcmp(filenames_encryption_mode, "adiantum")) { - filenames_mode = FS_ENCRYPTION_MODE_ADIANTUM; - } else { - LOG(ERROR) << "Invalid file names encryption mode: " - << filenames_encryption_mode; - return -1; - } - +bool EnsurePolicy(const EncryptionPolicy& policy, const std::string& directory) { union { fscrypt_policy_v1 v1; fscrypt_policy_v2 v2; - } policy; - memset(&policy, 0, sizeof(policy)); + } kern_policy; + memset(&kern_policy, 0, sizeof(kern_policy)); - switch (policy_version) { + switch (policy.options.version) { case 1: - if (key_raw_ref_length != FSCRYPT_KEY_DESCRIPTOR_SIZE) { - LOG(ERROR) << "Invalid key ref length for v1 policy: " << key_raw_ref_length; - return -1; + if (policy.key_raw_ref.size() != FSCRYPT_KEY_DESCRIPTOR_SIZE) { + LOG(ERROR) << "Invalid key descriptor length for v1 policy: " + << policy.key_raw_ref.size(); + return false; } // Careful: FSCRYPT_POLICY_V1 is actually 0 in the API, so make sure // to use it here instead of a literal 1. - policy.v1.version = FSCRYPT_POLICY_V1; - policy.v1.contents_encryption_mode = contents_mode; - policy.v1.filenames_encryption_mode = filenames_mode; - policy.v1.flags = fscrypt_get_policy_flags(filenames_mode, policy_version); - memcpy(policy.v1.master_key_descriptor, key_raw_ref, FSCRYPT_KEY_DESCRIPTOR_SIZE); + kern_policy.v1.version = FSCRYPT_POLICY_V1; + kern_policy.v1.contents_encryption_mode = policy.options.contents_mode; + kern_policy.v1.filenames_encryption_mode = policy.options.filenames_mode; + kern_policy.v1.flags = policy.options.flags; + policy.key_raw_ref.copy(reinterpret_cast<char*>(kern_policy.v1.master_key_descriptor), + FSCRYPT_KEY_DESCRIPTOR_SIZE); break; case 2: - if (key_raw_ref_length != FSCRYPT_KEY_IDENTIFIER_SIZE) { - LOG(ERROR) << "Invalid key ref length for v2 policy: " << key_raw_ref_length; - return -1; + if (policy.key_raw_ref.size() != FSCRYPT_KEY_IDENTIFIER_SIZE) { + LOG(ERROR) << "Invalid key identifier length for v2 policy: " + << policy.key_raw_ref.size(); + return false; } - policy.v2.version = FSCRYPT_POLICY_V2; - policy.v2.contents_encryption_mode = contents_mode; - policy.v2.filenames_encryption_mode = filenames_mode; - policy.v2.flags = fscrypt_get_policy_flags(filenames_mode, policy_version); - memcpy(policy.v2.master_key_identifier, key_raw_ref, FSCRYPT_KEY_IDENTIFIER_SIZE); + kern_policy.v2.version = FSCRYPT_POLICY_V2; + kern_policy.v2.contents_encryption_mode = policy.options.contents_mode; + kern_policy.v2.filenames_encryption_mode = policy.options.filenames_mode; + kern_policy.v2.flags = policy.options.flags; + policy.key_raw_ref.copy(reinterpret_cast<char*>(kern_policy.v2.master_key_identifier), + FSCRYPT_KEY_IDENTIFIER_SIZE); break; default: - LOG(ERROR) << "Invalid encryption policy version: " << policy_version; - return -1; + LOG(ERROR) << "Invalid encryption policy version: " << policy.options.version; + return false; } - char ref[MAX_KEY_REF_SIZE_HEX]; - keyrefstring(key_raw_ref, key_raw_ref_length, ref); - - android::base::unique_fd fd(open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC)); + android::base::unique_fd fd(open(directory.c_str(), O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC)); if (fd == -1) { PLOG(ERROR) << "Failed to open directory " << directory; - return -1; + return false; } bool already_encrypted = fscrypt_is_encrypted(fd); @@ -220,7 +306,7 @@ int fscrypt_policy_ensure(const char* directory, const char* key_raw_ref, size_t // FS_IOC_SET_ENCRYPTION_POLICY will set the policy if the directory is // unencrypted; otherwise it will verify that the existing policy matches. // Setting the policy will fail if the directory is already nonempty. - if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &policy) != 0) { + if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &kern_policy) != 0) { std::string reason; switch (errno) { case EEXIST: @@ -230,20 +316,23 @@ int fscrypt_policy_ensure(const char* directory, const char* key_raw_ref, size_t reason = strerror(errno); break; } - LOG(ERROR) << "Failed to set encryption policy of " << directory << " to " << ref - << " modes " << contents_mode << "/" << filenames_mode << ": " << reason; + LOG(ERROR) << "Failed to set encryption policy of " << directory << " to " + << PolicyDebugString(policy) << ": " << reason; if (errno == ENOTEMPTY) { - log_ls(directory); + log_ls(directory.c_str()); } - return -1; + return false; } if (already_encrypted) { - LOG(INFO) << "Verified that " << directory << " has the encryption policy " << ref - << " modes " << contents_mode << "/" << filenames_mode; + LOG(INFO) << "Verified that " << directory << " has the encryption policy " + << PolicyDebugString(policy); } else { - LOG(INFO) << "Encryption policy of " << directory << " set to " << ref << " modes " - << contents_mode << "/" << filenames_mode; + LOG(INFO) << "Encryption policy of " << directory << " set to " + << PolicyDebugString(policy); } - return 0; + return true; } + +} // namespace fscrypt +} // namespace android diff --git a/libfscrypt/include/fscrypt/fscrypt.h b/libfscrypt/include/fscrypt/fscrypt.h index 13358bb7..2b809866 100644 --- a/libfscrypt/include/fscrypt/fscrypt.h +++ b/libfscrypt/include/fscrypt/fscrypt.h @@ -17,23 +17,45 @@ #ifndef _FSCRYPT_H_ #define _FSCRYPT_H_ -#include <sys/cdefs.h> -#include <stdbool.h> -#include <cutils/multiuser.h> +#include <string> -__BEGIN_DECLS +// TODO: switch to <linux/fscrypt.h> once it's in Bionic +#define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 0x08 bool fscrypt_is_native(); -int fscrypt_policy_ensure(const char* directory, const char* key_raw_ref, size_t key_raw_ref_length, - const char* contents_encryption_mode, - const char* filenames_encryption_mode, int policy_version); - static const char* fscrypt_unencrypted_folder = "/unencrypted"; static const char* fscrypt_key_ref = "/unencrypted/ref"; static const char* fscrypt_key_per_boot_ref = "/unencrypted/per_boot_ref"; static const char* fscrypt_key_mode = "/unencrypted/mode"; -__END_DECLS +namespace android { +namespace fscrypt { + +struct EncryptionOptions { + int version; + int contents_mode; + int filenames_mode; + int flags; + + // Ensure that "version" is not valid on creation and so must be explicitly set + EncryptionOptions() : version(0) {} +}; + +struct EncryptionPolicy { + EncryptionOptions options; + std::string key_raw_ref; +}; + +void BytesToHex(const std::string& bytes, std::string* hex); + +bool OptionsToString(const EncryptionOptions& options, std::string* options_string); + +bool ParseOptions(const std::string& options_string, EncryptionOptions* options); + +bool EnsurePolicy(const EncryptionPolicy& policy, const std::string& directory); + +} // namespace fscrypt +} // namespace android #endif // _FSCRYPT_H_ diff --git a/libfscrypt/tests/Android.bp b/libfscrypt/tests/Android.bp new file mode 100644 index 00000000..985b425f --- /dev/null +++ b/libfscrypt/tests/Android.bp @@ -0,0 +1,33 @@ +// 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. + +cc_test { + name: "libfscrypt_unit_test", + + shared_libs: [ + "libbase", + ], + static_libs: [ + "libfscrypt", + ], + srcs: [ + "fscrypt_test.cpp", + ], + + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], +} diff --git a/libfscrypt/tests/fscrypt_test.cpp b/libfscrypt/tests/fscrypt_test.cpp new file mode 100644 index 00000000..677f0f22 --- /dev/null +++ b/libfscrypt/tests/fscrypt_test.cpp @@ -0,0 +1,138 @@ +/* + * 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 <linux/fs.h> + +#include <fscrypt/fscrypt.h> + +#include <gtest/gtest.h> + +using namespace android::fscrypt; + +/* modes not supported by upstream kernel, so not in <linux/fs.h> */ +#define FS_ENCRYPTION_MODE_AES_256_HEH 126 +#define FS_ENCRYPTION_MODE_PRIVATE 127 + +TEST(fscrypt, ParseOptions) { + EncryptionOptions options; + std::string options_string; + + EXPECT_FALSE(ParseOptions("", &options)); + EXPECT_FALSE(ParseOptions("blah", &options)); + + EXPECT_TRUE(ParseOptions("software", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); + + EXPECT_TRUE(ParseOptions("aes-256-xts", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); + + EXPECT_TRUE(ParseOptions("adiantum", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("adiantum:adiantum:v1", options_string); + + EXPECT_TRUE(ParseOptions("adiantum:aes-256-heh", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_HEH, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("adiantum:aes-256-heh:v1", options_string); + + EXPECT_TRUE(ParseOptions("ice", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("ice:aes-256-cts:v1", options_string); + + EXPECT_FALSE(ParseOptions("ice:blah", &options)); + + EXPECT_TRUE(ParseOptions("ice:aes-256-cts", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("ice:aes-256-cts:v1", options_string); + + EXPECT_TRUE(ParseOptions("ice:aes-256-heh", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_HEH, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("ice:aes-256-heh:v1", options_string); + + EXPECT_TRUE(ParseOptions("ice:adiantum", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_PRIVATE, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_ADIANTUM, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16 | FS_POLICY_FLAG_DIRECT_KEY, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("ice:adiantum:v1", options_string); + + EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); + + EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts:v1", &options)); + EXPECT_EQ(1, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_4, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("aes-256-xts:aes-256-cts:v1", options_string); + + EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts:v2", &options)); + EXPECT_EQ(2, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("aes-256-xts:aes-256-cts:v2", options_string); + + EXPECT_TRUE(ParseOptions("aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized", &options)); + EXPECT_EQ(2, options.version); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_XTS, options.contents_mode); + EXPECT_EQ(FS_ENCRYPTION_MODE_AES_256_CTS, options.filenames_mode); + EXPECT_EQ(FS_POLICY_FLAGS_PAD_16 | FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64, options.flags); + EXPECT_TRUE(OptionsToString(options, &options_string)); + EXPECT_EQ("aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized", options_string); + + EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:v2:", &options)); + EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:v2:foo", &options)); + EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:blah", &options)); + EXPECT_FALSE(ParseOptions("aes-256-xts:aes-256-cts:vblah", &options)); +} diff --git a/libperfmgr/tools/ConfigVerifier.cc b/libperfmgr/tools/ConfigVerifier.cc index a08fd006..2e25e950 100644 --- a/libperfmgr/tools/ConfigVerifier.cc +++ b/libperfmgr/tools/ConfigVerifier.cc @@ -44,23 +44,6 @@ class NodeVerifier : public HintManager { return false; } - for (const auto& node : nodes) { - std::vector<std::string> values = node->GetValues(); - std::string default_value = values[node->GetDefaultIndex()]; - // Always set to default first - values.insert(values.begin(), default_value); - // And reset to default after test - values.push_back(default_value); - for (const auto& value : values) { - if (!android::base::WriteStringToFile(value, node->GetPath())) { - LOG(ERROR) << "Failed to write to node: " << node->GetPath() - << " with value: " << value; - return false; - } - LOG(VERBOSE) << "Wrote to node: " << node->GetPath() - << " with value: " << value; - } - } return true; } diff --git a/simpleperf/JITDebugReader.cpp b/simpleperf/JITDebugReader.cpp index 6de16aac..e48e2270 100644 --- a/simpleperf/JITDebugReader.cpp +++ b/simpleperf/JITDebugReader.cpp @@ -566,15 +566,14 @@ bool JITDebugReader::ReadNewCodeEntriesImpl(Process& process, const Descriptor& // once we hit an entry with timestamp <= last_action_timestmap. break; } - if (entry.symfile_size == 0) { - continue; + if (entry.symfile_size > 0) { + CodeEntry code_entry; + code_entry.addr = current_entry_addr; + code_entry.symfile_addr = entry.symfile_addr; + code_entry.symfile_size = entry.symfile_size; + code_entry.timestamp = entry.register_timestamp; + new_code_entries->push_back(code_entry); } - CodeEntry code_entry; - code_entry.addr = current_entry_addr; - code_entry.symfile_addr = entry.symfile_addr; - code_entry.symfile_size = entry.symfile_size; - code_entry.timestamp = entry.register_timestamp; - new_code_entries->push_back(code_entry); entry_addr_set.insert(current_entry_addr); prev_entry_addr = current_entry_addr; current_entry_addr = entry.next_addr; @@ -608,6 +607,9 @@ void JITDebugReader::ReadJITCodeDebugInfo(Process& process, tmp_file->DoNotRemove(); } auto callback = [&](const ElfFileSymbol& symbol) { + if (symbol.len == 0) { // Some arm labels can have zero length. + return; + } LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr << " - " << (symbol.vaddr + symbol.len) << " with size " << symbol.len; debug_info->emplace_back(process.pid, jit_entry.timestamp, symbol.vaddr, symbol.len, diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp index 82f494f8..184f9359 100644 --- a/simpleperf/cmd_record_test.cpp +++ b/simpleperf/cmd_record_test.cpp @@ -747,7 +747,7 @@ TEST(record_cmd, cpu_percent_option) { class RecordingAppHelper { public: bool InstallApk(const std::string& apk_path, const std::string& package_name) { - if (Workload::RunCmd({"pm", "install", "-t", apk_path})) { + if (Workload::RunCmd({"pm", "install", "-t", "--abi", GetABI(), apk_path})) { installed_packages_.emplace_back(package_name); return true; } @@ -785,6 +785,20 @@ class RecordingAppHelper { } private: + const char* GetABI() { +#if defined(__i386__) + return "x86"; +#elif defined(__x86_64__) + return "x86_64"; +#elif defined(__aarch64__) + return "arm64-v8a"; +#elif defined(__arm__) + return "armeabi-v7a"; +#else + #error "unrecognized ABI" +#endif + } + std::vector<std::string> installed_packages_; std::unique_ptr<Workload> app_start_proc_; TemporaryFile perf_data_file_; @@ -894,6 +908,13 @@ TEST(record_cmd, cs_etm_event) { ASSERT_TRUE(RunRecordCmd({"-e", "cs-etm"}, tmpfile.path)); std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path); ASSERT_TRUE(reader); + + // cs-etm uses sample period instead of sample freq. + ASSERT_EQ(reader->AttrSection().size(), 1u); + const perf_event_attr* attr = reader->AttrSection()[0].attr; + ASSERT_EQ(attr->freq, 0); + ASSERT_EQ(attr->sample_period, 1); + bool has_auxtrace_info = false; bool has_auxtrace = false; bool has_aux = false; diff --git a/simpleperf/command.cpp b/simpleperf/command.cpp index d751d610..e937e19b 100644 --- a/simpleperf/command.cpp +++ b/simpleperf/command.cpp @@ -24,7 +24,6 @@ #include <android-base/logging.h> #include <android-base/parsedouble.h> #include <android-base/parseint.h> -#include <android-base/quick_exit.h> #include "utils.h" @@ -177,9 +176,9 @@ bool RunSimpleperfCmd(int argc, char** argv) { bool result = command->Run(args); LOG(DEBUG) << "command '" << command_name << "' " << (result ? "finished successfully" : "failed"); - // Quick exit to avoid cost freeing memory and closing files. + // Quick exit to avoid the cost of freeing memory and closing files. fflush(stdout); fflush(stderr); - android::base::quick_exit(result ? 0 : 1); + _Exit(result ? 0 : 1); return result; } diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp index e1cba8cc..c7c7a38a 100644 --- a/simpleperf/event_selection_set.cpp +++ b/simpleperf/event_selection_set.cpp @@ -174,6 +174,11 @@ bool EventSelectionSet::BuildAndCheckEventSelection(const std::string& event_nam if (event_type->event_type.type == PERF_TYPE_TRACEPOINT) { selection->event_attr.freq = 0; selection->event_attr.sample_period = DEFAULT_SAMPLE_PERIOD_FOR_TRACEPOINT_EVENT; + } else if (IsEtmEventType(event_type->event_type.type)) { + // ETM recording has no sample frequency to adjust. Using sample frequency only wastes time + // enabling/disabling etm devices. So don't adjust frequency by default. + selection->event_attr.freq = 0; + selection->event_attr.sample_period = 1; } else { selection->event_attr.freq = 1; // Set default sample freq here may print msg "Adjust sample freq to max allowed sample |