summaryrefslogtreecommitdiff
path: root/sal
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2013-08-24 16:07:22 +0300
committerTor Lillqvist <tml@iki.fi>2013-08-25 00:29:17 +0300
commitfcdfc62f760b7e33025973a460f90023b59bad8f (patch)
tree1beb55664e00e5e29fe4a174ff92d560acfa38b1 /sal
parentf8ed55b38c41a4fba3bbafaf03a39cf4718259e0 (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.cxx51
-rw-r--r--sal/osl/unx/file_misc.cxx2
-rw-r--r--sal/osl/unx/file_stat.cxx4
-rw-r--r--sal/osl/unx/uunxapi.cxx144
-rw-r--r--sal/osl/unx/uunxapi.h5
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