VirtualBox

Changeset 98824 in vbox


Ignore:
Timestamp:
Mar 2, 2023 5:06:36 PM (21 months ago)
Author:
vboxsync
Message:

Guest Control: Made the directory entry reading really dynamic by letting the guest tell us the size it reports to the guest (limited by GSTCTL_DIRENTRY_MAX_SIZE). Re-introduced the #pragma pack(1) because we need the structures on mixed bitness (32 / 64 or vice versa) with the same size. bugref:9783

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/GuestControl.h

    r98820 r98824  
    303303 * Additional Unix Attributes (GSTCTLFSOBJATTRADD_UNIX).
    304304 */
     305#pragma pack(1)
    305306typedef struct GSTCTLFSOBJATTRUNIX
    306307{
     
    344345    RTDEV           Device;
    345346} GSTCTLFSOBJATTRUNIX;
     347#pragma pack()
     348AssertCompileSize(GSTCTLFSOBJATTRUNIX, 36);
    346349
    347350/**
     
    549552typedef GSTCTLDIRENTRYEX const *PCGSTCTLDIRENTRYEX;
    550553
    551 /** The maximum size (in bytes) of a GSTCTLDIRENTRYEX (includes dynamic szName[pDirEntry->cbName + 1]). */
    552 #define GSTCTL_DIRENTRY_MAX_SIZE    (sizeof(GSTCTLDIRENTRYEX) + RTPATH_MAX)
     554/** The maximum size (in bytes) of an entry file name (at least RT_UOFFSETOF(GSTCTLDIRENTRYEX, szName[2]). */
     555#define GSTCTL_DIRENTRY_MAX_SIZE    4096
    553556
    554557} /* namespace guestControl */
  • trunk/include/VBox/HostServices/GuestControlSvc.h

    r98823 r98824  
    10631063    /** Handle of directory listing to read the next entry for. */
    10641064    HGCMFunctionParameter handle;
    1065     /** Maximum directory entry size (in bytes) to use.
    1066      *  @sa GSTCTL_DIRENTRY_MAX_SIZE */
    1067     HGCMFunctionParameter max_entry_size;
    10681065} HGCMMsgDirRead;
    10691066
  • trunk/include/VBox/VBoxGuestLib.h

    r98818 r98824  
    11201120VBGLR3DECL(int) VbglR3GuestCtrlDirGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfFlags, GSTCTLDIRFILTER *penmFilter, GSTCTLFSOBJATTRADD *penmReadAttrAdd, uint32_t *pfReadFlags);
    11211121VBGLR3DECL(int) VbglR3GuestCtrlDirGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
    1122 VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *pcbDirEntry);
     1122VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
    11231123VBGLR3DECL(int) VbglR3GuestCtrlDirGetRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
    11241124/** @} */
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp

    r98818 r98824  
    10711071 * @param   pCtx                Guest control command context to use.
    10721072 * @param   puHandle            Where to return the directory handle to rewind.
    1073  * @param   pcbDirEntry         Where to return the directory entry size.
    1074  */
    1075 VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *pcbDirEntry)
    1076 {
    1077     AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    1078     AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
     1073 */
     1074VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
     1075{
     1076    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1077    AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
    10791078
    10801079    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    1081     AssertPtrReturn(pcbDirEntry, VERR_INVALID_POINTER);
    10821080
    10831081    int rc;
     
    10881086        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_READ);
    10891087        VbglHGCMParmUInt32Set(&Msg.handle, 0);
    1090         VbglHGCMParmUInt32Set(&Msg.max_entry_size, 0);
    10911088
    10921089        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     
    10951092            Msg.context.GetUInt32(&pCtx->uContextID);
    10961093            Msg.handle.GetUInt32(puHandle);
    1097             Msg.max_entry_size.GetUInt32(pcbDirEntry);
    10981094        }
    10991095    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     
    22742270 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
    22752271 * @param   pEntry              Directory entry to send.
    2276  * @param   cbSize              Size (in bytes) of \a pDirEntry to send.
    2277  *                              This might be needed as the size can be bigger than GSTCTLDIRENTRYEX.
     2272 * @param   cbSize              Size (in bytes) of the OFFSET(GSTCTLDIRENTRYEX, szName[pEntry->cbName + 1]).
    22782273 *                              See RTDirReadEx() for more information.
    22792274 * @param   pszUser             Associated user ID (owner, uid) as a string.
     
    23092304 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
    23102305 * @param   pEntry              Directory entry to send.
    2311  * @param   cbSize              Size (in bytes) of \a pDirEntry to send.
    2312  *                              This might be needed as the size can be bigger than GSTCTLDIRENTRYEX.
     2306 * @param   cbSize              Size (in bytes) of the OFFSET(GSTCTLDIRENTRYEX, szName[pEntry->cbName + 1]).
    23132307 *                              See RTDirReadEx() for more information.
    23142308 */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h

    r98818 r98824  
    3333
    3434#include <iprt/critsect.h>
     35#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     36# include <iprt/dir.h>
     37#endif
    3538#include <iprt/list.h>
    3639#include <iprt/req.h>
     
    225228    /** How many processes do we allow keeping around at a time? */
    226229    uint32_t                        uProcsMaxKept;
     230#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
    227231    /** The uid cache for this session. */
    228232    VGSVCIDCACHE                    UidCache;
    229233    /** The gid cache for this session. */
    230234    VGSVCIDCACHE                    GidCache;
     235    /** Scratch buffer for holding the directory reading entry.
     236     *  Currently NOT serialized, i.e. only can be used for one read at a time. */
     237    PRTDIRENTRYEX                   pDirEntryEx;
     238    /** Size (in bytes) of \a pDirEntryEx. */
     239    size_t                          cbDirEntryEx;
     240#endif
    231241} VBOXSERVICECTRLSESSION;
    232242/** Pointer to guest session. */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp

    r98818 r98824  
    11421142     * Retrieve the message.
    11431143     */
    1144     uint32_t           uHandle;
    1145     size_t             cbDirEntry = 0;
    1146     GSTCTLDIRENTRYEX   DirEntryEx;
    1147     int rc = VbglR3GuestCtrlDirGetRead(pHostCtx, &uHandle, (uint32_t *)&cbDirEntry);
     1144    uint32_t uHandle;
     1145    int rc = VbglR3GuestCtrlDirGetRead(pHostCtx, &uHandle);
    11481146    if (RT_SUCCESS(rc))
    11491147    {
     
    11511149        if (pDir)
    11521150        {
    1153             RT_ZERO(DirEntryEx);
     1151            PRTDIRENTRYEX pDirEntryEx = pSession->pDirEntryEx;
     1152
     1153            size_t cbDirEntry = pSession->cbDirEntryEx;
     1154            rc = RTDirReadEx(pDir->hDir, pDirEntryEx, &cbDirEntry, (RTFSOBJATTRADD)pDir->enmReadAttrAdd, pDir->fRead);
     1155
     1156            /* Paranoia. */
     1157            AssertStmt(cbDirEntry <= pSession->cbDirEntryEx, rc = VERR_BUFFER_OVERFLOW);
     1158
     1159            VGSvcVerbose(2, "[Dir %s] Read next entry '%s' -> %Rrc (%zu bytes)\n",
     1160                         pDir->pszPathAbs, RT_SUCCESS(rc) ? pDirEntryEx->szName : "<None>", rc, cbDirEntry);
     1161
     1162            const char *pszUser  = VGSvcIdCacheGetUidName(&pSession->UidCache,
     1163                                                          pDirEntryEx->Info.Attr.u.Unix.uid, pDirEntryEx->szName, pDir->pszPathAbs);
     1164            const char *pszGroup = VGSvcIdCacheGetGidName(&pSession->GidCache,
     1165                                                          pDirEntryEx->Info.Attr.u.Unix.gid, pDirEntryEx->szName, pDir->pszPathAbs);
     1166
     1167            VGSvcVerbose(2, "[Dir %s] Entry '%s': %zu bytes, uid=%s (%d), gid=%s (%d)\n",
     1168                         pDir->pszPathAbs, pDirEntryEx->szName, pDirEntryEx->Info.cbObject,
     1169                         pszUser ? pszUser : "", pDirEntryEx->Info.Attr.u.UnixOwner.uid,
     1170                         pszGroup ? pszGroup : "", pDirEntryEx->Info.Attr.u.UnixGroup.gid);
    11541171
    11551172            /*
     
    11591176             * Ditto for RTFSOBJATTRADD == GSTCTLFSOBJATTRADD.
    11601177             */
    1161             AssertCompileSize(DirEntryEx, sizeof(RTDIRENTRYEX));
    1162             AssertCompile    (RT_OFFSETOF(GSTCTLDIRENTRYEX, Info)   == RT_OFFSETOF(RTDIRENTRYEX, Info));
    1163             AssertCompile    (RT_OFFSETOF(GSTCTLDIRENTRYEX, szName) == RT_OFFSETOF(RTDIRENTRYEX, szName));
    1164             AssertCompile    (RT_OFFSETOF(GSTCTLFSOBJINFO,  Attr)   == RT_OFFSETOF(RTFSOBJINFO,  Attr));
    1165 
    1166             PRTDIRENTRYEX pDirEntryExRuntime = (PRTDIRENTRYEX)&DirEntryEx;
    1167 
    1168             rc = RTDirReadEx(pDir->hDir, pDirEntryExRuntime, &cbDirEntry, (RTFSOBJATTRADD)pDir->enmReadAttrAdd, pDir->fRead);
    1169 
    1170             /* Paranoia. */
    1171             AssertStmt(cbDirEntry <= _256K, rc = VERR_BUFFER_OVERFLOW);
    1172 
    1173             VGSvcVerbose(2, "[Dir %s] Read next entry '%s' -> %Rrc\n",
    1174                          pDir->pszPathAbs, RT_SUCCESS(rc) ? DirEntryEx.szName : "<None>", rc);
    1175 
    1176             const char *pszUser  = VGSvcIdCacheGetUidName(&pSession->UidCache, DirEntryEx.Info.Attr.u.Unix.uid, DirEntryEx.szName,
    1177                                                           pDir->pszPathAbs);
    1178             const char *pszGroup = VGSvcIdCacheGetGidName(&pSession->GidCache, DirEntryEx.Info.Attr.u.Unix.gid, DirEntryEx.szName,
    1179                                                           pDir->pszPathAbs);
    1180 
    1181             VGSvcVerbose(2, "[Dir %s] Entry '%s': %zu bytes, uid=%s (%d), gid=%s (%d)\n",
    1182                          pDir->pszPathAbs, DirEntryEx.szName, DirEntryEx.Info.cbObject,
    1183                          pszUser ? pszUser : "", DirEntryEx.Info.Attr.u.UnixOwner.uid,
    1184                          pszGroup ? pszGroup : "", DirEntryEx.Info.Attr.u.UnixGroup.gid);
    1185 
    1186             int rc2 = VbglR3GuestCtrlDirCbReadEx(pHostCtx, rc,
    1187                                                  &DirEntryEx, (uint32_t)(sizeof(GSTCTLDIRENTRYEX) + cbDirEntry),
    1188                                                  pszUser, pszGroup);
     1178            AssertCompile(sizeof(GSTCTLDIRENTRYEX)              == sizeof(RTDIRENTRYEX));
     1179            AssertCompile(RT_OFFSETOF(GSTCTLDIRENTRYEX, Info)   == RT_OFFSETOF(RTDIRENTRYEX, Info));
     1180            AssertCompile(RT_OFFSETOF(GSTCTLDIRENTRYEX, cbName) == RT_OFFSETOF(RTDIRENTRYEX, cbName));
     1181            AssertCompile(RT_OFFSETOF(GSTCTLDIRENTRYEX, szName) == RT_OFFSETOF(RTDIRENTRYEX, szName));
     1182            AssertCompile(RT_OFFSETOF(GSTCTLFSOBJINFO,  Attr)   == RT_OFFSETOF(RTFSOBJINFO,  Attr));
     1183
     1184            PGSTCTLDIRENTRYEX pGstCtlDirEntryEx = (PGSTCTLDIRENTRYEX)pDirEntryEx;
     1185
     1186            int rc2 = VbglR3GuestCtrlDirCbReadEx(pHostCtx, rc, pGstCtlDirEntryEx, cbDirEntry, pszUser, pszGroup);
    11891187            if (RT_FAILURE(rc2))
    11901188                VGSvcError("Failed to report directory read status (%Rrc), rc=%Rrc\n", rc, rc2);
     
    27282726    int rc = VGSvcGstCtrlSessionClose(pSession);
    27292727
     2728#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2729    RTMemFree(pSession->pDirEntryEx);
     2730#endif
     2731
    27302732    /* Destroy critical section. */
    27312733    RTCritSectDelete(&pSession->CritSect);
     
    27502752    pSession->fFlags = fFlags;
    27512753
     2754#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
    27522755    RT_ZERO(pSession->UidCache);
    27532756    RT_ZERO(pSession->GidCache);
     2757
     2758    pSession->cbDirEntryEx = GSTCTL_DIRENTRY_MAX_SIZE;
     2759    pSession->pDirEntryEx  = (PRTDIRENTRYEX)RTMemAlloc(pSession->cbDirEntryEx);
     2760    AssertPtrReturn(pSession->pDirEntryEx, VERR_NO_MEMORY);
     2761#endif
    27542762
    27552763    /* Init critical section for protecting the thread lists. */
  • trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp

    r98818 r98824  
    516516        case GUEST_DIR_NOTIFYTYPE_READ:
    517517        {
    518             ASSERT_GUEST_MSG_STMT_BREAK(pSvcCbData->mParms == 7, ("mParms=%u\n", pSvcCbData->mParms),
     518            ASSERT_GUEST_MSG_STMT_BREAK(pSvcCbData->mParms == 6, ("mParms=%u\n", pSvcCbData->mParms),
    519519                                        vrc = VERR_WRONG_PARAMETER_COUNT);
    520520            ASSERT_GUEST_MSG_STMT_BREAK(pSvcCbData->mpaParms[idx].type == VBOX_HGCM_SVC_PARM_PTR,
     
    525525            vrc = HGCMSvcGetPv(&pSvcCbData->mpaParms[idx++], (void **)&pEntry, &cbEntry);
    526526            AssertRCBreak(vrc);
    527             AssertBreakStmt(   cbEntry >= sizeof(GSTCTLDIRENTRYEX)
     527            AssertBreakStmt(   cbEntry >= RT_UOFFSETOF(GSTCTLDIRENTRYEX, szName[2])
    528528                            && cbEntry <= GSTCTL_DIRENTRY_MAX_SIZE, VERR_INVALID_PARAMETER);
    529529            dataCb.u.read.pEntry  = (PGSTCTLDIRENTRYEX)RTMemDup(pEntry, cbEntry);
     
    775775        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
    776776        HGCMSvcSetU32(&paParms[i++], mObjectID /* Guest directory handle */);
    777         HGCMSvcSetU32(&paParms[i++], GSTCTL_DIRENTRY_MAX_SIZE);
    778777
    779778        vrc = sendMessage(HOST_MSG_DIR_READ, i, paParms);
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