diff options
Diffstat (limited to 'applypatch/applypatch.c')
-rw-r--r-- | applypatch/applypatch.c | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c index cb9bc2349..2c86e0984 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" @@ -31,7 +32,7 @@ #include "edify/expr.h" static int LoadPartitionContents(const char* filename, FileContents* file); -static ssize_t FileSink(unsigned char* data, ssize_t len, void* token); +static ssize_t FileSink(const unsigned char* data, ssize_t len, void* token); static int GenerateTarget(FileContents* source_file, const Value* source_patch_value, FileContents* copy_file, @@ -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; } @@ -247,7 +231,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { break; } if (next != read) { - printf("short read (%d bytes of %d) for partition \"%s\"\n", + printf("short read (%zu bytes of %zu) for partition \"%s\"\n", read, next, partition); free(file->data); file->data = NULL; @@ -274,7 +258,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { if (memcmp(sha_so_far, parsed_sha, SHA_DIGEST_SIZE) == 0) { // we have a match. stop reading the partition; we'll return // the data we've read so far. - printf("partition read matched size %d sha %s\n", + printf("partition read matched size %zu sha %s\n", size[index[i]], sha1sum[index[i]]); break; } @@ -325,7 +309,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. int SaveFileContents(const char* filename, const FileContents* file) { - int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR); if (fd < 0) { printf("failed to open \"%s\" for write: %s\n", filename, strerror(errno)); @@ -340,8 +324,14 @@ int SaveFileContents(const char* filename, const FileContents* file) { close(fd); return -1; } - fsync(fd); - close(fd); + if (fsync(fd) != 0) { + printf("fsync of \"%s\" failed: %s\n", filename, strerror(errno)); + return -1; + } + if (close(fd) != 0) { + printf("close of \"%s\" failed: %s\n", filename, strerror(errno)); + return -1; + } if (chmod(filename, file->st.st_mode) != 0) { printf("chmod of \"%s\" failed: %s\n", filename, strerror(errno)); @@ -402,7 +392,7 @@ int WriteToPartition(unsigned char* data, size_t len, size_t written = mtd_write_data(ctx, (char*)data, len); if (written != len) { - printf("only wrote %d of %d bytes to MTD %s\n", + printf("only wrote %zu of %zu bytes to MTD %s\n", written, len, partition); mtd_write_close(ctx); return -1; @@ -424,7 +414,7 @@ int WriteToPartition(unsigned char* data, size_t len, { size_t start = 0; int success = 0; - int fd = open(partition, O_RDWR); + int fd = open(partition, O_RDWR | O_SYNC); if (fd < 0) { printf("failed to open %s: %s\n", partition, strerror(errno)); return -1; @@ -449,7 +439,22 @@ int WriteToPartition(unsigned char* data, size_t len, } start += written; } - fsync(fd); + if (fsync(fd) != 0) { + printf("failed to sync to %s (%s)\n", + partition, strerror(errno)); + return -1; + } + if (close(fd) != 0) { + printf("failed to close %s (%s)\n", + partition, strerror(errno)); + return -1; + } + fd = open(partition, O_RDONLY); + if (fd < 0) { + printf("failed to reopen %s for verify (%s)\n", + partition, strerror(errno)); + return -1; + } // drop caches so our subsequent verification read // won't just be reading the cache. @@ -476,20 +481,20 @@ int WriteToPartition(unsigned char* data, size_t len, if (errno == EINTR) { read_count = 0; } else { - printf("verify read error %s at %d: %s\n", + printf("verify read error %s at %zu: %s\n", partition, p, strerror(errno)); return -1; } } if ((size_t)read_count < to_read) { - printf("short verify read %s at %d: %d %d %s\n", + printf("short verify read %s at %zu: %zd %zu %s\n", partition, p, read_count, to_read, strerror(errno)); } so_far += read_count; } if (memcmp(buffer, data+p, to_read)) { - printf("verification failed starting at %d\n", p); + printf("verification failed starting at %zu\n", p); start = p; break; } @@ -579,7 +584,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 +599,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; } @@ -615,7 +620,7 @@ int ShowLicenses() { return 0; } -ssize_t FileSink(unsigned char* data, ssize_t len, void* token) { +ssize_t FileSink(const unsigned char* data, ssize_t len, void* token) { int fd = *(int *)token; ssize_t done = 0; ssize_t wrote; @@ -636,7 +641,7 @@ typedef struct { ssize_t pos; } MemorySinkInfo; -ssize_t MemorySink(unsigned char* data, ssize_t len, void* token) { +ssize_t MemorySink(const unsigned char* data, ssize_t len, void* token) { MemorySinkInfo* msi = (MemorySinkInfo*)token; if (msi->size - msi->pos < len) { return -1; @@ -730,8 +735,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 +754,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 +770,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; @@ -938,7 +940,8 @@ static int GenerateTarget(FileContents* source_file, strcpy(outname, target_filename); strcat(outname, ".patch"); - output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + output = open(outname, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, + S_IRUSR | S_IWUSR); if (output < 0) { printf("failed to open output file %s: %s\n", outname, strerror(errno)); @@ -969,8 +972,14 @@ static int GenerateTarget(FileContents* source_file, } if (output >= 0) { - fsync(output); - close(output); + if (fsync(output) != 0) { + printf("failed to fsync file \"%s\" (%s)\n", outname, strerror(errno)); + result = 1; + } + if (close(output) != 0) { + printf("failed to close file \"%s\" (%s)\n", outname, strerror(errno)); + result = 1; + } } if (result != 0) { |