diff options
author | 2018-12-06 13:09:06 +0100 | |
---|---|---|
committer | 2019-11-15 07:32:25 -0800 | |
commit | eb84ee8d000762f213b19b874d60785864cc99ed (patch) | |
tree | 336fe7a0fbfba429e60cb994caade802ddfa1ae1 | |
parent | 993e82eec7d79b7cc5a406f740e95aed9f950a99 (diff) |
Remove legacy idmap binary
The idmap tool has been replaced by idmap2. Remove now obsolete code
related to the old binary.
Bug: 118711077
Test: atest OverlayDeviceTests OverlayHostTests
Change-Id: Ie1b8fe6f53ce5308b3a1ee6b9f4719cd830a2ecf
-rw-r--r-- | cmds/idmap/Android.bp | 38 | ||||
-rw-r--r-- | cmds/idmap/create.cpp | 233 | ||||
-rw-r--r-- | cmds/idmap/idmap.cpp | 283 | ||||
-rw-r--r-- | cmds/idmap/idmap.h | 38 | ||||
-rw-r--r-- | cmds/idmap/inspect.cpp | 313 | ||||
-rw-r--r-- | cmds/idmap/scan.cpp | 281 | ||||
-rw-r--r-- | core/java/android/content/res/AssetManager.java | 44 | ||||
-rw-r--r-- | core/jni/android_util_AssetManager.cpp | 102 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/Installer.java | 22 |
9 files changed, 0 insertions, 1354 deletions
diff --git a/cmds/idmap/Android.bp b/cmds/idmap/Android.bp deleted file mode 100644 index ae5d74a47000..000000000000 --- a/cmds/idmap/Android.bp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2012 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. - -cc_binary { - name: "idmap", - - srcs: [ - "idmap.cpp", - "create.cpp", - "scan.cpp", - "inspect.cpp", - ], - - shared_libs: [ - "liblog", - "libutils", - "libandroidfw", - "libcutils", - ], - - cflags: [ - "-Wall", - "-Werror", - "-Wunused", - "-Wunreachable-code", - ], -} diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp deleted file mode 100644 index f415f8f5dd75..000000000000 --- a/cmds/idmap/create.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "idmap.h" - -#include <memory> -#include <androidfw/AssetManager.h> -#include <androidfw/ResourceTypes.h> -#include <androidfw/ZipFileRO.h> -#include <utils/String8.h> - -#include <fcntl.h> -#include <sys/file.h> -#include <sys/stat.h> - -using namespace android; - -namespace { - int get_zip_entry_crc(const char *zip_path, const char *entry_name, uint32_t *crc) - { - std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(zip_path)); - if (zip.get() == NULL) { - return -1; - } - ZipEntryRO entry = zip->findEntryByName(entry_name); - if (entry == NULL) { - return -1; - } - if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, crc)) { - return -1; - } - zip->releaseEntry(entry); - return 0; - } - - int open_idmap(const char *path) - { - int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644)); - if (fd == -1) { - ALOGD("error: open %s: %s\n", path, strerror(errno)); - goto fail; - } - if (fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) { - ALOGD("error: fchmod %s: %s\n", path, strerror(errno)); - goto fail; - } - if (TEMP_FAILURE_RETRY(flock(fd, LOCK_EX)) != 0) { - ALOGD("error: flock %s: %s\n", path, strerror(errno)); - goto fail; - } - - return fd; -fail: - if (fd != -1) { - close(fd); - unlink(path); - } - return -1; - } - - int write_idmap(int fd, const uint32_t *data, size_t size) - { - if (lseek(fd, 0, SEEK_SET) < 0) { - return -1; - } - size_t bytesLeft = size; - while (bytesLeft > 0) { - ssize_t w = TEMP_FAILURE_RETRY(write(fd, data + size - bytesLeft, bytesLeft)); - if (w < 0) { - fprintf(stderr, "error: write: %s\n", strerror(errno)); - return -1; - } - bytesLeft -= static_cast<size_t>(w); - } - return 0; - } - - bool is_idmap_stale_fd(const char *target_apk_path, const char *overlay_apk_path, int idmap_fd) - { - static const size_t N = ResTable::IDMAP_HEADER_SIZE_BYTES; - struct stat st; - if (fstat(idmap_fd, &st) == -1) { - return true; - } - if (st.st_size < static_cast<off_t>(N)) { - // file is empty or corrupt - return true; - } - - char buf[N]; - size_t bytesLeft = N; - if (lseek(idmap_fd, 0, SEEK_SET) < 0) { - return true; - } - for (;;) { - ssize_t r = TEMP_FAILURE_RETRY(read(idmap_fd, buf + N - bytesLeft, bytesLeft)); - if (r < 0) { - return true; - } - bytesLeft -= static_cast<size_t>(r); - if (bytesLeft == 0) { - break; - } - if (r == 0) { - // "shouldn't happen" - return true; - } - } - - uint32_t version, cached_target_crc, cached_overlay_crc; - String8 cached_target_path, cached_overlay_path; - if (!ResTable::getIdmapInfo(buf, N, &version, &cached_target_crc, &cached_overlay_crc, - &cached_target_path, &cached_overlay_path)) { - return true; - } - - if (version != ResTable::IDMAP_CURRENT_VERSION) { - return true; - } - - if (cached_target_path != target_apk_path) { - return true; - } - if (cached_overlay_path != overlay_apk_path) { - return true; - } - - uint32_t actual_target_crc, actual_overlay_crc; - if (get_zip_entry_crc(target_apk_path, AssetManager::RESOURCES_FILENAME, - &actual_target_crc) == -1) { - return true; - } - if (get_zip_entry_crc(overlay_apk_path, AssetManager::RESOURCES_FILENAME, - &actual_overlay_crc) == -1) { - return true; - } - - return cached_target_crc != actual_target_crc || cached_overlay_crc != actual_overlay_crc; - } - - bool is_idmap_stale_path(const char *target_apk_path, const char *overlay_apk_path, - const char *idmap_path) - { - struct stat st; - if (stat(idmap_path, &st) == -1) { - // non-existing idmap is always stale; on other errors, abort idmap generation - return errno == ENOENT; - } - - int idmap_fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY)); - if (idmap_fd == -1) { - return false; - } - bool is_stale = is_idmap_stale_fd(target_apk_path, overlay_apk_path, idmap_fd); - close(idmap_fd); - return is_stale; - } - - int create_idmap(const char *target_apk_path, const char *overlay_apk_path, - uint32_t **data, size_t *size) - { - uint32_t target_crc, overlay_crc; - if (get_zip_entry_crc(target_apk_path, AssetManager::RESOURCES_FILENAME, - &target_crc) == -1) { - return -1; - } - if (get_zip_entry_crc(overlay_apk_path, AssetManager::RESOURCES_FILENAME, - &overlay_crc) == -1) { - return -1; - } - - AssetManager am; - bool b = am.createIdmap(target_apk_path, overlay_apk_path, target_crc, overlay_crc, - data, size); - return b ? 0 : -1; - } - - int create_and_write_idmap(const char *target_apk_path, const char *overlay_apk_path, - int fd, bool check_if_stale) - { - if (check_if_stale) { - if (!is_idmap_stale_fd(target_apk_path, overlay_apk_path, fd)) { - // already up to date -- nothing to do - return 0; - } - } - - uint32_t *data = NULL; - size_t size; - - if (create_idmap(target_apk_path, overlay_apk_path, &data, &size) == -1) { - return -1; - } - - if (write_idmap(fd, data, size) == -1) { - free(data); - return -1; - } - - free(data); - return 0; - } -} - -int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path, - const char *idmap_path) -{ - if (!is_idmap_stale_path(target_apk_path, overlay_apk_path, idmap_path)) { - // already up to date -- nothing to do - return EXIT_SUCCESS; - } - - int fd = open_idmap(idmap_path); - if (fd == -1) { - return EXIT_FAILURE; - } - - int r = create_and_write_idmap(target_apk_path, overlay_apk_path, fd, false); - close(fd); - if (r != 0) { - unlink(idmap_path); - } - return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE; -} - -int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd) -{ - return create_and_write_idmap(target_apk_path, overlay_apk_path, fd, true) == 0 ? - EXIT_SUCCESS : EXIT_FAILURE; -} - -int idmap_verify_fd(const char *target_apk_path, const char *overlay_apk_path, int fd) -{ - return !is_idmap_stale_fd(target_apk_path, overlay_apk_path, fd) ? - EXIT_SUCCESS : EXIT_FAILURE; -} diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp deleted file mode 100644 index 8f86ed8f7d32..000000000000 --- a/cmds/idmap/idmap.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "idmap.h" - -#include <private/android_filesystem_config.h> // for AID_SYSTEM - -#include <stdlib.h> -#include <string.h> - -namespace { - const char *usage = "NAME\n\ - idmap - create or display idmap files\n\ -\n\ -SYNOPSIS \n\ - idmap --help \n\ - idmap --fd target overlay fd \n\ - idmap --path target overlay idmap \n\ - idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\ - dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\ - idmap --inspect idmap \n\ - idmap --verify target overlay fd \n\ -\n\ -DESCRIPTION \n\ - Idmap files play an integral part in the runtime resource overlay framework. An idmap \n\ - file contains a mapping of resource identifiers between overlay package and its target \n\ - package; this mapping is used during resource lookup. Idmap files also act as control \n\ - files by their existence: if not present, the corresponding overlay package is ignored \n\ - when the resource context is created. \n\ -\n\ - Idmap files are stored in /data/resource-cache. For each pair (target package, overlay \n\ - package), there exists exactly one idmap file, or none if the overlay should not be used. \n\ -\n\ -NOMENCLATURE \n\ - target: the original, non-overlay, package. Each target package may be associated with \n\ - any number of overlay packages. \n\ -\n\ - overlay: an overlay package. Each overlay package is associated with exactly one target \n\ - package, specified in the overlay's manifest using the <overlay target=\"...\"/> \n\ - tag. \n\ -\n\ -OPTIONS \n\ - --help: display this help \n\ -\n\ - --fd: create idmap for target package 'target' (path to apk) and overlay package 'overlay' \n\ - (path to apk); write results to file descriptor 'fd' (integer). This invocation \n\ - version is intended to be used by a parent process with higher privileges to call \n\ - idmap in a controlled way: the parent will open a suitable file descriptor, fork, \n\ - drop its privileges and exec. This tool will continue execution without the extra \n\ - privileges, but still have write access to a file it could not have opened on its \n\ - own. \n\ -\n\ - --path: create idmap for target package 'target' (path to apk) and overlay package \n\ - 'overlay' (path to apk); write results to 'idmap' (path). \n\ -\n\ - --scan: non-recursively search directory 'dir-to-scan' (path) for static overlay packages \n\ - with target package 'target-package-name-to-look-for' (package name) present at\n\ - 'path-to-target-apk' (path to apk). For each overlay package found, create an\n\ - idmap file in 'dir-to-hold-idmaps' (path). \n\ -\n\ - --inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\ - debug-friendly format. \n\ -\n\ - --verify: verify if idmap corresponding to file descriptor 'fd' (integer) is made from \n\ - target package 'target' (path to apk) and overlay package 'overlay'. \n\ -\n\ -EXAMPLES \n\ - Create an idmap file: \n\ -\n\ - $ adb shell idmap --path /system/app/target.apk \\ \n\ - /vendor/overlay/overlay.apk \\ \n\ - /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\ -\n\ - Display an idmap file: \n\ -\n\ - $ adb shell idmap --inspect /data/resource-cache/vendor@overlay@overlay.apk@idmap \n\ - SECTION ENTRY VALUE COMMENT \n\ - IDMAP HEADER magic 0x706d6469 \n\ - base crc 0xb65a383f \n\ - overlay crc 0x7b9675e8 \n\ - base path .......... /path/to/target.apk \n\ - overlay path .......... /path/to/overlay.apk \n\ - DATA HEADER target pkg 0x0000007f \n\ - types count 0x00000003 \n\ - DATA BLOCK target type 0x00000002 \n\ - overlay type 0x00000002 \n\ - entry count 0x00000001 \n\ - entry offset 0x00000000 \n\ - entry 0x00000000 drawable/drawable \n\ - DATA BLOCK target type 0x00000003 \n\ - overlay type 0x00000003 \n\ - entry count 0x00000001 \n\ - entry offset 0x00000000 \n\ - entry 0x00000000 xml/integer \n\ - DATA BLOCK target type 0x00000004 \n\ - overlay type 0x00000004 \n\ - entry count 0x00000001 \n\ - entry offset 0x00000000 \n\ - entry 0x00000000 raw/lorem_ipsum \n\ -\n\ - In this example, the overlay package provides three alternative resource values:\n\ - drawable/drawable, xml/integer, and raw/lorem_ipsum \n\ -\n\ -NOTES \n\ - This tool and its expected invocation from installd is modelled on dexopt."; - - bool verify_directory_readable(const char *path) - { - return access(path, R_OK | X_OK) == 0; - } - - bool verify_directory_writable(const char *path) - { - return access(path, W_OK) == 0; - } - - bool verify_file_readable(const char *path) - { - return access(path, R_OK) == 0; - } - - bool verify_root_or_system() - { - uid_t uid = getuid(); - gid_t gid = getgid(); - - return (uid == 0 && gid == 0) || (uid == AID_SYSTEM && gid == AID_SYSTEM); - } - - int maybe_create_fd(const char *target_apk_path, const char *overlay_apk_path, - const char *idmap_str) - { - // anyone (not just root or system) may do --fd -- the file has - // already been opened by someone else on our behalf - - char *endptr; - int idmap_fd = strtol(idmap_str, &endptr, 10); - if (*endptr != '\0') { - fprintf(stderr, "error: failed to parse file descriptor argument %s\n", idmap_str); - return -1; - } - - if (!verify_file_readable(target_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); - return -1; - } - - if (!verify_file_readable(overlay_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); - return -1; - } - - return idmap_create_fd(target_apk_path, overlay_apk_path, idmap_fd); - } - - int maybe_create_path(const char *target_apk_path, const char *overlay_apk_path, - const char *idmap_path) - { - if (!verify_root_or_system()) { - fprintf(stderr, "error: permission denied: not user root or user system\n"); - return -1; - } - - if (!verify_file_readable(target_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); - return -1; - } - - if (!verify_file_readable(overlay_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); - return -1; - } - - return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path); - } - - int maybe_verify_fd(const char *target_apk_path, const char *overlay_apk_path, - const char *idmap_str) - { - char *endptr; - int idmap_fd = strtol(idmap_str, &endptr, 10); - if (*endptr != '\0') { - fprintf(stderr, "error: failed to parse file descriptor argument %s\n", idmap_str); - return -1; - } - - if (!verify_file_readable(target_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); - return -1; - } - - if (!verify_file_readable(overlay_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno)); - return -1; - } - - return idmap_verify_fd(target_apk_path, overlay_apk_path, idmap_fd); - } - - int maybe_scan(const char *target_package_name, const char *target_apk_path, - const char *idmap_dir, const android::Vector<const char *> *overlay_dirs) - { - if (!verify_root_or_system()) { - fprintf(stderr, "error: permission denied: not user root or user system\n"); - return -1; - } - - if (!verify_file_readable(target_apk_path)) { - ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno)); - return -1; - } - - if (!verify_directory_writable(idmap_dir)) { - ALOGD("error: no write access to %s: %s\n", idmap_dir, strerror(errno)); - return -1; - } - - const size_t N = overlay_dirs->size(); - for (size_t i = 0; i < N; i++) { - const char *dir = overlay_dirs->itemAt(i); - if (!verify_directory_readable(dir)) { - ALOGD("error: no read access to %s: %s\n", dir, strerror(errno)); - return -1; - } - } - - return idmap_scan(target_package_name, target_apk_path, idmap_dir, overlay_dirs); - } - - int maybe_inspect(const char *idmap_path) - { - // anyone (not just root or system) may do --inspect - if (!verify_file_readable(idmap_path)) { - ALOGD("error: failed to read idmap %s: %s\n", idmap_path, strerror(errno)); - return -1; - } - return idmap_inspect(idmap_path); - } -} - -int main(int argc, char **argv) -{ -#if 0 - { - char buf[1024]; - buf[0] = '\0'; - for (int i = 0; i < argc; ++i) { - strncat(buf, argv[i], sizeof(buf) - 1); - strncat(buf, " ", sizeof(buf) - 1); - } - ALOGD("%s:%d: uid=%d gid=%d argv=%s\n", __FILE__, __LINE__, getuid(), getgid(), buf); - } -#endif - - if (argc == 2 && !strcmp(argv[1], "--help")) { - printf("%s\n", usage); - return 0; - } - - if (argc == 5 && !strcmp(argv[1], "--fd")) { - return maybe_create_fd(argv[2], argv[3], argv[4]); - } - - if (argc == 5 && !strcmp(argv[1], "--path")) { - return maybe_create_path(argv[2], argv[3], argv[4]); - } - - if (argc == 5 && !strcmp(argv[1], "--verify")) { - return maybe_verify_fd(argv[2], argv[3], argv[4]); - } - - if (argc >= 6 && !strcmp(argv[1], "--scan")) { - android::Vector<const char *> v; - for (int i = 5; i < argc; i++) { - v.push(argv[i]); - } - return maybe_scan(argv[2], argv[3], argv[4], &v); - } - - if (argc == 3 && !strcmp(argv[1], "--inspect")) { - return maybe_inspect(argv[2]); - } - - fprintf(stderr, "Usage: don't use this (cf dexopt usage).\n"); - return EXIT_FAILURE; -} diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h deleted file mode 100644 index 5962108c9f7e..000000000000 --- a/cmds/idmap/idmap.h +++ /dev/null @@ -1,38 +0,0 @@ - -#ifndef _IDMAP_H_ -#define _IDMAP_H_ - -#define LOG_TAG "idmap" - -#include <utils/Log.h> -#include <utils/Vector.h> - -#include <errno.h> -#include <stdio.h> - -#ifndef TEMP_FAILURE_RETRY -// Used to retry syscalls that can return EINTR. -#define TEMP_FAILURE_RETRY(exp) ({ \ - typeof (exp) _rc; \ - do { \ - _rc = (exp); \ - } while (_rc == -1 && errno == EINTR); \ - _rc; }) -#endif - -int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path, - const char *idmap_path); - -int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd); - -int idmap_verify_fd(const char *target_apk_path, const char *overlay_apk_path, int fd); - -// Regarding target_package_name: the idmap_scan implementation should -// be able to extract this from the manifest in target_apk_path, -// simplifying the external API. -int idmap_scan(const char *target_package_name, const char *target_apk_path, - const char *idmap_dir, const android::Vector<const char *> *overlay_dirs); - -int idmap_inspect(const char *idmap_path); - -#endif // _IDMAP_H_ diff --git a/cmds/idmap/inspect.cpp b/cmds/idmap/inspect.cpp deleted file mode 100644 index 20005e2766d8..000000000000 --- a/cmds/idmap/inspect.cpp +++ /dev/null @@ -1,313 +0,0 @@ -#include "idmap.h" - -#include <androidfw/AssetManager.h> -#include <androidfw/ResourceTypes.h> -#include <utils/ByteOrder.h> -#include <utils/String8.h> - -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/stat.h> - -using namespace android; - -namespace { - static const uint32_t IDMAP_MAGIC = 0x504D4449; - static const size_t PATH_LENGTH = 256; - - void printe(const char *fmt, ...); - - class IdmapBuffer { - private: - const char* buf_; - size_t len_; - size_t pos_; - public: - IdmapBuffer() : buf_((const char *)MAP_FAILED), len_(0), pos_(0) {} - - ~IdmapBuffer() { - if (buf_ != MAP_FAILED) { - munmap(const_cast<char*>(buf_), len_); - } - } - - status_t init(const char *idmap_path) { - struct stat st; - int fd; - - if (stat(idmap_path, &st) < 0) { - printe("failed to stat idmap '%s': %s\n", idmap_path, strerror(errno)); - return UNKNOWN_ERROR; - } - len_ = st.st_size; - if ((fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY))) < 0) { - printe("failed to open idmap '%s': %s\n", idmap_path, strerror(errno)); - return UNKNOWN_ERROR; - } - if ((buf_ = (const char*)mmap(NULL, len_, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) { - close(fd); - printe("failed to mmap idmap: %s\n", strerror(errno)); - return UNKNOWN_ERROR; - } - close(fd); - return NO_ERROR; - } - - status_t nextUint32(uint32_t* i) { - if (!buf_) { - printe("failed to read next uint32_t: buffer not initialized\n"); - return UNKNOWN_ERROR; - } - - if (pos_ + sizeof(uint32_t) > len_) { - printe("failed to read next uint32_t: end of buffer reached at pos=0x%08x\n", - pos_); - return UNKNOWN_ERROR; - } - - if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x3) != 0) { - printe("failed to read next uint32_t: not aligned on 4-byte boundary\n"); - return UNKNOWN_ERROR; - } - - *i = dtohl(*reinterpret_cast<const uint32_t*>(buf_ + pos_)); - pos_ += sizeof(uint32_t); - return NO_ERROR; - } - - status_t nextUint16(uint16_t* i) { - if (!buf_) { - printe("failed to read next uint16_t: buffer not initialized\n"); - return UNKNOWN_ERROR; - } - - if (pos_ + sizeof(uint16_t) > len_) { - printe("failed to read next uint16_t: end of buffer reached at pos=0x%08x\n", - pos_); - return UNKNOWN_ERROR; - } - - if ((reinterpret_cast<uintptr_t>(buf_ + pos_) & 0x1) != 0) { - printe("failed to read next uint32_t: not aligned on 2-byte boundary\n"); - return UNKNOWN_ERROR; - } - - *i = dtohs(*reinterpret_cast<const uint16_t*>(buf_ + pos_)); - pos_ += sizeof(uint16_t); - return NO_ERROR; - } - - status_t nextPath(char *b) { - if (!buf_) { - printe("failed to read next path: buffer not initialized\n"); - return UNKNOWN_ERROR; - } - if (pos_ + PATH_LENGTH > len_) { - printe("failed to read next path: end of buffer reached at pos=0x%08x\n", pos_); - return UNKNOWN_ERROR; - } - memcpy(b, buf_ + pos_, PATH_LENGTH); - pos_ += PATH_LENGTH; - return NO_ERROR; - } - }; - - void printe(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - fprintf(stderr, "error: "); - vfprintf(stderr, fmt, ap); - va_end(ap); - } - - void print_header() { - printf("SECTION ENTRY VALUE COMMENT\n"); - } - - void print(const char *section, const char *subsection, uint32_t value, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - printf("%-12s %-12s 0x%08x ", section, subsection, value); - vprintf(fmt, ap); - printf("\n"); - va_end(ap); - } - - void print_path(const char *section, const char *subsection, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - printf("%-12s %-12s .......... ", section, subsection); - vprintf(fmt, ap); - printf("\n"); - va_end(ap); - } - - status_t resource_metadata(const AssetManager& am, uint32_t res_id, - String8 *package, String8 *type, String8 *name) { - const ResTable& rt = am.getResources(); - struct ResTable::resource_name data; - if (!rt.getResourceName(res_id, false, &data)) { - printe("failed to get resource name id=0x%08x\n", res_id); - return UNKNOWN_ERROR; - } - if (package != NULL) { - *package = String8(String16(data.package, data.packageLen)); - } - if (type != NULL) { - *type = String8(String16(data.type, data.typeLen)); - } - if (name != NULL) { - *name = String8(String16(data.name, data.nameLen)); - } - return NO_ERROR; - } - - status_t parse_idmap_header(IdmapBuffer& buf, AssetManager& am) { - uint32_t i; - char path[PATH_LENGTH]; - - status_t err = buf.nextUint32(&i); - if (err != NO_ERROR) { - return err; - } - - if (i != IDMAP_MAGIC) { - printe("not an idmap file: actual magic constant 0x%08x does not match expected magic " - "constant 0x%08x\n", i, IDMAP_MAGIC); - return UNKNOWN_ERROR; - } - - print_header(); - print("IDMAP HEADER", "magic", i, ""); - - err = buf.nextUint32(&i); - if (err != NO_ERROR) { - return err; - } - print("", "version", i, ""); - - err = buf.nextUint32(&i); - if (err != NO_ERROR) { - return err; - } - print("", "base crc", i, ""); - - err = buf.nextUint32(&i); - if (err != NO_ERROR) { - return err; - } - print("", "overlay crc", i, ""); - - err = buf.nextPath(path); - if (err != NO_ERROR) { - // printe done from IdmapBuffer::nextPath - return err; - } - print_path("", "base path", "%s", path); - - if (!am.addAssetPath(String8(path), NULL)) { - printe("failed to add '%s' as asset path\n", path); - return UNKNOWN_ERROR; - } - - err = buf.nextPath(path); - if (err != NO_ERROR) { - // printe done from IdmapBuffer::nextPath - return err; - } - print_path("", "overlay path", "%s", path); - - return NO_ERROR; - } - - status_t parse_data(IdmapBuffer& buf, const AssetManager& am) { - const uint32_t packageId = am.getResources().getBasePackageId(0); - - uint16_t data16; - status_t err = buf.nextUint16(&data16); - if (err != NO_ERROR) { - return err; - } - print("DATA HEADER", "target pkg", static_cast<uint32_t>(data16), ""); - - err = buf.nextUint16(&data16); - if (err != NO_ERROR) { - return err; - } - print("", "types count", static_cast<uint32_t>(data16), ""); - - uint32_t typeCount = static_cast<uint32_t>(data16); - while (typeCount > 0) { - typeCount--; - - err = buf.nextUint16(&data16); - if (err != NO_ERROR) { - return err; - } - const uint32_t targetTypeId = static_cast<uint32_t>(data16); - print("DATA BLOCK", "target type", targetTypeId, ""); - - err = buf.nextUint16(&data16); - if (err != NO_ERROR) { - return err; - } - print("", "overlay type", static_cast<uint32_t>(data16), ""); - - err = buf.nextUint16(&data16); - if (err != NO_ERROR) { - return err; - } - const uint32_t entryCount = static_cast<uint32_t>(data16); - print("", "entry count", entryCount, ""); - - err = buf.nextUint16(&data16); - if (err != NO_ERROR) { - return err; - } - const uint32_t entryOffset = static_cast<uint32_t>(data16); - print("", "entry offset", entryOffset, ""); - - for (uint32_t i = 0; i < entryCount; i++) { - uint32_t data32; - err = buf.nextUint32(&data32); - if (err != NO_ERROR) { - return err; - } - - uint32_t resID = (packageId << 24) | (targetTypeId << 16) | (entryOffset + i); - String8 type; - String8 name; - err = resource_metadata(am, resID, NULL, &type, &name); - if (err != NO_ERROR) { - return err; - } - if (data32 != ResTable_type::NO_ENTRY) { - print("", "entry", data32, "%s/%s", type.string(), name.string()); - } - } - } - - return NO_ERROR; - } -} - -int idmap_inspect(const char *idmap_path) { - IdmapBuffer buf; - if (buf.init(idmap_path) < 0) { - // printe done from IdmapBuffer::init - return EXIT_FAILURE; - } - AssetManager am; - if (parse_idmap_header(buf, am) != NO_ERROR) { - // printe done from parse_idmap_header - return EXIT_FAILURE; - } - if (parse_data(buf, am) != NO_ERROR) { - // printe done from parse_data_header - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp deleted file mode 100644 index 847dda3df91f..000000000000 --- a/cmds/idmap/scan.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#include <dirent.h> -#include <inttypes.h> -#include <sys/file.h> -#include <sys/stat.h> - -#include "idmap.h" - -#include <memory> -#include <androidfw/ResourceTypes.h> -#include <androidfw/StreamingZipInflater.h> -#include <androidfw/ZipFileRO.h> -#include <cutils/properties.h> -#include <private/android_filesystem_config.h> // for AID_SYSTEM -#include <utils/SortedVector.h> -#include <utils/String16.h> -#include <utils/String8.h> - -#define NO_OVERLAY_TAG (-1000) - -using namespace android; - -namespace { - struct Overlay { - Overlay() {} - Overlay(const String8& a, const String8& i, int p) : - apk_path(a), idmap_path(i), priority(p) {} - - bool operator<(Overlay const& rhs) const - { - return rhs.priority > priority; - } - - String8 apk_path; - String8 idmap_path; - int priority; - }; - - bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector) - { - // the file is opened for appending so that it doesn't get truncated - // before we can guarantee mutual exclusion via the flock - FILE* fout = fopen(filename, "a"); - if (fout == NULL) { - return false; - } - - if (TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_EX)) != 0) { - fclose(fout); - return false; - } - - if (TEMP_FAILURE_RETRY(ftruncate(fileno(fout), 0)) != 0) { - TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); - fclose(fout); - return false; - } - - for (size_t i = 0; i < overlayVector.size(); ++i) { - const Overlay& overlay = overlayVector[i]; - fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string()); - } - - TEMP_FAILURE_RETRY(fflush(fout)); - TEMP_FAILURE_RETRY(flock(fileno(fout), LOCK_UN)); - fclose(fout); - - // Make file world readable since Zygote (running as root) will read - // it when creating the initial AssetManger object - const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644 - if (chmod(filename, mode) == -1) { - unlink(filename); - return false; - } - - return true; - } - - String8 flatten_path(const char *path) - { - String16 tmp(path); - tmp.replaceAll('/', '@'); - return String8(tmp); - } - - bool check_property(String16 property, String16 value) { - char propBuf[PROPERTY_VALUE_MAX]; - property_get(String8(property).c_str(), propBuf, NULL); - return String8(value) == propBuf; - } - - int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name, - bool* is_static_overlay) - { - const size_t N = parser.getAttributeCount(); - String16 target; - int priority = -1; - String16 propName = String16(); - String16 propValue = String16(); - for (size_t i = 0; i < N; ++i) { - size_t len; - String16 key(parser.getAttributeName(i, &len)); - if (key == String16("targetPackage")) { - const char16_t *p = parser.getAttributeStringValue(i, &len); - if (p != NULL) { - target = String16(p, len); - } - } else if (key == String16("priority")) { - Res_value v; - if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { - priority = v.data; - if (priority < 0 || priority > 9999) { - return -1; - } - } - } else if (key == String16("isStatic")) { - Res_value v; - if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) { - *is_static_overlay = (v.data != 0); - } - } else if (key == String16("requiredSystemPropertyName")) { - const char16_t *p = parser.getAttributeStringValue(i, &len); - if (p != NULL) { - propName = String16(p, len); - } - } else if (key == String16("requiredSystemPropertyValue")) { - const char16_t *p = parser.getAttributeStringValue(i, &len); - if (p != NULL) { - propValue = String16(p, len); - } - } - } - - // Note that conditional property enablement/exclusion only applies if - // the attribute is present. In its absence, all overlays are presumed enabled. - if (propName.size() > 0 && propValue.size() > 0) { - // if property set & equal to value, then include overlay - otherwise skip - if (!check_property(propName, propValue)) { - return NO_OVERLAY_TAG; - } - } - - if (target == String16(target_package_name)) { - return priority; - } - return NO_OVERLAY_TAG; - } - - int parse_manifest(const void *data, size_t size, const char *target_package_name) - { - ResXMLTree parser; - parser.setTo(data, size); - if (parser.getError() != NO_ERROR) { - ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError()); - return -1; - } - - ResXMLParser::event_code_t type; - bool is_static_overlay = false; - int priority = NO_OVERLAY_TAG; - do { - type = parser.next(); - if (type == ResXMLParser::START_TAG) { - size_t len; - String16 tag(parser.getElementName(&len)); - if (tag == String16("overlay")) { - priority = parse_overlay_tag(parser, target_package_name, &is_static_overlay); - break; - } - } - } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT); - - if (is_static_overlay) { - return priority; - } - return NO_OVERLAY_TAG; - } - - int parse_apk(const char *path, const char *target_package_name) - { - std::unique_ptr<ZipFileRO> zip(ZipFileRO::open(path)); - if (zip.get() == NULL) { - ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path); - return -1; - } - ZipEntryRO entry; - if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) { - ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__); - return -1; - } - uint32_t uncompLen = 0; - uint16_t method; - if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) { - ALOGW("%s: failed to read entry info\n", __FUNCTION__); - return -1; - } - if (method != ZipFileRO::kCompressDeflated) { - ALOGW("%s: cannot handle zip compression method %" PRIu16 "\n", __FUNCTION__, method); - return -1; - } - FileMap *dataMap = zip->createEntryFileMap(entry); - if (dataMap == NULL) { - ALOGW("%s: failed to create FileMap\n", __FUNCTION__); - return -1; - } - char *buf = new char[uncompLen]; - if (NULL == buf) { - ALOGW("%s: failed to allocate %" PRIu32 " byte\n", __FUNCTION__, uncompLen); - delete dataMap; - return -1; - } - StreamingZipInflater inflater(dataMap, uncompLen); - if (inflater.read(buf, uncompLen) < 0) { - ALOGW("%s: failed to inflate %" PRIu32 " byte\n", __FUNCTION__, uncompLen); - delete[] buf; - delete dataMap; - return -1; - } - - int priority = parse_manifest(buf, static_cast<size_t>(uncompLen), target_package_name); - delete[] buf; - delete dataMap; - return priority; - } -} - -int idmap_scan(const char *target_package_name, const char *target_apk_path, - const char *idmap_dir, const android::Vector<const char *> *overlay_dirs) -{ - String8 filename = String8(idmap_dir); - filename.appendPath("overlays.list"); - - SortedVector<Overlay> overlayVector; - const size_t N = overlay_dirs->size(); - for (size_t i = 0; i < N; ++i) { - const char *overlay_dir = overlay_dirs->itemAt(i); - DIR *dir = opendir(overlay_dir); - if (dir == NULL) { - return EXIT_FAILURE; - } - - struct dirent *dirent; - while ((dirent = readdir(dir)) != NULL) { - struct stat st; - char overlay_apk_path[PATH_MAX + 1]; - snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name); - if (stat(overlay_apk_path, &st) < 0) { - continue; - } - if (!S_ISREG(st.st_mode)) { - continue; - } - - int priority = parse_apk(overlay_apk_path, target_package_name); - if (priority < 0) { - continue; - } - - String8 idmap_path(idmap_dir); - idmap_path.appendPath(flatten_path(overlay_apk_path + 1)); - idmap_path.append("@idmap"); - - if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) { - ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n", - target_apk_path, overlay_apk_path, idmap_path.string()); - continue; - } - - Overlay overlay(String8(overlay_apk_path), idmap_path, priority); - overlayVector.add(overlay); - } - - closedir(dir); - } - - if (!writePackagesList(filename.string(), overlayVector)) { - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 070e282a0eb2..32ce117a156c 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -40,16 +40,10 @@ import android.util.TypedValue; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; -import libcore.io.IoUtils; - -import java.io.BufferedReader; import java.io.FileDescriptor; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.channels.FileLock; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; @@ -212,7 +206,6 @@ public final class AssetManager implements AutoCloseable { return; } - try { final ArrayList<ApkAssets> apkAssets = new ArrayList<>(); apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/)); @@ -236,42 +229,6 @@ public final class AssetManager implements AutoCloseable { } /** - * Loads the static runtime overlays declared in /data/resource-cache/overlays.list. - * Throws an exception if the file is corrupt or if loading the APKs referenced by the file - * fails. Returns quietly if the overlays.list file doesn't exist. - * @param outApkAssets The list to fill with the loaded ApkAssets. - */ - private static void loadStaticRuntimeOverlays(ArrayList<ApkAssets> outApkAssets) - throws IOException { - final FileInputStream fis; - try { - fis = new FileInputStream("/data/resource-cache/overlays.list"); - } catch (FileNotFoundException e) { - // We might not have any overlays, this is fine. We catch here since ApkAssets - // loading can also fail with the same exception, which we would want to propagate. - Log.i(TAG, "no overlays.list file found"); - return; - } - - try { - // Acquire a lock so that any idmap scanning doesn't impact the current set. - // The order of this try-with-resources block matters. We must release the lock, and - // then close the file streams when exiting the block. - try (final BufferedReader br = new BufferedReader(new InputStreamReader(fis)); - final FileLock flock = fis.getChannel().lock(0, Long.MAX_VALUE, true /*shared*/)) { - for (String line; (line = br.readLine()) != null; ) { - final String idmapPath = line.split(" ")[1]; - outApkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/)); - } - } - } finally { - // When BufferedReader is closed above, FileInputStream is closed as well. But let's be - // paranoid. - IoUtils.closeQuietly(fis); - } - } - - /** * Return a global shared asset manager that provides access to only * system assets (no application assets). * @hide @@ -1645,7 +1602,6 @@ public final class AssetManager implements AutoCloseable { private static native long nativeAssetGetLength(long assetPtr); private static native long nativeAssetGetRemainingLength(long assetPtr); - private static native void nativeVerifySystemIdmaps(); private static native String[] nativeCreateIdmapsForStaticOverlaysTargetingAndroid(); private static native @Nullable Map nativeGetOverlayableMap(long ptr, @NonNull String packageName); diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 5c4dc2335822..ff596b440867 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -121,107 +121,6 @@ constexpr inline static ApkAssetsCookie JavaCookieToApkAssetsCookie(jint cookie) return cookie > 0 ? static_cast<ApkAssetsCookie>(cookie - 1) : kInvalidCookie; } -// This is called by zygote (running as user root) as part of preloadResources. -static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) { - switch (pid_t pid = fork()) { - case -1: - PLOG(ERROR) << "failed to fork for idmap"; - break; - - // child - case 0: { - struct __user_cap_header_struct capheader; - struct __user_cap_data_struct capdata; - - memset(&capheader, 0, sizeof(capheader)); - memset(&capdata, 0, sizeof(capdata)); - - capheader.version = _LINUX_CAPABILITY_VERSION; - capheader.pid = 0; - - if (capget(&capheader, &capdata) != 0) { - PLOG(ERROR) << "capget"; - exit(1); - } - - capdata.effective = capdata.permitted; - if (capset(&capheader, &capdata) != 0) { - PLOG(ERROR) << "capset"; - exit(1); - } - - if (setgid(AID_SYSTEM) != 0) { - PLOG(ERROR) << "setgid"; - exit(1); - } - - if (setuid(AID_SYSTEM) != 0) { - PLOG(ERROR) << "setuid"; - exit(1); - } - - // Generic idmap parameters - const char* argv[11]; - int argc = 0; - struct stat st; - - memset(argv, 0, sizeof(argv)); - argv[argc++] = AssetManager::IDMAP_BIN; - argv[argc++] = "--scan"; - argv[argc++] = AssetManager::TARGET_PACKAGE_NAME; - argv[argc++] = AssetManager::TARGET_APK_PATH; - argv[argc++] = AssetManager::IDMAP_DIR; - - // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined, - // use VENDOR_OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in - // addition to VENDOR_OVERLAY_DIR. - std::string overlay_theme_path = base::GetProperty(AssetManager::OVERLAY_THEME_DIR_PROPERTY, - ""); - if (!overlay_theme_path.empty()) { - overlay_theme_path = - std::string(AssetManager::VENDOR_OVERLAY_DIR) + "/" + overlay_theme_path; - if (stat(overlay_theme_path.c_str(), &st) == 0) { - argv[argc++] = overlay_theme_path.c_str(); - } - } - - if (stat(AssetManager::VENDOR_OVERLAY_DIR, &st) == 0) { - argv[argc++] = AssetManager::VENDOR_OVERLAY_DIR; - } - - if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) { - argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR; - } - - if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) { - argv[argc++] = AssetManager::SYSTEM_EXT_OVERLAY_DIR; - } - - if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) { - argv[argc++] = AssetManager::ODM_OVERLAY_DIR; - } - - if (stat(AssetManager::OEM_OVERLAY_DIR, &st) == 0) { - argv[argc++] = AssetManager::OEM_OVERLAY_DIR; - } - - // Finally, invoke idmap (if any overlay directory exists) - if (argc > 5) { - execv(AssetManager::IDMAP_BIN, (char* const*)argv); - PLOG(ERROR) << "failed to execv for idmap"; - exit(1); // should never get here - } else { - exit(0); - } - } break; - - // parent - default: - waitpid(pid, nullptr, 0); - break; - } -} - static jobjectArray NativeCreateIdmapsForStaticOverlaysTargetingAndroid(JNIEnv* env, jclass /*clazz*/) { // --input-directory can be given multiple times, but idmap2 expects the directory to exist @@ -1665,7 +1564,6 @@ static const JNINativeMethod gAssetManagerMethods[] = { {"nativeAssetGetRemainingLength", "(J)J", (void*)NativeAssetGetRemainingLength}, // System/idmap related methods. - {"nativeVerifySystemIdmaps", "()V", (void*)NativeVerifySystemIdmaps}, {"nativeCreateIdmapsForStaticOverlaysTargetingAndroid", "()[Ljava/lang/String;", (void*)NativeCreateIdmapsForStaticOverlaysTargetingAndroid}, {"nativeGetOverlayableMap", "(JLjava/lang/String;)Ljava/util/Map;", diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index b3b0029326d5..26cd42daa9f8 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -354,28 +354,6 @@ public class Installer extends SystemService { } } - public void idmap(String targetApkPath, String overlayApkPath, int uid) - throws InstallerException { - if (!checkBeforeRemote()) return; - BlockGuard.getVmPolicy().onPathAccess(targetApkPath); - BlockGuard.getVmPolicy().onPathAccess(overlayApkPath); - try { - mInstalld.idmap(targetApkPath, overlayApkPath, uid); - } catch (Exception e) { - throw InstallerException.from(e); - } - } - - public void removeIdmap(String overlayApkPath) throws InstallerException { - if (!checkBeforeRemote()) return; - BlockGuard.getVmPolicy().onPathAccess(overlayApkPath); - try { - mInstalld.removeIdmap(overlayApkPath); - } catch (Exception e) { - throw InstallerException.from(e); - } - } - public void rmdex(String codePath, String instructionSet) throws InstallerException { assertValidInstructionSet(instructionSet); if (!checkBeforeRemote()) return; |