aboutsummaryrefslogtreecommitdiffstats
path: root/updater
diff options
context:
space:
mode:
authorKoushik Dutta <koushd@gmail.com>2012-07-15 16:02:14 -0700
committerKoushik Dutta <koushd@gmail.com>2012-07-15 16:02:14 -0700
commit117a088d8db229ca1501e21feeb5829254900b62 (patch)
treec5205d4471e563be969d6fd5234014b32ed4781e /updater
parenta96fdfd99afa5cadfa5492920a73843cea1e462b (diff)
downloadbootable_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.mk9
-rw-r--r--updater/install.c263
-rw-r--r--updater/updater.c16
-rw-r--r--updater/updater.h9
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, &timestamp,
- 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