[Libreoffice-commits] core.git: 5 commits - desktop/source include/sal sal/osl ucb/source

Tor Lillqvist tml at iki.fi
Sat Aug 24 14:31:44 PDT 2013


 desktop/source/deployment/manager/dp_manager.cxx |    5 
 include/sal/log-areas.dox                        |    1 
 sal/osl/unx/file.cxx                             |  132 +++-------------
 sal/osl/unx/file_misc.cxx                        |    2 
 sal/osl/unx/file_stat.cxx                        |    4 
 sal/osl/unx/uunxapi.cxx                          |  187 +++++++++++++++++++++--
 sal/osl/unx/uunxapi.h                            |    9 -
 ucb/source/ucp/file/shell.cxx                    |   21 ++
 8 files changed, 240 insertions(+), 121 deletions(-)

New commits:
commit 70a05c8ee8129941c801bb0e6bc93ea8e42bc254
Author: Tor Lillqvist <tml at iki.fi>
Date:   Sat Aug 24 22:43:43 2013 +0300

    Avoid OS X sandbox messages when just checking if a pathname is a directory
    
    Calling stat() on an arbitrary directory doesn't cause any sandbox
    violation, it seems, even if the process has no access to that
    directory. Calling opendir() on it is a sandbox violation.
    
    Change-Id: I776c04653cbeeb511a4a1e455fcc2b10ed4a0e5c

diff --git a/ucb/source/ucp/file/shell.cxx b/ucb/source/ucp/file/shell.cxx
index b9c0390..a9cd7e4 100644
--- a/ucb/source/ucp/file/shell.cxx
+++ b/ucb/source/ucp/file/shell.cxx
@@ -17,6 +17,10 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <config_features.h>
+
+#include <sys/stat.h>
+
 #include <stack>
 #include "osl/diagnose.h"
 #include <rtl/uri.hxx>
@@ -2074,6 +2078,23 @@ sal_Bool SAL_CALL shell::ensuredir( sal_Int32 CommandId,
     else
         aPath = rUnqPath;
 
+#if HAVE_FEATURE_MACOSX_SANDBOX
+
+    // Avoid annoying sandbox messages in the system.log from the
+    // below aDirectory.open(), which ends up calling opendir().
+    // Surely it is easier to just call stat()? Calling stat() on an
+    // arbitrary (?) directory does not seem to cause any sandbox
+    // violation, while opendir() does. (Sorry I could not be bothered
+    // to use some complex cross-platform abstraction over stat() here
+    // in this OS X specific code block.)
+
+    OUString aDirName;
+    struct stat s;
+    if( osl::FileBase::getSystemPathFromFileURL( aPath, aDirName ) == osl::FileBase::E_None &&
+        stat(OUStringToOString( aDirName, RTL_TEXTENCODING_UTF8).getStr(), &s ) == 0 &&
+        S_ISDIR( s.st_mode ) )
+        return sal_True;
+#endif
 
     // HACK: create directory on a mount point with nobrowse option
     // returns ENOSYS in any case !!
commit fa9ef668fb8b0abfdf85d641048580fa7c2fee3e
Author: Tor Lillqvist <tml at iki.fi>
Date:   Sat Aug 24 22:01:18 2013 +0300

    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

diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index 9ed1892..a0ef50e 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 9b40644..7eb2ed9 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 0e4106e..3b431ad 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
commit 2599bc9d6723daee921e3bf65124928bf56c8241
Author: Tor Lillqvist <tml at iki.fi>
Date:   Sat Aug 24 21:45:25 2013 +0300

    Switch from OSL_TRACE to SAL_INFO()
    
    Change-Id: I2222a8db929e2f17aff9f72ff2ae1ca6e081e576

diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index e7c60c2..f888b8c 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -21,6 +21,7 @@ certain functionality.
 @section SAL
 
 @li @c sal.debug - SAL debugging functionality
+ at li @c sal.file
 @li @c sal.osl - SAL OSL library
 @li @c sal.rtl - SAL RTL library
 @li @c sal.textenc - the textencoding SAL library
diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index debccf9..9ed1892 100644
--- a/sal/osl/unx/file.cxx
+++ b/sal/osl/unx/file.cxx
@@ -25,6 +25,8 @@
 #include "osl/diagnose.h"
 #include "rtl/alloc.h"
 
+#include <sal/log.hxx>
+
 #include "system.h"
 #include "createfilehandlefromfd.hxx"
 #include "file_error_transl.h"
@@ -52,13 +54,12 @@
 #include <osl/detail/android-bootstrap.h>
 #endif
 
-#ifdef DEBUG_OSL_FILE
-#   define OSL_FILE_TRACE osl_trace
-#else
-#   define OSL_FILE_TRACE(fmt, ...)
-#endif
-
-
+template< typename charT, typename traits > std::basic_ostream<charT, traits> &
+operator <<(
+    std::basic_ostream<charT, traits> & stream, rtl_String * string)
+{
+    return stream << rtl_string_getStr(string);
+}
 
 /*******************************************************************
  *
@@ -292,7 +293,7 @@ sal_uInt64 FileHandle_Impl::getPos() const
 
 oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos)
 {
-    OSL_FILE_TRACE("FileHandle_Impl::setPos(%d, %lld) => %lld", m_fd, getPos(), uPos);
+    SAL_INFO("osl.file", "FileHandle_Impl::setPos(" << m_fd << ", " << getPos() << ") => " << uPos);
     m_fileptr = sal::static_int_cast< off_t >(uPos);
     return osl_File_E_None;
 }
@@ -339,7 +340,7 @@ oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize)
             return (result);
     }
 
-    OSL_FILE_TRACE("osl_setFileSize(%d, %lld) => %ld", m_fd, getSize(), nSize);
+    SAL_INFO("osl.file", "osl_setFileSize(" << m_fd << ", " << getSize() << ") => " << nSize);
     m_size = sal::static_int_cast< sal_uInt64 >(nSize);
     return osl_File_E_None;
 }
@@ -388,7 +389,7 @@ oslFileError FileHandle_Impl::readAt (
     if (-1 == nBytes)
         return oslTranslateFileError (OSL_FET_ERROR, errno);
 
-    OSL_FILE_TRACE("FileHandle_Impl::readAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
+    SAL_INFO("sal.file", "FileHandle_Impl::readAt(" << m_fd << ", " << nOffset << ", " << nBytes << ")");
     *pBytesRead = nBytes;
     return osl_File_E_None;
 }
@@ -411,7 +412,7 @@ oslFileError FileHandle_Impl::writeAt (
     if (-1 == nBytes)
         return oslTranslateFileError (OSL_FET_ERROR, errno);
 
-    OSL_FILE_TRACE("FileHandle_Impl::writeAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
+    SAL_INFO("sal.file", "FileHandle_Impl::writeAt(" << m_fd << ", " << nOffset << ", " << nBytes << ")");
     m_size = std::max (m_size, sal::static_int_cast< sal_uInt64 >(nOffset + nBytes));
 
     *pBytesWritten = nBytes;
@@ -480,7 +481,7 @@ oslFileError FileHandle_Impl::readFileAt (
             }
 
             size_t const bytes = std::min (m_buflen - bufpos, nBytesRequested);
-            OSL_FILE_TRACE("FileHandle_Impl::readFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
+            SAL_INFO("sal.file", "FileHandle_Impl::readFileAt(" << m_fd << ", " << nOffset << ", " << bytes << ")");
 
             memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes);
             nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes;
@@ -547,7 +548,7 @@ oslFileError FileHandle_Impl::writeFileAt (
             }
 
             size_t const bytes = std::min (m_bufsiz - bufpos, nBytesToWrite);
-            OSL_FILE_TRACE("FileHandle_Impl::writeFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
+            SAL_INFO("sal.file", "FileHandle_Impl::writeFileAt(" << m_fd << ", " << nOffset << ", " << bytes << ")");
 
             memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes);
             nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes;
@@ -742,8 +743,7 @@ oslFileHandle osl::detail::createFileHandleFromFD( int fd )
         pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
     }
 
-    OSL_FILE_TRACE("osl::detail::createFileHandleFromFD(%d, writeable) => %s",
-                   pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
+    SAL_INFO("sal.file", "osl::detail::createFileHandleFromFD(" << pImpl->m_fd << ", writeable) => " << pImpl->m_strFilePath);
     return (oslFileHandle)(pImpl);
 }
 
@@ -864,8 +864,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
         void *address;
         size_t size;
         address = lo_apkentry(cpFilePath, &size);
-        OSL_TRACE("osl_openFile(%s) => %p",
-                  cpFilePath, address);
+        SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << ") => " << address);
         if (address == NULL)
         {
             errno = ENOENT;
@@ -924,10 +923,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
     if (-1 == fd)
     {
         int saved_errno = errno;
-        OSL_TRACE("osl_openFile(%s, %s) failed: %s",
-                  cpFilePath,
-                  flags & O_RDWR ? "writeable":"readonly",
-                  strerror(saved_errno));
+        SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << ", " << (flags & O_RDWR ? "writeable":"readonly") << ") failed: " << strerror(saved_errno));
         return oslTranslateFileError (OSL_FET_ERROR, saved_errno);
     }
 
@@ -939,11 +935,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
         if (-1 == f)
         {
             int saved_errno = errno;
-            OSL_TRACE("osl_openFile(%s, %s): fcntl(%d, F_GETFL) failed: %s",
-                      cpFilePath,
-                      flags & O_RDWR ? "writeable":"readonly",
-                      fd,
-                      strerror(saved_errno));
+            SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << ", " << (flags & O_RDWR ? "writeable":"readonly") << "): fcntl(" << fd << ", F_GETFL) failed: " << strerror(saved_errno));
             eRet = oslTranslateFileError (OSL_FET_ERROR, saved_errno);
             (void) close(fd);
             return eRet;
@@ -951,11 +943,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
         if (-1 == fcntl (fd, F_SETFL, (f & ~O_NONBLOCK)))
         {
             int saved_errno = errno;
-            OSL_TRACE("osl_openFile(%s, %s): fcntl(%d, F_SETFL) failed: %s",
-                      cpFilePath,
-                      flags & O_RDWR ? "writeable":"readonly",
-                      fd,
-                      strerror(saved_errno));
+             SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << ", " << (flags & O_RDWR ? "writeable":"readonly") << "): fcntl(" << fd << ", F_SETFL) failed: " << strerror(saved_errno));
             eRet = oslTranslateFileError (OSL_FET_ERROR, saved_errno);
             (void) close(fd);
             return eRet;
@@ -967,11 +955,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
     if (-1 == fstat (fd, &aFileStat))
     {
         int saved_errno = errno;
-        OSL_TRACE("osl_openFile(%s, %s): fstat(%d) failed: %s",
-                  cpFilePath,
-                  flags & O_RDWR ? "writeable":"readonly",
-                  fd,
-                  strerror(saved_errno));
+        SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << ", " << (flags & O_RDWR ? "writeable":"readonly") << "): fstat(" << fd << ") failed: " << strerror(saved_errno));
         eRet = oslTranslateFileError (OSL_FET_ERROR, saved_errno);
         (void) close(fd);
         return eRet;
@@ -979,8 +963,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
     if (!S_ISREG(aFileStat.st_mode))
     {
         /* we only open regular files here */
-        OSL_TRACE("osl_openFile(%s): not a regular file",
-                  cpFilePath);
+        SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << "): not a regular file");
         (void) close(fd);
         return osl_File_E_INVAL;
     }
@@ -1010,11 +993,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
             if (-1 == fcntl (fd, F_SETLK, &aflock))
             {
                 int saved_errno = errno;
-                OSL_TRACE("osl_openFile(%s, %s): fcntl(%d, F_SETLK) failed: %s",
-                          cpFilePath,
-                          flags & O_RDWR ? "writeable":"readonly",
-                          fd,
-                          strerror(saved_errno));
+                SAL_INFO("sal.file", "osl_openFile(" << cpFilePath << ", " << (flags & O_RDWR ? "writeable":"readonly") << "): fcntl(" << fd << ", F_SETLK) failed: " << strerror(saved_errno));
                 eRet = oslTranslateFileError (OSL_FET_ERROR, saved_errno);
                 (void) close(fd);
                 return eRet;
@@ -1035,10 +1014,7 @@ SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_u
         pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
     pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
 
-    OSL_TRACE("osl_openFile(%s, %s) => %d",
-              rtl_string_getStr(pImpl->m_strFilePath),
-              flags & O_RDWR ? "writeable":"readonly",
-              pImpl->m_fd);
+    SAL_INFO("sal.file", "osl_openFile(" << pImpl->m_strFilePath << ", " << (flags & O_RDWR ? "writeable":"readonly") << ") => " << pImpl->m_fd);
 
     *pHandle = (oslFileHandle)(pImpl);
     return osl_File_E_None;
@@ -1077,7 +1053,7 @@ SAL_CALL osl_closeFile( oslFileHandle Handle )
     if (pImpl == 0)
         return osl_File_E_INVAL;
 
-    OSL_TRACE("osl_closeFile(%s:%d)", rtl_string_getStr(pImpl->m_strFilePath), pImpl->m_fd);
+    SAL_INFO("sal.file", "osl_closeFile(" << pImpl->m_strFilePath << ":" << pImpl->m_fd << ")");
 
     if (pImpl->m_kind == FileHandle_Impl::KIND_MEM)
     {
@@ -1124,7 +1100,7 @@ SAL_CALL osl_syncFile(oslFileHandle Handle)
 
     FileHandle_Impl::Guard lock (&(pImpl->m_mutex));
 
-    OSL_TRACE("osl_syncFile(%d)", pImpl->m_fd);
+    SAL_INFO("sal.file", "osl_syncFile(" << pImpl->m_fd << ")");
     oslFileError result = pImpl->syncFile();
     if (result != osl_File_E_None)
         return (result);
@@ -1231,13 +1207,12 @@ SAL_CALL osl_mapFile (
         int e = posix_madvise(p, nLength, POSIX_MADV_WILLNEED);
         if (e != 0)
         {
-            OSL_TRACE(
-                "posix_madvise(..., POSIX_MADV_WILLNEED) failed with %d", e);
+            SAL_INFO("sal.file", "posix_madvise(..., POSIX_MADV_WILLNEED) failed with " << e);
         }
 #elif defined SOLARIS
         if (madvise(static_cast< caddr_t >(p), nLength, MADV_WILLNEED) != 0)
         {
-            OSL_TRACE("madvise(..., MADV_WILLNEED) failed with %d", errno);
+            SAL_INFO("sal.file", "madvise(..., MADV_WILLNEED) failed with " << strerror(errno));
         }
 #endif
     }
commit 8492cd9f9a861e2aaa60390bffea994d6102fdb8
Author: Tor Lillqvist <tml at iki.fi>
Date:   Sat Aug 24 17:53:07 2013 +0300

    The "shared" extensions are read-only when HAVE_FEATURE_READONLY_INSTALLSET
    
    Change-Id: Ia7b9a5a297ecc3bf8eedae10ee8918b5db40a5e6

diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx
index 05ff8df..309b32d 100644
--- a/desktop/source/deployment/manager/dp_manager.cxx
+++ b/desktop/source/deployment/manager/dp_manager.cxx
@@ -17,6 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <config_features.h>
 
 #include "dp_ucb.h"
 #include "dp_resource.h"
@@ -358,7 +359,11 @@ Reference<deployment::XPackageManager> PackageManagerImpl::create(
         that->m_registrationData = "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER";
         that->m_registryCache = "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/registry";
         logFile = "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/log.txt";
+#if !HAVE_FEATURE_READONLY_INSTALLSET
+        // The "shared" extensions are read-only when we have a
+        // read-only installset.
         stamp = "$UNO_SHARED_PACKAGES_CACHE";
+#endif
     }
     else if ( context == "bundled" ) {
         that->m_activePackages = "vnd.sun.star.expand:$BUNDLED_EXTENSIONS";
commit fcdfc62f760b7e33025973a460f90023b59bad8f
Author: Tor Lillqvist <tml at iki.fi>
Date:   Sat Aug 24 16:07:22 2013 +0300

    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

diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index cf9e491..debccf9 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 0ee3a66..99b5a4d 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 85331ba..5d6bd10 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 83c321f..9b40644 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 286c482..0e4106e 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


More information about the Libreoffice-commits mailing list