Add enableFsVerity function in VerityUtils.h
Bug: 218672709
Test: Replace "com.android.sepolicy.cert-release.der" -> "com.android.sepolicy.cert-debug.der" in
selinux.cpp > kSigningCertRelease, then manual tests
Change-Id: I5b1cd99200af2835aab58c2a5354494b74e71abc
diff --git a/ondevice-signing/VerityUtils.cpp b/ondevice-signing/VerityUtils.cpp
index 8ea0727..cd9a1ea 100644
--- a/ondevice-signing/VerityUtils.cpp
+++ b/ondevice-signing/VerityUtils.cpp
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <asm/byteorder.h>
@@ -125,6 +126,19 @@
}
}
};
+
+static Result<void> measureFsVerity(int fd, const fsverity_digest* digest) {
+ if (ioctl(fd, FS_IOC_MEASURE_VERITY, digest) != 0) {
+ if (errno == ENODATA) {
+ return Error() << "File is not in fs-verity";
+ } else {
+ return ErrnoError() << "Failed to FS_IOC_MEASURE_VERITY";
+ }
+ }
+
+ return {};
+}
+
} // namespace
template <typename T> using trailing_unique_ptr = std::unique_ptr<T, DeleteAsPODArray<T>>;
@@ -198,14 +212,12 @@
static Result<std::string> isFileInVerity(int fd) {
auto d = makeUniqueWithTrailingData<fsverity_digest>(FS_VERITY_MAX_DIGEST_SIZE);
d->digest_size = FS_VERITY_MAX_DIGEST_SIZE;
- auto ret = ioctl(fd, FS_IOC_MEASURE_VERITY, d.get());
- if (ret < 0) {
- if (errno == ENODATA) {
- return Error() << "File is not in fs-verity";
- } else {
- return ErrnoError() << "Failed to FS_IOC_MEASURE_VERITY";
- }
+
+ const auto& status = measureFsVerity(fd, d.get());
+ if (!status.ok()) {
+ return status.error();
}
+
return toHex({&d->digest[0], &d->digest[d->digest_size]});
}
@@ -256,6 +268,31 @@
return digests;
}
+Result<void> enableFsVerity(const std::string& path, const std::string& signature_path) {
+ unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+ if (!fd.ok()) {
+ return Error() << "Can't open " << path;
+ }
+
+ std::string signature;
+ android::base::ReadFileToString(signature_path, &signature);
+ std::vector<uint8_t> span = std::vector<uint8_t>(signature.begin(), signature.end());
+
+ const auto& enable = enableFsVerity(fd.get(), span);
+ if (!enable.ok()) {
+ return enable.error();
+ }
+
+ auto digest = makeUniqueWithTrailingData<fsverity_digest>(FS_VERITY_MAX_DIGEST_SIZE);
+ digest->digest_size = FS_VERITY_MAX_DIGEST_SIZE;
+ const auto& measure = measureFsVerity(fd.get(), digest.get());
+ if (!measure.ok()) {
+ return measure.error();
+ }
+
+ return {};
+}
+
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/include/VerityUtils.h b/ondevice-signing/include/VerityUtils.h
index 0650563..e6e49c7 100644
--- a/ondevice-signing/include/VerityUtils.h
+++ b/ondevice-signing/include/VerityUtils.h
@@ -36,6 +36,10 @@
android::base::Result<std::map<std::string, std::string>>
addFilesToVerityRecursive(const std::string& path, const SigningKey& key);
+// Enable verity on the provided file, using the given PKCS7 signature.
+android::base::Result<void> enableFsVerity(const std::string& path,
+ const std::string& signature_path);
+
android::base::Result<void>
verifyAllFilesUsingCompOs(const std::string& directory_path,
const std::map<std::string, std::string>& digests,