diff options
author | 2018-01-20 15:06:39 -0800 | |
---|---|---|
committer | 2018-01-23 07:47:49 -0800 | |
commit | c6d738a320a612454e6c7588affcfb1f8886dd8c (patch) | |
tree | 6f8b074207a3ea60e4cb004f2b8fe9f25f64de2e | |
parent | 57188c67b60d7d97fd5908ea08d5d558fe3b3abf (diff) |
installd: implement measureFsverityRootHash
Test: Observed to ioctl, will soon integrate with the actual ioctl
Bug: 30972906
Change-Id: I30729abbdc540093d2b33d0451a29c5bbf0fb83d
-rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 40 | ||||
-rw-r--r-- | cmds/installd/InstalldNativeService.h | 2 | ||||
-rw-r--r-- | cmds/installd/binder/android/os/IInstalld.aidl | 1 |
3 files changed, 43 insertions, 0 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 1627756490..bc91285ef4 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -18,6 +18,7 @@ #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER +#include <algorithm> #include <errno.h> #include <fstream> #include <fts.h> @@ -90,6 +91,7 @@ static constexpr const char* IDMAP_SUFFIX = "@idmap"; // fsverity assumes the page size is always 4096. If not, the feature can not be // enabled. static constexpr int kVerityPageSize = 4096; +static constexpr size_t kSha256Size = 32; static constexpr const char* kPropApkVerityMode = "ro.apk_verity.mode"; // NOTE: keep in sync with Installer @@ -2357,6 +2359,14 @@ struct fsverity_set { __u64 flags; }; +struct fsverity_root_hash { + short root_hash_algorithm; + short flags; + __u8 reserved[4]; + __u8 root_hash[64]; +}; + +#define FS_IOC_MEASURE_FSVERITY _IOW('f', 2733, struct fsverity_root_hash) #define FS_IOC_SET_FSVERITY _IOW('f', 2734, struct fsverity_set) #define FSVERITY_FLAG_ENABLED 0x0001 @@ -2423,6 +2433,36 @@ binder::Status InstalldNativeService::installApkVerity(const std::string& filePa return ok(); } +binder::Status InstalldNativeService::assertFsverityRootHashMatches(const std::string& filePath, + const std::vector<uint8_t>& expectedHash) { + ENFORCE_UID(AID_SYSTEM); + if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) { + return ok(); + } + // TODO: also check fsverity support in the current file system if compiled with DEBUG. + if (expectedHash.size() != kSha256Size) { + return error("verity hash size should be " + std::to_string(kSha256Size) + " but is " + + std::to_string(expectedHash.size())); + } + + // TODO(71871109): Validate filePath. + ::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY)); + if (fd.get() < 0) { + return error("Failed to open " + filePath + ": " + strerror(errno)); + } + + struct fsverity_root_hash config; + memset(&config, 0, sizeof(config)); + config.root_hash_algorithm = 0; // SHA256 + memcpy(config.root_hash, expectedHash.data(), std::min(sizeof(config.root_hash), kSha256Size)); + if (ioctl(fd.get(), FS_IOC_MEASURE_FSVERITY, &config) < 0) { + // This includes an expected failure case with no FSVerity setup. It normally happens when + // the apk does not contains the Merkle tree root hash. + return error("Failed to measure fsverity on " + filePath + ": " + strerror(errno)); + } + return ok(); // hashes match +} + binder::Status InstalldNativeService::reconcileSecondaryDexFile( const std::string& dexPath, const std::string& packageName, int32_t uid, const std::vector<std::string>& isas, const std::unique_ptr<std::string>& volumeUuid, diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index cef62cde5e..887a2fc372 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -120,6 +120,8 @@ public: const std::unique_ptr<std::string>& outputPath); binder::Status installApkVerity(const std::string& filePath, const ::android::base::unique_fd& verityInput); + binder::Status assertFsverityRootHashMatches(const std::string& filePath, + const std::vector<uint8_t>& expectedHash); binder::Status reconcileSecondaryDexFile(const std::string& dexPath, const std::string& packageName, int32_t uid, const std::vector<std::string>& isa, const std::unique_ptr<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return); diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl index c819e98d89..3725fc01eb 100644 --- a/cmds/installd/binder/android/os/IInstalld.aidl +++ b/cmds/installd/binder/android/os/IInstalld.aidl @@ -82,6 +82,7 @@ interface IInstalld { void deleteOdex(@utf8InCpp String apkPath, @utf8InCpp String instructionSet, @nullable @utf8InCpp String outputPath); void installApkVerity(@utf8InCpp String filePath, in FileDescriptor verityInput); + void assertFsverityRootHashMatches(@utf8InCpp String filePath, in byte[] expectedHash); boolean reconcileSecondaryDexFile(@utf8InCpp String dexPath, @utf8InCpp String pkgName, int uid, in @utf8InCpp String[] isas, @nullable @utf8InCpp String volume_uuid, |