From 779701db515d1a0d363d5a8896252f331bc4e22a Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Thu, 9 Feb 2012 14:13:23 -0500 Subject: Extend recovery and updater to support setting file security contexts. Extend minzip, recovery, and updater to set the security context on files based on the file_contexts configuration included in the package. Change-Id: Ied379f266a16c64f2b4dca15dc39b98fcce16f29 --- updater/Android.mk | 3 ++- updater/install.c | 46 +++++++++++++++++++++++++++++++++++++++------- updater/updater.c | 15 +++++++++++++++ updater/updater.h | 9 +++++++++ 4 files changed, 65 insertions(+), 8 deletions(-) (limited to 'updater') diff --git a/updater/Android.mk b/updater/Android.mk index 2c51f9990..f8ccb76b5 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -22,12 +22,13 @@ ifeq ($(TARGET_USERIMAGES_USE_EXT4), true) LOCAL_CFLAGS += -DUSE_EXT4 LOCAL_C_INCLUDES += system/extras/ext4_utils LOCAL_STATIC_LIBRARIES += libext4_utils libz +endif + ifeq ($(HAVE_SELINUX), true) LOCAL_C_INCLUDES += external/libselinux/include LOCAL_STATIC_LIBRARIES += libselinux LOCAL_CFLAGS += -DHAVE_SELINUX endif # HAVE_SELINUX -endif LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz diff --git a/updater/install.c b/updater/install.c index 7b4b99b01..a59c4edac 100644 --- a/updater/install.c +++ b/updater/install.c @@ -79,8 +79,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; @@ -177,25 +193,34 @@ 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= -// fs_type="ext4" partition_type="EMMC" location=device fs_size= +// fs_type="yaffs2" partition_type="MTD" location=partition fs_size= mount_point= +// fs_type="ext4" partition_type="EMMC" location=device fs_size= mount_point= // 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 +// mount_point is used with SELinux as the location of the mount point, absent otherwise 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 != 4 && argc != 5) { + return ErrorAbort(state, "%s() expects 4 or 5 args, got %d", name, argc); } char* fs_type; char* partition_type; char* location; char* fs_size; + char* mount_point = NULL; + +#ifdef HAVE_SELINUX + if (ReadArgs(state, argv, 5, &fs_type, &partition_type, &location, &fs_size, &mount_point) < 0) { + return NULL; + } +#else if (ReadArgs(state, argv, 4, &fs_type, &partition_type, &location, &fs_size) < 0) { return NULL; } +#endif if (strlen(fs_type) == 0) { ErrorAbort(state, "fs_type argument to %s() can't be empty", name); @@ -211,6 +236,13 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } +#ifdef HAVE_SELINUX + if (!mount_point || strlen(mount_point) == 0) { + ErrorAbort(state, "mount_point argument to %s() can't be empty", name); + goto done; + } +#endif + if (strcmp(partition_type, "MTD") == 0) { mtd_scan_partitions(); const MtdPartition* mtd = mtd_find_partition_by_name(location); @@ -240,7 +272,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); @@ -347,7 +379,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" : "")); diff --git a/updater/updater.c b/updater/updater.c index aa626d29b..5f1580870 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 @@ -103,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 bd60dc1fd..a00872ca4 100644 --- a/updater/updater.h +++ b/updater/updater.h @@ -20,10 +20,19 @@ #include #include "minzip/Zip.h" +#ifdef HAVE_SELINUX +#include +#include +#else +struct selabel_handle; +#endif + typedef struct { FILE* cmd_pipe; ZipArchive* package_zip; int version; } UpdaterInfo; +extern struct selabel_handle *sehandle; + #endif -- cgit v1.2.3