summaryrefslogtreecommitdiffstats
path: root/minelf/Retouch.c
diff options
context:
space:
mode:
Diffstat (limited to 'minelf/Retouch.c')
-rw-r--r--minelf/Retouch.c210
1 files changed, 0 insertions, 210 deletions
diff --git a/minelf/Retouch.c b/minelf/Retouch.c
index a25380b34..d75eec1e8 100644
--- a/minelf/Retouch.c
+++ b/minelf/Retouch.c
@@ -194,213 +194,3 @@ int retouch_mask_data(uint8_t *binary_object,
if (retouch_offset != NULL) *retouch_offset = offset_candidate;
return RETOUCH_DATA_MATCHED;
}
-
-// On success, _override is set to the offset that was actually applied.
-// This implies that once we randomize to an offset we stick with it.
-// This in turn is necessary in order to guarantee recovery after crash.
-bool retouch_one_library(const char *binary_name,
- const char *binary_sha1,
- int32_t retouch_offset,
- int32_t *retouch_offset_override) {
- bool success = true;
- int result;
-
- FileContents file;
- file.data = NULL;
-
- char binary_name_atomic[strlen(binary_name)+10];
- strcpy(binary_name_atomic, binary_name);
- strcat(binary_name_atomic, ".atomic");
-
- // We need a path that exists for calling statfs() later.
- //
- // Assume that binary_name (eg "/system/app/Foo.apk") is located
- // on the same filesystem as its top-level directory ("/system").
- char target_fs[strlen(binary_name)+1];
- char* slash = strchr(binary_name+1, '/');
- if (slash != NULL) {
- int count = slash - binary_name;
- strncpy(target_fs, binary_name, count);
- target_fs[count] = '\0';
- } else {
- strcpy(target_fs, binary_name);
- }
-
- result = LoadFileContents(binary_name, &file, RETOUCH_DONT_MASK);
-
- if (result == 0) {
- // Figure out the *apparent* offset to which this file has been
- // retouched. If it looks good, we will skip processing (we might
- // have crashed and during this recovery pass we don't want to
- // overwrite a valuable saved file in /cache---which would happen
- // if we blindly retouch everything again). NOTE: This implies
- // that we might have to override the supplied retouch offset. We
- // can do the override only once though: everything should match
- // afterward.
-
- int32_t inferred_offset;
- int retouch_probe_result = retouch_mask_data(file.data,
- file.size,
- NULL,
- &inferred_offset);
-
- if (retouch_probe_result == RETOUCH_DATA_MATCHED) {
- if ((retouch_offset == inferred_offset) ||
- ((retouch_offset != 0 && inferred_offset != 0) &&
- (retouch_offset_override != NULL))) {
- // This file is OK already and we are allowed to override.
- // Let's just return the offset override value. It is critical
- // to skip regardless of override: a broken file might need
- // recovery down the list and we should not mess up the saved
- // copy by doing unnecessary retouching.
- //
- // NOTE: If retouching was already started with a different
- // value, we will not be allowed to override. This happens
- // if on the retouch list there is a patched binary (which is
- // masked in apply_patch()) before there is a non-patched
- // binary.
- if (retouch_offset_override != NULL)
- *retouch_offset_override = inferred_offset;
- success = true;
- goto out;
- } else {
- // Retouch to zero (mask the retouching), to make sure that
- // the SHA-1 check will pass below.
- int32_t zero = 0;
- retouch_mask_data(file.data, file.size, &zero, NULL);
- SHA(file.data, file.size, file.sha1);
- }
- }
-
- if (retouch_probe_result == RETOUCH_DATA_NOTAPPLICABLE) {
- // In the case of not retouchable, fake it. We do not want
- // to do the normal processing and overwrite the backup file:
- // we might be recovering!
- //
- // We return a zero override, which tells the caller that we
- // simply skipped the file.
- if (retouch_offset_override != NULL)
- *retouch_offset_override = 0;
- success = true;
- goto out;
- }
-
- // If we get here, either there was a mismatch in the offset, or
- // the file has not been processed yet. Continue with normal
- // processing.
- }
-
- if (result != 0 || FindMatchingPatch(file.sha1, &binary_sha1, 1) < 0) {
- free(file.data);
- printf("Attempting to recover source from '%s' ...\n",
- CACHE_TEMP_SOURCE);
- result = LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK);
- if (result != 0 || FindMatchingPatch(file.sha1, &binary_sha1, 1) < 0) {
- printf(" failed.\n");
- success = false;
- goto out;
- }
- printf(" succeeded.\n");
- }
-
- // Retouch in-memory before worrying about backing up the original.
- //
- // Recovery steps will be oblivious to the actual retouch offset used,
- // so might as well write out the already-retouched copy. Then, in the
- // usual case, we will just swap the file locally, with no more writes
- // needed. In the no-free-space case, we will then write the same to the
- // original location.
-
- result = retouch_mask_data(file.data, file.size, &retouch_offset, NULL);
- if (result != RETOUCH_DATA_MATCHED) {
- success = false;
- goto out;
- }
- if (retouch_offset_override != NULL)
- *retouch_offset_override = retouch_offset;
-
- // How much free space do we need?
- bool enough_space = false;
- size_t free_space = FreeSpaceForFile(target_fs);
- // 50% margin when estimating the space needed.
- enough_space = (free_space > (file.size * 3 / 2));
-
- // The experts say we have to allow for a retry of the
- // whole process to avoid filesystem weirdness.
- int retry = 1;
- bool made_copy = false;
- do {
- // First figure out where to store a copy of the original.
- // Ideally leave the original itself intact until the
- // atomic swap. If no room on the same partition, fall back
- // to the cache partition and remove the original.
-
- if (!enough_space) {
- printf("Target is %ldB; free space is %ldB: not enough.\n",
- (long)file.size, (long)free_space);
-
- retry = 0;
- if (MakeFreeSpaceOnCache(file.size) < 0) {
- printf("Not enough free space on '/cache'.\n");
- success = false;
- goto out;
- }
- if (SaveFileContents(CACHE_TEMP_SOURCE, &file) < 0) {
- printf("Failed to back up source file.\n");
- success = false;
- goto out;
- }
- made_copy = true;
- unlink(binary_name);
-
- size_t free_space = FreeSpaceForFile(target_fs);
- printf("(now %ld bytes free for target)\n", (long)free_space);
- }
-
- result = SaveFileContents(binary_name_atomic, &file);
- if (result != 0) {
- // Maybe the filesystem was optimistic: retry.
- enough_space = false;
- unlink(binary_name_atomic);
- printf("Saving the retouched contents failed; retrying.\n");
- continue;
- }
-
- // Succeeded; no need to retry.
- break;
- } while (retry-- > 0);
-
- // Give the .atomic file the same owner, group, and mode of the
- // original source file.
- if (chmod(binary_name_atomic, file.st.st_mode) != 0) {
- printf("chmod of \"%s\" failed: %s\n",
- binary_name_atomic, strerror(errno));
- success = false;
- goto out;
- }
- if (chown(binary_name_atomic, file.st.st_uid, file.st.st_gid) != 0) {
- printf("chown of \"%s\" failed: %s\n",
- binary_name_atomic,
- strerror(errno));
- success = false;
- goto out;
- }
-
- // Finally, rename the .atomic file to replace the target file.
- if (rename(binary_name_atomic, binary_name) != 0) {
- printf("rename of .atomic to \"%s\" failed: %s\n",
- binary_name, strerror(errno));
- success = false;
- goto out;
- }
-
- // If this run created a copy, and we're here, we can delete it.
- if (made_copy) unlink(CACHE_TEMP_SOURCE);
-
- out:
- // clean up
- free(file.data);
- unlink(binary_name_atomic);
-
- return success;
-}