Index: /trunk/include/iprt/dir.h
===================================================================
--- /trunk/include/iprt/dir.h	(revision 39625)
+++ /trunk/include/iprt/dir.h	(revision 39626)
@@ -305,5 +305,5 @@
  * @{ */
 /** Don't allow symbolic links as part of the path. */
-#define RTDIROPENFILTERED_FLAGS_NO_SYMLINKS  RT_BIT(0)
+#define RTDIROPEN_FLAGS_NO_SYMLINKS  RT_BIT(0)
 /** @} */
 
Index: /trunk/include/iprt/path.h
===================================================================
--- /trunk/include/iprt/path.h	(revision 39625)
+++ /trunk/include/iprt/path.h	(revision 39626)
@@ -127,4 +127,6 @@
 /** Last component: Follow if link. */
 #define RTPATH_F_FOLLOW_LINK      RT_BIT_32(1)
+/** Don't allow symbolic links as part of the path. */
+#define RTPATH_F_NO_SYMLINKS      RT_BIT_32(2)
 /** @} */
 
@@ -133,6 +135,6 @@
  * @remarks The parameters will be referenced multiple times. */
 #define RTPATH_F_IS_VALID(fFlags, fIgnore) \
-    (    ((fFlags) & ~(uint32_t)(fIgnore)) == RTPATH_F_ON_LINK \
-      || ((fFlags) & ~(uint32_t)(fIgnore)) == RTPATH_F_FOLLOW_LINK )
+    (    ((fFlags) & ~(uint32_t)(fIgnore | RTPATH_F_NO_SYMLINKS)) == RTPATH_F_ON_LINK \
+      || ((fFlags) & ~(uint32_t)(fIgnore | RTPATH_F_NO_SYMLINKS)) == RTPATH_F_FOLLOW_LINK )
 
 
Index: /trunk/src/VBox/HostServices/SharedFolders/service.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedFolders/service.cpp	(revision 39625)
+++ /trunk/src/VBox/HostServices/SharedFolders/service.cpp	(revision 39626)
@@ -244,8 +244,8 @@
             else
             {
-                pszFolderName = (char*)RTStrAlloc(cbFolderName);
+                pszFolderName = (char*)RTStrAlloc(cbFolderName + 1);
                 AssertReturn(pszFolderName, VERR_NO_MEMORY);
 
-                rc = SSMR3GetStrZ(pSSM, mapping.pszFolderName, cbFolderName);
+                rc = SSMR3GetStrZ(pSSM, pszFolderName, cbFolderName + 1);
                 AssertRCReturn(rc, rc);
                 mapping.pszFolderName = pszFolderName;
Index: /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp	(revision 39625)
+++ /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp	(revision 39626)
@@ -42,8 +42,4 @@
 #endif
 
-// never follow symbolic links */
-//#define SHFL_RT_LINK(pClient) ((pClient)->fu32Flags & SHFL_CF_SYMLINKS ? RTPATH_F_ON_LINK : RTPATH_F_FOLLOW_LINK)
-#define SHFL_RT_LINK(pClient) (RTPATH_F_ON_LINK)
-
 /**
  * @todo find a better solution for supporting the execute bit for non-windows
@@ -139,5 +135,5 @@
     strcat(pDirEntry->szName, szWildCard);
 
-    rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, RTDIROPENFILTERED_FLAGS_NO_SYMLINKS);
+    rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, RTDIROPEN_FLAGS_NO_SYMLINKS);
     *(pszStartComponent-1) = RTPATH_DELIMITER;
     if (RT_FAILURE(rc))
@@ -148,5 +144,6 @@
         size_t cbDirEntrySize = cbDirEntry;
 
-        rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+        rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING,
+                         RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
         if (rc == VERR_NO_MORE_FILES)
             break;
@@ -426,5 +423,6 @@
     if (RT_SUCCESS(rc))
     {
-        /* When the host file system is case sensitive and the guest expects a case insensitive fs, then problems can occur */
+        /* When the host file system is case sensitive and the guest expects
+         * a case insensitive fs, then problems can occur */
         if (     vbsfIsHostMappingCaseSensitive(root)
             &&  !vbsfIsGuestMappingCaseSensitive(root))
@@ -435,5 +433,6 @@
             if (fWildCard || fPreserveLastComponent)
             {
-                /* strip off the last path component, that has to be preserved: contains the wildcard(s) or a 'rename' target. */
+                /* strip off the last path component, that has to be preserved:
+                 * contains the wildcard(s) or a 'rename' target. */
                 size_t cb = strlen(pszFullPath);
                 char *pszSrc = pszFullPath + cb - 1;
@@ -470,5 +469,6 @@
 
             /** @todo don't check when creating files or directories; waste of time */
-            rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+            rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING,
+                                   RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
             if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
             {
@@ -484,5 +484,6 @@
                     {
                         *pszSrc = 0;
-                        rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+                        rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING,
+                                               RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
                         *pszSrc = RTPATH_DELIMITER;
                         if (rc == VINF_SUCCESS)
@@ -520,5 +521,6 @@
                             fEndOfString = false;
                             *pszEnd = 0;
-                            rc = RTPathQueryInfoEx(pszSrc, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+                            rc = RTPathQueryInfoEx(pszSrc, &info, RTFSOBJATTRADD_NOTHING,
+                                                   RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
                             Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);
                         }
@@ -860,5 +862,6 @@
 
             /** @todo Possible race left here. */
-            if (RT_SUCCESS(RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient))))
+            if (RT_SUCCESS(RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING,
+                                             RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS)))
             {
 #ifdef RT_OS_WINDOWS
@@ -1032,5 +1035,5 @@
             /* Open the directory now */
             rc = RTDirOpenFiltered(&pHandle->dir.Handle, pszPath,
-                                   RTDIRFILTER_NONE, RTDIROPENFILTERED_FLAGS_NO_SYMLINKS);
+                                   RTDIRFILTER_NONE, RTDIROPEN_FLAGS_NO_SYMLINKS);
             if (RT_SUCCESS(rc))
             {
@@ -1130,10 +1133,19 @@
  * @retval  pParms->Info   On success, information returned about the file
  */
-static int vbsfLookupFile(SHFLCLIENTDATA *pClient, char *pszPath, SHFLCREATEPARMS *pParms)
+static int vbsfLookupFile(SHFLCLIENTDATA *pClient, SHFLROOT root, char *pszPath, SHFLCREATEPARMS *pParms)
 {
     RTFSOBJINFO info;
     int rc;
 
-    rc = RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+    char szRealPath[RTPATH_MAX + 1];
+    const char *pszRoot = vbsfMappingsQueryHostRoot(root);
+    AssertReturn(pszRoot, VERR_INVALID_PARAMETER);
+    rc = RTPathReal(pszPath, szRealPath, sizeof(szRealPath));
+    AssertRCReturn(rc, rc);
+    if (!RTPathStartsWith(szRealPath, pszRoot))
+        return VERR_TOO_MANY_SYMLINKS;
+
+    rc = RTPathQueryInfoEx(pszPath, &info, RTFSOBJATTRADD_NOTHING,
+                           RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
     LogFlow(("SHFL_CF_LOOKUP\n"));
     /* Client just wants to know if the object exists. */
@@ -1234,5 +1246,5 @@
         if (BIT_FLAG(pParms->CreateFlags, SHFL_CF_LOOKUP))
         {
-            rc = vbsfLookupFile(pClient, pszFullPath, pParms);
+            rc = vbsfLookupFile(pClient, root, pszFullPath, pParms);
         }
         else
@@ -1241,5 +1253,6 @@
             RTFSOBJINFO info;
 
-            rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+            rc = RTPathQueryInfoEx(pszFullPath, &info, RTFSOBJATTRADD_NOTHING,
+                                   RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
             LogFlow(("RTPathQueryInfoEx returned %Rrc\n", rc));
 
@@ -1295,11 +1308,7 @@
             {
                 if (BIT_FLAG(pParms->CreateFlags, SHFL_CF_DIRECTORY))
-                {
                     rc = vbsfOpenDir(pClient, pszFullPath, pParms);
-                }
                 else
-                {
                     rc = vbsfOpenFile(pClient, pszFullPath, pParms);
-                }
             }
             else
@@ -1505,5 +1514,5 @@
     PRTDIR         DirHandle;
     bool           fUtf8;
-
+    
     fUtf8 = BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8) != 0;
 
@@ -1546,6 +1555,23 @@
             if (RT_SUCCESS(rc))
             {
+#if 0
+                const char *pszRoot = vbsfMappingsQueryHostRoot(root);
+                if (!pszRoot)
+                {
+                    rc = VERR_INVALID_PARAMETER;
+                    goto end;
+                }
+                char szRealPath[RTPATH_MAX + 1];
+                rc = RTPathReal(pszFullPath, szRealPath, sizeof(szRealPath));
+                if (RT_FAILURE(rc))
+                    goto end;
+                if (!RTPathStartsWith(szRealPath, pszRoot))
+                {
+                    rc = VERR_TOO_MANY_SYMLINKS;
+                    goto end;
+                }
+#endif
                 rc = RTDirOpenFiltered(&pHandle->dir.SearchHandle, pszFullPath,
-                                       RTDIRFILTER_WINNT, RTDIROPENFILTERED_FLAGS_NO_SYMLINKS);
+                                       RTDIRFILTER_WINNT, RTDIROPEN_FLAGS_NO_SYMLINKS);
 
                 /* free the path string */
@@ -1576,5 +1602,6 @@
             pDirEntry = pDirEntryOrg;
 
-            rc = RTDirReadEx(DirHandle, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+            rc = RTDirReadEx(DirHandle, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING,
+                             RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
             if (rc == VERR_NO_MORE_FILES)
             {
@@ -2295,5 +2322,6 @@
     {
         RTFSOBJINFO info;
-        rc = RTPathQueryInfoEx(pszFullNewPath, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
+        rc = RTPathQueryInfoEx(pszFullNewPath, &info, RTFSOBJATTRADD_NOTHING,
+                               RTPATH_F_ON_LINK | RTPATH_F_NO_SYMLINKS);
         if (RT_SUCCESS(rc))
             vbfsCopyFsObjInfoFromIprt(pInfo, &info);
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 39625)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 39626)
@@ -615,4 +615,5 @@
 	r3/posix/RTTimeSet-posix.cpp \
 	r3/posix/rtmempage-exec-mmap-heap-posix.cpp \
+	r3/posix/rtPathOpenPathFh.cpp \
 	r3/posix/dir-posix.cpp \
 	r3/posix/env-posix.cpp \
@@ -1173,4 +1174,5 @@
 	r3/posix/env-posix.cpp \
 	r3/posix/fileio-posix.cpp \
+	r3/posix/rtPathOpenPathFh.cpp \
 	r3/posix/fileio2-posix.cpp \
 	r3/posix/path-posix.cpp \
Index: /trunk/src/VBox/Runtime/include/internal/dir.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/dir.h	(revision 39625)
+++ /trunk/src/VBox/Runtime/include/internal/dir.h	(revision 39626)
@@ -129,5 +129,5 @@
  *                      wildcard expression.
  */
-int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf);
+int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf, uint32_t fOpen);
 
 #endif
Index: /trunk/src/VBox/Runtime/include/internal/path.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/path.h	(revision 39625)
+++ /trunk/src/VBox/Runtime/include/internal/path.h	(revision 39626)
@@ -48,5 +48,5 @@
 DECLHIDDEN(int)     rtPathPosixRename(const char *pszSrc, const char *pszDst, unsigned fRename, RTFMODE fFileType);
 DECLHIDDEN(int)     rtPathWin32MoveRename(const char *pszSrc, const char *pszDst, uint32_t fFlags, RTFMODE fFileType);
-
+DECLHIDDEN(int)     rtPathOpenPathNoFollowFh(const char *pszPath, int *fh, const char **ppszName);
 
 /**
Index: /trunk/src/VBox/Runtime/r3/dir.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/dir.cpp	(revision 39625)
+++ /trunk/src/VBox/Runtime/r3/dir.cpp	(revision 39626)
@@ -517,6 +517,7 @@
  * @param   pszFilter   Pointer to where the filter start in the path. NULL if no filter.
  * @param   enmFilter   The type of filter to apply.
- */
-static int rtDirOpenCommon(PRTDIR *ppDir, const char *pszPath, const char *pszFilter, RTDIRFILTER enmFilter)
+ * @param   fOpen       Open flags, RTDIROPENFILTERED_FLAGS_*.
+ */
+static int rtDirOpenCommon(PRTDIR *ppDir, const char *pszPath, const char *pszFilter, RTDIRFILTER enmFilter, uint32_t fOpen)
 {
     /*
@@ -646,5 +647,5 @@
      * Hand it over to the native part.
      */
-    rc = rtDirNativeOpen(pDir, szRealPath);
+    rc = rtDirNativeOpen(pDir, szRealPath, fOpen);
     if (RT_SUCCESS(rc))
         *ppDir = pDir;
@@ -668,5 +669,5 @@
      * Take common cause with RTDirOpenFiltered().
      */
-    int rc = rtDirOpenCommon(ppDir, pszPath, NULL,  RTDIRFILTER_NONE);
+    int rc = rtDirOpenCommon(ppDir, pszPath, NULL,  RTDIRFILTER_NONE, 0);
     LogFlow(("RTDirOpen(%p:{%p}, %p:{%s}): return %Rrc\n", ppDir, *ppDir, pszPath, pszPath, rc));
     return rc;
@@ -711,5 +712,5 @@
      * and initialize the handle, and finally call the backend.
      */
-    int rc = rtDirOpenCommon(ppDir, pszPath, pszFilter, enmFilter);
+    int rc = rtDirOpenCommon(ppDir, pszPath, pszFilter, enmFilter, fOpen);
 
     LogFlow(("RTDirOpenFiltered(%p:{%p}, %p:{%s}, %d): return %Rrc\n",
Index: /trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp	(revision 39625)
+++ /trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp	(revision 39626)
@@ -194,5 +194,5 @@
 
 
-int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf)
+int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf, uint32_t fOpen)
 {
     NOREF(pszPathBuf); /* only used on windows */
@@ -205,5 +205,28 @@
     if (RT_SUCCESS(rc))
     {
-        pDir->pDir = opendir(pszNativePath);
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
+        /* XXX Darwin? */
+        if (fOpen & RTDIROPEN_FLAGS_NO_SYMLINKS)
+        {
+            const char *pszName;
+            int fhDir;
+            rc = rtPathOpenPathNoFollowFh(pszNativePath, &fhDir, &pszName);
+            printf("rtPathOpenPathNoFollowFh '%s' => %d\n", pszNativePath, rc);
+            AssertRCReturn(rc, rc);
+            if (pszName != NULL)
+            {
+                AssertMsgFailed(("Path name '%s' contains filename\n", pszNativePath));
+                return VERR_INVALID_PARAMETER;
+            }
+            pDir->pDir = fdopendir(fhDir);
+            /*
+             * do NOT close fhDir, it will be closed implicitely when closing pDir!
+             */
+        }
+        else
+#endif
+        {
+            pDir->pDir = opendir(pszNativePath);
+        }
         if (pDir->pDir)
         {
Index: /trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp	(revision 39625)
+++ /trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp	(revision 39626)
@@ -204,5 +204,25 @@
         return (rc);
 
-    int fh = open(pszNativeFilename, fOpenMode, fMode);
+    int fh;
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
+    /* XXX Darwin? */
+    if (fOpen & RTFILE_O_NO_SYMLINKS)
+    {
+        const char *pszName;
+        int fhDir;
+        rc = rtPathOpenPathNoFollowFh(pszNativeFilename, &fhDir, &pszName);
+        if (RT_FAILURE(rc))
+        {
+            rtPathFreeNative(pszNativeFilename, pszFilename);
+            return rc;
+        }
+        fh = openat(fhDir, pszName, fOpenMode, fMode | O_NOFOLLOW);
+        close(fhDir);
+    }
+    else
+#endif
+    {
+        fh = open(pszNativeFilename, fOpenMode, fMode);
+    }
     int iErr = errno;
 
Index: /trunk/src/VBox/Runtime/r3/posix/rtPathOpenPathFh.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/rtPathOpenPathFh.cpp	(revision 39626)
+++ /trunk/src/VBox/Runtime/r3/posix/rtPathOpenPathFh.cpp	(revision 39626)
@@ -0,0 +1,103 @@
+/* $Id$ */
+/** @file
+ * IPRT - rtPathOpenFd.cpp
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "internal/iprt.h"
+#include "internal/path.h"
+#include <iprt/err.h>
+#include <iprt/path.h>
+#include <iprt/string.h>
+
+
+DECLHIDDEN(int) rtPathOpenPathNoFollowFh(const char *pszPath, int *pFh, const char **ppszName)
+{
+#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
+    const char *psz = pszPath;
+    const char *pszName = pszPath;
+    int fh = -1;
+
+    AssertPtrReturn(pFh, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pszPath, VERR_INVALID_PARAMETER);
+    /* must be an absolute path */
+    AssertReturn(*pszPath == '/', VERR_INVALID_PARAMETER);
+
+    for (;; psz++)
+    {
+        switch (*psz)
+        {
+            /* handle separators. */
+            case '/':
+            {
+                int fhNew;
+                if (fh == -1)
+                {
+                    /* root directory */
+                    fhNew = open("/", O_RDONLY | O_NOFOLLOW);
+                }
+                else
+                {
+                    /* subdirectory */
+                    char szTmpPath[RTPATH_MAX + 1];
+                    RTStrCopyEx(szTmpPath, sizeof(szTmpPath), pszName, psz - pszName);
+                    fhNew = openat(fh, szTmpPath, O_RDONLY | O_NOFOLLOW);
+                    close(fh);
+                }
+                if (fhNew < 0)
+                    return RTErrConvertFromErrno(errno);
+                fh = fhNew;
+                pszName = psz + 1;
+                break;
+            }
+
+            /*
+             * The end. Complete the results.
+             */
+            case '\0':
+            {
+                if (ppszName)
+                    *ppszName = *pszName != '\0' ? pszName : NULL;
+                *pFh = fh;
+                return VINF_SUCCESS;
+            }
+        }
+    }
+
+    /* will never get here */
+    return 0;
+#else
+    return VERR_NOT_IMPLEMENTED;
+#endif
+}
Index: /trunk/src/VBox/Runtime/r3/win/dir-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/dir-win.cpp	(revision 39625)
+++ /trunk/src/VBox/Runtime/r3/win/dir-win.cpp	(revision 39626)
@@ -130,5 +130,5 @@
 
 
-int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf)
+int rtDirNativeOpen(PRTDIR pDir, char *pszPathBuf, uint32_t fOpen)
 {
     /*
