aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk12
-rw-r--r--minzip/Android.mk8
-rw-r--r--minzip/DirUtil.c21
-rw-r--r--minzip/DirUtil.h10
-rw-r--r--minzip/Zip.c25
-rw-r--r--minzip/Zip.h10
-rw-r--r--recovery.cpp17
-rw-r--r--roots.cpp4
-rw-r--r--updater/Android.mk6
-rw-r--r--updater/install.c46
-rw-r--r--updater/updater.c15
-rw-r--r--updater/updater.h9
12 files changed, 167 insertions, 16 deletions
diff --git a/Android.mk b/Android.mk
index 036da9e..21e6946 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 b1ee674..6c1d096 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 20c89cd..0d49b57 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 0d5ea7c..f8be640 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 46d2f82..54d5d55 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 739dbf5..4bb9ef6 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 726442b..baafadc 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:");
diff --git a/roots.cpp b/roots.cpp
index 9345cb0..ca37cf1 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -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 8d731db..f8ccb76 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 7b7bfc9..31f08b8 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, &timestamp,
- 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 aa626d2..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
@@ -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 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