diff options
author | Koushik Dutta <koushd@gmail.com> | 2012-07-15 16:02:14 -0700 |
---|---|---|
committer | Koushik Dutta <koushd@gmail.com> | 2012-07-15 16:02:14 -0700 |
commit | 117a088d8db229ca1501e21feeb5829254900b62 (patch) | |
tree | c5205d4471e563be969d6fd5234014b32ed4781e /updater | |
parent | a96fdfd99afa5cadfa5492920a73843cea1e462b (diff) | |
download | bootable_recovery-117a088d8db229ca1501e21feeb5829254900b62.zip bootable_recovery-117a088d8db229ca1501e21feeb5829254900b62.tar.gz bootable_recovery-117a088d8db229ca1501e21feeb5829254900b62.tar.bz2 |
derped up the updater
Change-Id: Idbfb2399fcf6dbcf29f3049ff155d56f9a9a2a68
Diffstat (limited to 'updater')
-rw-r--r-- | updater/Android.mk | 9 | ||||
-rw-r--r-- | updater/install.c | 263 | ||||
-rw-r--r-- | updater/updater.c | 16 | ||||
-rw-r--r-- | updater/updater.h | 9 |
4 files changed, 143 insertions, 154 deletions
diff --git a/updater/Android.mk b/updater/Android.mk index d859c7b..f8ccb76 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -4,7 +4,6 @@ LOCAL_PATH := $(call my-dir) updater_src_files := \ install.c \ - ../mounts.c \ updater.c # @@ -25,12 +24,16 @@ LOCAL_C_INCLUDES += system/extras/ext4_utils LOCAL_STATIC_LIBRARIES += libext4_utils libz endif -LOCAL_STATIC_LIBRARIES += libflashutils libmtdutils libmmcutils libbmlutils +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_STATIC_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz LOCAL_STATIC_LIBRARIES += libmincrypt libbz -LOCAL_STATIC_LIBRARIES += libminelf libcrecovery +LOCAL_STATIC_LIBRARIES += libminelf LOCAL_STATIC_LIBRARIES += libcutils libstdc++ libc LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. diff --git a/updater/install.c b/updater/install.c index c9d21f2..f981017 100644 --- a/updater/install.c +++ b/updater/install.c @@ -33,14 +33,11 @@ #include "edify/expr.h" #include "mincrypt/sha.h" #include "minzip/DirUtil.h" -#include "minelf/Retouch.h" -#include "mounts.h" +#include "mtdutils/mounts.h" #include "mtdutils/mtdutils.h" #include "updater.h" #include "applypatch/applypatch.h" -#include "flashutils/flashutils.h" - #ifdef USE_EXT4 #include "make_ext4fs.h" #endif @@ -81,8 +78,24 @@ Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } +#ifdef HAVE_SELINUX + char *secontext = NULL; + + if (sehandle) { + selabel_lookup(sehandle, &secontext, mount_point, 0755); + setfscreatecon(secontext); + } +#endif + mkdir(mount_point, 0755); +#ifdef HAVE_SELINUX + if (secontext) { + freecon(secontext); + setfscreatecon(NULL); + } +#endif + if (strcmp(partition_type, "MTD") == 0) { mtd_scan_partitions(); const MtdPartition* mtd; @@ -179,23 +192,25 @@ done: } -// format(fs_type, partition_type, location, fs_size) +// format(fs_type, partition_type, location, fs_size, mount_point) // -// fs_type="yaffs2" partition_type="MTD" location=partition fs_size=<bytes> -// fs_type="ext4" partition_type="EMMC" location=device fs_size=<bytes> +// fs_type="yaffs2" partition_type="MTD" location=partition fs_size=<bytes> mount_point=<location> +// fs_type="ext4" partition_type="EMMC" location=device fs_size=<bytes> mount_point=<location> // if fs_size == 0, then make_ext4fs uses the entire partition. // if fs_size > 0, that is the size to use // if fs_size < 0, then reserve that many bytes at the end of the partition Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; - if (argc != 4) { - return ErrorAbort(state, "%s() expects 4 args, got %d", name, argc); + if (argc != 5) { + return ErrorAbort(state, "%s() expects 5 args, got %d", name, argc); } char* fs_type; char* partition_type; char* location; char* fs_size; - if (ReadArgs(state, argv, 4, &fs_type, &partition_type, &location, &fs_size) < 0) { + char* mount_point; + + if (ReadArgs(state, argv, 5, &fs_type, &partition_type, &location, &fs_size, &mount_point) < 0) { return NULL; } @@ -213,6 +228,11 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } + if (strlen(mount_point) == 0) { + ErrorAbort(state, "mount_point argument to %s() can't be empty", name); + goto done; + } + if (strcmp(partition_type, "MTD") == 0) { mtd_scan_partitions(); const MtdPartition* mtd = mtd_find_partition_by_name(location); @@ -242,7 +262,7 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { result = location; #ifdef USE_EXT4 } else if (strcmp(fs_type, "ext4") == 0) { - int status = make_ext4fs(location, atoll(fs_size)); + int status = make_ext4fs(location, atoll(fs_size), mount_point, sehandle); if (status != 0) { fprintf(stderr, "%s: make_ext4fs failed (%d) on %s", name, status, location); @@ -251,24 +271,6 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { } result = location; #endif - } else if (strcmp(fs_type, "ext2") == 0) { - int status = format_ext2_device(location); - if (status != 0) { - fprintf(stderr, "%s: format_ext2_device failed (%d) on %s", - name, status, location); - result = strdup(""); - goto done; - } - result = location; - } else if (strcmp(fs_type, "ext3") == 0) { - int status = format_ext3_device(location); - if (status != 0) { - fprintf(stderr, "%s: format_ext3_device failed (%d) on %s", - name, status, location); - result = strdup(""); - goto done; - } - result = location; } else { fprintf(stderr, "%s: unsupported fs_type \"%s\" partition_type \"%s\"", name, fs_type, partition_type); @@ -367,7 +369,7 @@ Value* PackageExtractDirFn(const char* name, State* state, bool success = mzExtractRecursive(za, zip_path, dest_path, MZ_EXTRACT_FILES_ONLY, ×tamp, - NULL, NULL); + NULL, NULL, sehandle); free(zip_path); free(dest_path); return StringValue(strdup(success ? "t" : "")); @@ -455,119 +457,6 @@ Value* PackageExtractFileFn(const char* name, State* state, } -// retouch_binaries(lib1, lib2, ...) -Value* RetouchBinariesFn(const char* name, State* state, - int argc, Expr* argv[]) { - UpdaterInfo* ui = (UpdaterInfo*)(state->cookie); - - char **retouch_entries = ReadVarArgs(state, argc, argv); - if (retouch_entries == NULL) { - return StringValue(strdup("t")); - } - - // some randomness from the clock - int32_t override_base; - bool override_set = false; - int32_t random_base = time(NULL) % 1024; - // some more randomness from /dev/random - FILE *f_random = fopen("/dev/random", "rb"); - uint16_t random_bits = 0; - if (f_random != NULL) { - fread(&random_bits, 2, 1, f_random); - random_bits = random_bits % 1024; - fclose(f_random); - } - random_base = (random_base + random_bits) % 1024; - - // make sure we never randomize to zero; this let's us look at a file - // and know for sure whether it has been processed; important in the - // crash recovery process - if (random_base == 0) random_base = 1; - // make sure our randomization is page-aligned - random_base *= -0x1000; - override_base = random_base; - - int i = 0; - bool success = true; - while (i < (argc - 1)) { - success = success && retouch_one_library(retouch_entries[i], - retouch_entries[i+1], - random_base, - override_set ? - NULL : - &override_base); - if (!success) - ErrorAbort(state, "Failed to retouch '%s'.", retouch_entries[i]); - - free(retouch_entries[i]); - free(retouch_entries[i+1]); - i += 2; - - if (success && override_base != 0) { - random_base = override_base; - override_set = true; - } - } - if (i < argc) { - free(retouch_entries[i]); - success = false; - } - free(retouch_entries); - - if (!success) { - Value* v = malloc(sizeof(Value)); - v->type = VAL_STRING; - v->data = NULL; - v->size = -1; - return v; - } - return StringValue(strdup("t")); -} - - -// undo_retouch_binaries(lib1, lib2, ...) -Value* UndoRetouchBinariesFn(const char* name, State* state, - int argc, Expr* argv[]) { - UpdaterInfo* ui = (UpdaterInfo*)(state->cookie); - - char **retouch_entries = ReadVarArgs(state, argc, argv); - if (retouch_entries == NULL) { - return StringValue(strdup("t")); - } - - int i = 0; - bool success = true; - int32_t override_base; - while (i < (argc-1)) { - success = success && retouch_one_library(retouch_entries[i], - retouch_entries[i+1], - 0 /* undo => offset==0 */, - NULL); - if (!success) - ErrorAbort(state, "Failed to unretouch '%s'.", - retouch_entries[i]); - - free(retouch_entries[i]); - free(retouch_entries[i+1]); - i += 2; - } - if (i < argc) { - free(retouch_entries[i]); - success = false; - } - free(retouch_entries); - - if (!success) { - Value* v = malloc(sizeof(Value)); - v->type = VAL_STRING; - v->data = NULL; - v->size = -1; - return v; - } - return StringValue(strdup("t")); -} - - // symlink target src1 src2 ... // unlinks any previously existing src1, src2, etc before creating symlinks. Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { @@ -584,21 +473,27 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { return NULL; } + int bad = 0; int i; for (i = 0; i < argc-1; ++i) { if (unlink(srcs[i]) < 0) { if (errno != ENOENT) { fprintf(stderr, "%s: failed to remove %s: %s\n", name, srcs[i], strerror(errno)); + ++bad; } } if (symlink(target, srcs[i]) < 0) { fprintf(stderr, "%s: failed to symlink %s to %s: %s\n", name, srcs[i], target, strerror(errno)); + ++bad; } free(srcs[i]); } free(srcs); + if (bad) { + return ErrorAbort(state, "%s: some symlinks failed", name); + } return StringValue(strdup("")); } @@ -617,6 +512,7 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) { char* end; int i; + int bad = 0; int uid = strtoul(args[0], &end, 0); if (*end != '\0' || args[0][0] == 0) { @@ -658,10 +554,12 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) { if (chown(args[i], uid, gid) < 0) { fprintf(stderr, "%s: chown of %s to %d %d failed: %s\n", name, args[i], uid, gid, strerror(errno)); + ++bad; } if (chmod(args[i], mode) < 0) { fprintf(stderr, "%s: chmod of %s to %o failed: %s\n", name, args[i], mode, strerror(errno)); + ++bad; } } } @@ -673,6 +571,10 @@ done: } free(args); + if (bad) { + free(result); + return ErrorAbort(state, "%s: some changes failed", name); + } return StringValue(result); } @@ -810,11 +712,12 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { return NULL; } + char* partition = NULL; if (partition_value->type != VAL_STRING) { ErrorAbort(state, "partition argument to %s must be string", name); goto done; } - char* partition = partition_value->data; + partition = partition_value->data; if (strlen(partition) == 0) { ErrorAbort(state, "partition argument to %s can't be empty", name); goto done; @@ -824,14 +727,66 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } - char* filename = contents->data; - if (0 == restore_raw_partition(NULL, partition, filename)) - result = strdup(partition); - else { + mtd_scan_partitions(); + const MtdPartition* mtd = mtd_find_partition_by_name(partition); + if (mtd == NULL) { + fprintf(stderr, "%s: no mtd partition named \"%s\"\n", name, partition); + result = strdup(""); + goto done; + } + + MtdWriteContext* ctx = mtd_write_partition(mtd); + if (ctx == NULL) { + fprintf(stderr, "%s: can't write mtd partition \"%s\"\n", + name, partition); result = strdup(""); goto done; } + bool success; + + if (contents->type == VAL_STRING) { + // we're given a filename as the contents + char* filename = contents->data; + FILE* f = fopen(filename, "rb"); + if (f == NULL) { + fprintf(stderr, "%s: can't open %s: %s\n", + name, filename, strerror(errno)); + result = strdup(""); + goto done; + } + + success = true; + char* buffer = malloc(BUFSIZ); + int read; + while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) { + int wrote = mtd_write_data(ctx, buffer, read); + success = success && (wrote == read); + } + free(buffer); + fclose(f); + } else { + // we're given a blob as the contents + ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size); + success = (wrote == contents->size); + } + if (!success) { + fprintf(stderr, "mtd_write_data to %s failed: %s\n", + partition, strerror(errno)); + } + + if (mtd_erase_blocks(ctx, -1) == -1) { + fprintf(stderr, "%s: error erasing blocks of %s\n", name, partition); + } + if (mtd_write_close(ctx) != 0) { + fprintf(stderr, "%s: error closing write of %s\n", name, partition); + } + + printf("%s %s partition\n", + success ? "wrote" : "failed to write", partition); + + result = success ? partition : strdup(""); + done: if (result != partition) FreeValue(partition_value); FreeValue(contents); @@ -990,6 +945,14 @@ Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(buffer); } +Value* WipeCacheFn(const char* name, State* state, int argc, Expr* argv[]) { + if (argc != 0) { + return ErrorAbort(state, "%s() expects no args, got %d", name, argc); + } + fprintf(((UpdaterInfo*)(state->cookie))->cmd_pipe, "wipe_cache\n"); + return StringValue(strdup("t")); +} + Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc < 1) { return ErrorAbort(state, "%s() expects at least 1 arg", name); @@ -1147,8 +1110,6 @@ void RegisterInstallFunctions() { RegisterFunction("delete_recursive", DeleteFn); RegisterFunction("package_extract_dir", PackageExtractDirFn); RegisterFunction("package_extract_file", PackageExtractFileFn); - RegisterFunction("retouch_binaries", RetouchBinariesFn); - RegisterFunction("undo_retouch_binaries", UndoRetouchBinariesFn); RegisterFunction("symlink", SymlinkFn); RegisterFunction("set_perm", SetPermFn); RegisterFunction("set_perm_recursive", SetPermFn); @@ -1164,6 +1125,8 @@ void RegisterInstallFunctions() { RegisterFunction("read_file", ReadFileFn); RegisterFunction("sha1_check", Sha1CheckFn); + RegisterFunction("wipe_cache", WipeCacheFn); + RegisterFunction("ui_print", UIPrintFn); RegisterFunction("run_program", RunProgramFn); diff --git a/updater/updater.c b/updater/updater.c index 6bc4f40..5f15808 100644 --- a/updater/updater.c +++ b/updater/updater.c @@ -32,6 +32,8 @@ // (Note it's "updateR-script", not the older "update-script".) #define SCRIPT_NAME "META-INF/com/google/android/updater-script" +struct selabel_handle *sehandle; + int main(int argc, char** argv) { // Various things log information to stdout or stderr more or less // at random. The log file makes more sense if buffering is @@ -63,7 +65,6 @@ int main(int argc, char** argv) { // Extract the script from the package. char* package_data = argv[3]; - setenv("UPDATE_PACKAGE", package_data, 1); ZipArchive za; int err; err = mzOpenZipArchive(package_data, &za); @@ -104,6 +105,19 @@ int main(int argc, char** argv) { return 6; } +#ifdef HAVE_SELINUX + struct selinux_opt seopts[] = { + { SELABEL_OPT_PATH, "/file_contexts" } + }; + + sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); + + if (!sehandle) { + fprintf(stderr, "Warning: No file_contexts\n"); + fprintf(cmd_pipe, "ui_print Warning: No file_contexts\n"); + } +#endif + // Evaluate the parsed script. UpdaterInfo updater_info; diff --git a/updater/updater.h b/updater/updater.h index bd60dc1..a00872c 100644 --- a/updater/updater.h +++ b/updater/updater.h @@ -20,10 +20,19 @@ #include <stdio.h> #include "minzip/Zip.h" +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#include <selinux/label.h> +#else +struct selabel_handle; +#endif + typedef struct { FILE* cmd_pipe; ZipArchive* package_zip; int version; } UpdaterInfo; +extern struct selabel_handle *sehandle; + #endif |