Merge "Replacing manual CBOR with serde-cbor"
diff --git a/fsverity/Android.bp b/fsverity/Android.bp
index b1d8965..5fb38ae 100644
--- a/fsverity/Android.bp
+++ b/fsverity/Android.bp
@@ -12,6 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "system_security_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["system_security_license"],
+}
+
python_library_host {
name: "fsverity_digests_proto_python",
srcs: [
diff --git a/fsverity/OWNERS b/fsverity/OWNERS
new file mode 100644
index 0000000..f9e7b25
--- /dev/null
+++ b/fsverity/OWNERS
@@ -0,0 +1,5 @@
+alanstokes@google.com
+ebiggers@google.com
+jeffv@google.com
+jiyong@google.com
+victorhsieh@google.com
diff --git a/fsverity_init/Android.bp b/fsverity_init/Android.bp
index 39d4e6b..83c5945 100644
--- a/fsverity_init/Android.bp
+++ b/fsverity_init/Android.bp
@@ -10,17 +10,34 @@
cc_binary {
name: "fsverity_init",
srcs: [
- "fsverity_init.cpp",
+ "main.cpp",
],
static_libs: [
"libc++fs",
+ "libfsverity_init",
+ "libmini_keyctl_static",
+ ],
+ shared_libs: [
+ "libbase",
+ "libkeyutils",
+ "liblog",
+ ],
+ cflags: ["-Werror", "-Wall", "-Wextra"],
+}
+
+cc_library {
+ name: "libfsverity_init",
+ srcs: ["fsverity_init.cpp"],
+ static_libs: [
+ "libc++fs",
"libmini_keyctl_static",
],
shared_libs: [
"libbase",
"libkeyutils",
"liblog",
- "liblogwrap",
],
cflags: ["-Werror", "-Wall", "-Wextra"],
+ export_include_dirs: ["include"],
+ recovery_available: true,
}
diff --git a/fsverity_init/OWNERS b/fsverity_init/OWNERS
new file mode 100644
index 0000000..f9e7b25
--- /dev/null
+++ b/fsverity_init/OWNERS
@@ -0,0 +1,5 @@
+alanstokes@google.com
+ebiggers@google.com
+jeffv@google.com
+jiyong@google.com
+victorhsieh@google.com
diff --git a/fsverity_init/fsverity_init.cpp b/fsverity_init/fsverity_init.cpp
index 7bc6022..61f84dd 100644
--- a/fsverity_init/fsverity_init.cpp
+++ b/fsverity_init/fsverity_init.cpp
@@ -81,47 +81,3 @@
LoadKeyFromDirectory(keyring_id, "fsv_system_", "/system/etc/security/fsverity");
LoadKeyFromDirectory(keyring_id, "fsv_product_", "/product/etc/security/fsverity");
}
-
-int main(int argc, const char** argv) {
- if (argc < 2) {
- LOG(ERROR) << "Not enough arguments";
- return -1;
- }
-
- key_serial_t keyring_id = android::GetKeyringId(".fs-verity");
- if (keyring_id < 0) {
- LOG(ERROR) << "Failed to find .fs-verity keyring id";
- return -1;
- }
-
- const std::string_view command = argv[1];
-
- if (command == "--load-verified-keys") {
- LoadKeyFromVerifiedPartitions(keyring_id);
- } else if (command == "--load-extra-key") {
- if (argc != 3) {
- LOG(ERROR) << "--load-extra-key requires <key_name> argument.";
- return -1;
- }
- if (!LoadKeyFromStdin(keyring_id, argv[2])) {
- return -1;
- }
- } else if (command == "--lock") {
- // Requires files backed by fs-verity to be verified with a key in .fs-verity
- // keyring.
- if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
- PLOG(ERROR) << "Failed to enforce fs-verity signature";
- }
-
- if (!android::base::GetBoolProperty("ro.debuggable", false)) {
- if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
- PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
- }
- }
- } else {
- LOG(ERROR) << "Unknown argument(s).";
- return -1;
- }
-
- return 0;
-}
diff --git a/fsverity_init/include/fsverity_init.h b/fsverity_init/include/fsverity_init.h
new file mode 100644
index 0000000..c3bc93b
--- /dev/null
+++ b/fsverity_init/include/fsverity_init.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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 <mini_keyctl_utils.h>
+
+bool LoadKeyFromStdin(key_serial_t keyring_id, const char* keyname);
+void LoadKeyFromFile(key_serial_t keyring_id, const char* keyname, const std::string& path);
+void LoadKeyFromVerifiedPartitions(key_serial_t keyring_id);
diff --git a/fsverity_init/main.cpp b/fsverity_init/main.cpp
new file mode 100644
index 0000000..3f75dca
--- /dev/null
+++ b/fsverity_init/main.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 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 <string>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <fsverity_init.h>
+#include <log/log.h>
+#include <mini_keyctl_utils.h>
+
+int main(int argc, const char** argv) {
+ if (argc < 2) {
+ LOG(ERROR) << "Not enough arguments";
+ return -1;
+ }
+
+ key_serial_t keyring_id = android::GetKeyringId(".fs-verity");
+ if (keyring_id < 0) {
+ LOG(ERROR) << "Failed to find .fs-verity keyring id";
+ return -1;
+ }
+
+ const std::string_view command = argv[1];
+
+ if (command == "--load-verified-keys") {
+ LoadKeyFromVerifiedPartitions(keyring_id);
+ } else if (command == "--load-extra-key") {
+ if (argc != 3) {
+ LOG(ERROR) << "--load-extra-key requires <key_name> argument.";
+ return -1;
+ }
+ if (!LoadKeyFromStdin(keyring_id, argv[2])) {
+ return -1;
+ }
+ } else if (command == "--lock") {
+ // Requires files backed by fs-verity to be verified with a key in .fs-verity
+ // keyring.
+ if (!android::base::WriteStringToFile("1", "/proc/sys/fs/verity/require_signatures")) {
+ PLOG(ERROR) << "Failed to enforce fs-verity signature";
+ }
+
+ if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+ if (keyctl_restrict_keyring(keyring_id, nullptr, nullptr) < 0) {
+ PLOG(ERROR) << "Cannot restrict .fs-verity keyring";
+ }
+ }
+ } else {
+ LOG(ERROR) << "Unknown argument(s).";
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 1cfb4f6..1e9126d 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -19,6 +19,7 @@
#include <iostream>
#include <memory>
#include <string>
+#include <variant>
#include <vector>
#include <base/command_line.h>
diff --git a/keystore2/src/maintenance.rs b/keystore2/src/maintenance.rs
index 3f6cf36..57abc26 100644
--- a/keystore2/src/maintenance.rs
+++ b/keystore2/src/maintenance.rs
@@ -215,6 +215,8 @@
fn migrate_key_namespace(source: &KeyDescriptor, destination: &KeyDescriptor) -> Result<()> {
let caller_uid = ThreadState::get_calling_uid();
+ let migrate_any_key_permission =
+ check_keystore_permission(KeystorePerm::MigrateAnyKey).is_ok();
DB.with(|db| {
let key_id_guard = match source.domain {
@@ -227,9 +229,12 @@
KeyEntryLoadBits::NONE,
caller_uid,
|k, av| {
- check_key_permission(KeyPerm::Use, k, &av)?;
- check_key_permission(KeyPerm::Delete, k, &av)?;
- check_key_permission(KeyPerm::Grant, k, &av)
+ if !migrate_any_key_permission {
+ check_key_permission(KeyPerm::Use, k, &av)?;
+ check_key_permission(KeyPerm::Delete, k, &av)?;
+ check_key_permission(KeyPerm::Grant, k, &av)?;
+ }
+ Ok(())
},
)
})
@@ -245,7 +250,10 @@
};
db.borrow_mut().migrate_key_namespace(key_id_guard, destination, caller_uid, |k| {
- check_key_permission(KeyPerm::Rebind, k, &None)
+ if !migrate_any_key_permission {
+ check_key_permission(KeyPerm::Rebind, k, &None)?;
+ }
+ Ok(())
})
})
}
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index f280341..e6d61b0 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -145,6 +145,10 @@
/// Checked when IKeystoreMaintenance::deleteAllKeys is called.
#[selinux(name = delete_all_keys)]
DeleteAllKeys,
+ /// Checked when migrating any key from any namespace to any other namespace. It was
+ /// introduced for migrating keys when an app leaves a sharedUserId.
+ #[selinux(name = migrate_any_key)]
+ MigrateAnyKey,
}
);
diff --git a/ondevice-signing/VerityUtils.cpp b/ondevice-signing/VerityUtils.cpp
index 2beb7eb..e5a872a 100644
--- a/ondevice-signing/VerityUtils.cpp
+++ b/ondevice-signing/VerityUtils.cpp
@@ -155,15 +155,10 @@
return {};
}
-Result<std::string> enableFsVerity(const std::string& path, const SigningKey& key) {
- unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
- if (!fd.ok()) {
- return ErrnoError() << "Failed to open " << path;
- }
-
- auto digest = createDigest(fd.get());
+Result<std::string> enableFsVerity(int fd, const SigningKey& key) {
+ auto digest = createDigest(fd);
if (!digest.ok()) {
- return Error() << digest.error() << ": " << path;
+ return Error() << digest.error();
}
auto signed_digest = signDigest(key, digest.value());
@@ -176,36 +171,26 @@
return pkcs7_data.error();
}
- auto enabled = enableFsVerity(fd.get(), pkcs7_data.value());
+ auto enabled = enableFsVerity(fd, pkcs7_data.value());
if (!enabled.ok()) {
- return Error() << enabled.error() << ": " << path;
+ return Error() << enabled.error();
}
// Return the root hash as a hex string
return toHex(digest.value());
}
-Result<std::map<std::string, std::string>> addFilesToVerityRecursive(const std::string& path,
- const SigningKey& key) {
- std::map<std::string, std::string> digests;
-
- std::error_code ec;
- auto it = std::filesystem::recursive_directory_iterator(path, ec);
- for (auto end = std::filesystem::recursive_directory_iterator(); it != end; it.increment(ec)) {
- if (it->is_regular_file()) {
- LOG(INFO) << "Adding " << it->path() << " to fs-verity...";
- auto result = enableFsVerity(it->path(), key);
- if (!result.ok()) {
- return result.error();
- }
- digests[it->path()] = *result;
- }
- }
- if (ec) {
- return Error() << "Failed to iterate " << path << ": " << ec.message();
+Result<std::string> enableFsVerity(const std::string& path, const SigningKey& key) {
+ unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+ if (!fd.ok()) {
+ return ErrnoError() << "Failed to open " << path;
}
- return digests;
+ auto enableStatus = enableFsVerity(fd.get(), key);
+ if (!enableStatus.ok()) {
+ return Error() << path << ": " << enableStatus.error();
+ }
+ return enableStatus;
}
Result<std::string> isFileInVerity(int fd) {
@@ -228,7 +213,7 @@
return ErrnoError() << "Failed to open " << path;
}
- auto digest = isFileInVerity(fd);
+ auto digest = isFileInVerity(fd.get());
if (!digest.ok()) {
return Error() << digest.error() << ": " << path;
}
@@ -236,6 +221,39 @@
return digest;
}
+Result<std::map<std::string, std::string>> addFilesToVerityRecursive(const std::string& path,
+ const SigningKey& key) {
+ std::map<std::string, std::string> digests;
+
+ std::error_code ec;
+ auto it = std::filesystem::recursive_directory_iterator(path, ec);
+ for (auto end = std::filesystem::recursive_directory_iterator(); it != end; it.increment(ec)) {
+ if (it->is_regular_file()) {
+ unique_fd fd(TEMP_FAILURE_RETRY(open(it->path().c_str(), O_RDONLY | O_CLOEXEC)));
+ if (!fd.ok()) {
+ return ErrnoError() << "Failed to open " << path;
+ }
+ auto digest = isFileInVerity(fd);
+ if (!digest.ok()) {
+ LOG(INFO) << "Adding " << it->path() << " to fs-verity...";
+ auto result = enableFsVerity(fd, key);
+ if (!result.ok()) {
+ return result.error();
+ }
+ digests[it->path()] = *result;
+ } else {
+ LOG(INFO) << it->path() << " was already in fs-verity.";
+ digests[it->path()] = *digest;
+ }
+ }
+ }
+ if (ec) {
+ return Error() << "Failed to iterate " << path << ": " << ec.message();
+ }
+
+ return digests;
+}
+
Result<std::map<std::string, std::string>> verifyAllFilesInVerity(const std::string& path) {
std::map<std::string, std::string> digests;
std::error_code ec;
diff --git a/ondevice-signing/VerityUtils.h b/ondevice-signing/VerityUtils.h
index 8d8e62c..76b2229 100644
--- a/ondevice-signing/VerityUtils.h
+++ b/ondevice-signing/VerityUtils.h
@@ -25,6 +25,8 @@
android::base::Result<std::map<std::string, std::string>>
verifyAllFilesInVerity(const std::string& path);
+// Note that this function will skip files that are already in fs-verity, and
+// for those files it will return the existing digest.
android::base::Result<std::map<std::string, std::string>>
addFilesToVerityRecursive(const std::string& path, const SigningKey& key);
diff --git a/provisioner/rkp_factory_extraction_tool.cpp b/provisioner/rkp_factory_extraction_tool.cpp
index 2e59dbd..9786c3d 100644
--- a/provisioner/rkp_factory_extraction_tool.cpp
+++ b/provisioner/rkp_factory_extraction_tool.cpp
@@ -77,9 +77,13 @@
uint8_t* writePtr = challenge.data();
while (bytesRemaining > 0) {
int bytesRead = getrandom(writePtr, bytesRemaining, /*flags=*/0);
- if (bytesRead < 0 && errno != EINTR) {
- std::cerr << errno << ": " << strerror(errno) << std::endl;
- exit(-1);
+ if (bytesRead < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ std::cerr << errno << ": " << strerror(errno) << std::endl;
+ exit(-1);
+ }
}
bytesRemaining -= bytesRead;
writePtr += bytesRead;
@@ -158,7 +162,7 @@
auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder);
if (!rkp_service) {
std::cerr << "Unable to get binder object for '" << fullName << "', skipping.";
- return;
+ exit(-1);
}
std::vector<uint8_t> keysToSignMac;