diff options
author | Tor Lillqvist <tml@iki.fi> | 2013-08-24 22:01:18 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@iki.fi> | 2013-08-25 00:29:18 +0300 |
commit | fa9ef668fb8b0abfdf85d641048580fa7c2fee3e (patch) | |
tree | 44ec2474ab4842628c4906ae20cf1e1397b73d30 /sal | |
parent | 2599bc9d6723daee921e3bf65124928bf56c8241 (diff) |
More work on a sandboxed LibreOffice on OS X
In particular, surround also the ftruncate() operation that
osl_setFileSize() does with access through a security scope bookmark
for the file, if available. This fixes file saving in a sandboxed
LibreOffice. (But oh boy, does simply saving an ODT document go though
a weird dance of file operations.)
Luckily the C++ oslFileHandle abstraction keeps the pathname that the
file was opened with, so even if ftruncate() as such takes only the
file descriptor, we can get at the pathname to retrieve our security
scope bookmark.
Change-Id: I8acb1b2f3fb3ec0cea833697b7f1d4a1912ed551
Diffstat (limited to 'sal')
-rw-r--r-- | sal/osl/unx/file.cxx | 2 | ||||
-rw-r--r-- | sal/osl/unx/uunxapi.cxx | 59 | ||||
-rw-r--r-- | sal/osl/unx/uunxapi.h | 4 |
3 files changed, 50 insertions, 15 deletions
diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx index 9ed1892dc031..a0ef50eae0e7 100644 --- a/sal/osl/unx/file.cxx +++ b/sal/osl/unx/file.cxx @@ -307,7 +307,7 @@ sal_uInt64 FileHandle_Impl::getSize() const oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize) { off_t const nSize = sal::static_int_cast< off_t >(uSize); - if (-1 == ftruncate (m_fd, nSize)) + if (-1 == ftruncate_with_name (m_fd, nSize, m_strFilePath)) { /* Failure. Save original result. Try fallback algorithm */ oslFileError result = oslTranslateFileError (OSL_FET_ERROR, errno); diff --git a/sal/osl/unx/uunxapi.cxx b/sal/osl/unx/uunxapi.cxx index 9b40644e8b27..7eb2ed910467 100644 --- a/sal/osl/unx/uunxapi.cxx +++ b/sal/osl/unx/uunxapi.cxx @@ -127,7 +127,6 @@ static rtl::OString macxp_resolveAliasAndConvert(rtl::OString p) int access_u(const rtl_uString* pustrPath, int mode) { rtl::OString fn = OUStringToOString(pustrPath); -#ifndef MACOSX #ifdef ANDROID if (strncmp(fn.getStr(), "/assets", sizeof("/assets")-1) == 0 && (fn.getStr()[sizeof("/assets")-1] == '\0' || @@ -144,18 +143,18 @@ int access_u(const rtl_uString* pustrPath, int mode) return 0; } #endif - return access(fn.getStr(), mode); -#else + +#ifdef MACOSX + fn = macxp_resolveAliasAndConvert(fn); +#endif accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); - int result = access(macxp_resolveAliasAndConvert(fn).getStr(), mode); + int result = access(fn.getStr(), mode); done_accessing_file_path(fn.getStr(), state); return result; - -#endif } sal_Bool realpath_u(const rtl_uString* pustrFileName, rtl_uString** ppustrResolvedName) @@ -176,12 +175,12 @@ sal_Bool realpath_u(const rtl_uString* pustrFileName, rtl_uString** ppustrResolv } #endif - accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); - #ifdef MACOSX fn = macxp_resolveAliasAndConvert(fn); #endif + accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); + char rp[PATH_MAX]; bool bRet = realpath(fn.getStr(), rp); @@ -205,7 +204,14 @@ int stat_c(const char* cpPath, struct stat* buf) cpPath[sizeof("/assets")-1] == '/')) return lo_apk_lstat(cpPath, buf); #endif - return stat(cpPath, buf); + + accessFilePathState *state = prepare_to_access_file_path(cpPath); + + int result = stat(cpPath, buf); + + done_accessing_file_path(cpPath, state); + + return result; } int lstat_c(const char* cpPath, struct stat* buf) @@ -229,11 +235,12 @@ int lstat_c(const char* cpPath, struct stat* buf) int lstat_u(const rtl_uString* pustrPath, struct stat* buf) { rtl::OString fn = OUStringToOString(pustrPath); -#ifndef MACOSX - return lstat_c(fn.getStr(), buf); -#else - return lstat(macxp_resolveAliasAndConvert(fn).getStr(), buf); + +#ifdef MACOSX + fn = macxp_resolveAliasAndConvert(fn); #endif + + return lstat_c(fn.getStr(), buf); } int mkdir_u(const rtl_uString* path, mode_t mode) @@ -271,4 +278,30 @@ int utime_c(const char *cpPath, struct utimbuf *times) return result; } +int ftruncate_with_name(int fd, sal_uInt64 uSize, rtl_String* path) +{ + /* When sandboxed on OS X, ftruncate(), even if it takes an + * already open file descriptor which was retuned from an open() + * call already checked by the sandbox, still requires a security + * scope bookmark for the file to be active in case the file is + * one that the sandbox doesn't otherwise allow access to. Luckily + * LibreOffice usually calls ftruncate() through the helpful C++ + * abstraction layer that keeps the pathname around. + */ + + rtl::OString fn = rtl::OString(path); + +#ifdef MACOSX + fn = macxp_resolveAliasAndConvert(fn); +#endif + + accessFilePathState *state = prepare_to_access_file_path(fn.getStr()); + + int result = ftruncate(fd, uSize); + + done_accessing_file_path(fn.getStr(), 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 0e4106e70742..3b431ad292e2 100644 --- a/sal/osl/unx/uunxapi.h +++ b/sal/osl/unx/uunxapi.h @@ -45,7 +45,7 @@ int access_u(const rtl_uString* pustrPath, int mode); **********************************/ sal_Bool realpath_u( const rtl_uString* pustrFileName, - rtl_uString** ppustrResolvedName); + rtl_uString** ppustrResolvedName); int stat_c(const char *cpPath, struct stat* buf); @@ -59,6 +59,8 @@ int open_c(const char *cpPath, int oflag, int mode); int utime_c(const char *cpPath, struct utimbuf *times); +int ftruncate_with_name(int fd, sal_uInt64 uSize, rtl_String* path); + #ifdef __cplusplus } #endif |