summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-11-05 12:35:27 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-11-05 12:35:27 +0000
commit072c490777eebd75c0fdb415e31ab0a485a3ff5d (patch)
treecd762306a7599ab655b83cc4642415d5d2535923
parent6a9029542ce465b65f12221bdb6c9b74cec3252f (diff)
parent3d56a0b774ec0306652e614550730431d773ef37 (diff)
downloadextras-072c490777eebd75c0fdb415e31ab0a485a3ff5d.tar.gz
Snap for 5988121 from 3d56a0b774ec0306652e614550730431d773ef37 to qt-aml-networking-release
Change-Id: Ia843446f9faf09b97c52d162235c5f29b25dac62
l---------libfscrypt/.clang-format1
-rw-r--r--libfscrypt/fscrypt.cpp269
-rw-r--r--libfscrypt/include/fscrypt/fscrypt.h40
-rw-r--r--libfscrypt/tests/Android.bp33
-rw-r--r--libfscrypt/tests/fscrypt_test.cpp138
-rw-r--r--libperfmgr/tools/ConfigVerifier.cc17
-rw-r--r--simpleperf/JITDebugReader.cpp18
-rw-r--r--simpleperf/cmd_record_test.cpp23
-rw-r--r--simpleperf/command.cpp5
-rw-r--r--simpleperf/event_selection_set.cpp5
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