diff options
author | Tor Lillqvist <tml@iki.fi> | 2013-08-24 16:07:22 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@iki.fi> | 2013-08-25 00:29:17 +0300 |
commit | fcdfc62f760b7e33025973a460f90023b59bad8f (patch) | |
tree | 1beb55664e00e5e29fe4a174ff92d560acfa38b1 /sal | |
parent | f8ed55b38c41a4fba3bbafaf03a39cf4718259e0 (diff) |
Do more syscalls using a security scope bookmark on OS X when sandboxed
Move the handling of the bookmarks to the wrappers in uunxapi.cxx, and
add wrappers for open() and utime().
Change-Id: I92f9941152b567545eea60f2aaae6a3b8d35e792
Diffstat (limited to 'sal')
-rw-r--r-- | sal/osl/unx/file.cxx | 51 | ||||
-rw-r--r-- | sal/osl/unx/file_misc.cxx | 2 | ||||
-rw-r--r-- | sal/osl/unx/file_stat.cxx | 4 | ||||
-rw-r--r-- | sal/osl/unx/uunxapi.cxx | 144 | ||||
-rw-r--r-- | sal/osl/unx/uunxapi.h | 5 |
5 files changed, 144 insertions, 62 deletions
diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx index cf9e49132d05..debccf93b3c1 100644 --- a/sal/osl/unx/file.cxx +++ b/sal/osl/unx/file.cxx @@ -29,6 +29,7 @@ #include "createfilehandlefromfd.hxx" #include "file_error_transl.h" #include "file_url.h" +#include "uunxapi.h" #include <algorithm> #include <limits> @@ -43,7 +44,7 @@ #include <sys/mount.h> #define HAVE_O_EXLOCK -#include <Foundation/Foundation.h> +#include <CoreFoundation/CoreFoundation.h> #endif /* MACOSX */ @@ -842,17 +843,6 @@ SAL_CALL osl_openMemoryAsFile( void *address, size_t size, oslFileHandle *pHandl #define OPEN_CREATE_FLAGS ( O_CREAT | O_RDWR ) #endif -#if defined(MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 && HAVE_FEATURE_MACOSX_SANDBOX - -static NSUserDefaults *userDefaults = NULL; - -static void get_user_defaults() -{ - userDefaults = [NSUserDefaults standardUserDefaults]; -} - -#endif - oslFileError SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_uInt32 uFlags ) { @@ -916,41 +906,8 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u flags = osl_file_adjustLockFlags (cpFilePath, flags); } -#if defined(MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 && HAVE_FEATURE_MACOSX_SANDBOX - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, &get_user_defaults); - NSURL *fileURL = NULL; - NSData *data = NULL; - NSURL *scopeURL = NULL; - BOOL stale; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - if (userDefaults != NULL) - fileURL = [NSURL fileURLWithPath:[NSString stringWithUTF8String:cpFilePath]]; - - if (fileURL != NULL) - data = [userDefaults dataForKey:[@"bookmarkFor:" stringByAppendingString:[fileURL absoluteString]]]; - - if (data != NULL) - scopeURL = [NSURL URLByResolvingBookmarkData:data - options:NSURLBookmarkResolutionWithSecurityScope - relativeToURL:nil - bookmarkDataIsStale:&stale - error:nil]; - if (scopeURL != NULL) - [scopeURL startAccessingSecurityScopedResource]; -#endif - /* open the file */ - int fd = open( cpFilePath, flags, mode ); - - -#if defined(MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 && HAVE_FEATURE_MACOSX_SANDBOX - if (scopeURL != NULL) - [scopeURL stopAccessingSecurityScopedResource]; - [pool release]; -#endif + int fd = open_c( cpFilePath, flags, mode ); #ifdef IOS /* Horrible hack: If opening for RDWR and getting EPERM, just try @@ -961,7 +918,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u if (-1 == fd && (flags & O_RDWR) && EPERM == errno) { int rdonly_flags = (flags & ~O_ACCMODE) | O_RDONLY; - fd = open( cpFilePath, rdonly_flags, mode ); + fd = open_c( cpFilePath, rdonly_flags, mode ); } #endif if (-1 == fd) diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx index 0ee3a66c1bb2..99b5a4d5add3 100644 --- a/sal/osl/unx/file_misc.cxx +++ b/sal/osl/unx/file_misc.cxx @@ -740,7 +740,7 @@ static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* p nUID=aFileStat.st_uid; nGID=aFileStat.st_gid; - nRet = stat(pszDestPath,&aFileStat); + nRet = stat_c(pszDestPath,&aFileStat); if ( nRet < 0 ) { nRet=errno; diff --git a/sal/osl/unx/file_stat.cxx b/sal/osl/unx/file_stat.cxx index 85331ba164f0..5d6bd109482d 100644 --- a/sal/osl/unx/file_stat.cxx +++ b/sal/osl/unx/file_stat.cxx @@ -327,7 +327,7 @@ static oslFileError osl_psz_setFileTime ( struct tm* pTM=0; #endif - nRet = lstat(pszFilePath,&aFileStat); + nRet = lstat_c(pszFilePath,&aFileStat); if ( nRet < 0 ) { @@ -385,7 +385,7 @@ static oslFileError osl_psz_setFileTime ( fprintf(stderr,"Modification now '%s'\n",ctime(&aTimeBuffer.modtime)); #endif - nRet=utime(pszFilePath,&aTimeBuffer); + nRet = utime_c(pszFilePath,&aTimeBuffer); if ( nRet < 0 ) { nRet=errno; diff --git a/sal/osl/unx/uunxapi.cxx b/sal/osl/unx/uunxapi.cxx index 83c321fccca0..9b40644e8b27 100644 --- a/sal/osl/unx/uunxapi.cxx +++ b/sal/osl/unx/uunxapi.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_features.h> + #include "uunxapi.h" #include "system.h" #include <limits.h> @@ -33,14 +35,84 @@ inline rtl::OString OUStringToOString(const rtl_uString* s) osl_getThreadTextEncoding()); } +#if defined(MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 && HAVE_FEATURE_MACOSX_SANDBOX + +static NSUserDefaults *userDefaults = NULL; + +static void get_user_defaults() +{ + userDefaults = [NSUserDefaults standardUserDefaults]; +} + +typedef struct { + NSURL *scopeURL; + NSAutoreleasePool *pool; +} accessFilePathState; + +static accessFilePathState * +prepare_to_access_file_path( const char *cpFilePath ) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, &get_user_defaults); + NSURL *fileURL = nil; + NSData *data = nil; + BOOL stale; + accessFilePathState *state; + + // If malloc() fails we are screwed anyway + state = (accessFilePathState*) malloc(sizeof(accessFilePathState)); + + state->pool = [[NSAutoreleasePool alloc] init]; + state->scopeURL = nil; + + if (userDefaults != nil) + fileURL = [NSURL fileURLWithPath:[NSString stringWithUTF8String:cpFilePath]]; + + if (fileURL != nil) + data = [userDefaults dataForKey:[@"bookmarkFor:" stringByAppendingString:[fileURL absoluteString]]]; + + if (data != nil) + state->scopeURL = [NSURL URLByResolvingBookmarkData:data + options:NSURLBookmarkResolutionWithSecurityScope + relativeToURL:nil + bookmarkDataIsStale:&stale + error:nil]; + if (state->scopeURL != nil) + [state->scopeURL startAccessingSecurityScopedResource]; + + return state; +} + +static void +done_accessing_file_path( const char * /*cpFilePath*/, accessFilePathState *state ) +{ + int saved_errno = errno; + + if (state->scopeURL != nil) + [state->scopeURL stopAccessingSecurityScopedResource]; + [state->pool release]; + free(state); + + errno = saved_errno; +} + +#else + +typedef void accessFilePathState; + +#define prepare_to_access_file_path( cpFilePath ) NULL + +#define done_accessing_file_path( cpFilePath, state ) ((void) cpFilePath, (void) state) + +#endif + #ifdef MACOSX /* * Helper function for resolving Mac native alias files (not the same as unix alias files) * and to return the resolved alias as rtl::OString */ -inline rtl::OString macxp_resolveAliasAndConvert(const rtl_uString* s) +static rtl::OString macxp_resolveAliasAndConvert(rtl::OString p) { - rtl::OString p = OUStringToOString(s); sal_Char path[PATH_MAX]; if (p.getLength() < PATH_MAX) { @@ -54,8 +126,8 @@ inline rtl::OString macxp_resolveAliasAndConvert(const rtl_uString* s) int access_u(const rtl_uString* pustrPath, int mode) { -#ifndef MACOSX rtl::OString fn = OUStringToOString(pustrPath); +#ifndef MACOSX #ifdef ANDROID if (strncmp(fn.getStr(), "/assets", sizeof("/assets")-1) == 0 && (fn.getStr()[sizeof("/assets")-1] == '\0' || @@ -74,13 +146,20 @@ int access_u(const rtl_uString* pustrPath, int mode) #endif return access(fn.getStr(), mode); #else - return access(macxp_resolveAliasAndConvert(pustrPath).getStr(), mode); + + accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); + + int result = access(macxp_resolveAliasAndConvert(fn).getStr(), mode); + + done_accessing_file_path(fn.getStr(), state); + + return result; + #endif } sal_Bool realpath_u(const rtl_uString* pustrFileName, rtl_uString** ppustrResolvedName) { -#ifndef MACOSX rtl::OString fn = OUStringToOString(pustrFileName); #ifdef ANDROID if (strncmp(fn.getStr(), "/assets", sizeof("/assets")-1) == 0 && @@ -96,12 +175,18 @@ sal_Bool realpath_u(const rtl_uString* pustrFileName, rtl_uString** ppustrResolv return sal_True; } #endif -#else - rtl::OString fn = macxp_resolveAliasAndConvert(pustrFileName); + + accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); + +#ifdef MACOSX + fn = macxp_resolveAliasAndConvert(fn); #endif + char rp[PATH_MAX]; bool bRet = realpath(fn.getStr(), rp); + done_accessing_file_path(fn.getStr(), state); + if (bRet) { rtl::OUString resolved = rtl::OStringToOUString(rtl::OString(static_cast<sal_Char*>(rp)), @@ -131,22 +216,59 @@ int lstat_c(const char* cpPath, struct stat* buf) cpPath[sizeof("/assets")-1] == '/')) return lo_apk_lstat(cpPath, buf); #endif - return lstat(cpPath, buf); + + accessFilePathState *state = prepare_to_access_file_path(cpPath); + + int result = lstat(cpPath, buf); + + done_accessing_file_path(cpPath, state); + + return result; } int lstat_u(const rtl_uString* pustrPath, struct stat* buf) { -#ifndef MACOSX rtl::OString fn = OUStringToOString(pustrPath); +#ifndef MACOSX return lstat_c(fn.getStr(), buf); #else - return lstat(macxp_resolveAliasAndConvert(pustrPath).getStr(), buf); + return lstat(macxp_resolveAliasAndConvert(fn).getStr(), buf); #endif } int mkdir_u(const rtl_uString* path, mode_t mode) { - return mkdir(OUStringToOString(path).getStr(), mode); + rtl::OString fn = OUStringToOString(path); + + accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); + + int result = mkdir(OUStringToOString(path).getStr(), mode); + + done_accessing_file_path(fn.getStr(), state); + + return result; +} + +int open_c(const char *cpPath, int oflag, int mode) +{ + accessFilePathState *state = prepare_to_access_file_path(cpPath); + + int result = open(cpPath, oflag, mode); + + done_accessing_file_path(cpPath, state); + + return result; +} + +int utime_c(const char *cpPath, struct utimbuf *times) +{ + accessFilePathState *state = prepare_to_access_file_path(cpPath); + + int result = utime(cpPath, times); + + done_accessing_file_path(cpPath, state); + + return result; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/unx/uunxapi.h b/sal/osl/unx/uunxapi.h index 286c48230f7d..0e4106e70742 100644 --- a/sal/osl/unx/uunxapi.h +++ b/sal/osl/unx/uunxapi.h @@ -31,7 +31,6 @@ extern "C" { #endif -/* @see access */ int access_u(const rtl_uString* pustrPath, int mode); /*********************************** @@ -56,6 +55,10 @@ int lstat_u(const rtl_uString* pustrPath, struct stat* buf); int mkdir_u(const rtl_uString* path, mode_t mode); +int open_c(const char *cpPath, int oflag, int mode); + +int utime_c(const char *cpPath, struct utimbuf *times); + #ifdef __cplusplus } #endif |