VirtualBox

Changeset 105087 in vbox for trunk/src/VBox/HostServices


Ignore:
Timestamp:
Jul 1, 2024 11:27:59 PM (8 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
163708
Message:

doc/manual,include/VBox,Frontends/VBoxManage,HostServices/SharedFolders,
Main/{include,SharedFolder,Console,Machine,VirtualBox.xidl}: Add a
new attribute to ISharedFolder for specifying a symbolic link creation
policy to restrict the source pathname when creating symbolic links
within a guest. The symbolic link policies are represented by a new
enumeration of type SymlinkPolicy_T which includes values for no
restrictions ('any'), symlink sources only within the subtree of the
share ('subtree'), symlink sources as any relative path ('relative'),
and no symlinks allowed ('forbidden'). The symlink policy can only be
applied to permanent shared folders at this stage. bugref:10619

Location:
trunk/src/VBox/HostServices/SharedFolders
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedFolders/Makefile.kmk

    r105018 r105087  
    3939VBoxSharedFolders_NAME.os2  = VBoxSFld
    4040VBoxSharedFolders_DEFS      = VBOX_WITH_HGCM RTSHFL
    41 VBoxSharedFolders_INCS.win  = \
    42         $(VBOX_PATH_SDK)
     41ifdef VBOX_WITH_XPCOM
     42 VBoxSharedFolders_DEFS    += VBOX_WITH_XPCOM
     43 VBoxSharedFolders_INCS    += $(VBOX_XPCOM_INCS)
     44 ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
     45  VBoxSharedFolders_DEFS   += VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
     46 endif
     47else # COM
     48 VBoxSharedFolders_INCS    += \
     49        $(VBOX_PATH_SDK) \
     50        $(VBOX_PATH_SDK)/bindings/mscom/include
     51endif
    4352
    4453VBoxSharedFolders_LDFLAGS.darwin = \
  • trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp

    r105018 r105087  
    164164
    165165
    166 static DECLCALLBACK(int) svcUnload (void *)
     166static DECLCALLBACK(int) svcUnload(void *)
    167167{
    168168    int rc = VINF_SUCCESS;
     
    176176}
    177177
    178 static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient, uint32_t fRequestor, bool fRestoring)
     178static DECLCALLBACK(int) svcConnect(void *, uint32_t u32ClientID, void *pvClient, uint32_t fRequestor, bool fRestoring)
    179179{
    180180    RT_NOREF(u32ClientID, fRequestor, fRestoring);
     
    187187}
    188188
    189 static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
     189static DECLCALLBACK(int) svcDisconnect(void *, uint32_t u32ClientID, void *pvClient)
    190190{
    191191    RT_NOREF1(u32ClientID);
     
    455455}
    456456
    457 static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient,
    458                                    uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival)
     457static DECLCALLBACK(void) svcCall(void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient,
     458                                  uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival)
    459459{
    460460    RT_NOREF(u32ClientID, tsArrival);
     
    618618                   )
    619619                {
    620                     AssertMsgFailed (("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n",
     620                    AssertMsgFailed(("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n",
    621621                                      cbPath, cbParms, sizeof(SHFLSTRING), sizeof (SHFLCREATEPARMS)));
    622622                    rc = VERR_INVALID_PARAMETER;
     
    631631
    632632                    /* Execute the function. */
    633                     rc = vbsfCreate (pClient, root, pPath, cbPath, pParms);
     633                    rc = vbsfCreate(pClient, root, pPath, cbPath, pParms);
    634634
    635635                    if (RT_SUCCESS(rc))
     
    680680                {
    681681                    /* Execute the function. */
    682                     rc = vbsfClose (pClient, root, Handle);
     682                    rc = vbsfClose(pClient, root, Handle);
    683683
    684684                    if (RT_SUCCESS(rc))
     
    845845                     *       completed, the another thread must call
    846846                     *
    847                      *           g_pHelpers->pfnCallComplete (callHandle, rc);
     847                     *           g_pHelpers->pfnCallComplete(callHandle, rc);
    848848                     *
    849849                     * The operation is async.
     
    939939
    940940                    /* Execute the function. */
    941                     rc = vbsfDirList (pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles);
     941                    rc = vbsfDirList(pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles);
    942942
    943943                    if (g_pStatusLed)
     
    10021002                {
    10031003                    /* Execute the function. */
    1004                     rc = vbsfReadLink (pClient, root, pPath, cbPath, pBuffer, cbBuffer);
     1004                    rc = vbsfReadLink(pClient, root, pPath, cbPath, pBuffer, cbBuffer);
    10051005
    10061006                    if (RT_SUCCESS(rc))
     
    10481048                {
    10491049                    /* Execute the function. */
    1050                     rc = vbsfMapFolder (pClient, pszMapName, delimiter, false,  &root);
     1050                    rc = vbsfMapFolder(pClient, pszMapName, delimiter, false,  &root);
    10511051
    10521052                    if (RT_SUCCESS(rc))
     
    11181118                /* Execute the function. */
    11191119                if (RT_SUCCESS(rc))
    1120                     rc = vbsfMapFolder (pClient, pszMapName, delimiter, fCaseSensitive, &root);
     1120                    rc = vbsfMapFolder(pClient, pszMapName, delimiter, fCaseSensitive, &root);
    11211121
    11221122                if (RT_SUCCESS(rc))
     
    11561156
    11571157                /* Execute the function. */
    1158                 rc = vbsfUnmapFolder (pClient, root);
     1158                rc = vbsfUnmapFolder(pClient, root);
    11591159
    11601160                if (RT_SUCCESS(rc))
     
    12081208                    if (flags & SHFL_INFO_SET)
    12091209                    {
    1210                         rc = vbsfSetFSInfo (pClient, root, Handle, flags, &length, pBuffer);
     1210                        rc = vbsfSetFSInfo(pClient, root, Handle, flags, &length, pBuffer);
    12111211
    12121212                        if (flags & SHFL_INFO_FILE)
     
    12231223                    else /* SHFL_INFO_GET */
    12241224                    {
    1225                         rc = vbsfQueryFSInfo (pClient, root, Handle, flags, &length, pBuffer);
     1225                        rc = vbsfQueryFSInfo(pClient, root, Handle, flags, &length, pBuffer);
    12261226
    12271227                        if (flags & SHFL_INFO_FILE)
     
    13391339                {
    13401340                    /* Execute the function. */
    1341                     rc = vbsfRename (pClient, root, pSrc, pDest, flags);
     1341                    rc = vbsfRename(pClient, root, pSrc, pDest, flags);
    13421342                    if (RT_SUCCESS(rc))
    13431343                    {
     
    13891389                    /* Execute the function. */
    13901390
    1391                     rc = vbsfFlush (pClient, root, Handle);
     1391                    rc = vbsfFlush(pClient, root, Handle);
    13921392
    13931393                    if (RT_SUCCESS(rc))
     
    14471447                {
    14481448                    /* Execute the function. */
    1449                     rc = vbsfSymlink (pClient, root, pNewPath, pOldPath, pInfo);
     1449                    rc = vbsfSymlink(pClient, root, pNewPath, pOldPath, pInfo);
    14501450                    if (RT_SUCCESS(rc))
    14511451                    {
     
    16461646         * it was processed synchronously.
    16471647         */
    1648         g_pHelpers->pfnCallComplete (callHandle, rc);
     1648        g_pHelpers->pfnCallComplete(callHandle, rc);
    16491649    }
    16501650
     
    16681668 * security reasons.
    16691669 */
    1670 static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1670static DECLCALLBACK(int) svcHostCall(void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    16711671{
    16721672    int rc = VINF_SUCCESS;
     
    17001700                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT   /* fFlags */
    17011701                 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR     /* auto mount point */
     1702                 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT   /* symlink policy */
    17021703                )
    17031704        {
     
    17111712            uint32_t fFlags             = paParms[2].u.uint32;
    17121713            SHFLSTRING *pAutoMountPoint = (SHFLSTRING *)paParms[3].u.pointer.addr;
     1714            SymlinkPolicy_T enmSymlinkPolicy = (SymlinkPolicy_T)paParms[4].u.uint32;
    17131715
    17141716            /* Verify parameters values. */
     
    17411743                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS),
    17421744                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING),
    1743                                          /* fPlaceholder = */ false);
     1745                                         /* fPlaceholder = */ false,
     1746                                         enmSymlinkPolicy);
    17441747                    if (RT_SUCCESS(rc))
    17451748                    {
     
    17851788            {
    17861789                /* Execute the function. */
    1787                 rc = vbsfMappingsRemove (pString);
     1790                rc = vbsfMappingsRemove(pString);
    17881791
    17891792                if (RT_SUCCESS(rc))
     
    18441847}
    18451848
    1846 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
     1849extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad(VBOXHGCMSVCFNTABLE *ptable)
    18471850{
    18481851    int rc = VINF_SUCCESS;
  • trunk/src/VBox/HostServices/SharedFolders/mappings.cpp

    r105018 r105087  
    186186    return vbsfMappingsAdd(pLoadedMapping->pszFolderName, pLoadedMapping->pMapName,
    187187                           pLoadedMapping->fWritable, pLoadedMapping->fAutoMount, pLoadedMapping->pAutoMountPoint,
    188                            pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true);
     188                           pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true,
     189                           pLoadedMapping->enmSymlinkPolicy);
    189190}
    190191
     
    340341 */
    341342int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable,
    342                     bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder)
     343                    bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder,
     344                    SymlinkPolicy_T enmSymlinkPolicy)
    343345{
    344346    unsigned i;
     
    369371    for (i = 0; i < SHFL_MAX_MAPPINGS; i++)
    370372    {
    371         if (g_FolderMapping[i].fValid == false)
     373        if (!g_FolderMapping[i].fValid)
    372374        {
    373375            /* Make sure the folder name is an absolute path, otherwise we're
     
    398400            g_FolderMapping[i].fPlaceholder    = fPlaceholder;
    399401            g_FolderMapping[i].fLoadedRootId   = false;
     402            g_FolderMapping[i].enmSymlinkPolicy = enmSymlinkPolicy;
    400403
    401404            /* Check if the host file system is case sensitive */
     
    446449    for (unsigned i = 0; i < SHFL_MAX_MAPPINGS; i++)
    447450    {
    448         if (g_FolderMapping[i].fValid == true)
     451        if (g_FolderMapping[i].fValid)
    449452        {
    450453            if (!RTUtf16LocaleICmp(g_FolderMapping[i].pMapName->String.utf16, pMapName->String.utf16))
     
    599602int vbsfMappingsQueryName(PSHFLCLIENTDATA pClient, SHFLROOT root, SHFLSTRING *pString)
    600603{
    601     LogFlow(("vbsfMappingsQuery: pClient = %p, root = %d, *pString = %p\n", pClient, root, pString));
     604    LogFlow(("vbsfMappingsQueryName: pClient = %p, root = %d, *pString = %p\n", pClient, root, pString));
    602605
    603606    int rc;
     
    633636        rc = VERR_INVALID_PARAMETER;
    634637
    635     LogFlow(("vbsfMappingsQuery:Name return rc = %Rrc\n", rc));
     638    LogFlow(("vbsfMappingsQueryName returns rc = %Rrc\n", rc));
    636639    return rc;
    637640}
     
    655658        rc = VERR_FILE_NOT_FOUND;
    656659
    657     LogFlow(("vbsfMappingsQuery:Writable return rc = %Rrc\n", rc));
     660    LogFlow(("vbsfMappingsQueryWritable returns rc = %Rrc\n", rc));
    658661
    659662    return rc;
     
    670673    AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER);
    671674
    672     if (pFolderMapping->fValid == true)
     675    if (pFolderMapping->fValid)
    673676        *fAutoMount = pFolderMapping->fAutoMount;
    674677    else
    675678        rc = VERR_FILE_NOT_FOUND;
    676679
    677     LogFlow(("vbsfMappingsQueryAutoMount:Writable return rc = %Rrc\n", rc));
     680    LogFlow(("vbsfMappingsQueryAutoMount returns rc = %Rrc\n", rc));
    678681
    679682    return rc;
     
    685688    int rc = VINF_SUCCESS;
    686689
    687     LogFlow(("vbsfMappingsQueryAutoMount: pClient = %p, root = %d\n", pClient, root));
     690    LogFlow(("vbsfMappingsQuerySymlinksCreate: pClient = %p, root = %d\n", pClient, root));
    688691
    689692    MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
    690693    AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER);
    691694
    692     if (pFolderMapping->fValid == true)
     695    if (pFolderMapping->fValid)
    693696        *fSymlinksCreate = pFolderMapping->fSymlinksCreate;
    694697    else
    695698        rc = VERR_FILE_NOT_FOUND;
    696699
    697     LogFlow(("vbsfMappingsQueryAutoMount:SymlinksCreate return rc = %Rrc\n", rc));
     700    LogFlow(("vbsfMappingsQuerySymlinksCreate returns rc = %Rrc\n", rc));
     701
     702    return rc;
     703}
     704
     705int vbsfMappingsQuerySymlinkPolicy(PSHFLCLIENTDATA pClient, SHFLROOT root, SymlinkPolicy_T *enmSymlinkPolicy)
     706{
     707    RT_NOREF1(pClient);
     708    int rc = VINF_SUCCESS;
     709
     710    LogFlow(("vbsfMappingsQuerySymlinkPolicy: pClient = %p, root = %d\n", pClient, root));
     711
     712    MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
     713    AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER);
     714
     715    if (pFolderMapping->fValid)
     716        *enmSymlinkPolicy = pFolderMapping->enmSymlinkPolicy;
     717    else
     718        rc = VERR_FILE_NOT_FOUND;
     719
     720    LogFlow(("vbsfMappingsQuerySymlinkPolicy returns rc = %Rrc\n", rc));
    698721
    699722    return rc;
     
    879902        return VERR_FILE_NOT_FOUND;
    880903    }
    881     Assert(pFolderMapping->fValid == true && pFolderMapping->cMappings > 0);
     904    Assert(pFolderMapping->fValid && pFolderMapping->cMappings > 0);
    882905
    883906    AssertLogRelReturn(root < RT_ELEMENTS(pClient->acMappings), VERR_INTERNAL_ERROR);
  • trunk/src/VBox/HostServices/SharedFolders/mappings.h

    r105018 r105087  
    5252                                             still has. fMissing is always true for this mapping. */
    5353    bool        fLoadedRootId;          /**< Set if vbsfMappingLoaded has found this mapping already. */
     54    SymlinkPolicy_T enmSymlinkPolicy;   /**< Symbolic link creation policy within the guest. */
    5455} MAPPING;
    5556/** Pointer to a MAPPING structure. */
     
    6162
    6263int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable,
    63                     bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder);
     64                    bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder,
     65                    SymlinkPolicy_T enmSymlinkPolicy);
    6466int vbsfMappingsRemove(PSHFLSTRING pMapName);
    6567
     
    6971int vbsfMappingsQueryAutoMount(PSHFLCLIENTDATA pClient, SHFLROOT root, bool *fAutoMount);
    7072int vbsfMappingsQuerySymlinksCreate(PSHFLCLIENTDATA pClient, SHFLROOT root, bool *fSymlinksCreate);
     73int vbsfMappingsQuerySymlinkPolicy(PSHFLCLIENTDATA pClient, SHFLROOT root, SymlinkPolicy_T *enmSymlinkPolicy);
    7174int vbsfMappingsQueryInfo(PSHFLCLIENTDATA pClient, SHFLROOT root, PSHFLSTRING pNameBuf, PSHFLSTRING pMntPtBuf,
    7275                          uint64_t *pfFlags, uint32_t *puVersion);
  • trunk/src/VBox/HostServices/SharedFolders/shfl.h

    r105018 r105087  
    7676typedef SHFLCLIENTDATA *PSHFLCLIENTDATA;
    7777
     78/** This enum is included here to avoid a build dependency on the VirtualBox
     79 * COM definitions pulled in by VBox/com/VirtualBox.h. */
     80typedef enum SymlinkPolicy_T {
     81    SymlinkPolicy_None,
     82    SymlinkPolicy_Forbidden,
     83    SymlinkPolicy_AllowedInShareSubtree,
     84    SymlinkPolicy_AllowedToRelativeTargets,
     85    SymlinkPolicy_AllowedToAnyTarget,
     86#ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK
     87    SymlinkPolicy_32BitHack = 0x7fffffff
     88#endif /* VBOX_WITH_XPCOM_CPP_ENUM_HACK */
     89} SymlinkPolicy_T;
    7890
    7991/** @def SHFL_CLIENT_NEED_WINDOWS_ERROR_STYLE_ADJUST_ON_POSIX
  • trunk/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk

    r105018 r105087  
    6969 tstSharedFolderService_DEFS    = VBOX_WITH_HGCM UNITTEST
    7070 tstSharedFolderService_INCS    = ..
     71 ifneq ($(KBUILD_TARGET),win)
     72  tstSharedFolderService_DEFS  += VBOX_WITH_XPCOM
     73  tstSharedFolderService_INCS  += $(VBOX_XPCOM_INCS)
     74 endif
     75 tstSharedFolderService_INCS.win += $(VBOX_PATH_SDK)/bindings/mscom/include
    7176 tstSharedFolderService_SOURCES = \
    7277        tstSharedFolderService.cpp \
  • trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp

    r105018 r105087  
    587587}
    588588
     589extern int testRTSymlinkCreate(const char *pszSymlink, const char *pszTarget, RTSYMLINKTYPE enmType, uint32_t fCreate)
     590{
     591    if (g_fFailIfNotLowercase && !RTStrIsLowerCased(strpbrk(pszSymlink, "/\\")))
     592        return VERR_FILE_NOT_FOUND;
     593    RT_NOREF4(pszSymlink, pszTarget, enmType, fCreate);
     594    return 0;
     595}
     596
    589597
    590598/*********************************************************************************************************************************
     
    678686}
    679687
     688static void fillTestShflStringUtf8(union TESTSHFLSTRING *pDest,
     689                                   const char *pcszSource)
     690{
     691    const size_t cchSource = strlen(pcszSource);
     692    AssertRelease(  cchSource * 2 + 2
     693                  < sizeof(*pDest) - RT_UOFFSETOF(SHFLSTRING, String));
     694    pDest->string.u16Length = (uint16_t)cchSource;
     695    pDest->string.u16Size   = pDest->string.u16Length + 1;
     696    memcpy(pDest->string.String.utf8, pcszSource, pDest->string.u16Size);
     697}
     698
    680699static SHFLROOT initWithWritableMapping(RTTEST hTest,
    681700                                        VBOXHGCMSVCFNTABLE *psvcTable,
     
    683702                                        const char *pcszFolderName,
    684703                                        const char *pcszMapping,
    685                                         bool fCaseSensitive = true)
     704                                        bool fCaseSensitive = true,
     705                                        SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget)
    686706{
    687707    VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING,
     
    706726    HGCMSvcSetPv(&aParms[1], &Mapping,   RT_UOFFSETOF(SHFLSTRING, String)
    707727                                   + Mapping.string.u16Size);
    708     HGCMSvcSetU32(&aParms[2], 1);
     728    HGCMSvcSetU32(&aParms[2], SHFL_ADD_MAPPING_F_WRITABLE | SHFL_ADD_MAPPING_F_CREATE_SYMLINKS);
    709729    HGCMSvcSetPv(&aParms[3], &AutoMountPoint, SHFLSTRING_HEADER_SIZE + AutoMountPoint.string.u16Size);
     730    HGCMSvcSetU32(&aParms[4], enmSymlinkPolicy);
    710731    rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
    711732                                SHFL_CPARMS_ADD_MAPPING, aParms);
     
    774795        *pResult = CreateParms.Result;
    775796    return VINF_SUCCESS;
     797}
     798
     799static int createSymlink(VBOXHGCMSVCFNTABLE *psvcTable, SHFLROOT Root,
     800                         const char *pcszSourcePath, const char *pcszSymlinkPath)
     801{
     802    VBOXHGCMSVCPARM aParms[SHFL_CPARMS_SYMLINK];
     803    union TESTSHFLSTRING sourcePath;
     804    union TESTSHFLSTRING symlinkPath;
     805    SHFLFSOBJINFO ObjInfo;
     806    VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
     807
     808    /* vbsfSymlink() only supports UTF-8 */
     809    fillTestShflStringUtf8(&sourcePath, pcszSourcePath);
     810    fillTestShflStringUtf8(&symlinkPath, pcszSymlinkPath);
     811    psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
     812                       psvcTable->pvService, SHFL_FN_SET_UTF8,
     813                       RT_ELEMENTS(aParms), aParms, 0);
     814
     815    RT_ZERO(ObjInfo);
     816    HGCMSvcSetU32(&aParms[0], Root);
     817    HGCMSvcSetPv(&aParms[1], &symlinkPath,  RT_UOFFSETOF(SHFLSTRING, String)
     818                                + symlinkPath.string.u16Size);
     819    HGCMSvcSetPv(&aParms[2], &sourcePath,   RT_UOFFSETOF(SHFLSTRING, String)
     820                                + sourcePath.string.u16Size);
     821    HGCMSvcSetPv(&aParms[3], &ObjInfo, sizeof(ObjInfo));
     822    psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
     823                       psvcTable->pvService, SHFL_FN_SYMLINK,
     824                       RT_ELEMENTS(aParms), aParms, 0);
     825    return callHandle.rc;
    776826}
    777827
     
    10061056}
    10071057
     1058static int testSymlinkCreationForSpecificPolicy(RTTEST hTest, SymlinkPolicy_T enmSymlinkPolicy)
     1059{
     1060    VBOXHGCMSVCFNTABLE  svcTable;
     1061    VBOXHGCMSVCHELPERS  svcHelpers;
     1062    SHFLROOT Root;
     1063    const RTFILE hFile = (RTFILE) 0x10000;
     1064    SHFLCREATERESULT Result;
     1065    int rc;
     1066
     1067    Root = initWithWritableMapping(hTest, &svcTable, &svcHelpers,
     1068                                   "/test/mapping", "testname",
     1069                                   true, enmSymlinkPolicy);
     1070    g_testRTFileOpen_hFile = hFile;
     1071    rc = createFile(&svcTable, Root, "file", SHFL_CF_ACCESS_READ, NULL, &Result);
     1072    RTTEST_CHECK_RC_OK(hTest, rc);
     1073    RTTEST_CHECK_MSG(hTest,
     1074                     !strcmp(&g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0],
     1075                             "/test/mapping/file"),
     1076                     (hTest, "pszFilename=%s\n", &g_testRTFileOpen_szName[RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS ? 2 : 0]));
     1077    RTTEST_CHECK_MSG(hTest, g_testRTFileOpen_fOpen == 0x181,
     1078                     (hTest, "fOpen=%llu\n", LLUIFY(g_testRTFileOpen_fOpen)));
     1079    RTTEST_CHECK_MSG(hTest, Result == SHFL_FILE_CREATED,
     1080                     (hTest, "Result=%d\n", (int)Result));
     1081
     1082    /* regular symlink creation should succeed unless no symlinks allowed */
     1083    rc = createSymlink(&svcTable, Root, "file", "symlink");
     1084    if (enmSymlinkPolicy == SymlinkPolicy_Forbidden)
     1085        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1086                         (hTest, "enmSymlinkPolicy=SymlinkPolicy_Forbidden 'ln -s file symlink' failed: rc=%Rrc\n", rc));
     1087    else
     1088        RTTEST_CHECK_RC_OK(hTest, rc);
     1089
     1090    /* absolute path to symlink sources only allowed for the 'any' policy */
     1091    rc = createSymlink(&svcTable, Root, "/path/to/file", "abs-symlink");
     1092    if (enmSymlinkPolicy == SymlinkPolicy_AllowedToAnyTarget)
     1093        RTTEST_CHECK_RC_OK(hTest, rc);
     1094    else
     1095        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1096                         (hTest, "enmSymlinkPolicy=%d 'ln -s file /absolute/path/symlink' failed: rc=%Rrc\n",
     1097                         enmSymlinkPolicy, rc));
     1098
     1099    /* relative path symlink sources with '..' components allowed only with 'relative' policy */
     1100    rc = createSymlink(&svcTable, Root, "./directory/../file", "rel-symlink");
     1101    if (   enmSymlinkPolicy == SymlinkPolicy_Forbidden
     1102        || enmSymlinkPolicy == SymlinkPolicy_AllowedInShareSubtree)
     1103        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1104                         (hTest, "enmSymlinkPolicy=%d 'ln -s ./path/../symlink' failed: rc=%Rrc\n",
     1105                         enmSymlinkPolicy, rc));
     1106    else
     1107        RTTEST_CHECK_RC_OK(hTest, rc);
     1108
     1109    /* relative path symlink source with no '..' components always OK */
     1110    rc = createSymlink(&svcTable, Root, "./directory/file", "dotslash-symlink");
     1111    if (enmSymlinkPolicy == SymlinkPolicy_Forbidden)
     1112        RTTEST_CHECK_MSG(hTest, rc == VERR_WRITE_PROTECT,
     1113                         (hTest, "enmSymlinkPolicy=%d 'ln -s ./path/../symlink' failed: rc=%Rrc\n",
     1114                         enmSymlinkPolicy, rc));
     1115    else
     1116        RTTEST_CHECK_RC_OK(hTest, rc);
     1117
     1118    unmapAndRemoveMapping(hTest, &svcTable, Root, "testname");
     1119    rc = svcTable.pfnDisconnect(NULL, 0, svcTable.pvService);
     1120    AssertReleaseRC(rc);
     1121    rc = svcTable.pfnUnload(NULL);
     1122    AssertReleaseRC(rc);
     1123    RTTestGuardedFree(hTest, svcTable.pvService);
     1124    RTTEST_CHECK_MSG(hTest, g_testRTFileClose_hFile == hFile,
     1125                     (hTest, "File=%u\n", (uintptr_t)g_testRTFileClose_hFile));
     1126
     1127    return rc;
     1128}
     1129
     1130void testSymlinkCreation(RTTEST hTest)
     1131{
     1132    SymlinkPolicy_T aEnmSymlinkPolicy[4] = {
     1133        SymlinkPolicy_AllowedToAnyTarget,
     1134        SymlinkPolicy_AllowedInShareSubtree,
     1135        SymlinkPolicy_AllowedToRelativeTargets,
     1136        SymlinkPolicy_Forbidden
     1137    };
     1138
     1139    RTTestSub(hTest, "Create variety of symlinks with different symlink policies");
     1140    for (size_t i = 0; i < RT_ELEMENTS(aEnmSymlinkPolicy); i++)
     1141        testSymlinkCreationForSpecificPolicy(hTest, aEnmSymlinkPolicy[i]);
     1142}
     1143
    10081144void testReadFileSimple(RTTEST hTest)
    10091145{
  • trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.h

    r105018 r105087  
    123123/* Sub-tests for testSymlink(). */
    124124void testSymlinkBadParameters(RTTEST hTest);
     125void testSymlinkCreation(RTTEST hTest);
    125126
    126127void testMappingsAdd(RTTEST hTest);
  • trunk/src/VBox/HostServices/SharedFolders/teststubs.h

    r105018 r105087  
    101101#define RTSymlinkRead        testRTSymlinkRead
    102102extern int testRTSymlinkRead(const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead);
     103#define RTSymlinkCreate      testRTSymlinkCreate
     104extern int testRTSymlinkCreate(const char *pszSymlink, const char *pszTarget, RTSYMLINKTYPE enmType, uint32_t fCreate);
    103105
    104106#endif /* !VBOX_INCLUDED_SRC_SharedFolders_teststubs_h */
  • trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp

    r105018 r105087  
    256256    uint32_t fu32PathFlags = 0;
    257257    uint32_t fu32Options =   VBSF_O_PATH_CHECK_ROOT_ESCAPE
    258                            | (fWildCard? VBSF_O_PATH_WILDCARD: 0)
    259                            | (fPreserveLastComponent? VBSF_O_PATH_PRESERVE_LAST_COMPONENT: 0);
     258                           | (fWildCard ? VBSF_O_PATH_WILDCARD : 0)
     259                           | (fPreserveLastComponent ? VBSF_O_PATH_PRESERVE_LAST_COMPONENT : 0);
    260260
    261261    int rc = vbsfPathGuestToHost(pClient, root, pPath, cbPath,
     
    25982598    testSymlinkBadParameters(hTest);
    25992599    /* Add tests as required... */
    2600 }
    2601 #endif
    2602 int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pNewPath, SHFLSTRING *pOldPath, SHFLFSOBJINFO *pInfo)
     2600    testSymlinkCreation(hTest);
     2601}
     2602#endif
     2603
     2604int vbsfSymlink(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pSymlinkPath, SHFLSTRING *pSourcePath, SHFLFSOBJINFO *pInfo)
    26032605{
    26042606    int rc = VINF_SUCCESS;
    26052607
    2606     char *pszFullNewPath = NULL;
    2607     char *pszFullOldPath = NULL;
     2608    char *pszFullSymlinkPath = NULL;
     2609    char *pszFullSourcePath = NULL;
    26082610
    26092611    /* XXX: no support for UCS2 at the moment. */
     
    26172619        return VERR_WRITE_PROTECT; /* XXX or VERR_TOO_MANY_SYMLINKS? */
    26182620
    2619     rc = vbsfBuildFullPath(pClient, root, pNewPath, pNewPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullNewPath, NULL);
    2620     AssertRCReturn(rc, rc);
    2621 
    2622     /* Verify that the link target can be a valid host path, i.e. does not contain invalid characters. */
     2621    rc = vbsfBuildFullPath(pClient, root, pSymlinkPath, pSymlinkPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullSymlinkPath,
     2622                           NULL);
     2623    if (RT_FAILURE(rc))
     2624        return rc;
     2625
     2626    /*
     2627     * The symbolic link source path may be located outside of the shared folder so thus
     2628     * we don't call vbsfBuildFullPath() which includes VBSF_O_PATH_CHECK_ROOT_ESCAPE to
     2629     * verify that the pathname resides within the shared folder.  Instead we call the
     2630     * heart of vbsfBuildFullPath() which is vbsfPathGuestToHost() to perform a subset
     2631     * of its checks to verify that the symbolic link source is a valid path by checking
     2632     * for invalid characters, replacing path delimiters if the guest uses a different
     2633     * slash than the host, and evaluating the symbolic link policy if one has been set.
     2634     * We don't collapse path components of '..' for example or alter the path otherwise
     2635     * as this is the documented behavior of symbolic links: the source pathname can be
     2636     * any pathname and isn't required to exist.
     2637     */
    26232638    uint32_t fu32PathFlags = 0;
    2624     uint32_t fu32Options = 0;
    2625     rc = vbsfPathGuestToHost(pClient, root, pOldPath, pOldPath->u16Size + SHFLSTRING_HEADER_SIZE,
    2626                              &pszFullOldPath, NULL, fu32Options, &fu32PathFlags);
     2639    uint32_t fu32Options = VBSF_O_PATH_CHECK_SYMLINK_POLICY;
     2640    rc = vbsfPathGuestToHost(pClient, root, pSourcePath, pSourcePath->u16Size + SHFLSTRING_HEADER_SIZE,
     2641                             &pszFullSourcePath, NULL, fu32Options, &fu32PathFlags);
    26272642    if (RT_FAILURE(rc))
    26282643    {
    2629         vbsfFreeFullPath(pszFullNewPath);
     2644        vbsfFreeFullPath(pszFullSymlinkPath);
    26302645        return rc;
    26312646    }
    26322647
    2633     /** @todo r=bird: We _must_ perform slash conversion on the target (what this
    2634      *        code calls 'pOldPath' for some peculiar reason)! */
    2635 
    2636     rc = RTSymlinkCreate(pszFullNewPath, (const char *)pOldPath->String.utf8,
    2637                          RTSYMLINKTYPE_UNKNOWN, 0);
     2648    rc = RTSymlinkCreate(pszFullSymlinkPath, pszFullSourcePath, RTSYMLINKTYPE_UNKNOWN, 0);
    26382649    if (RT_SUCCESS(rc))
    26392650    {
    26402651        RTFSOBJINFO info;
    2641         rc = RTPathQueryInfoEx(pszFullNewPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     2652        rc = RTPathQueryInfoEx(pszFullSymlinkPath, &info, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
    26422653        if (RT_SUCCESS(rc))
    26432654            vbfsCopyFsObjInfoFromIprt(pInfo, &info);
    26442655    }
    26452656
    2646     vbsfFreeFullPath(pszFullOldPath);
    2647     vbsfFreeFullPath(pszFullNewPath);
     2657    vbsfFreeFullPath(pszFullSourcePath);
     2658    vbsfFreeFullPath(pszFullSymlinkPath);
    26482659
    26492660    return rc;
  • trunk/src/VBox/HostServices/SharedFolders/vbsfpath.cpp

    r105018 r105087  
    5454# include <Carbon/Carbon.h>
    5555#endif
     56#include <VBox/com/defs.h> /* For S_OK. */
    5657
    5758#ifdef UNITTEST
     
    438439}
    439440
     441/**
     442 * Validate the symbolic link creation policy inside a guest operating in a shared folder.
     443 *
     444 * @returns S_OK or VERR_WRITE_PROTECT.
     445 * @param pchSymlinkPath    The pathname of the symbolic link within the guest.
     446 * @param enmSymlinkPolicy  The symbolic link creation policy being evaluated.
     447 *
     448 * The enmSymlinkPolicy symlink creation policies are:
     449 *  - @a none:       no policy set
     450 *  - @a any:        no restrictions
     451 *  - @a forbidden:  no symlinks allowed
     452 *  - @a relative:   relative paths only ('..' path components allowed)
     453 *  - @a subtree:    relative paths only within the shared folder (no '..' path components allowed)
     454 */
     455static int vbsfPathEvalSymlinkPolicy(const char *pchSymlinkPath, SymlinkPolicy_T enmSymlinkPolicy)
     456{
     457    /* If no symlink policy has been set we continue the historical behaviour of applying no
     458     * additional restrictions.  The "any" policy also has no symlink path limitations. */
     459    if (   enmSymlinkPolicy == SymlinkPolicy_None
     460        || enmSymlinkPolicy == SymlinkPolicy_AllowedToAnyTarget)
     461        return S_OK;
     462
     463    /* No absolute paths allowed except for the "any" policy.  The symlink path can't
     464     * contain '..' components if the "subtree" policy in effect. */
     465    if (   RTPathStartsWithRoot(pchSymlinkPath)
     466        || enmSymlinkPolicy == SymlinkPolicy_Forbidden
     467        || (   enmSymlinkPolicy == SymlinkPolicy_AllowedInShareSubtree
     468            && RTStrStr(pchSymlinkPath, "..")))
     469        return VERR_WRITE_PROTECT;
     470
     471    return S_OK;
     472}
     473
    440474int vbsfPathGuestToHost(SHFLCLIENTDATA *pClient, SHFLROOT hRoot,
    441475                        PCSHFLSTRING pGuestString, uint32_t cbGuestString,
     
    565599                const char *pchSrc = pchGuestPath;
    566600
    567                 /* Strip leading delimiters from the path the guest specified. */
    568                 while (   cbSrc > 0
    569                        && *pchSrc == pClient->PathDelimiter)
    570                 {
    571                     ++pchSrc;
    572                     --cbSrc;
     601                /* when validating source file pathnames for symbolic links we don't modify the path */
     602                if (!(fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY))
     603                {
     604                    /* Strip leading delimiters from the path the guest specified. */
     605                    while (   cbSrc > 0
     606                           && *pchSrc == pClient->PathDelimiter)
     607                    {
     608                        ++pchSrc;
     609                        --cbSrc;
     610                    }
    573611                }
    574612
     
    615653                    *pchDst++ = 0;
    616654
    617                     /* Construct the full host path removing '.' and '..'. */
    618                     rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc);
     655                    /* check if a symbolic link creation policy has been set */
     656                    if (fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY)
     657                    {
     658                        /* copy the verified symlink source file path to be returned to the caller */
     659                        rc = RTStrCopy(pszFullPath, cbFullPathAlloc, pchVerifiedPath);
     660                        if (RT_SUCCESS(rc))
     661                        {
     662                            SymlinkPolicy_T enmSymlinkPolicy;
     663                            rc = vbsfMappingsQuerySymlinkPolicy(pClient, hRoot, &enmSymlinkPolicy);
     664                            if (RT_SUCCESS(rc))
     665                                rc = vbsfPathEvalSymlinkPolicy(pchVerifiedPath, enmSymlinkPolicy);
     666                        }
     667                    }
     668                    else
     669                    {
     670                        /* Construct the full host path removing '.' and '..'. */
     671                        rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc);
     672                    }
    619673                    if (RT_SUCCESS(rc))
    620674                    {
     
    667721                    else
    668722                    {
    669                         LogFunc(("vbsfPathAbs %Rrc\n", rc));
     723                        if (fu32Options & VBSF_O_PATH_CHECK_SYMLINK_POLICY)
     724                            LogFunc(("vbsfPathEvalSymlinkPolicy() returns rc=%Rrc\n", rc));
     725                        else
     726                            LogFunc(("vbsfPathAbs %Rrc\n", rc));
    670727                    }
    671728                }
  • trunk/src/VBox/HostServices/SharedFolders/vbsfpath.h

    r105018 r105087  
    3838#define VBSF_O_PATH_PRESERVE_LAST_COMPONENT UINT32_C(0x00000002)
    3939#define VBSF_O_PATH_CHECK_ROOT_ESCAPE       UINT32_C(0x00000004)
     40#define VBSF_O_PATH_CHECK_SYMLINK_POLICY    UINT32_C(0x00000008)
    4041
    4142#define VBSF_F_PATH_HAS_WILDCARD_IN_PREFIX UINT32_C(0x00000001) /* A component before the last one contains a wildcard. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette