From db314d69f023d2a6c8956073aa9d283e20b280ef Mon Sep 17 00:00:00 2001 From: Hristo Bojinov Date: Mon, 2 Aug 2010 10:29:49 -0700 Subject: Working ASLR implementation Separate files for retouch functionality are in minelf/* ASLR for shared libraries is controlled by "-a" in ota_from_target_files. Binary files are self-contained. Retouch logic can recover from crashes. Signed-off-by: Hristo Bojinov Change-Id: I76c596abf4febd68c14f9d807ac62e8751e0b1bd --- applypatch/Android.mk | 4 ++-- applypatch/applypatch.c | 42 ++++++++++++++++++++++++++++++++---------- applypatch/applypatch.h | 9 ++++++--- applypatch/main.c | 2 +- 4 files changed, 41 insertions(+), 16 deletions(-) (limited to 'applypatch') diff --git a/applypatch/Android.mk b/applypatch/Android.mk index e91e4bf88..eff1d77b3 100644 --- a/applypatch/Android.mk +++ b/applypatch/Android.mk @@ -31,7 +31,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := main.c LOCAL_MODULE := applypatch LOCAL_C_INCLUDES += bootable/recovery -LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz +LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz libminelf LOCAL_SHARED_LIBRARIES += libz libcutils libstdc++ libc include $(BUILD_EXECUTABLE) @@ -43,7 +43,7 @@ LOCAL_MODULE := applypatch_static LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_TAGS := eng LOCAL_C_INCLUDES += bootable/recovery -LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz +LOCAL_STATIC_LIBRARIES += libapplypatch libmtdutils libmincrypt libbz libminelf LOCAL_STATIC_LIBRARIES += libz libcutils libstdc++ libc include $(BUILD_EXECUTABLE) diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c index d18282117..1d9ef6efb 100644 --- a/applypatch/applypatch.c +++ b/applypatch/applypatch.c @@ -30,16 +30,21 @@ #include "mtdutils/mtdutils.h" #include "edify/expr.h" -static int SaveFileContents(const char* filename, FileContents file); +int SaveFileContents(const char* filename, FileContents file); static int LoadPartitionContents(const char* filename, FileContents* file); int ParseSha1(const char* str, uint8_t* digest); static ssize_t FileSink(unsigned char* data, ssize_t len, void* token); static int mtd_partitions_scanned = 0; -// Read a file into memory; store it and its associated metadata in -// *file. Return 0 on success. -int LoadFileContents(const char* filename, FileContents* file) { +// 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 +// metadata in *file. +// +// Return 0 on success. +int LoadFileContents(const char* filename, FileContents* file, + int retouch_flag) { file->data = NULL; // A special 'filename' beginning with "MTD:" or "EMMC:" means to @@ -75,6 +80,20 @@ 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(file->data, file->size, file->sha1); return 0; } @@ -303,7 +322,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { // Save the contents of the given FileContents object under the given // filename. Return 0 on success. -static int SaveFileContents(const char* filename, FileContents file) { +int SaveFileContents(const char* filename, FileContents file) { int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC); if (fd < 0) { printf("failed to open \"%s\" for write: %s\n", @@ -477,7 +496,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) != 0 || + if (LoadFileContents(filename, &file, RETOUCH_DO_MASK) != 0 || (num_patches > 0 && FindMatchingPatch(file.sha1, patch_sha1_str, num_patches) < 0)) { printf("file \"%s\" doesn't have any of expected " @@ -491,7 +510,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) != 0) { + if (LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK) != 0) { printf("failed to load cache file\n"); return 1; } @@ -617,7 +636,8 @@ int applypatch(const char* source_filename, int made_copy = 0; // We try to load the target file into the source_file object. - if (LoadFileContents(target_filename, &source_file) == 0) { + if (LoadFileContents(target_filename, &source_file, + RETOUCH_DO_MASK) == 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. @@ -633,7 +653,8 @@ int applypatch(const char* source_filename, // Need to load the source file: either we failed to load the // target file, or we did but it's different from the source file. free(source_file.data); - LoadFileContents(source_filename, &source_file); + LoadFileContents(source_filename, &source_file, + RETOUCH_DO_MASK); } if (source_file.data != NULL) { @@ -648,7 +669,8 @@ int applypatch(const char* source_filename, free(source_file.data); printf("source file is bad; trying copy\n"); - if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file) < 0) { + if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file, + RETOUCH_DO_MASK) < 0) { // fail. printf("failed to read copy file\n"); return 1; diff --git a/applypatch/applypatch.h b/applypatch/applypatch.h index 10c01259a..a78c89bfe 100644 --- a/applypatch/applypatch.h +++ b/applypatch/applypatch.h @@ -19,6 +19,7 @@ #include #include "mincrypt/sha.h" +#include "minelf/Retouch.h" #include "edify/expr.h" typedef struct _Patch { @@ -59,10 +60,12 @@ int applypatch_check(const char* filename, int num_patches, char** const patch_sha1_str); -// Read a file into memory; store it and its associated metadata in -// *file. Return 0 on success. -int LoadFileContents(const char* filename, FileContents* file); +int LoadFileContents(const char* filename, FileContents* file, + int retouch_flag); +int SaveFileContents(const char* filename, FileContents file); void FreeFileContents(FileContents* file); +int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str, + int num_patches); // bsdiff.c void ShowBSDiffLicense(); diff --git a/applypatch/main.c b/applypatch/main.c index 3917f86ed..7025a2e2e 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) != 0) { + if (LoadFileContents(colon, &fc, RETOUCH_DONT_MASK) != 0) { goto abort; } (*patches)[i] = malloc(sizeof(Value)); -- cgit v1.2.3