Loading cmds/installd/InstalldNativeService.cpp +0 −152 Original line number Diff line number Diff line Loading @@ -103,11 +103,6 @@ static constexpr const char* PKG_LIB_POSTFIX = "/lib"; static constexpr const char* CACHE_DIR_POSTFIX = "/cache"; static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache"; // 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"; static constexpr const char* kFuseProp = "persist.sys.fuse"; /** Loading Loading @@ -261,12 +256,6 @@ binder::Status checkArgumentPath(const std::optional<std::string>& path) { } \ } #define ASSERT_PAGE_SIZE_4K() { \ if (getpagesize() != kVerityPageSize) { \ return error("FSVerity only supports 4K pages"); \ } \ } #ifdef GRANULAR_LOCKS /** Loading Loading @@ -2972,147 +2961,6 @@ binder::Status InstalldNativeService::deleteOdex(const std::string& packageName, return *_aidl_return == -1 ? error() : ok(); } // This kernel feature is experimental. // TODO: remove local definition once upstreamed #ifndef FS_IOC_ENABLE_VERITY #define FS_IOC_ENABLE_VERITY _IO('f', 133) #define FS_IOC_SET_VERITY_MEASUREMENT _IOW('f', 134, struct fsverity_measurement) #define FS_VERITY_ALG_SHA256 1 struct fsverity_measurement { __u16 digest_algorithm; __u16 digest_size; __u32 reserved1; __u64 reserved2[3]; __u8 digest[]; }; #endif binder::Status InstalldNativeService::installApkVerity(const std::string& packageName, const std::string& filePath, android::base::unique_fd verityInputAshmem, int32_t contentSize) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PACKAGE_NAME(packageName); CHECK_ARGUMENT_PATH(filePath); LOCK_PACKAGE(); if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) { return ok(); } #ifndef NDEBUG ASSERT_PAGE_SIZE_4K(); #endif // TODO: also check fsverity support in the current file system if compiled with DEBUG. // TODO: change ashmem to some temporary file to support huge apk. if (!ashmem_valid(verityInputAshmem.get())) { return error("FD is not an ashmem"); } // 1. Seek to the next page boundary beyond the end of the file. ::android::base::unique_fd wfd(open(filePath.c_str(), O_WRONLY)); if (wfd.get() < 0) { return error("Failed to open " + filePath); } struct stat st; if (fstat(wfd.get(), &st) < 0) { return error("Failed to stat " + filePath); } // fsverity starts from the block boundary. off_t padding = kVerityPageSize - st.st_size % kVerityPageSize; if (padding == kVerityPageSize) { padding = 0; } if (lseek(wfd.get(), st.st_size + padding, SEEK_SET) < 0) { return error("Failed to lseek " + filePath); } // 2. Write everything in the ashmem to the file. Note that allocated // ashmem size is multiple of page size, which is different from the // actual content size. int shmSize = ashmem_get_size_region(verityInputAshmem.get()); if (shmSize < 0) { return error("Failed to get ashmem size: " + std::to_string(shmSize)); } if (contentSize < 0) { return error("Invalid content size: " + std::to_string(contentSize)); } if (contentSize > shmSize) { return error("Content size overflow: " + std::to_string(contentSize) + " > " + std::to_string(shmSize)); } auto data = std::unique_ptr<void, std::function<void (void *)>>( mmap(nullptr, contentSize, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0), [contentSize] (void* ptr) { if (ptr != MAP_FAILED) { munmap(ptr, contentSize); } }); if (data.get() == MAP_FAILED) { return error("Failed to mmap the ashmem"); } char* cursor = reinterpret_cast<char*>(data.get()); int remaining = contentSize; while (remaining > 0) { int ret = TEMP_FAILURE_RETRY(write(wfd.get(), cursor, remaining)); if (ret < 0) { return error("Failed to write to " + filePath + " (" + std::to_string(remaining) + + "/" + std::to_string(contentSize) + ")"); } cursor += ret; remaining -= ret; } wfd.reset(); // 3. Enable fsverity (needs readonly fd. Once it's done, the file becomes immutable. ::android::base::unique_fd rfd(open(filePath.c_str(), O_RDONLY)); if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, nullptr) < 0) { return error("Failed to enable fsverity on " + filePath); } return ok(); } binder::Status InstalldNativeService::assertFsverityRootHashMatches( const std::string& packageName, const std::string& filePath, const std::vector<uint8_t>& expectedHash) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PACKAGE_NAME(packageName); CHECK_ARGUMENT_PATH(filePath); LOCK_PACKAGE(); 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())); } ::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY)); if (fd.get() < 0) { return error("Failed to open " + filePath + ": " + strerror(errno)); } unsigned int buffer_size = sizeof(fsverity_measurement) + kSha256Size; std::vector<char> buffer(buffer_size, 0); fsverity_measurement* config = reinterpret_cast<fsverity_measurement*>(buffer.data()); config->digest_algorithm = FS_VERITY_ALG_SHA256; config->digest_size = kSha256Size; memcpy(config->digest, expectedHash.data(), kSha256Size); if (ioctl(fd.get(), FS_IOC_SET_VERITY_MEASUREMENT, 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::optional<std::string>& volumeUuid, Loading cmds/installd/InstalldNativeService.h +0 −5 Original line number Diff line number Diff line Loading @@ -165,11 +165,6 @@ public: binder::Status deleteOdex(const std::string& packageName, const std::string& apkPath, const std::string& instructionSet, const std::optional<std::string>& outputPath, int64_t* _aidl_return); binder::Status installApkVerity(const std::string& packageName, const std::string& filePath, android::base::unique_fd verityInput, int32_t contentSize); binder::Status assertFsverityRootHashMatches(const std::string& packageName, 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::optional<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return); Loading cmds/installd/binder/android/os/IInstalld.aidl +0 −4 Original line number Diff line number Diff line Loading @@ -97,10 +97,6 @@ interface IInstalld { @utf8InCpp String instructionSet, @utf8InCpp String outputPath); long deleteOdex(@utf8InCpp String packageName, @utf8InCpp String apkPath, @utf8InCpp String instructionSet, @nullable @utf8InCpp String outputPath); void installApkVerity(@utf8InCpp String packageName, @utf8InCpp String filePath, in FileDescriptor verityInput, int contentSize); void assertFsverityRootHashMatches(@utf8InCpp String packageName, @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, Loading data/etc/android.software.window_magnification.xml 0 → 100644 +22 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2022 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. --> <!-- This is the feature indicating device supports window magnifier. And the hand-held and PC platform should support this. --> <permissions> <feature name="android.software.window_magnification" /> </permissions> data/etc/go_handheld_core_hardware.xml +1 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ <feature name="android.software.autofill" /> <feature name="android.software.cant_save_state" /> <feature name="android.software.secure_lock_screen" /> <feature name="android.software.window_magnification" /> <!-- Feature to specify if the device supports adding device admins. --> <feature name="android.software.device_admin" /> Loading Loading
cmds/installd/InstalldNativeService.cpp +0 −152 Original line number Diff line number Diff line Loading @@ -103,11 +103,6 @@ static constexpr const char* PKG_LIB_POSTFIX = "/lib"; static constexpr const char* CACHE_DIR_POSTFIX = "/cache"; static constexpr const char* CODE_CACHE_DIR_POSTFIX = "/code_cache"; // 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"; static constexpr const char* kFuseProp = "persist.sys.fuse"; /** Loading Loading @@ -261,12 +256,6 @@ binder::Status checkArgumentPath(const std::optional<std::string>& path) { } \ } #define ASSERT_PAGE_SIZE_4K() { \ if (getpagesize() != kVerityPageSize) { \ return error("FSVerity only supports 4K pages"); \ } \ } #ifdef GRANULAR_LOCKS /** Loading Loading @@ -2972,147 +2961,6 @@ binder::Status InstalldNativeService::deleteOdex(const std::string& packageName, return *_aidl_return == -1 ? error() : ok(); } // This kernel feature is experimental. // TODO: remove local definition once upstreamed #ifndef FS_IOC_ENABLE_VERITY #define FS_IOC_ENABLE_VERITY _IO('f', 133) #define FS_IOC_SET_VERITY_MEASUREMENT _IOW('f', 134, struct fsverity_measurement) #define FS_VERITY_ALG_SHA256 1 struct fsverity_measurement { __u16 digest_algorithm; __u16 digest_size; __u32 reserved1; __u64 reserved2[3]; __u8 digest[]; }; #endif binder::Status InstalldNativeService::installApkVerity(const std::string& packageName, const std::string& filePath, android::base::unique_fd verityInputAshmem, int32_t contentSize) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PACKAGE_NAME(packageName); CHECK_ARGUMENT_PATH(filePath); LOCK_PACKAGE(); if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) { return ok(); } #ifndef NDEBUG ASSERT_PAGE_SIZE_4K(); #endif // TODO: also check fsverity support in the current file system if compiled with DEBUG. // TODO: change ashmem to some temporary file to support huge apk. if (!ashmem_valid(verityInputAshmem.get())) { return error("FD is not an ashmem"); } // 1. Seek to the next page boundary beyond the end of the file. ::android::base::unique_fd wfd(open(filePath.c_str(), O_WRONLY)); if (wfd.get() < 0) { return error("Failed to open " + filePath); } struct stat st; if (fstat(wfd.get(), &st) < 0) { return error("Failed to stat " + filePath); } // fsverity starts from the block boundary. off_t padding = kVerityPageSize - st.st_size % kVerityPageSize; if (padding == kVerityPageSize) { padding = 0; } if (lseek(wfd.get(), st.st_size + padding, SEEK_SET) < 0) { return error("Failed to lseek " + filePath); } // 2. Write everything in the ashmem to the file. Note that allocated // ashmem size is multiple of page size, which is different from the // actual content size. int shmSize = ashmem_get_size_region(verityInputAshmem.get()); if (shmSize < 0) { return error("Failed to get ashmem size: " + std::to_string(shmSize)); } if (contentSize < 0) { return error("Invalid content size: " + std::to_string(contentSize)); } if (contentSize > shmSize) { return error("Content size overflow: " + std::to_string(contentSize) + " > " + std::to_string(shmSize)); } auto data = std::unique_ptr<void, std::function<void (void *)>>( mmap(nullptr, contentSize, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0), [contentSize] (void* ptr) { if (ptr != MAP_FAILED) { munmap(ptr, contentSize); } }); if (data.get() == MAP_FAILED) { return error("Failed to mmap the ashmem"); } char* cursor = reinterpret_cast<char*>(data.get()); int remaining = contentSize; while (remaining > 0) { int ret = TEMP_FAILURE_RETRY(write(wfd.get(), cursor, remaining)); if (ret < 0) { return error("Failed to write to " + filePath + " (" + std::to_string(remaining) + + "/" + std::to_string(contentSize) + ")"); } cursor += ret; remaining -= ret; } wfd.reset(); // 3. Enable fsverity (needs readonly fd. Once it's done, the file becomes immutable. ::android::base::unique_fd rfd(open(filePath.c_str(), O_RDONLY)); if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, nullptr) < 0) { return error("Failed to enable fsverity on " + filePath); } return ok(); } binder::Status InstalldNativeService::assertFsverityRootHashMatches( const std::string& packageName, const std::string& filePath, const std::vector<uint8_t>& expectedHash) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_PACKAGE_NAME(packageName); CHECK_ARGUMENT_PATH(filePath); LOCK_PACKAGE(); 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())); } ::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY)); if (fd.get() < 0) { return error("Failed to open " + filePath + ": " + strerror(errno)); } unsigned int buffer_size = sizeof(fsverity_measurement) + kSha256Size; std::vector<char> buffer(buffer_size, 0); fsverity_measurement* config = reinterpret_cast<fsverity_measurement*>(buffer.data()); config->digest_algorithm = FS_VERITY_ALG_SHA256; config->digest_size = kSha256Size; memcpy(config->digest, expectedHash.data(), kSha256Size); if (ioctl(fd.get(), FS_IOC_SET_VERITY_MEASUREMENT, 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::optional<std::string>& volumeUuid, Loading
cmds/installd/InstalldNativeService.h +0 −5 Original line number Diff line number Diff line Loading @@ -165,11 +165,6 @@ public: binder::Status deleteOdex(const std::string& packageName, const std::string& apkPath, const std::string& instructionSet, const std::optional<std::string>& outputPath, int64_t* _aidl_return); binder::Status installApkVerity(const std::string& packageName, const std::string& filePath, android::base::unique_fd verityInput, int32_t contentSize); binder::Status assertFsverityRootHashMatches(const std::string& packageName, 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::optional<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return); Loading
cmds/installd/binder/android/os/IInstalld.aidl +0 −4 Original line number Diff line number Diff line Loading @@ -97,10 +97,6 @@ interface IInstalld { @utf8InCpp String instructionSet, @utf8InCpp String outputPath); long deleteOdex(@utf8InCpp String packageName, @utf8InCpp String apkPath, @utf8InCpp String instructionSet, @nullable @utf8InCpp String outputPath); void installApkVerity(@utf8InCpp String packageName, @utf8InCpp String filePath, in FileDescriptor verityInput, int contentSize); void assertFsverityRootHashMatches(@utf8InCpp String packageName, @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, Loading
data/etc/android.software.window_magnification.xml 0 → 100644 +22 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2022 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. --> <!-- This is the feature indicating device supports window magnifier. And the hand-held and PC platform should support this. --> <permissions> <feature name="android.software.window_magnification" /> </permissions>
data/etc/go_handheld_core_hardware.xml +1 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ <feature name="android.software.autofill" /> <feature name="android.software.cant_save_state" /> <feature name="android.software.secure_lock_screen" /> <feature name="android.software.window_magnification" /> <!-- Feature to specify if the device supports adding device admins. --> <feature name="android.software.device_admin" /> Loading