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
This commit is contained in:
+44
-18
@@ -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, ©_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,
|
||||
©_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 = ©_file;
|
||||
source_to_use = copy_file;
|
||||
patch = copy_patch_value;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user