diff options
-rw-r--r-- | edify/Android.mk | 2 | ||||
-rw-r--r-- | minadbd/Android.mk | 2 | ||||
-rw-r--r-- | otafault/Android.mk | 1 | ||||
-rw-r--r-- | otautil/DirUtil.cpp | 56 | ||||
-rw-r--r-- | otautil/DirUtil.h | 13 | ||||
-rw-r--r-- | roots.cpp | 233 | ||||
-rw-r--r-- | tests/unit/dirutil_test.cpp | 32 | ||||
-rw-r--r-- | uncrypt/Android.mk | 1 | ||||
-rw-r--r-- | updater/install.cpp | 28 |
9 files changed, 121 insertions, 247 deletions
diff --git a/edify/Android.mk b/edify/Android.mk index d8058c16f..ffd54c208 100644 --- a/edify/Android.mk +++ b/edify/Android.mk @@ -34,7 +34,6 @@ LOCAL_MODULE := edify_parser LOCAL_YACCFLAGS := -v LOCAL_CPPFLAGS += -Wno-unused-parameter LOCAL_CPPFLAGS += -Wno-deprecated-register -LOCAL_CLANG := true LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. LOCAL_STATIC_LIBRARIES += libbase @@ -51,7 +50,6 @@ LOCAL_CFLAGS := -Werror LOCAL_CPPFLAGS := -Wno-unused-parameter LOCAL_CPPFLAGS += -Wno-deprecated-register LOCAL_MODULE := libedify -LOCAL_CLANG := true LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. LOCAL_STATIC_LIBRARIES += libbase diff --git a/minadbd/Android.mk b/minadbd/Android.mk index de0b0c890..8d86fd653 100644 --- a/minadbd/Android.mk +++ b/minadbd/Android.mk @@ -15,7 +15,6 @@ LOCAL_SRC_FILES := \ minadbd.cpp \ minadbd_services.cpp \ -LOCAL_CLANG := true LOCAL_MODULE := libminadbd LOCAL_CFLAGS := $(minadbd_cflags) LOCAL_CONLY_FLAGS := -Wimplicit-function-declaration @@ -27,7 +26,6 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) -LOCAL_CLANG := true LOCAL_MODULE := minadbd_test LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_SRC_FILES := fuse_adb_provider_test.cpp diff --git a/otafault/Android.mk b/otafault/Android.mk index ec4cdb365..7b5aab0b8 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -32,7 +32,6 @@ LOCAL_CFLAGS := \ LOCAL_SRC_FILES := config.cpp ota_io.cpp LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libotafault -LOCAL_CLANG := true LOCAL_C_INCLUDES := bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs) diff --git a/otautil/DirUtil.cpp b/otautil/DirUtil.cpp index e08e360c0..ad344dedf 100644 --- a/otautil/DirUtil.cpp +++ b/otautil/DirUtil.cpp @@ -160,59 +160,3 @@ dirCreateHierarchy(const char *path, int mode, } return 0; } - -int -dirUnlinkHierarchy(const char *path) -{ - struct stat st; - DIR *dir; - struct dirent *de; - int fail = 0; - - /* is it a file or directory? */ - if (lstat(path, &st) < 0) { - return -1; - } - - /* a file, so unlink it */ - if (!S_ISDIR(st.st_mode)) { - return unlink(path); - } - - /* a directory, so open handle */ - dir = opendir(path); - if (dir == NULL) { - return -1; - } - - /* recurse over components */ - errno = 0; - while ((de = readdir(dir)) != NULL) { - //TODO: don't blow the stack - char dn[PATH_MAX]; - if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) { - continue; - } - snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name); - if (dirUnlinkHierarchy(dn) < 0) { - fail = 1; - break; - } - errno = 0; - } - /* in case readdir or unlink_recursive failed */ - if (fail || errno < 0) { - int save = errno; - closedir(dir); - errno = save; - return -1; - } - - /* close directory handle */ - if (closedir(dir) < 0) { - return -1; - } - - /* delete target directory */ - return rmdir(path); -} diff --git a/otautil/DirUtil.h b/otautil/DirUtil.h index 85b83c387..beecc1081 100644 --- a/otautil/DirUtil.h +++ b/otautil/DirUtil.h @@ -17,13 +17,8 @@ #ifndef MINZIP_DIRUTIL_H_ #define MINZIP_DIRUTIL_H_ -#include <stdbool.h> #include <utime.h> -#ifdef __cplusplus -extern "C" { -#endif - struct selabel_handle; /* Like "mkdir -p", try to guarantee that all directories @@ -43,12 +38,4 @@ int dirCreateHierarchy(const char *path, int mode, const struct utimbuf *timestamp, bool stripFileName, struct selabel_handle* sehnd); -/* rm -rf <path> - */ -int dirUnlinkHierarchy(const char *path); - -#ifdef __cplusplus -} -#endif - #endif // MINZIP_DIRUTIL_H_ @@ -16,147 +16,140 @@ #include "roots.h" -#include <errno.h> +#include <ctype.h> +#include <fcntl.h> #include <stdlib.h> #include <sys/mount.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> -#include <ctype.h> -#include <fcntl.h> #include <android-base/logging.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> +#include <android-base/unique_fd.h> +#include <cryptfs.h> #include <ext4_utils/wipe.h> #include <fs_mgr.h> #include "common.h" #include "mounts.h" -#include "cryptfs.h" - -static struct fstab *fstab = NULL; -extern struct selabel_handle *sehandle; +static struct fstab* fstab = nullptr; -void load_volume_table() -{ - int i; - int ret; +extern struct selabel_handle* sehandle; - fstab = fs_mgr_read_fstab_default(); - if (!fstab) { - LOG(ERROR) << "failed to read default fstab"; - return; - } +void load_volume_table() { + fstab = fs_mgr_read_fstab_default(); + if (!fstab) { + LOG(ERROR) << "Failed to read default fstab"; + return; + } - ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk"); - if (ret < 0 ) { - LOG(ERROR) << "failed to add /tmp entry to fstab"; - fs_mgr_free_fstab(fstab); - fstab = NULL; - return; - } + int ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk"); + if (ret == -1) { + LOG(ERROR) << "Failed to add /tmp entry to fstab"; + fs_mgr_free_fstab(fstab); + fstab = nullptr; + return; + } - printf("recovery filesystem table\n"); - printf("=========================\n"); - for (i = 0; i < fstab->num_entries; ++i) { - Volume* v = &fstab->recs[i]; - printf(" %d %s %s %s %lld\n", i, v->mount_point, v->fs_type, - v->blk_device, v->length); - } - printf("\n"); + printf("recovery filesystem table\n"); + printf("=========================\n"); + for (int i = 0; i < fstab->num_entries; ++i) { + const Volume* v = &fstab->recs[i]; + printf(" %d %s %s %s %lld\n", i, v->mount_point, v->fs_type, v->blk_device, v->length); + } + printf("\n"); } Volume* volume_for_path(const char* path) { - return fs_mgr_get_entry_for_mount_point(fstab, path); + return fs_mgr_get_entry_for_mount_point(fstab, path); } // Mount the volume specified by path at the given mount_point. int ensure_path_mounted_at(const char* path, const char* mount_point) { - Volume* v = volume_for_path(path); - if (v == NULL) { - LOG(ERROR) << "unknown volume for path [" << path << "]"; - return -1; - } - if (strcmp(v->fs_type, "ramdisk") == 0) { - // the ramdisk is always mounted. - return 0; - } + Volume* v = volume_for_path(path); + if (v == nullptr) { + LOG(ERROR) << "unknown volume for path [" << path << "]"; + return -1; + } + if (strcmp(v->fs_type, "ramdisk") == 0) { + // The ramdisk is always mounted. + return 0; + } - if (!scan_mounted_volumes()) { - LOG(ERROR) << "failed to scan mounted volumes"; - return -1; - } + if (!scan_mounted_volumes()) { + LOG(ERROR) << "Failed to scan mounted volumes"; + return -1; + } - if (!mount_point) { - mount_point = v->mount_point; - } + if (!mount_point) { + mount_point = v->mount_point; + } - MountedVolume* mv = find_mounted_volume_by_mount_point(mount_point); - if (mv) { - // volume is already mounted - return 0; - } + const MountedVolume* mv = find_mounted_volume_by_mount_point(mount_point); + if (mv != nullptr) { + // Volume is already mounted. + return 0; + } - mkdir(mount_point, 0755); // in case it doesn't already exist - - if (strcmp(v->fs_type, "ext4") == 0 || - strcmp(v->fs_type, "squashfs") == 0 || - strcmp(v->fs_type, "vfat") == 0) { - int result = mount(v->blk_device, mount_point, v->fs_type, v->flags, v->fs_options); - if (result == -1 && fs_mgr_is_formattable(v)) { - LOG(ERROR) << "failed to mount " << mount_point << " (" << strerror(errno) - << ") , formatting....."; - bool crypt_footer = fs_mgr_is_encryptable(v) && !strcmp(v->key_loc, "footer"); - if (fs_mgr_do_format(v, crypt_footer) == 0) { - result = mount(v->blk_device, mount_point, v->fs_type, v->flags, v->fs_options); - } else { - PLOG(ERROR) << "failed to format " << mount_point; - return -1; - } - } + mkdir(mount_point, 0755); // in case it doesn't already exist + + if (strcmp(v->fs_type, "ext4") == 0 || strcmp(v->fs_type, "squashfs") == 0 || + strcmp(v->fs_type, "vfat") == 0) { + int result = mount(v->blk_device, mount_point, v->fs_type, v->flags, v->fs_options); + if (result == -1 && fs_mgr_is_formattable(v)) { + PLOG(ERROR) << "Failed to mount " << mount_point << "; formatting"; + bool crypt_footer = fs_mgr_is_encryptable(v) && !strcmp(v->key_loc, "footer"); + if (fs_mgr_do_format(v, crypt_footer) == 0) { + result = mount(v->blk_device, mount_point, v->fs_type, v->flags, v->fs_options); + } else { + PLOG(ERROR) << "Failed to format " << mount_point; + return -1; + } + } - if (result == -1) { - PLOG(ERROR) << "failed to mount " << mount_point; - return -1; - } - return 0; + if (result == -1) { + PLOG(ERROR) << "Failed to mount " << mount_point; + return -1; } + return 0; + } - LOG(ERROR) << "unknown fs_type \"" << v->fs_type << "\" for " << mount_point; - return -1; + LOG(ERROR) << "unknown fs_type \"" << v->fs_type << "\" for " << mount_point; + return -1; } int ensure_path_mounted(const char* path) { - // Mount at the default mount point. - return ensure_path_mounted_at(path, nullptr); + // Mount at the default mount point. + return ensure_path_mounted_at(path, nullptr); } int ensure_path_unmounted(const char* path) { - Volume* v = volume_for_path(path); - if (v == NULL) { - LOG(ERROR) << "unknown volume for path [" << path << "]"; - return -1; - } - if (strcmp(v->fs_type, "ramdisk") == 0) { - // the ramdisk is always mounted; you can't unmount it. - return -1; - } + const Volume* v = volume_for_path(path); + if (v == nullptr) { + LOG(ERROR) << "unknown volume for path [" << path << "]"; + return -1; + } + if (strcmp(v->fs_type, "ramdisk") == 0) { + // The ramdisk is always mounted; you can't unmount it. + return -1; + } - if (!scan_mounted_volumes()) { - LOG(ERROR) << "failed to scan mounted volumes"; - return -1; - } + if (!scan_mounted_volumes()) { + LOG(ERROR) << "Failed to scan mounted volumes"; + return -1; + } - MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); - if (mv == NULL) { - // volume is already unmounted - return 0; - } + MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); + if (mv == nullptr) { + // Volume is already unmounted. + return 0; + } - return unmount_mounted_volume(mv); + return unmount_mounted_volume(mv); } static int exec_cmd(const char* path, char* const argv[]) { @@ -173,6 +166,23 @@ static int exec_cmd(const char* path, char* const argv[]) { return WEXITSTATUS(status); } +static ssize_t get_file_size(int fd, uint64_t reserve_len) { + struct stat buf; + int ret = fstat(fd, &buf); + if (ret) return 0; + + ssize_t computed_size; + if (S_ISREG(buf.st_mode)) { + computed_size = buf.st_size - reserve_len; + } else if (S_ISBLK(buf.st_mode)) { + computed_size = get_block_device_size(fd) - reserve_len; + } else { + computed_size = 0; + } + + return computed_size; +} + int format_volume(const char* volume, const char* directory) { Volume* v = volume_for_path(volume); if (v == NULL) { @@ -212,7 +222,16 @@ int format_volume(const char* volume, const char* directory) { if (v->length != 0) { length = v->length; } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) { - length = -CRYPT_FOOTER_OFFSET; + android::base::unique_fd fd(open(v->blk_device, O_RDONLY)); + if (fd < 0) { + PLOG(ERROR) << "get_file_size: failed to open " << v->blk_device; + return -1; + } + length = get_file_size(fd.get(), CRYPT_FOOTER_OFFSET); + if (length <= 0) { + LOG(ERROR) << "get_file_size: invalid size " << length << " for " << v->blk_device; + return -1; + } } int result; if (strcmp(v->fs_type, "ext4") == 0) { @@ -270,16 +289,6 @@ int format_volume(const char* volume, const char* directory) { result = exec_cmd(e2fsdroid_argv[0], const_cast<char**>(e2fsdroid_argv)); } } else { /* Has to be f2fs because we checked earlier. */ - if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) { - LOG(ERROR) << "format_volume: crypt footer + negative length (" << length - << ") not supported on " << v->fs_type; - return -1; - } - if (length < 0) { - LOG(ERROR) << "format_volume: negative length (" << length - << ") not supported on " << v->fs_type; - return -1; - } char *num_sectors = nullptr; if (length >= 512 && asprintf(&num_sectors, "%zd", length / 512) <= 0) { LOG(ERROR) << "format_volume: failed to create " << v->fs_type @@ -304,7 +313,7 @@ int format_volume(const char* volume, const char* directory) { } int format_volume(const char* volume) { - return format_volume(volume, NULL); + return format_volume(volume, nullptr); } int setup_install_mounts() { @@ -322,12 +331,12 @@ int setup_install_mounts() { if (strcmp(v->mount_point, "/tmp") == 0 || strcmp(v->mount_point, "/cache") == 0) { if (ensure_path_mounted(v->mount_point) != 0) { - LOG(ERROR) << "failed to mount " << v->mount_point; + LOG(ERROR) << "Failed to mount " << v->mount_point; return -1; } } else { if (ensure_path_unmounted(v->mount_point) != 0) { - LOG(ERROR) << "failed to unmount " << v->mount_point; + LOG(ERROR) << "Failed to unmount " << v->mount_point; return -1; } } diff --git a/tests/unit/dirutil_test.cpp b/tests/unit/dirutil_test.cpp index 5e2ae4fb5..e62032c68 100644 --- a/tests/unit/dirutil_test.cpp +++ b/tests/unit/dirutil_test.cpp @@ -116,35 +116,3 @@ TEST(DirUtilTest, create_mode_and_timestamp) { ASSERT_EQ(0, rmdir((prefix + "/a/b").c_str())); ASSERT_EQ(0, rmdir((prefix + "/a").c_str())); } - -TEST(DirUtilTest, unlink_invalid) { - // File doesn't exist. - ASSERT_EQ(-1, dirUnlinkHierarchy("doesntexist")); - - // Nonexistent directory. - TemporaryDir td; - std::string path(td.path); - ASSERT_EQ(-1, dirUnlinkHierarchy((path + "/a").c_str())); - ASSERT_EQ(ENOENT, errno); -} - -TEST(DirUtilTest, unlink_smoke) { - // Unlink a file. - TemporaryFile tf; - ASSERT_EQ(0, dirUnlinkHierarchy(tf.path)); - ASSERT_EQ(-1, access(tf.path, F_OK)); - - TemporaryDir td; - std::string path(td.path); - constexpr mode_t mode = 0700; - ASSERT_EQ(0, mkdir((path + "/a").c_str(), mode)); - ASSERT_EQ(0, mkdir((path + "/a/b").c_str(), mode)); - ASSERT_EQ(0, mkdir((path + "/a/b/c").c_str(), mode)); - ASSERT_EQ(0, mkdir((path + "/a/d").c_str(), mode)); - - // Remove "../a" recursively. - ASSERT_EQ(0, dirUnlinkHierarchy((path + "/a").c_str())); - - // Verify it's gone. - ASSERT_EQ(-1, access((path + "/a").c_str(), F_OK)); -} diff --git a/uncrypt/Android.mk b/uncrypt/Android.mk index 59084b0bb..cb60c721e 100644 --- a/uncrypt/Android.mk +++ b/uncrypt/Android.mk @@ -16,7 +16,6 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_CLANG := true LOCAL_SRC_FILES := uncrypt.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. LOCAL_MODULE := uncrypt diff --git a/updater/install.cpp b/updater/install.cpp index bfe91e7f9..8e54c2e75 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -95,34 +95,6 @@ void uiPrintf(State* _Nonnull state, const char* _Nonnull format, ...) { uiPrint(state, error_msg); } -static bool is_dir(const std::string& dirpath) { - struct stat st; - return stat(dirpath.c_str(), &st) == 0 && S_ISDIR(st.st_mode); -} - -// Create all parent directories of name, if necessary. -static bool make_parents(const std::string& name) { - size_t prev_end = 0; - while (prev_end < name.size()) { - size_t next_end = name.find('/', prev_end + 1); - if (next_end == std::string::npos) { - break; - } - std::string dir_path = name.substr(0, next_end); - if (!is_dir(dir_path)) { - int result = mkdir(dir_path.c_str(), 0700); - if (result != 0) { - PLOG(ERROR) << "failed to mkdir " << dir_path << " when make parents for " << name; - return false; - } - - LOG(INFO) << "created [" << dir_path << "]"; - } - prev_end = next_end; - } - return true; -} - // mount(fs_type, partition_type, location, mount_point) // mount(fs_type, partition_type, location, mount_point, mount_options) |