diff options
author | Michael Bestas <mkbestas@lineageos.org> | 2018-03-25 21:14:41 +0300 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2018-04-01 18:59:39 +0300 |
commit | 6e48da0dd09ba3ccd7c84a147aed502ca9429dc5 (patch) | |
tree | 3b67e11a27f319a945cf2431cda3fb4352e3897b | |
parent | 8dbb46938854fc06a5468c119537fcf67d12fbfe (diff) |
Remove QC releasetools and recovery extensions
* They are outdated and they aren't used by anyone
Change-Id: I93d3f47718a0ce413ff8b4d773d342565544ba27
-rw-r--r-- | recovery/Android.mk | 1 | ||||
-rw-r--r-- | recovery/miniui/Android.mk | 19 | ||||
-rw-r--r-- | recovery/miniui/msm_recovery_ui.cpp | 56 | ||||
-rw-r--r-- | recovery/oem-recovery/Android.mk | 12 | ||||
-rw-r--r-- | recovery/oem-recovery/dec.cpp | 401 | ||||
-rw-r--r-- | recovery/oem-recovery/dec.h | 33 | ||||
-rw-r--r-- | recovery/oem-recovery/gpt-utils.cpp | 782 | ||||
-rw-r--r-- | recovery/oem-recovery/gpt-utils.h | 56 | ||||
-rw-r--r-- | recovery/oem-recovery/oem-updater.cpp | 89 | ||||
-rwxr-xr-x | releasetools.py | 382 |
10 files changed, 0 insertions, 1831 deletions
diff --git a/recovery/Android.mk b/recovery/Android.mk deleted file mode 100644 index 6571161..0000000 --- a/recovery/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) diff --git a/recovery/miniui/Android.mk b/recovery/miniui/Android.mk deleted file mode 100644 index 8754add..0000000 --- a/recovery/miniui/Android.mk +++ /dev/null @@ -1,19 +0,0 @@ -ifeq ($(TARGET_RECOVERY_UI_LIB),librecovery_ui_msm) -ifneq ($(TARGET_SIMULATOR),true) -ifneq ($(filter arm arm64, $(TARGET_ARCH)),) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := librecovery_ui_msm - -LOCAL_MODULE_TAGS := optional - -LOCAL_C_INCLUDES += $(call project-path-for,recovery) - -LOCAL_SRC_FILES += msm_recovery_ui.cpp - -include $(BUILD_STATIC_LIBRARY) -endif # TARGET_ARCH == arm -endif # !TARGET_SIMULATOR -endif diff --git a/recovery/miniui/msm_recovery_ui.cpp b/recovery/miniui/msm_recovery_ui.cpp deleted file mode 100644 index 8f29050..0000000 --- a/recovery/miniui/msm_recovery_ui.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (c) 2015, The Linux Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "device.h" -#include "screen_ui.h" - - -class MSM_Device : public Device -{ -public: - MSM_Device(ScreenRecoveryUI* ui) : Device(ui) {} - - bool PostWipeDevice() { - clear_keys_required = true; - return true; - } - - char const* GetRebootReason() { - if (clear_keys_required) - return "keys clear"; - return ""; - } - -private: - bool clear_keys_required = false; -}; - -Device* make_device() { - return new MSM_Device(new ScreenRecoveryUI); -} diff --git a/recovery/oem-recovery/Android.mk b/recovery/oem-recovery/Android.mk deleted file mode 100644 index 033ac82..0000000 --- a/recovery/oem-recovery/Android.mk +++ /dev/null @@ -1,12 +0,0 @@ -ifneq ($(filter librecovery_updater_msm,$(TARGET_RECOVERY_UPDATER_LIBS)),) -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE_TAGS := optional -LOCAL_C_INCLUDES := $(call project-path-for,recovery) \ - system/core/libsparse \ - $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include -LOCAL_SRC_FILES := gpt-utils.cpp dec.cpp oem-updater.cpp -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr -LOCAL_MODULE := librecovery_updater_msm -include $(BUILD_STATIC_LIBRARY) -endif diff --git a/recovery/oem-recovery/dec.cpp b/recovery/oem-recovery/dec.cpp deleted file mode 100644 index a8b1d2c..0000000 --- a/recovery/oem-recovery/dec.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/mman.h> -#include <linux/qseecom.h> -#include <linux/msm_ion.h> - -/* Service IDs */ -#define SCM_SVC_SSD 0x07 - -/* Service specific command IDs */ -#define SSD_PARSE_MD_ID 0x06 -#define SSD_DECRYPT_IMG_FRAG_ID 0x07 - -/* SSD parsing status messages from TZ */ -#define SSD_PMD_ENCRYPTED 0 -#define SSD_PMD_NOT_ENCRYPTED 1 -#define SSD_PMD_PARSING_INCOMPLETE 6 - -#define SSD_HEADER_MIN_SIZE 128 -#define MULTIPLICATION_FACTOR 2 - -#define SMCMOD_DECRYPT_REQ_OP_METADATA 1 -#define SMCMOD_DECRYPT_REQ_OP_IMG_FRAG 2 - -struct smcmod_decrypt_req { - uint32_t service_id; /* in */ - uint32_t command_id; /* in */ - uint32_t operation; /* in */ - - union { - struct { - uint32_t len; - uint32_t ion_fd; - } metadata; - struct { - uint32_t ctx_id; - uint32_t last_frag; - uint32_t frag_len; - uint32_t ion_fd; - uint32_t offset; - } img_frag; - } request; - - union { - struct { - uint32_t status; - uint32_t ctx_id; - uint32_t end_offset; - } metadata; - struct { - uint32_t status; - } img_frag; - } response; -}; - -#define SMCMOD_IOC_MAGIC 0x97 -#define SMCMOD_IOCTL_DECRYPT_CMD \ - _IOWR(SMCMOD_IOC_MAGIC, 37, struct smcmod_decrypt_req) - -struct ion_buf_handle { - unsigned char *buffer; - uint32_t buffer_len; - int ion_fd; - int ifd_data_fd; - struct ion_handle_data ion_alloc_handle; -}; - -static int -ion_memalloc(struct ion_buf_handle *buf, uint32_t size, uint32_t heap) -{ - struct ion_allocation_data alloc_data; - struct ion_fd_data fd_data; - unsigned char *va; - struct ion_handle_data handle_data; - int ion_fd; - int rc; - - ion_fd = open("/dev/ion", O_RDONLY); - if (ion_fd < 0) { - fprintf(stderr, "Cannot open ION device (%s)\n", strerror(errno)); - return -1; - } - - alloc_data.len = (size + 4095) & ~4095; - alloc_data.align = 4096; - - alloc_data.flags = 0; - alloc_data.heap_id_mask = ION_HEAP(heap); - - /* Set the buffers to be uncached */ - alloc_data.flags = 0; - - rc = ioctl(ion_fd, ION_IOC_ALLOC, &alloc_data); - if (rc) { - fprintf(stderr, "ION buffer allocation failed (%s)\n", - strerror(errno)); - goto alloc_fail; - } - - if (alloc_data.handle) { - fd_data.handle = alloc_data.handle; - } else { - fprintf(stderr, "ION alloc data returned NULL\n"); - rc = -1; - goto alloc_fail; - } - - rc = ioctl(ion_fd, ION_IOC_MAP, &fd_data); - if (rc) { - fprintf(stderr, "ION map call failed(%s)\n", strerror(errno)); - goto ioctl_fail; - } - - va = (unsigned char*)mmap(NULL, alloc_data.len, PROT_READ | PROT_WRITE, - MAP_SHARED, fd_data.fd, 0); - if (va == MAP_FAILED) { - fprintf(stderr, "ION memory map failed (%s)\n", strerror(errno)); - rc = -1; - goto map_fail; - } - - buf->ion_fd = ion_fd; - buf->ifd_data_fd = fd_data.fd; - buf->buffer = va; - buf->ion_alloc_handle.handle = alloc_data.handle; - buf->buffer_len = alloc_data.len; - - memset(buf->buffer, 0, buf->buffer_len); - return 0; - -map_fail: -ioctl_fail: - handle_data.handle = alloc_data.handle; - if (buf->ifd_data_fd) - close(buf->ifd_data_fd); - rc = ioctl(ion_fd, ION_IOC_FREE, &handle_data); - if (rc) - fprintf(stderr, "ION free failed (%s)\n", strerror(errno)); -alloc_fail: - if (ion_fd >= 0) - close(ion_fd); - buf->ion_fd = -1; - return rc; -} - -static int ion_memfree(struct ion_buf_handle *handle) -{ - struct ion_handle_data handle_data; - int ret; - - ret = munmap(handle->buffer, (handle->buffer_len + 4095) & ~4095); - if (ret) - fprintf(stderr, "munmap failed (%s)\n", strerror(errno)); - - handle_data.handle = handle->ion_alloc_handle.handle; - close(handle->ifd_data_fd); - ret = ioctl(handle->ion_fd, ION_IOC_FREE, &handle_data); - if (ret) - fprintf(stderr, "ION free failed (%s)\n", strerror(errno)); - close(handle->ion_fd); - - return ret; -} - -static int ion_buffer_clean_inval(struct ion_buf_handle *buf, uint32_t cmd) -{ - struct ion_flush_data data; - int rc; - - data.fd = buf->ifd_data_fd; - data.vaddr = buf->buffer; - data.length = buf->buffer_len; - data.offset = 0; - data.handle = buf->ion_alloc_handle.handle; - - rc = ioctl(buf->ion_fd, cmd, &data); - if (rc < 0) - fprintf(stderr, "clean_inval cache failed (%s)\n", strerror(errno)); - - return rc; -} - -static int is_encrypted(int smcmod_fd, struct ion_buf_handle *buf, - uint32_t len, uint32_t *ctx_id, uint32_t *end_offset) -{ - struct smcmod_decrypt_req req; - uint32_t status; - int ret; - - req.service_id = SCM_SVC_SSD; - req.command_id = SSD_PARSE_MD_ID; - req.operation = SMCMOD_DECRYPT_REQ_OP_METADATA; - req.request.metadata.len = - (len >= SSD_HEADER_MIN_SIZE) ? SSD_HEADER_MIN_SIZE : len; - req.request.metadata.ion_fd = buf->ifd_data_fd; - - do { - ret = ioctl(smcmod_fd, SMCMOD_IOCTL_DECRYPT_CMD, &req); - if (ret < 0) - fprintf(stderr, "%s: ioctl ret=%d, %s\n", __func__, ret, - strerror(errno)); - - status = req.response.metadata.status; - - if (!ret && (status == SSD_PMD_PARSING_INCOMPLETE)) { - req.request.metadata.len *= MULTIPLICATION_FACTOR; - continue; - } else { - break; - } - } while (1); - - if (!ret) { - if (status == SSD_PMD_ENCRYPTED) { - *ctx_id = req.response.metadata.ctx_id; - *end_offset = req.response.metadata.end_offset; - ret = 1; - } else { - fprintf(stderr, "Image is not encrypted (response status %d)\n", - status); - } - } else { - fprintf(stderr, "%s: call failed\n", __func__); - } - - return ret; -} - -static int decrypt(int smcmod_fd, struct ion_buf_handle *buf, uint32_t len, - uint32_t md_ctx, uint32_t offset) -{ - struct smcmod_decrypt_req req; - int ret; - - req.service_id = SCM_SVC_SSD; - req.command_id = SSD_DECRYPT_IMG_FRAG_ID; - req.operation = SMCMOD_DECRYPT_REQ_OP_IMG_FRAG; - req.request.img_frag.ctx_id = md_ctx; - req.request.img_frag.last_frag = 1; - req.request.img_frag.ion_fd = buf->ifd_data_fd; - req.request.img_frag.frag_len = len - offset; - req.request.img_frag.offset = offset; - - ret = ioctl(smcmod_fd, SMCMOD_IOCTL_DECRYPT_CMD, &req); - if (ret < 0) { - fprintf(stderr, "decrypt ioctl failed (%s)\n", strerror(errno)); - return ret; - } - - return 0; -} - -static int save_file(const char *fname, unsigned char *buf, size_t len) -{ - FILE *file; - size_t written; - - file = fopen(fname, "wb"); - if (!file) { - fprintf(stderr, "Failed to open %s (%s)\n", fname, strerror(errno)); - return -errno; - } - - written = fwrite(buf, len, 1, file); - if (written != 1) { - fclose(file); - fprintf(stderr, "Failed to write %s (%s)\n", fname, strerror(errno)); - return -errno; - } - fflush(file); - fclose(file); - fprintf(stdout, "%s written %d bytes\n", fname, len); - return 0; -} - -int decrypt_image(const char *src_file, const char *dst_file) -{ - int ret = -1; - uint32_t md_ctx = 0, offset = 0; - uint32_t fsize = 0; - FILE *file = NULL; - struct ion_buf_handle ionbuf; - int smcmod_fd = -1; - int qseecom_fd = -1; - size_t read; - - memset(&ionbuf, 0, sizeof(ionbuf)); - ionbuf.ion_fd = -1; - - qseecom_fd = open("/dev/qseecom", O_RDWR); - if (qseecom_fd < 0) { - fprintf(stderr, "Failed to open /dev/qseecom device (%s)\n", - strerror(errno)); - goto exit; - } - - smcmod_fd = open("/dev/smcmod", O_RDWR); - if (smcmod_fd < 0) { - fprintf(stderr, "Failed to open /dev/smcmod device (%s)\n", - strerror(errno)); - goto exit; - } - - file = fopen(src_file, "rb"); - if (!file) { - fprintf(stderr, "Failed to open %s (%s)\n", src_file, strerror(errno)); - goto exit; - } - - fseek(file, 0, SEEK_END); - fsize = ftell(file); - fseek(file, 0, SEEK_SET); - - ret = ion_memalloc(&ionbuf, fsize, ION_PIL1_HEAP_ID); - if (ret) - goto exit; - - read = fread(ionbuf.buffer, fsize, 1, file); - if (read != 1) { - fprintf(stderr, "Failed to read %s (%s)\n", src_file, strerror(errno)); - ret = -errno; - goto exit; - } - - ret = ion_buffer_clean_inval(&ionbuf, ION_IOC_CLEAN_INV_CACHES); - if (ret < 0) - goto exit; - - ret = ioctl(qseecom_fd, QSEECOM_IOCTL_PERF_ENABLE_REQ); - if (ret < 0) - goto exit; - - ret = is_encrypted(smcmod_fd, &ionbuf, fsize, &md_ctx, &offset); - if (ret < 0) - goto exit; - - if (ret == 1) { - fprintf(stdout, "decrypting %s ...\n", src_file); - ret = decrypt(smcmod_fd, &ionbuf, fsize, md_ctx, offset); - if (ret < 0) - goto exit; - - ion_buffer_clean_inval(&ionbuf, ION_IOC_INV_CACHES); - - ret = save_file(dst_file, ionbuf.buffer + offset, fsize - offset); - if (ret < 0) - goto exit; - - fprintf(stdout, "decrypting done!\n"); - } - -exit: - if (ionbuf.ion_fd >= 0) - ion_memfree(&ionbuf); - - if (qseecom_fd >= 0) { - ioctl(qseecom_fd, QSEECOM_IOCTL_PERF_DISABLE_REQ); - close(qseecom_fd); - } - - if (smcmod_fd >= 0) - close(smcmod_fd); - - if (file) - fclose(file); - - return ret; -} diff --git a/recovery/oem-recovery/dec.h b/recovery/oem-recovery/dec.h deleted file mode 100644 index b08f5b2..0000000 --- a/recovery/oem-recovery/dec.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __DEC_H__ -#define __DEC_H__ -int decrypt_image(const char *src_file, const char *dst_file); -#endif diff --git a/recovery/oem-recovery/gpt-utils.cpp b/recovery/oem-recovery/gpt-utils.cpp deleted file mode 100644 index a62f54e..0000000 --- a/recovery/oem-recovery/gpt-utils.cpp +++ /dev/null @@ -1,782 +0,0 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _LARGEFILE64_SOURCE /* enable lseek64() */ - -/****************************************************************************** - * INCLUDE SECTION - ******************************************************************************/ -#include <stdio.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <linux/fs.h> -#include "gpt-utils.h" -#ifdef __cplusplus -extern "C" { -#endif -#include "sparse_crc32.h" -#ifdef __cplusplus -} -#endif - - -/****************************************************************************** - * DEFINE SECTION - ******************************************************************************/ -#define BLK_DEV_FILE "/dev/block/mmcblk0" -#define UFS_DEV_DIR "/dev/block/sda" -#define BOOT_DEV_DIR "/dev/block/bootdevice/by-name" -/* list the names of the backed-up partitions to be swapped */ -#define PTN_SWAP_LIST "sbl1", "rpm", "tz", "aboot", "hyp", "lksecapp", "keymaster", "cmnlib", "cmnlib64", "pmic" -/* extension used for the backup partitions - tzbak, abootbak, etc. */ -#define BAK_PTN_NAME_EXT "bak" - -/* GPT defines */ -#define GPT_SIGNATURE "EFI PART" -#define HEADER_SIZE_OFFSET 12 -#define HEADER_CRC_OFFSET 16 -#define PRIMARY_HEADER_OFFSET 24 -#define BACKUP_HEADER_OFFSET 32 -#define FIRST_USABLE_LBA_OFFSET 40 -#define LAST_USABLE_LBA_OFFSET 48 -#define PENTRIES_OFFSET 72 -#define PARTITION_COUNT_OFFSET 80 -#define PENTRY_SIZE_OFFSET 84 -#define PARTITION_CRC_OFFSET 88 - -#define TYPE_GUID_OFFSET 0 -#define TYPE_GUID_SIZE 16 -#define PTN_ENTRY_SIZE 128 -#define UNIQUE_GUID_OFFSET 16 -#define FIRST_LBA_OFFSET 32 -#define LAST_LBA_OFFSET 40 -#define ATTRIBUTE_FLAG_OFFSET 48 -#define PARTITION_NAME_OFFSET 56 - -#define MAX_GPT_NAME_SIZE 72 -#define MAX_PATH_LEN 255 -#define MAX_LUNS 26 -//This will allow us to get the root lun path from the path to the partition. -//i.e: from /dev/block/sdaXXX get /dev/block/sda. The assumption here is that -//the boot critical luns lie between sda to sdz which is acceptable because -//only user added external disks,etc would lie beyond that limit which do not -//contain partitions that interest us here. -#define PATH_TRUNCATE_LOC 14 - -/****************************************************************************** - * MACROS - ******************************************************************************/ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -#define GET_4_BYTES(ptr) ((uint32_t) *((uint8_t *)(ptr)) | \ - ((uint32_t) *((uint8_t *)(ptr) + 1) << 8) | \ - ((uint32_t) *((uint8_t *)(ptr) + 2) << 16) | \ - ((uint32_t) *((uint8_t *)(ptr) + 3) << 24)) - -#define GET_8_BYTES(ptr) ((uint64_t) *((uint8_t *)(ptr)) | \ - ((uint64_t) *((uint8_t *)(ptr) + 1) << 8) | \ - ((uint64_t) *((uint8_t *)(ptr) + 2) << 16) | \ - ((uint64_t) *((uint8_t *)(ptr) + 3) << 24) | \ - ((uint64_t) *((uint8_t *)(ptr) + 4) << 32) | \ - ((uint64_t) *((uint8_t *)(ptr) + 5) << 40) | \ - ((uint64_t) *((uint8_t *)(ptr) + 6) << 48) | \ - ((uint64_t) *((uint8_t *)(ptr) + 7) << 56)) - -#define PUT_4_BYTES(ptr, y) *((uint8_t *)(ptr)) = (y) & 0xff; \ - *((uint8_t *)(ptr) + 1) = ((y) >> 8) & 0xff; \ - *((uint8_t *)(ptr) + 2) = ((y) >> 16) & 0xff; \ - *((uint8_t *)(ptr) + 3) = ((y) >> 24) & 0xff; - - - -/****************************************************************************** - * TYPES - ******************************************************************************/ -enum gpt_instance { - PRIMARY_GPT = 0, - SECONDARY_GPT -}; - -enum boot_chain { - NORMAL_BOOT = 0, - BACKUP_BOOT -}; - -enum gpt_state { - GPT_OK = 0, - GPT_BAD_SIGNATURE, - GPT_BAD_CRC -}; -//List of LUN's containing boot critical images. -//Required in the case of UFS devices -struct update_data { - char lun_list[MAX_LUNS][MAX_PATH_LEN]; - int num_valid_entries; -}; - -/****************************************************************************** - * FUNCTIONS - ******************************************************************************/ -/** - * ========================================================================== - * - * \brief Read/Write len bytes from/to block dev - * - * \param [in] fd block dev file descriptor (returned from open) - * \param [in] rw RW flag: 0 - read, != 0 - write - * \param [in] offset block dev offset [bytes] - RW start position - * \param [in] buf Pointer to the buffer containing the data - * \param [in] len RW size in bytes. Buf must be at least that big - * - * \return 0 on success - * - * ========================================================================== - */ -static int blk_rw(int fd, int rw, int64_t offset, uint8_t *buf, unsigned len) -{ - int r; - - if (lseek64(fd, offset, SEEK_SET) < 0) { - fprintf(stderr, "block dev lseek64 %lld failed: %s\n", offset, - strerror(errno)); - return -1; - } - - if (rw) - r = write(fd, buf, len); - else - r = read(fd, buf, len); - - if (r < 0) - fprintf(stderr, "block dev %s failed: %s\n", rw ? "write" : "read", - strerror(errno)); - else - r = 0; - - return r; -} - - - -/** - * ========================================================================== - * - * \brief Search within GPT for partition entry with the given name - * or it's backup twin (name-bak). - * - * \param [in] ptn_name Partition name to seek - * \param [in] pentries_start Partition entries array start pointer - * \param [in] pentries_end Partition entries array end pointer - * \param [in] pentry_size Single partition entry size [bytes] - * - * \return First partition entry pointer that matches the name or NULL - * - * ========================================================================== - */ -static uint8_t *gpt_pentry_seek(const char *ptn_name, - const uint8_t *pentries_start, - const uint8_t *pentries_end, - uint32_t pentry_size) -{ - char *pentry_name; - unsigned len = strlen(ptn_name); - - for (pentry_name = (char *) (pentries_start + PARTITION_NAME_OFFSET); - pentry_name < (char *) pentries_end; pentry_name += pentry_size) { - char name8[MAX_GPT_NAME_SIZE / 2]; - unsigned i; - - /* Partition names in GPT are UTF-16 - ignoring UTF-16 2nd byte */ - for (i = 0; i < sizeof(name8); i++) - name8[i] = pentry_name[i * 2]; - if (!strncmp(ptn_name, name8, len)) - if (name8[len] == 0 || !strcmp(&name8[len], BAK_PTN_NAME_EXT)) - return (uint8_t *) (pentry_name - PARTITION_NAME_OFFSET); - } - - return NULL; -} - - - -/** - * ========================================================================== - * - * \brief Swaps boot chain in GPT partition entries array - * - * \param [in] pentries_start Partition entries array start - * \param [in] pentries_end Partition entries array end - * \param [in] pentry_size Single partition entry size - * - * \return 0 on success, 1 if no backup partitions found - * - * ========================================================================== - */ -static int gpt_boot_chain_swap(const uint8_t *pentries_start, - const uint8_t *pentries_end, - uint32_t pentry_size) -{ - const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST }; - - int backup_not_found = 1; - unsigned i; - - for (i = 0; i < ARRAY_SIZE(ptn_swap_list); i++) { - uint8_t *ptn_entry; - uint8_t *ptn_bak_entry; - uint8_t ptn_swap[PTN_ENTRY_SIZE]; - - ptn_entry = gpt_pentry_seek(ptn_swap_list[i], pentries_start, - pentries_end, pentry_size); - if (ptn_entry == NULL) - continue; - - ptn_bak_entry = gpt_pentry_seek(ptn_swap_list[i], - ptn_entry + pentry_size, pentries_end, pentry_size); - if (ptn_bak_entry == NULL) { - fprintf(stderr, "'%s' partition not backup - skip safe update\n", - ptn_swap_list[i]); - continue; - } - - /* swap primary <-> backup partition entries */ - memcpy(ptn_swap, ptn_entry, PTN_ENTRY_SIZE); - memcpy(ptn_entry, ptn_bak_entry, PTN_ENTRY_SIZE); - memcpy(ptn_bak_entry, ptn_swap, PTN_ENTRY_SIZE); - backup_not_found = 0; - } - - return backup_not_found; -} - - - -/** - * ========================================================================== - * - * \brief Sets secondary GPT boot chain - * - * \param [in] fd block dev file descriptor - * \param [in] boot Boot chain to switch to - * - * \return 0 on success - * - * ========================================================================== - */ -static int gpt2_set_boot_chain(int fd, enum boot_chain boot) -{ - int64_t gpt2_header_offset; - uint64_t pentries_start_offset; - uint32_t gpt_header_size; - uint32_t pentry_size; - uint32_t pentries_array_size; - - uint8_t *gpt_header = NULL; - uint8_t *pentries = NULL; - uint32_t crc; - uint32_t blk_size = 0; - int r; - - if (ioctl(fd, BLKSSZGET, &blk_size) != 0) { - fprintf(stderr, "Failed to get GPT device block size: %s\n", - strerror(errno)); - r = -1; - goto EXIT; - } - gpt_header = (uint8_t*)malloc(blk_size); - if (!gpt_header) { - fprintf(stderr, "Failed to allocate memory to hold GPT block\n"); - r = -1; - goto EXIT; - } - gpt2_header_offset = lseek64(fd, 0, SEEK_END) - blk_size; - if (gpt2_header_offset < 0) { - fprintf(stderr, "Getting secondary GPT header offset failed: %s\n", - strerror(errno)); - r = -1; - goto EXIT; - } - - /* Read primary GPT header from block dev */ - r = blk_rw(fd, 0, blk_size, gpt_header, blk_size); - - if (r) { - fprintf(stderr, "Failed to read primary GPT header from blk dev\n"); - goto EXIT; - } - pentries_start_offset = - GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size; - pentry_size = GET_4_BYTES(gpt_header + PENTRY_SIZE_OFFSET); - pentries_array_size = - GET_4_BYTES(gpt_header + PARTITION_COUNT_OFFSET) * pentry_size; - - pentries = (uint8_t *) calloc(1, pentries_array_size); - if (pentries == NULL) { - fprintf(stderr, - "Failed to alloc memory for GPT partition entries array\n"); - r = -1; - goto EXIT; - } - /* Read primary GPT partititon entries array from block dev */ - r = blk_rw(fd, 0, pentries_start_offset, pentries, pentries_array_size); - if (r) - goto EXIT; - - crc = sparse_crc32(0, pentries, pentries_array_size); - if (GET_4_BYTES(gpt_header + PARTITION_CRC_OFFSET) != crc) { - fprintf(stderr, "Primary GPT partition entries array CRC invalid\n"); - r = -1; - goto EXIT; - } - - /* Read secondary GPT header from block dev */ - r = blk_rw(fd, 0, gpt2_header_offset, gpt_header, blk_size); - if (r) - goto EXIT; - - gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET); - pentries_start_offset = - GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size; - - if (boot == BACKUP_BOOT) { - r = gpt_boot_chain_swap(pentries, pentries + pentries_array_size, - pentry_size); - if (r) - goto EXIT; - } - - crc = sparse_crc32(0, pentries, pentries_array_size); - PUT_4_BYTES(gpt_header + PARTITION_CRC_OFFSET, crc); - - /* header CRC is calculated with this field cleared */ - PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0); - crc = sparse_crc32(0, gpt_header, gpt_header_size); - PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc); - - /* Write the modified GPT header back to block dev */ - r = blk_rw(fd, 1, gpt2_header_offset, gpt_header, blk_size); - if (!r) - /* Write the modified GPT partititon entries array back to block dev */ - r = blk_rw(fd, 1, pentries_start_offset, pentries, - pentries_array_size); - -EXIT: - if(gpt_header) - free(gpt_header); - if (pentries) - free(pentries); - return r; -} - - - -/** - * ========================================================================== - * - * \brief Checks GPT state (header signature and CRC) - * - * \param [in] fd block dev file descriptor - * \param [in] gpt GPT header to be checked - * \param [out] state GPT header state - * - * \return 0 on success - * - * ========================================================================== - */ -static int gpt_get_state(int fd, enum gpt_instance gpt, enum gpt_state *state) -{ - int64_t gpt_header_offset; - uint32_t gpt_header_size; - uint8_t *gpt_header = NULL; - uint32_t crc; - uint32_t blk_size = 0; - - *state = GPT_OK; - - if (ioctl(fd, BLKSSZGET, &blk_size) != 0) { - fprintf(stderr, "Failed to get GPT device block size: %s\n", - strerror(errno)); - goto error; - } - fprintf(stderr, "gpt_get_state: Block size is %d\n", - blk_size); - gpt_header = (uint8_t*)malloc(blk_size); - if (!gpt_header) { - fprintf(stderr, "gpt_get_state:Failed to alloc memory for header\n"); - goto error; - } - if (gpt == PRIMARY_GPT) - gpt_header_offset = blk_size; - else { - gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size; - if (gpt_header_offset < 0) { - fprintf(stderr, "gpt_get_state:Seek to end of GPT part fail\n"); - goto error; - } - } - - if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) { - fprintf(stderr, "gpt_get_state: blk_rw failed\n"); - goto error; - } - if (memcmp(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE))) - *state = GPT_BAD_SIGNATURE; - gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET); - - crc = GET_4_BYTES(gpt_header + HEADER_CRC_OFFSET); - /* header CRC is calculated with this field cleared */ - PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0); - if (sparse_crc32(0, gpt_header, gpt_header_size) != crc) - *state = GPT_BAD_CRC; - free(gpt_header); - return 0; -error: - if (gpt_header) - free(gpt_header); - return -1; -} - - - -/** - * ========================================================================== - * - * \brief Sets GPT header state (used to corrupt and fix GPT signature) - * - * \param [in] fd block dev file descriptor - * \param [in] gpt GPT header to be checked - * \param [in] state GPT header state to set (GPT_OK or GPT_BAD_SIGNATURE) - * - * \return 0 on success - * - * ========================================================================== - */ -static int gpt_set_state(int fd, enum gpt_instance gpt, enum gpt_state state) -{ - int64_t gpt_header_offset; - uint32_t gpt_header_size; - uint8_t *gpt_header = NULL; - uint32_t crc; - uint32_t blk_size = 0; - - if (ioctl(fd, BLKSSZGET, &blk_size) != 0) { - fprintf(stderr, "Failed to get GPT device block size: %s\n", - strerror(errno)); - goto error; - } - gpt_header = (uint8_t*)malloc(blk_size); - if (!gpt_header) { - fprintf(stderr, "Failed to alloc memory for gpt header\n"); - goto error; - } - if (gpt == PRIMARY_GPT) - gpt_header_offset = blk_size; - else { - gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size; - if (gpt_header_offset < 0) { - fprintf(stderr, "Failed to seek to end of GPT device\n"); - goto error; - } - } - if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) { - fprintf(stderr, "Failed to r/w gpt header\n"); - goto error; - } - if (state == GPT_OK) - memcpy(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE)); - else if (state == GPT_BAD_SIGNATURE) - *gpt_header = 0; - else { - fprintf(stderr, "gpt_set_state: Invalid state\n"); - goto error; - } - - gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET); - - /* header CRC is calculated with this field cleared */ - PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0); - crc = sparse_crc32(0, gpt_header, gpt_header_size); - PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc); - - if (blk_rw(fd, 1, gpt_header_offset, gpt_header, blk_size)) { - fprintf(stderr, "gpt_set_state: blk write failed\n"); - goto error; - } - return 0; -error: - if(gpt_header) - free(gpt_header); - return -1; -} - -//dev_path is the path to the block device that contains the GPT image that -//needs to be updated. This would be the device which holds one or more critical -//boot partitions and their backups. In the case of EMMC this function would -//be invoked only once on /dev/block/mmcblk1 since it holds the GPT image -//containing all the partitions For UFS devices it could potentially be -//invoked multiple times, once for each LUN containing critical image(s) and -//their backups -int prepare_partitions(enum boot_update_stage stage, const char *dev_path) -{ - int r; - int fd = -1; - enum gpt_state gpt_prim, gpt_second; - enum boot_update_stage internal_stage; - - if (!dev_path) { - fprintf(stderr, "Invalid dev_path passed to prepare_partitions\n"); - r = -1; - goto EXIT; - } - fd = open(dev_path, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Opening '%s' failed: %s\n", BLK_DEV_FILE, - strerror(errno)); - r = -1; - goto EXIT; - } - r = gpt_get_state(fd, PRIMARY_GPT, &gpt_prim) || - gpt_get_state(fd, SECONDARY_GPT, &gpt_second); - if (r) { - fprintf(stderr, "Getting GPT headers state failed\n"); - goto EXIT; - } - - /* These 2 combinations are unexpected and unacceptable */ - if (gpt_prim == GPT_BAD_CRC || gpt_second == GPT_BAD_CRC) { - fprintf(stderr, "GPT headers CRC corruption detected, aborting\n"); - r = -1; - goto EXIT; - } - if (gpt_prim == GPT_BAD_SIGNATURE && gpt_second == GPT_BAD_SIGNATURE) { - fprintf(stderr, "Both GPT headers corrupted, aborting\n"); - r = -1; - goto EXIT; - } - - /* Check internal update stage according GPT headers' state */ - if (gpt_prim == GPT_OK && gpt_second == GPT_OK) - internal_stage = UPDATE_MAIN; - else if (gpt_prim == GPT_BAD_SIGNATURE) - internal_stage = UPDATE_BACKUP; - else if (gpt_second == GPT_BAD_SIGNATURE) - internal_stage = UPDATE_FINALIZE; - else { - fprintf(stderr, "Abnormal GPTs state: primary (%d), secondary (%d), " - "aborting\n", gpt_prim, gpt_second); - r = -1; - goto EXIT; - } - - /* Stage already set - ready for update, exitting */ - if ((int) stage == (int) internal_stage - 1) - goto EXIT; - /* Unexpected stage given */ - if (stage != internal_stage) { - r = -1; - goto EXIT; - } - - switch (stage) { - case UPDATE_MAIN: - r = gpt2_set_boot_chain(fd, BACKUP_BOOT); - if (r) { - if (r < 0) - fprintf(stderr, - "Setting secondary GPT to backup boot failed\n"); - /* No backup partitions - do not corrupt GPT, do not flag error */ - else - r = 0; - goto EXIT; - } - - r = gpt_set_state(fd, PRIMARY_GPT, GPT_BAD_SIGNATURE); - if (r) { - fprintf(stderr, "Corrupting primary GPT header failed\n"); - goto EXIT; - } - - break; - case UPDATE_BACKUP: - r = gpt_set_state(fd, PRIMARY_GPT, GPT_OK); - if (r) { - fprintf(stderr, "Fixing primary GPT header failed\n"); - goto EXIT; - } - - r = gpt_set_state(fd, SECONDARY_GPT, GPT_BAD_SIGNATURE); - if (r) { - fprintf(stderr, "Corrupting secondary GPT header failed\n"); - goto EXIT; - } - - break; - case UPDATE_FINALIZE: - r = gpt2_set_boot_chain(fd, NORMAL_BOOT); - if (r < 0) { - fprintf(stderr, "Setting secondary GPT to normal boot failed\n"); - goto EXIT; - } - - r = gpt_set_state(fd, SECONDARY_GPT, GPT_OK); - if (r) { - fprintf(stderr, "Fixing secondary GPT header failed\n"); - goto EXIT; - } - - break; - default:; - } - -EXIT: - if (fd >= 0) { - fsync(fd); - close(fd); - } - return r; -} - -int add_lun_to_update_list(char *lun_path, struct update_data *dat) -{ - int i = 0; - struct stat st; - if (!lun_path || !dat){ - fprintf(stderr, "Invalid data passed to add_lun_to_update_list"); - return -1; - } - if (stat(lun_path, &st)) { - fprintf(stderr, "Unable to access %s. Skipping adding to list", - lun_path); - return -1; - } - if (dat->num_valid_entries == 0) { - fprintf(stderr, "Copying %s into lun_list[%d]\n", - lun_path, - i); - strlcpy(dat->lun_list[0], lun_path, - MAX_PATH_LEN * sizeof(char)); - dat->num_valid_entries = 1; - } else { - for (i = 0; (i < dat->num_valid_entries) && - (dat->num_valid_entries < MAX_LUNS - 1); i++) { - //Check if the current LUN is not already part - //of the lun list - if (!strncmp(lun_path,dat->lun_list[i], - strlen(dat->lun_list[i]))) { - //LUN already in list..Return - return 0; - } - } - fprintf(stderr, "Copying %s into lun_list[%d]\n", - lun_path, - dat->num_valid_entries); - //Add LUN path lun list - strlcpy(dat->lun_list[dat->num_valid_entries], lun_path, - MAX_PATH_LEN * sizeof(char)); - dat->num_valid_entries++; - } - return 0; -} - -int prepare_boot_update(enum boot_update_stage stage) -{ - int r, fd; - int is_ufs = 0; - struct stat ufs_dir_stat; - struct update_data data; - int rcode = 0; - int i = 0; - int is_error = 0; - const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST }; - //Holds /dev/block/bootdevice/by-name/*bak entry - char buf[MAX_PATH_LEN] = {0}; - //Holds the resolved path of the symlink stored in buf - char real_path[MAX_PATH_LEN] = {0}; - - if(stat(UFS_DEV_DIR, &ufs_dir_stat)) { - is_ufs = 0; - } else { - fprintf(stderr, "UFS device detected\n"); - is_ufs = 1; - } - if (!is_ufs) { - //emmc device. Just pass in path to mmcblk0 - return prepare_partitions(stage, BLK_DEV_FILE); - } else { - //Now we need to find the list of LUNs over - //which the boot critical images are spread - //and set them up for failsafe updates.To do - //this we find out where the symlinks for the - //each of the paths under - ///dev/block/bootdevice/by-name/PTN_SWAP_LIST - //actually point to. - memset(&data, '\0', sizeof(struct update_data)); - for (i=0; i < ARRAY_SIZE(ptn_swap_list); i++) { - snprintf(buf, sizeof(buf), - "%s/%sbak", - BOOT_DEV_DIR, - ptn_swap_list[i]); - fprintf(stderr, "Attempting to process %s\n", buf); - if (stat(buf, &ufs_dir_stat)) { - fprintf(stderr, "%s not present. Skipping\n", - buf); - continue; - } - if (readlink(buf, real_path, sizeof(real_path)) < 0) - { - fprintf(stderr, "readlink error. Skipping %s", - strerror(errno)); - } else { - real_path[PATH_TRUNCATE_LOC] = '\0'; - add_lun_to_update_list(real_path, &data); - } - memset(buf, '\0', sizeof(buf)); - memset(real_path, '\0', sizeof(real_path)); - } - for (i=0; i < data.num_valid_entries; i++) { - fprintf(stderr, "Preparing %s for update stage %d\n", - data.lun_list[i], - stage); - rcode = prepare_partitions(stage, data.lun_list[i]); - if (rcode != 0) - { - fprintf(stderr, "Failed to prepare %s.Continuing..\n", - data.lun_list[i]); - is_error = 1; - } - } - } - if (is_error) - return -1; - return 0; -} diff --git a/recovery/oem-recovery/gpt-utils.h b/recovery/oem-recovery/gpt-utils.h deleted file mode 100644 index 93a7c94..0000000 --- a/recovery/oem-recovery/gpt-utils.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __GPT_UTILS_H__ -#define __GPT_UTILS_H__ -#ifdef __cplusplus -extern "C" { -#endif -#include <unistd.h> -#include <stdlib.h> -/****************************************************************************** - * TYPES - ******************************************************************************/ -enum boot_update_stage { - UPDATE_MAIN = 1, - UPDATE_BACKUP, - UPDATE_FINALIZE -}; - - - -/****************************************************************************** - * FUNCTION PROTOTYPES - ******************************************************************************/ -int prepare_boot_update(enum boot_update_stage stage); - -#ifdef __cplusplus -} -#endif -#endif /* __GPT_UTILS_H__ */ diff --git a/recovery/oem-recovery/oem-updater.cpp b/recovery/oem-recovery/oem-updater.cpp deleted file mode 100644 index 4a6c8b4..0000000 --- a/recovery/oem-recovery/oem-updater.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "edify/expr.h" -#include "dec.h" -#include "gpt-utils.h" - -Value* DecryptFn(const char* name, State* state, int argc, Expr* argv[]) { - int rc = -1; - char *src_file, *dst_file; - - if (argc != 2) - return ErrorAbort(state, "%s expects 2 args, got %d", name, argc); - - if (ReadArgs(state, argv, 2, &src_file, &dst_file)) - return NULL; - - rc = decrypt_image(src_file, dst_file); - - free(src_file); - free(dst_file); - - return StringValue(strdup(rc >= 0 ? "t" : "")); -} - -Value* BootUpdateFn(const char* name, State* state, int argc, Expr* argv[]) -{ - int rc = 0; - char *stageStr; - enum boot_update_stage stage; - - if (argc != 1) - return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc); - - if (ReadArgs(state, argv, 1, &stageStr)) - return NULL; - - if (!strcmp(stageStr, "main")) - stage = UPDATE_MAIN; - else if (!strcmp(stageStr, "backup")) - stage = UPDATE_BACKUP; - else if (!strcmp(stageStr, "finalize")) - stage = UPDATE_FINALIZE; - else { - fprintf(stderr, "Unrecognized boot update stage, exitting\n"); - rc = -1; - } - - free(stageStr); - - if (!rc) - rc = prepare_boot_update(stage); - - return StringValue(strdup(rc ? "" : "t")); -} - -void Register_librecovery_updater_msm() { - RegisterFunction("msm.decrypt", DecryptFn); - RegisterFunction("msm.boot_update", BootUpdateFn); -} diff --git a/releasetools.py b/releasetools.py deleted file mode 100755 index 4dc95d8..0000000 --- a/releasetools.py +++ /dev/null @@ -1,382 +0,0 @@ -# Copyright (C) 2009 The Android Open Source Project -# Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. -# -# 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. - -"""Emit commands needed for QCOM devices during OTA installation -(installing the radio image).""" - -import common -import re - - -bootImages = {} -binImages = {} -fwImages = {} -imgImages = {} - -# Parse filesmap file containing firmware residing places -def LoadFilesMap(zip, name="RADIO/filesmap"): - try: - data = zip.read(name) - except KeyError: - print "Warning: could not find %s in %s." % (name, zip) - data = "" - d = {} - for line in data.split("\n"): - line = line.strip() - if not line or line.startswith("#"): - continue - pieces = line.split() - if not (len(pieces) == 2): - raise ValueError("malformed filesmap line: \"%s\"" % (line,)) - d[pieces[0]] = pieces[1] - return d - - -# Read firmware images from target files zip -def GetRadioFiles(z): - out = {} - for info in z.infolist(): - f = info.filename - if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")): - fn = f[6:] - if fn.startswith("filesmap"): - continue - data = z.read(f) - out[fn] = common.File(f, data) - return out - - -# Get firmware residing place from filesmap -def GetFileDestination(fn, filesmap): - # if file is encoded disregard the .enc extention - if fn.endswith('.enc'): - fn = fn[:-4] - - # get backup destination as well if present - backup = None - if fn + ".bak" in filesmap: - backup = filesmap[fn + ".bak"] - - # If full filename is not specified in filesmap get only the name part - # and look for this token - if fn not in filesmap: - fn = fn.split(".")[0] + ".*" - if fn not in filesmap: - print "warning radio-update: '%s' not found in filesmap" % (fn) - return None, backup - return filesmap[fn], backup - - -# Separate image types as each type needs different handling -def SplitFwTypes(files): - boot = {} - bin = {} - fw = {} - img = {} - - for f in files: - extIdx = -1 - dotSeparated = f.split(".") - while True: - if dotSeparated[extIdx] != 'p' and dotSeparated[extIdx] != 'enc': - break - extIdx -= 1 - - if dotSeparated[extIdx] == 'mbn' or dotSeparated[extIdx] == 'elf': - boot[f] = files[f] - elif dotSeparated[extIdx] == 'bin': - bin[f] = files[f] - elif dotSeparated[extIdx] == 'img': - img[f] = files[f] - else: - fw[f] = files[f] - return boot, bin, fw, img - - -# Prepare radio-update files and verify them -def OTA_VerifyEnd(info, api_version, target_zip, source_zip=None): - if api_version < 3: - print "warning radio-update: no support for api_version less than 3" - return False - - print "Loading radio filesmap..." - filesmap = LoadFilesMap(target_zip) - if filesmap == {}: - print "warning radio-update: no or invalid filesmap file found" - return False - - print "Loading radio target..." - tgt_files = GetRadioFiles(target_zip) - if tgt_files == {}: - print "warning radio-update: no radio images in input target_files" - return False - - src_files = None - if source_zip is not None: - print "Loading radio source..." - src_files = GetRadioFiles(source_zip) - - update_list = {} - largest_source_size = 0 - - print "Preparing radio-update files..." - for fn in tgt_files: - dest, destBak = GetFileDestination(fn, filesmap) - if dest is None: - continue - - tf = tgt_files[fn] - sf = None - if src_files is not None: - sf = src_files.get(fn, None) - - full = sf is None or fn.endswith('.enc') - if not full: - # no difference - skip this file - if tf.sha1 == sf.sha1: - continue - d = common.Difference(tf, sf) - _, _, d = d.ComputePatch() - # no difference - skip this file - if d is None: - continue - # if patch is almost as big as the file - don't bother patching - full = len(d) > tf.size * common.OPTIONS.patch_threshold - if not full: - f = "patch/firmware-update/" + fn + ".p" - common.ZipWriteStr(info.output_zip, f, d) - update_list[f] = (dest, destBak, tf, sf) - largest_source_size = max(largest_source_size, sf.size) - if full: - f = "firmware-update/" + fn - common.ZipWriteStr(info.output_zip, f, tf.data) - update_list[f] = (dest, destBak, None, None) - - global bootImages - global binImages - global fwImages - global imgImages - bootImages, binImages, fwImages, imgImages = SplitFwTypes(update_list) - - # If there are incremental patches verify them - if largest_source_size != 0: - info.script.Comment("---- radio update verification ----") - info.script.Print("Verifying radio-update...") - - for f in bootImages: - dest, destBak, tf, sf = bootImages[f] - # Not incremental - if sf is None: - continue - info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % - (dest, sf.size, sf.sha1, tf.size, tf.sha1)) - if destBak is not None: - info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % - (destBak, sf.size, sf.sha1, tf.size, tf.sha1)) - for f in binImages: - dest, destBak, tf, sf = binImages[f] - # Not incremental - if sf is None: - continue - info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % - (dest, sf.size, sf.sha1, tf.size, tf.sha1)) - last_mounted = "" - for f in fwImages: - dest, destBak, tf, sf = fwImages[f] - # Not incremental - if sf is None: - continue - # Get the filename without the path and the patch (.p) extention - f = f.split("/")[-1][:-2] - # Parse filesmap destination paths for "/dev/" pattern in the beginng. - # This would mean that the file must be written to block device - - # fs mount needed - if dest.startswith("/dev/"): - if last_mounted != dest: - info.script.AppendExtra('unmount("/firmware");') - info.script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' % - (dest)) - last_mounted = dest - dest = "/firmware/image/" + f - else: - dest = dest + "/" + f - info.script.PatchCheck(dest, tf.sha1, sf.sha1) - for f in imgImages: - dest, tf, sf = imgImages[f] - # Not incremental - if sf is None: - continue - info.script.PatchCheck("EMMC:%s:%d:%s:%d:%s" % - (dest, sf.size, sf.sha1, tf.size, tf.sha1)) - last_mounted = "" - - info.script.CacheFreeSpaceCheck(largest_source_size) - return True - - -def FullOTA_Assertions(info): - #TODO: Implement device specific asserstions. - return - - -def IncrementalOTA_Assertions(info): - #TODO: Implement device specific asserstions. - return - - -def IncrementalOTA_VerifyEnd(info): - OTA_VerifyEnd(info, info.target_version, info.target_zip, info.source_zip) - return - - -# This function handles only non-HLOS whole partition images -def InstallRawImage(script, f, dest, tf, sf): - if f.endswith('.p'): - script.ApplyPatch("EMMC:%s:%d:%s:%d:%s" % - (dest, sf.size, sf.sha1, tf.size, tf.sha1), - "-", tf.size, tf.sha1, sf.sha1, f) - elif f.endswith('.enc'): - # Get the filename without the path - fn = f.split("/")[-1] - script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (f, fn)) - script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (fn, dest)) - else: - script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest)) - return - - -# This function handles only non-HLOS boot images - files list must contain -# only such images (aboot, tz, etc) -def InstallBootImages(script, files): - bakExists = False - # update main partitions - script.AppendExtra('ifelse(msm.boot_update("main"), (') - for f in files: - dest, destBak, tf, sf = files[f] - if destBak is not None: - bakExists = True - InstallRawImage(script, f, dest, tf, sf) - script.AppendExtra('), "");') - - # update backup partitions - if bakExists: - script.AppendExtra('ifelse(msm.boot_update("backup"), (') - for f in files: - dest, destBak, tf, sf = files[f] - if destBak is not None: - InstallRawImage(script, f, destBak, tf, sf) - script.AppendExtra('), "");') - # just finalize primary update stage - else: - script.AppendExtra('msm.boot_update("backup");') - - # finalize partitions update - script.AppendExtra('msm.boot_update("finalize");') - return - - -# This function handles only non-HLOS bin images -def InstallBinImages(script, files): - for f in files: - dest, _, tf, sf = files[f] - InstallRawImage(script, f, dest, tf, sf) - return - - -# This function handles only non-HLOS firmware files that are not whole -# partition images (modem, dsp, etc) -def InstallFwImages(script, files): - last_mounted = "" - - for f in files: - dest, _, tf, sf = files[f] - # Get the filename without the path - fn = f.split("/")[-1] - # Parse filesmap destination paths for "/dev/" pattern in the beginng. - # This would mean that the file must be written to block device - - # fs mount needed - if dest.startswith("/dev/"): - if last_mounted != dest: - script.AppendExtra('unmount("/firmware");') - script.AppendExtra('mount("vfat", "EMMC", "%s", "/firmware");' % - (dest)) - last_mounted = dest - dest = "/firmware/image/" + fn - else: - dest = dest + "/" + fn - - if f.endswith('.p'): - script.ApplyPatch(dest[:-2], "-", tf.size, tf.sha1, sf.sha1, f) - elif f.endswith('.enc'): - script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (f, fn)) - script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (fn, dest[:-4])) - else: - script.AppendExtra('package_extract_file("%s", "%s");' % (f, dest)) - - if last_mounted != "": - script.AppendExtra('unmount("/firmware");') - return - -# This function handles *.img images -def InstallImgImages(script, files): - for f in files: - dest, _, tf, sf = files[f] - InstallRawImage(script, f, dest, tf, sf) - return - - -def OTA_InstallEnd(info): - print "Applying radio-update script modifications..." - info.script.Comment("---- radio update tasks ----") - info.script.Print("Patching firmware images...") - - if bootImages != {}: - InstallBootImages(info.script, bootImages) - if binImages != {}: - InstallBinImages(info.script, binImages) - if fwImages != {}: - InstallFwImages(info.script, fwImages) - if imgImages != {}: - InstallImgImages(info.script, imgImages) - return - - -def FullOTA_InstallEnd_MMC(info): - if OTA_VerifyEnd(info, info.input_version, info.input_zip): - OTA_InstallEnd(info) - return - - -def FullOTA_InstallEnd_MTD(info): - print "warning radio-update: radio update for NAND devices not supported" - return - - -def FullOTA_InstallEnd(info): - FullOTA_InstallEnd_MMC(info) - return - -def IncrementalOTA_InstallEnd_MMC(info): - OTA_InstallEnd(info) - return - - -def IncrementalOTA_InstallEnd_MTD(info): - print "warning radio-update: radio update for NAND devices not supported" - return - -def IncrementalOTA_InstallEnd(info): - IncrementalOTA_InstallEnd_MMC(info) - return |