VirtualBox

Changeset 97792 in vbox


Ignore:
Timestamp:
Dec 13, 2022 1:47:18 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154864
Message:

DnD/Fe/Qt: Added UIDnDHandler::getProcessIntetrityLevel() to retrieve the VM process' integrity level on Windows hosts. Will be logged along a warning if the VM process runs with a high(er) integrity level than most usual applications. Helps diagnosing drag'n drop not working because of UIPI (User Interface Privilege Isolation).

Location:
trunk/src/VBox/Frontends/VirtualBox/src/runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp

    r97787 r97792  
    8484    , m_pParent(pParent)
    8585    , m_fDataRetrieved(false)
    86 #ifndef RT_OS_WINDOWS
     86#ifdef RT_OS_WINDOWS
     87    , m_dwIntegrityLevel(0)
     88#else
    8789    , m_pMIMEData(NULL)
    8890#endif
     
    563565}
    564566
     567/**
     568 * Initializes the drag'n drop UI handler.
     569 *
     570 * @returns VBox status code.
     571 */
     572int UIDnDHandler::init(void)
     573{
     574    int vrc;
     575#ifdef RT_OS_WINDOWS
     576
     577# define CASE_INTEGRITY_LEVEL(a_Level) \
     578    case a_Level: \
     579        LogRel(("DnD: User Interface Privilege Isolation (UIPI) is running with %s\n", ##a_Level)); \
     580        break;
     581
     582    /*
     583     * Assign and log the current process integrity interity level, so that we have a better chance of diagnosing issues
     584     * when it comes to drag'n drop and UIPI (User Interface Privilege Isolation) -- a lower integrity level process
     585     * cannot drag'n drop stuff to a higher integrity level one.
     586     */
     587    vrc = getProcessIntetrityLevel(&m_dwIntegrityLevel);
     588    if (RT_SUCCESS(vrc))
     589    {
     590        switch (m_dwIntegrityLevel)
     591        {
     592            CASE_INTEGRITY_LEVEL(SECURITY_MANDATORY_UNTRUSTED_RID);
     593            CASE_INTEGRITY_LEVEL(SECURITY_MANDATORY_LOW_RID);
     594            CASE_INTEGRITY_LEVEL(SECURITY_MANDATORY_MEDIUM_RID);
     595            CASE_INTEGRITY_LEVEL(SECURITY_MANDATORY_HIGH_RID);
     596            CASE_INTEGRITY_LEVEL(SECURITY_MANDATORY_SYSTEM_RID);
     597            CASE_INTEGRITY_LEVEL(SECURITY_MANDATORY_PROTECTED_PROCESS_RID);
     598            default:
     599                break;
     600        }
     601
     602        if (m_dwIntegrityLevel > SECURITY_MANDATORY_MEDIUM_RID)
     603            LogRel(("DnD: Warning: The VM process' integrity level is higher than most regular processes on the system. "
     604                    "This means that drag'n drop most likely will not work with other applications!\n"));
     605    }
     606    else
     607        LogRel(("DnD: Unable to retrieve process integrity level (%Rrc) -- please report this bug!\n", vrc));
     608# undef CASE_INTEGRITY_LEVEL
     609
     610#else /* ! RT_OS_WINDOWS */
     611    vrc = VINF_SUCCESS;
     612#endif /* RT_OS_WINDOWS */
     613
     614    return vrc;
     615}
     616
    565617void UIDnDHandler::reset(void)
    566618{
     
    568620
    569621    m_fDataRetrieved = false;
    570 }
     622
     623#ifdef RT_OS_WINDOWS
     624    m_dwIntegrityLevel = 0;
     625#endif
     626}
     627
     628#ifdef RT_OS_WINDOWS
     629/**
     630 * Returns the process' current integrity level.
     631 *
     632 * @returns VBox status code.
     633 * @param   pdwIntegrityLevel   Where to return the detected process integrity level on success.
     634 */
     635/* static */
     636int UIDnDHandler::getProcessIntetrityLevel(DWORD *pdwIntegrityLevel)
     637{
     638    AssertPtrReturn(pdwIntegrityLevel, VERR_INVALID_POINTER);
     639
     640    int   vrc;
     641
     642# define PRINT_AND_ASSIGN_LAST_ERROR(a_Msg) \
     643    dwLastErr = GetLastError(); \
     644    vrc = RTErrConvertFromWin32(dwLastErr); \
     645    LogRel(("DnD: %s: %Rrc (%#x)\n", a_Msg, vrc, dwLastErr)); \
     646
     647    DWORD dwLastErr = 0;
     648
     649    DWORD  cb;
     650    HANDLE hToken;
     651    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
     652    {
     653        PRINT_AND_ASSIGN_LAST_ERROR("OpenProcessToken failed");
     654        return vrc;
     655    }
     656
     657    if (   !GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &cb)
     658        && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
     659    {
     660        PSID_AND_ATTRIBUTES pSidAndAttr = (PSID_AND_ATTRIBUTES)RTMemAlloc(cb);
     661        if (GetTokenInformation(hToken, TokenIntegrityLevel, pSidAndAttr, cb, &cb))
     662        {
     663            *pdwIntegrityLevel = *GetSidSubAuthority(pSidAndAttr->Sid, *GetSidSubAuthorityCount(pSidAndAttr->Sid) - 1U);
     664        }
     665        else
     666            PRINT_AND_ASSIGN_LAST_ERROR("GetTokenInformation(2) failed");
     667        RTMemFree(pSidAndAttr);
     668    }
     669    else if (   GetLastError() == ERROR_INVALID_PARAMETER
     670             || GetLastError() == ERROR_NOT_SUPPORTED)
     671    {
     672        /* Should never show, as we at least require Windows 7 nowadays on Windows hosts. */
     673        PRINT_AND_ASSIGN_LAST_ERROR("Querying process integrity level not supported");
     674    }
     675    else
     676        PRINT_AND_ASSIGN_LAST_ERROR("GetTokenInformation(1) failed");
     677
     678# undef PRINT_AND_ASSIGN_LAST_ERROR
     679
     680    CloseHandle(hToken);
     681    return vrc;
     682}
     683#endif /* RT_OS_WINDOWS */
    571684
    572685int UIDnDHandler::retrieveData(Qt::DropAction          dropAction,
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.h

    r97784 r97792  
    7474    } UIDnDDataSource;
    7575
     76    int                        init(void);
    7677    void                       reset(void);
    7778
     
    126127protected:
    127128
     129#ifdef RT_OS_WINDOWS
     130    static int                 getProcessIntetrityLevel(DWORD *pdwIntegrityLevel);
     131#endif
     132
     133protected:
     134
    128135    /** Pointer to UI session. */
    129136    UISession        *m_pSession;
     
    145152    QVector<uint8_t>  m_vecData;
    146153
    147 #ifndef RT_OS_WINDOWS
     154#ifdef RT_OS_WINDOWS
     155    /** Process integrity level we're running with. Needed for UIPI detection + logging.
     156     *  Set to 0 if not set yet or unavailable. */
     157    DWORD             m_dwIntegrityLevel;
     158#else /* !RT_OS_WINDOWS */
    148159    /** Pointer to MIMEData instance used for handling
    149160     *  own MIME times on non-Windows host OSes. */
    150161    UIDnDMIMEData    *m_pMIMEData;
    151162    friend class UIDnDMIMEData;
    152 #endif
     163#endif /* RT_OS_WINDOWS */
    153164};
    154165#endif /* !FEQT_INCLUDED_SRC_runtime_UIDnDHandler_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r97681 r97792  
    165165#ifdef VBOX_WITH_DRAG_AND_DROP
    166166    /* Prepare DnD: */
    167     pMachineView->prepareDnd();
     167    /* rc ignored */ pMachineView->prepareDnd();
    168168#endif
    169169
     
    992992
    993993#ifdef VBOX_WITH_DRAG_AND_DROP
    994 void UIMachineView::prepareDnd()
     994int UIMachineView::prepareDnd(void)
    995995{
    996996    /* Enable drag & drop: */
    997997    setAcceptDrops(true);
    998998
    999     /* Create the drag and drop handler instance: */
    1000     m_pDnDHandler = new UIDnDHandler(uisession(), this /* pParent */);
     999    int vrc;
     1000
     1001    try
     1002    {
     1003        /* Create the drag and drop handler instance: */
     1004        m_pDnDHandler = new UIDnDHandler(uisession(), this /* pParent */);
     1005        vrc = m_pDnDHandler->init();
     1006    }
     1007    catch (std::bad_alloc &)
     1008    {
     1009        vrc = VERR_NO_MEMORY;
     1010    }
     1011
     1012    if (RT_FAILURE(vrc))
     1013        LogRel(("DnD: Initialization failed with %Rrc\n", vrc));
     1014    return vrc;
    10011015}
    10021016#endif /* VBOX_WITH_DRAG_AND_DROP */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h

    r97512 r97792  
    177177    virtual void prepareCommon();
    178178#ifdef VBOX_WITH_DRAG_AND_DROP
    179     virtual void prepareDnd();
     179    virtual int prepareDnd();
    180180#endif
    181181    virtual void prepareFilters();
Note: See TracChangeset for help on using the changeset viewer.

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