Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c43c974 authored by Doug Zongker's avatar Doug Zongker
Browse files

fix failure to free memory

The applypatch function is somewhat sloppy about freeing memory (since
it was originally a standalone binary).  Fix some of that.

Change-Id: Ifd44d71ea189c0b5115493119fd57bc37533fd59
parent 53013c46
Loading
Loading
Loading
Loading
+44 −18
Original line number Diff line number Diff line
@@ -30,10 +30,16 @@
#include "mtdutils/mtdutils.h"
#include "edify/expr.h"

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 GenerateTarget(FileContents* source_file,
                          const Value* source_patch_value,
                          FileContents* copy_file,
                          const Value* copy_patch_value,
                          const char* source_filename,
                          const char* target_filename,
                          const uint8_t target_sha1[SHA_DIGEST_SIZE],
                          size_t target_size);

static int mtd_partitions_scanned = 0;

@@ -113,11 +119,6 @@ static int compare_size_indices(const void* a, const void* b) {
    }
}

void FreeFileContents(FileContents* file) {
    if (file) free(file->data);
    free(file);
}

// Load the contents of an MTD or EMMC partition into the provided
// FileContents.  filename should be a string of the form
// "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:..."  (or
@@ -322,7 +323,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, FileContents file) {
int SaveFileContents(const char* filename, const FileContents* file) {
    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
    if (fd < 0) {
        printf("failed to open \"%s\" for write: %s\n",
@@ -330,10 +331,10 @@ int SaveFileContents(const char* filename, FileContents file) {
        return -1;
    }

    ssize_t bytes_written = FileSink(file.data, file.size, &fd);
    if (bytes_written != file.size) {
    ssize_t bytes_written = FileSink(file->data, file->size, &fd);
    if (bytes_written != file->size) {
        printf("short write of \"%s\" (%ld bytes of %ld) (%s)\n",
               filename, (long)bytes_written, (long)file.size,
               filename, (long)bytes_written, (long)file->size,
               strerror(errno));
        close(fd);
        return -1;
@@ -341,11 +342,11 @@ int SaveFileContents(const char* filename, FileContents file) {
    fsync(fd);
    close(fd);

    if (chmod(filename, file.st.st_mode) != 0) {
    if (chmod(filename, file->st.st_mode) != 0) {
        printf("chmod of \"%s\" failed: %s\n", filename, strerror(errno));
        return -1;
    }
    if (chown(filename, file.st.st_uid, file.st.st_gid) != 0) {
    if (chown(filename, file->st.st_uid, file->st.st_gid) != 0) {
        printf("chown of \"%s\" failed: %s\n", filename, strerror(errno));
        return -1;
    }
@@ -503,6 +504,7 @@ int applypatch_check(const char* filename,
               "sha1 sums; checking cache\n", filename);

        free(file.data);
        file.data = NULL;

        // If the source file is missing or corrupted, it might be because
        // we were killed in the middle of patching it.  A copy of it
@@ -631,9 +633,10 @@ int applypatch(const char* source_filename,

    FileContents copy_file;
    FileContents source_file;
    copy_file.data = NULL;
    source_file.data = NULL;
    const Value* source_patch_value = NULL;
    const Value* copy_patch_value = NULL;
    int made_copy = 0;

    // We try to load the target file into the source_file object.
    if (LoadFileContents(target_filename, &source_file,
@@ -643,6 +646,7 @@ int applypatch(const char* source_filename,
            // has the desired hash, nothing for us to do.
            printf("\"%s\" is already target; no patch needed\n",
                   target_filename);
            free(source_file.data);
            return 0;
        }
    }
@@ -653,6 +657,7 @@ 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);
        source_file.data = NULL;
        LoadFileContents(source_filename, &source_file,
                         RETOUCH_DO_MASK);
    }
@@ -667,6 +672,7 @@ int applypatch(const char* source_filename,

    if (source_patch_value == NULL) {
        free(source_file.data);
        source_file.data = NULL;
        printf("source file is bad; trying copy\n");

        if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file,
@@ -685,16 +691,36 @@ int applypatch(const char* source_filename,
        if (copy_patch_value == NULL) {
            // fail.
            printf("copy file doesn't match source SHA-1s either\n");
            free(copy_file.data);
            return 1;
        }
    }

    int result = GenerateTarget(&source_file, source_patch_value,
                                &copy_file, copy_patch_value,
                                source_filename, target_filename,
                                target_sha1, target_size);
    free(source_file.data);
    free(copy_file.data);

    return result;
}

static int GenerateTarget(FileContents* source_file,
                          const Value* source_patch_value,
                          FileContents* copy_file,
                          const Value* copy_patch_value,
                          const char* source_filename,
                          const char* target_filename,
                          const uint8_t target_sha1[SHA_DIGEST_SIZE],
                          size_t target_size) {
    int retry = 1;
    SHA_CTX ctx;
    int output;
    MemorySinkInfo msi;
    FileContents* source_to_use;
    char* outname;
    int made_copy = 0;

    // assume that target_filename (eg "/system/app/Foo.apk") is located
    // on the same filesystem as its top-level directory ("/system").
@@ -723,7 +749,7 @@ int applypatch(const char* source_filename,

            // We still write the original source to cache, in case
            // the partition write is interrupted.
            if (MakeFreeSpaceOnCache(source_file.size) < 0) {
            if (MakeFreeSpaceOnCache(source_file->size) < 0) {
                printf("not enough free space on /cache\n");
                return 1;
            }
@@ -763,7 +789,7 @@ int applypatch(const char* source_filename,
                    return 1;
                }

                if (MakeFreeSpaceOnCache(source_file.size) < 0) {
                if (MakeFreeSpaceOnCache(source_file->size) < 0) {
                    printf("not enough free space on /cache\n");
                    return 1;
                }
@@ -782,10 +808,10 @@ int applypatch(const char* source_filename,

        const Value* patch;
        if (source_patch_value != NULL) {
            source_to_use = &source_file;
            source_to_use = source_file;
            patch = source_patch_value;
        } else {
            source_to_use = &copy_file;
            source_to_use = copy_file;
            patch = copy_patch_value;
        }

+1 −1
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ int applypatch_check(const char* filename,

int LoadFileContents(const char* filename, FileContents* file,
                     int retouch_flag);
int SaveFileContents(const char* filename, FileContents file);
int SaveFileContents(const char* filename, const FileContents* file);
void FreeFileContents(FileContents* file);
int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
                      int num_patches);