diff options
-rw-r--r-- | Android.mk | 12 | ||||
-rw-r--r-- | minzip/Android.mk | 8 | ||||
-rw-r--r-- | minzip/DirUtil.c | 21 | ||||
-rw-r--r-- | minzip/DirUtil.h | 10 | ||||
-rw-r--r-- | minzip/Zip.c | 25 | ||||
-rw-r--r-- | minzip/Zip.h | 10 | ||||
-rw-r--r-- | recovery.cpp | 17 | ||||
-rw-r--r-- | roots.cpp | 4 | ||||
-rw-r--r-- | updater/Android.mk | 6 | ||||
-rw-r--r-- | updater/install.c | 46 | ||||
-rw-r--r-- | updater/updater.c | 15 | ||||
-rw-r--r-- | updater/updater.h | 9 |
12 files changed, 167 insertions, 16 deletions
diff --git a/Android.mk b/Android.mk index 036da9ee3..21e6946c2 100644 --- a/Android.mk +++ b/Android.mk @@ -28,6 +28,12 @@ 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 + # This binary is in the recovery ramdisk, which is otherwise a copy of root. # It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses # a (redundant) copy of the binary in /system/bin for user builds. @@ -45,6 +51,12 @@ LOCAL_STATIC_LIBRARIES += libminzip libz libmtdutils libmincrypt libminadbd LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils LOCAL_STATIC_LIBRARIES += libstdc++ libc +ifeq ($(HAVE_SELINUX),true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_STATIC_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + LOCAL_C_INCLUDES += system/extras/ext4_utils include $(BUILD_EXECUTABLE) diff --git a/minzip/Android.mk b/minzip/Android.mk index b1ee67439..6c1d0969c 100644 --- a/minzip/Android.mk +++ b/minzip/Android.mk @@ -11,7 +11,13 @@ LOCAL_SRC_FILES := \ LOCAL_C_INCLUDES += \ external/zlib \ external/safe-iop/include - + +ifeq ($(HAVE_SELINUX),true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_STATIC_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif + LOCAL_MODULE := libminzip LOCAL_CFLAGS += -Wall diff --git a/minzip/DirUtil.c b/minzip/DirUtil.c index 20c89cd6f..0d49b5780 100644 --- a/minzip/DirUtil.c +++ b/minzip/DirUtil.c @@ -54,7 +54,8 @@ getPathDirStatus(const char *path) int dirCreateHierarchy(const char *path, int mode, - const struct utimbuf *timestamp, bool stripFileName) + const struct utimbuf *timestamp, bool stripFileName, + struct selabel_handle *sehnd) { DirStatus ds; @@ -144,7 +145,25 @@ dirCreateHierarchy(const char *path, int mode, } else if (ds == DMISSING) { int err; +#ifdef HAVE_SELINUX + char *secontext = NULL; + + if (sehnd) { + selabel_lookup(sehnd, &secontext, cpath, mode); + setfscreatecon(secontext); + } +#endif + err = mkdir(cpath, mode); + +#ifdef HAVE_SELINUX + + if (secontext) { + freecon(secontext); + setfscreatecon(NULL); + } +#endif + if (err != 0) { free(cpath); return -1; diff --git a/minzip/DirUtil.h b/minzip/DirUtil.h index 0d5ea7ccb..f8be64026 100644 --- a/minzip/DirUtil.h +++ b/minzip/DirUtil.h @@ -24,6 +24,13 @@ extern "C" { #endif +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#include <selinux/label.h> +#else +struct selabel_handle; +#endif + /* Like "mkdir -p", try to guarantee that all directories * specified in path are present, creating as many directories * as necessary. The specified mode is passed to all mkdir @@ -38,7 +45,8 @@ extern "C" { * (usually if some element of path is not a directory). */ int dirCreateHierarchy(const char *path, int mode, - const struct utimbuf *timestamp, bool stripFileName); + const struct utimbuf *timestamp, bool stripFileName, + struct selabel_handle* sehnd); /* rm -rf <path> */ diff --git a/minzip/Zip.c b/minzip/Zip.c index 46d2f829e..54d5d55a3 100644 --- a/minzip/Zip.c +++ b/minzip/Zip.c @@ -930,7 +930,8 @@ static const char *targetEntryPath(MzPathHelper *helper, ZipEntry *pEntry) bool mzExtractRecursive(const ZipArchive *pArchive, const char *zipDir, const char *targetDir, int flags, const struct utimbuf *timestamp, - void (*callback)(const char *fn, void *), void *cookie) + void (*callback)(const char *fn, void *), void *cookie, + struct selabel_handle *sehnd) { if (zipDir[0] == '/') { LOGE("mzExtractRecursive(): zipDir must be a relative path.\n"); @@ -1045,7 +1046,7 @@ bool mzExtractRecursive(const ZipArchive *pArchive, if (pEntry->fileName[pEntry->fileNameLen-1] == '/') { if (!(flags & MZ_EXTRACT_FILES_ONLY)) { int ret = dirCreateHierarchy( - targetFile, UNZIP_DIRMODE, timestamp, false); + targetFile, UNZIP_DIRMODE, timestamp, false, sehnd); if (ret != 0) { LOGE("Can't create containing directory for \"%s\": %s\n", targetFile, strerror(errno)); @@ -1059,7 +1060,7 @@ bool mzExtractRecursive(const ZipArchive *pArchive, * the containing directory exists. */ int ret = dirCreateHierarchy( - targetFile, UNZIP_DIRMODE, timestamp, true); + targetFile, UNZIP_DIRMODE, timestamp, true, sehnd); if (ret != 0) { LOGE("Can't create containing directory for \"%s\": %s\n", targetFile, strerror(errno)); @@ -1113,7 +1114,25 @@ bool mzExtractRecursive(const ZipArchive *pArchive, /* The entry is a regular file. * Open the target for writing. */ + +#ifdef HAVE_SELINUX + char *secontext = NULL; + + if (sehnd) { + selabel_lookup(sehnd, &secontext, targetFile, UNZIP_FILEMODE); + setfscreatecon(secontext); + } +#endif + int fd = creat(targetFile, UNZIP_FILEMODE); + +#ifdef HAVE_SELINUX + if (secontext) { + freecon(secontext); + setfscreatecon(NULL); + } +#endif + if (fd < 0) { LOGE("Can't create target file \"%s\": %s\n", targetFile, strerror(errno)); diff --git a/minzip/Zip.h b/minzip/Zip.h index 739dbf5f2..4bb9ef6a4 100644 --- a/minzip/Zip.h +++ b/minzip/Zip.h @@ -18,6 +18,13 @@ extern "C" { #endif +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#include <selinux/label.h> +#else +struct selabel_handle; +#endif + /* * One entry in the Zip archive. Treat this as opaque -- use accessors below. * @@ -212,7 +219,8 @@ enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 }; bool mzExtractRecursive(const ZipArchive *pArchive, const char *zipDir, const char *targetDir, int flags, const struct utimbuf *timestamp, - void (*callback)(const char *fn, void*), void *cookie); + void (*callback)(const char *fn, void*), void *cookie, + struct selabel_handle *sehnd); #ifdef __cplusplus } diff --git a/recovery.cpp b/recovery.cpp index 726442b84..baafadca0 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -45,6 +45,8 @@ extern "C" { #include "minadbd/adb.h" } +struct selabel_handle *sehandle; + static const struct option OPTIONS[] = { { "send_intent", required_argument, NULL, 's' }, { "update_package", required_argument, NULL, 'u' }, @@ -138,7 +140,7 @@ fopen_path(const char *path, const char *mode) { // When writing, try to create the containing directory, if necessary. // Use generous permissions, the system (init.rc) will reset them. - if (strchr("wa", mode[0])) dirCreateHierarchy(path, 0777, NULL, 1); + if (strchr("wa", mode[0])) dirCreateHierarchy(path, 0777, NULL, 1, sehandle); FILE *fp = fopen(path, mode); return fp; @@ -803,6 +805,19 @@ main(int argc, char **argv) { } } +#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"); + ui_print("Warning: No file_contexts\n"); + } +#endif + device->StartRecovery(); printf("Command:"); @@ -31,6 +31,8 @@ static int num_volumes = 0; static Volume* device_volumes = NULL; +extern struct selabel_handle *sehandle; + static int parse_options(char* options, Volume* volume) { char* option; while ((option = strtok(options, ","))) { @@ -269,7 +271,7 @@ int format_volume(const char* volume) { } if (strcmp(v->fs_type, "ext4") == 0) { - int result = make_ext4fs(v->device, v->length); + int result = make_ext4fs(v->device, v->length, volume, sehandle); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", v->device); return -1; diff --git a/updater/Android.mk b/updater/Android.mk index 8d731db3e..f8ccb76b5 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -24,6 +24,12 @@ 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 + 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 diff --git a/updater/install.c b/updater/install.c index 7b7bfc903..31f08b85f 100644 --- a/updater/install.c +++ b/updater/install.c @@ -78,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; @@ -176,25 +192,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=<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 +// 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); @@ -210,6 +235,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); @@ -239,7 +271,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); @@ -346,7 +378,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 <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 |