Allow previously signed fs-verity files.
AddFilesToVerityRecursive() would fail if any of the files considered
was already in fs-verity. This is not desirable in case of partial
compilation, where some files might already have been generated and
signed on a previous boot. Allow such files, because earlier code will
already have verified that their signature matched the signature that we
remember anyway.
Bug: 205276874
Test: atest odsign_e2e_tests
Change-Id: Iaf35607d0054bdcd00501c6102ad629ce9fe7ac3
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);