diff options
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | applypatch/applypatch.c | 35 | ||||
-rw-r--r-- | applypatch/applypatch.h | 4 | ||||
-rw-r--r-- | applypatch/main.c | 4 | ||||
-rw-r--r-- | minelf/Android.mk | 27 | ||||
-rw-r--r-- | minelf/Retouch.c | 196 | ||||
-rw-r--r-- | minelf/Retouch.h | 45 | ||||
-rw-r--r-- | updater/install.c | 2 |
8 files changed, 12 insertions, 302 deletions
@@ -106,7 +106,6 @@ include $(BUILD_EXECUTABLE) include $(LOCAL_PATH)/minui/Android.mk \ - $(LOCAL_PATH)/minelf/Android.mk \ $(LOCAL_PATH)/minzip/Android.mk \ $(LOCAL_PATH)/minadbd/Android.mk \ $(LOCAL_PATH)/mtdutils/Android.mk \ diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c index cb9bc23..c9c40c9 100644 --- a/applypatch/applypatch.c +++ b/applypatch/applypatch.c @@ -24,6 +24,7 @@ #include <sys/types.h> #include <fcntl.h> #include <unistd.h> +#include <stdbool.h> #include "mincrypt/sha.h" #include "applypatch.h" @@ -44,14 +45,11 @@ static int GenerateTarget(FileContents* source_file, static int mtd_partitions_scanned = 0; -// Read a file into memory; optionally (retouch_flag == RETOUCH_DO_MASK) mask -// the retouched entries back to their original value (such that SHA-1 checks -// don't fail due to randomization); store the file contents and associated +// Read a file into memory; store the file contents and associated // metadata in *file. // // Return 0 on success. -int LoadFileContents(const char* filename, FileContents* file, - int retouch_flag) { +int LoadFileContents(const char* filename, FileContents* file) { file->data = NULL; // A special 'filename' beginning with "MTD:" or "EMMC:" means to @@ -87,20 +85,6 @@ int LoadFileContents(const char* filename, FileContents* file, } fclose(f); - // apply_patch[_check] functions are blind to randomization. Randomization - // is taken care of in [Undo]RetouchBinariesFn. If there is a mismatch - // within a file, this means the file is assumed "corrupt" for simplicity. - if (retouch_flag) { - int32_t desired_offset = 0; - if (retouch_mask_data(file->data, file->size, - &desired_offset, NULL) != RETOUCH_DATA_MATCHED) { - printf("error trying to mask retouch entries\n"); - free(file->data); - file->data = NULL; - return -1; - } - } - SHA_hash(file->data, file->size, file->sha1); return 0; } @@ -579,7 +563,7 @@ int applypatch_check(const char* filename, // LoadFileContents is successful. (Useful for reading // partitions, where the filename encodes the sha1s; no need to // check them twice.) - if (LoadFileContents(filename, &file, RETOUCH_DO_MASK) != 0 || + if (LoadFileContents(filename, &file) != 0 || (num_patches > 0 && FindMatchingPatch(file.sha1, patch_sha1_str, num_patches) < 0)) { printf("file \"%s\" doesn't have any of expected " @@ -594,7 +578,7 @@ int applypatch_check(const char* filename, // exists and matches the sha1 we're looking for, the check still // passes. - if (LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK) != 0) { + if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) { printf("failed to load cache file\n"); return 1; } @@ -730,8 +714,7 @@ int applypatch(const char* source_filename, const Value* copy_patch_value = NULL; // We try to load the target file into the source_file object. - if (LoadFileContents(target_filename, &source_file, - RETOUCH_DO_MASK) == 0) { + if (LoadFileContents(target_filename, &source_file) == 0) { if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { // The early-exit case: the patch was already applied, this file // has the desired hash, nothing for us to do. @@ -750,8 +733,7 @@ int applypatch(const char* source_filename, // target file, or we did but it's different from the source file. free(source_file.data); source_file.data = NULL; - LoadFileContents(source_filename, &source_file, - RETOUCH_DO_MASK); + LoadFileContents(source_filename, &source_file); } if (source_file.data != NULL) { @@ -767,8 +749,7 @@ int applypatch(const char* source_filename, source_file.data = NULL; printf("source file is bad; trying copy\n"); - if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file, - RETOUCH_DO_MASK) < 0) { + if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file) < 0) { // fail. printf("failed to read copy file\n"); return 1; diff --git a/applypatch/applypatch.h b/applypatch/applypatch.h index f1f13a1..ee54c24 100644 --- a/applypatch/applypatch.h +++ b/applypatch/applypatch.h @@ -19,7 +19,6 @@ #include <sys/stat.h> #include "mincrypt/sha.h" -#include "minelf/Retouch.h" #include "edify/expr.h" typedef struct _Patch { @@ -61,8 +60,7 @@ int applypatch_check(const char* filename, int num_patches, char** const patch_sha1_str); -int LoadFileContents(const char* filename, FileContents* file, - int retouch_flag); +int LoadFileContents(const char* filename, FileContents* file); int SaveFileContents(const char* filename, const FileContents* file); void FreeFileContents(FileContents* file); int FindMatchingPatch(uint8_t* sha1, char* const * const patch_sha1_str, diff --git a/applypatch/main.c b/applypatch/main.c index f61db5d..8e9fe80 100644 --- a/applypatch/main.c +++ b/applypatch/main.c @@ -74,7 +74,7 @@ static int ParsePatchArgs(int argc, char** argv, (*patches)[i] = NULL; } else { FileContents fc; - if (LoadFileContents(colon, &fc, RETOUCH_DONT_MASK) != 0) { + if (LoadFileContents(colon, &fc) != 0) { goto abort; } (*patches)[i] = malloc(sizeof(Value)); @@ -103,7 +103,7 @@ int PatchMode(int argc, char** argv) { Value* bonus = NULL; if (argc >= 3 && strcmp(argv[1], "-b") == 0) { FileContents fc; - if (LoadFileContents(argv[2], &fc, RETOUCH_DONT_MASK) != 0) { + if (LoadFileContents(argv[2], &fc) != 0) { printf("failed to load bonus file %s\n", argv[2]); return 1; } diff --git a/minelf/Android.mk b/minelf/Android.mk deleted file mode 100644 index 0f41ff5..0000000 --- a/minelf/Android.mk +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2009 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. - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - Retouch.c - -LOCAL_C_INCLUDES += bootable/recovery - -LOCAL_MODULE := libminelf - -LOCAL_CFLAGS += -Wall - -include $(BUILD_STATIC_LIBRARY) diff --git a/minelf/Retouch.c b/minelf/Retouch.c deleted file mode 100644 index d75eec1..0000000 --- a/minelf/Retouch.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -#include <errno.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <strings.h> -#include "Retouch.h" -#include "applypatch/applypatch.h" - -typedef struct { - int32_t mmap_addr; - char tag[4]; /* 'P', 'R', 'E', ' ' */ -} prelink_info_t __attribute__((packed)); - -#define false 0 -#define true 1 - -static int32_t offs_prev; -static uint32_t cont_prev; - -static void init_compression_state(void) { - offs_prev = 0; - cont_prev = 0; -} - -// For details on the encoding used for relocation lists, please -// refer to build/tools/retouch/retouch-prepare.c. The intent is to -// save space by removing most of the inherent redundancy. - -static void decode_bytes(uint8_t *encoded_bytes, int encoded_size, - int32_t *dst_offset, uint32_t *dst_contents) { - if (encoded_size == 2) { - *dst_offset = offs_prev + (((encoded_bytes[0]&0x60)>>5)+1)*4; - - // if the original was negative, we need to 1-pad before applying delta - int32_t tmp = (((encoded_bytes[0] & 0x0000001f) << 8) | - encoded_bytes[1]); - if (tmp & 0x1000) tmp = 0xffffe000 | tmp; - *dst_contents = cont_prev + tmp; - } else if (encoded_size == 3) { - *dst_offset = offs_prev + (((encoded_bytes[0]&0x30)>>4)+1)*4; - - // if the original was negative, we need to 1-pad before applying delta - int32_t tmp = (((encoded_bytes[0] & 0x0000000f) << 16) | - (encoded_bytes[1] << 8) | - encoded_bytes[2]); - if (tmp & 0x80000) tmp = 0xfff00000 | tmp; - *dst_contents = cont_prev + tmp; - } else { - *dst_offset = - (encoded_bytes[0]<<24) | - (encoded_bytes[1]<<16) | - (encoded_bytes[2]<<8) | - encoded_bytes[3]; - if (*dst_offset == 0x3fffffff) *dst_offset = -1; - *dst_contents = - (encoded_bytes[4]<<24) | - (encoded_bytes[5]<<16) | - (encoded_bytes[6]<<8) | - encoded_bytes[7]; - } -} - -static uint8_t *decode_in_memory(uint8_t *encoded_bytes, - int32_t *offset, uint32_t *contents) { - int input_size, charIx; - uint8_t input[8]; - - input[0] = *(encoded_bytes++); - if (input[0] & 0x80) - input_size = 2; - else if (input[0] & 0x40) - input_size = 3; - else - input_size = 8; - - // we already read one byte.. - charIx = 1; - while (charIx < input_size) { - input[charIx++] = *(encoded_bytes++); - } - - // depends on the decoder state! - decode_bytes(input, input_size, offset, contents); - - offs_prev = *offset; - cont_prev = *contents; - - return encoded_bytes; -} - -int retouch_mask_data(uint8_t *binary_object, - int32_t binary_size, - int32_t *desired_offset, - int32_t *retouch_offset) { - retouch_info_t *r_info; - prelink_info_t *p_info; - - int32_t target_offset = 0; - if (desired_offset) target_offset = *desired_offset; - - int32_t p_offs = binary_size-sizeof(prelink_info_t); // prelink_info_t - int32_t r_offs = p_offs-sizeof(retouch_info_t); // retouch_info_t - int32_t b_offs; // retouch data blob - - // If not retouched, we say it was a match. This might get invoked on - // non-retouched binaries, so that's why we need to do this. - if (retouch_offset != NULL) *retouch_offset = target_offset; - if (r_offs < 0) return (desired_offset == NULL) ? - RETOUCH_DATA_NOTAPPLICABLE : RETOUCH_DATA_MATCHED; - p_info = (prelink_info_t *)(binary_object+p_offs); - r_info = (retouch_info_t *)(binary_object+r_offs); - if (strncmp(p_info->tag, "PRE ", 4) || - strncmp(r_info->tag, "RETOUCH ", 8)) - return (desired_offset == NULL) ? - RETOUCH_DATA_NOTAPPLICABLE : RETOUCH_DATA_MATCHED; - - b_offs = r_offs-r_info->blob_size; - if (b_offs < 0) { - printf("negative binary offset: %d = %d - %d\n", - b_offs, r_offs, r_info->blob_size); - return RETOUCH_DATA_ERROR; - } - uint8_t *b_ptr = binary_object+b_offs; - - // Retouched: let's go through the work then. - int32_t offset_candidate = target_offset; - bool offset_set = false, offset_mismatch = false; - init_compression_state(); - while (b_ptr < (uint8_t *)r_info) { - int32_t retouch_entry_offset; - uint32_t *retouch_entry; - uint32_t retouch_original_value; - - b_ptr = decode_in_memory(b_ptr, - &retouch_entry_offset, - &retouch_original_value); - if (retouch_entry_offset < (-1) || - retouch_entry_offset >= b_offs) { - printf("bad retouch_entry_offset: %d", retouch_entry_offset); - return RETOUCH_DATA_ERROR; - } - - // "-1" means this is the value in prelink_info_t, which also gets - // randomized. - if (retouch_entry_offset == -1) - retouch_entry = (uint32_t *)&(p_info->mmap_addr); - else - retouch_entry = (uint32_t *)(binary_object+retouch_entry_offset); - - if (desired_offset) - *retouch_entry = retouch_original_value + target_offset; - - // Infer the randomization shift, compare to previously inferred. - int32_t offset_of_this_entry = (int32_t)(*retouch_entry- - retouch_original_value); - if (!offset_set) { - offset_candidate = offset_of_this_entry; - offset_set = true; - } else { - if (offset_candidate != offset_of_this_entry) { - offset_mismatch = true; - printf("offset is mismatched: %d, this entry is %d," - " original 0x%x @ 0x%x", - offset_candidate, offset_of_this_entry, - retouch_original_value, retouch_entry_offset); - } - } - } - if (b_ptr > (uint8_t *)r_info) { - printf("b_ptr went too far: %p, while r_info is %p", - b_ptr, r_info); - return RETOUCH_DATA_ERROR; - } - - if (offset_mismatch) return RETOUCH_DATA_MISMATCHED; - if (retouch_offset != NULL) *retouch_offset = offset_candidate; - return RETOUCH_DATA_MATCHED; -} diff --git a/minelf/Retouch.h b/minelf/Retouch.h deleted file mode 100644 index 13bacd5..0000000 --- a/minelf/Retouch.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -#ifndef _MINELF_RETOUCH -#define _MINELF_RETOUCH - -#include <stdbool.h> -#include <sys/types.h> - -typedef struct { - char tag[8]; /* "RETOUCH ", not zero-terminated */ - uint32_t blob_size; /* in bytes, located right before this struct */ -} retouch_info_t __attribute__((packed)); - -#define RETOUCH_DONT_MASK 0 -#define RETOUCH_DO_MASK 1 - -#define RETOUCH_DATA_ERROR 0 // This is bad. Should not happen. -#define RETOUCH_DATA_MATCHED 1 // Up to an uniform random offset. -#define RETOUCH_DATA_MISMATCHED 2 // Partially randomized, or total mess. -#define RETOUCH_DATA_NOTAPPLICABLE 3 // Not retouched. Only when inferring. - -// Mask retouching in-memory. Used before apply_patch[_check]. -// Also used to determine status of retouching after a crash. -// -// If desired_offset is not NULL, then apply retouching instead, -// and return that in retouch_offset. -int retouch_mask_data(uint8_t *binary_object, - int32_t binary_size, - int32_t *desired_offset, - int32_t *retouch_offset); -#endif diff --git a/updater/install.c b/updater/install.c index 2cf00bf..e85ba50 100644 --- a/updater/install.c +++ b/updater/install.c @@ -1419,7 +1419,7 @@ Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) { v->type = VAL_BLOB; FileContents fc; - if (LoadFileContents(filename, &fc, RETOUCH_DONT_MASK) != 0) { + if (LoadFileContents(filename, &fc) != 0) { free(filename); v->size = -1; v->data = NULL; |