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 --- minzip/Android.mk | 8 +++++++- minzip/DirUtil.c | 21 ++++++++++++++++++++- minzip/DirUtil.h | 10 +++++++++- minzip/Zip.c | 25 ++++++++++++++++++++++--- minzip/Zip.h | 10 +++++++++- 5 files changed, 67 insertions(+), 7 deletions(-) (limited to 'minzip') 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 5d881f562..1f378b75c 100644 --- a/minzip/DirUtil.h +++ b/minzip/DirUtil.h @@ -20,6 +20,13 @@ #include #include +#ifdef HAVE_SELINUX +#include +#include +#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 @@ -34,7 +41,8 @@ * (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 */ 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 9f99fba5b..0b1c9d532 100644 --- a/minzip/Zip.h +++ b/minzip/Zip.h @@ -14,6 +14,13 @@ #include "Hash.h" #include "SysUtil.h" +#ifdef HAVE_SELINUX +#include +#include +#else +struct selabel_handle; +#endif + /* * One entry in the Zip archive. Treat this as opaque -- use accessors below. * @@ -208,6 +215,7 @@ 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); #endif /*_MINZIP_ZIP*/ -- cgit v1.2.3