Index: /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp	(revision 20019)
+++ /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp	(revision 20020)
@@ -178,4 +178,67 @@
 }
 
+static int vbsfPathCheck(const char *pUtf8Path, size_t cbPath)
+{
+    int rc = VINF_SUCCESS;
+
+    /* The pUtf8Path is what the guest sent. Verify that the path is within the root.
+     * Count '..' and other path components and check that we do not go over the root.
+     */
+
+    size_t i = 0;
+    int cComponents = 0; /* How many normal path components. */
+    int cParentDirs = 0; /* How many '..' components. */
+
+    for (;;)
+    {
+        /* Skip leading path delimiters. */
+        while (   i < cbPath
+               && (pUtf8Path[i] == '\\' || pUtf8Path[i] == '/'))
+            i++;
+
+        if (i >= cbPath)
+            break;
+
+        /* Check if that is a dot component. */
+        int cDots = 0;
+        while (i < cbPath && pUtf8Path[i] == '.')
+        {
+            cDots++;
+            i++;
+        }
+
+        if (   cDots >= 2 /* Consider all multidots sequences as a 'parent dir'. */
+            && (i >= cbPath || (pUtf8Path[i] == '\\' || pUtf8Path[i] == '/')))
+        {
+            cParentDirs++;
+        }
+        else if (   cDots == 1
+                 && (i >= cbPath || (pUtf8Path[i] == '\\' || pUtf8Path[i] == '/')))
+        {
+            /* Single dot, nothing changes. */
+        }
+        else
+        {
+            /* Skip this component. */
+            while (   i < cbPath
+                   && (pUtf8Path[i] != '\\' && pUtf8Path[i] != '/'))
+                i++;
+
+            cComponents++;
+        }
+
+        Assert(i >= cbPath || (pUtf8Path[i] == '\\' || pUtf8Path[i] == '/'));
+
+        /* Verify counters for every component. */
+        if (cParentDirs > cComponents)
+        {
+            rc = VERR_INVALID_NAME;
+            break;
+        }
+    }
+
+    return rc;
+}
+
 static int vbsfBuildFullPath (SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath,
                               uint32_t cbPath, char **ppszFullPath, uint32_t *pcbFullPathRoot, bool fWildCard = false)
@@ -200,5 +263,12 @@
         char *utf8Root;
 
-        rc = RTUtf16ToUtf8 (pwszRoot, &utf8Root);
+        /* Verify that the path is under the root directory. */
+        rc = vbsfPathCheck((char *)&pPath->String.utf8[0], pPath->u16Length);
+
+        if (RT_SUCCESS (rc))
+        {
+            rc = RTUtf16ToUtf8 (pwszRoot, &utf8Root);
+        }
+
         if (RT_SUCCESS (rc))
         {
@@ -345,6 +415,6 @@
                     AssertFailed();
 #ifdef RT_OS_DARWIN
-                	RTMemFree(pPath);
-                	pPath = pPathParameter;
+                    RTMemFree(pPath);
+                    pPath = pPathParameter;
 #endif
                     return rc;
@@ -352,4 +422,16 @@
 
                 uint32_t l = (uint32_t)strlen (dst);
+
+                /* Verify that the path is under the root directory. */
+                rc = vbsfPathCheck(dst, l);
+
+                if (RT_FAILURE(rc))
+                {
+#ifdef RT_OS_DARWIN
+                    RTMemFree(pPath);
+                    pPath = pPathParameter;
+#endif
+                    return rc;
+                }
 
                 cb -= l;
