VirtualBox

Changeset 53002 in vbox for trunk


Ignore:
Timestamp:
Oct 8, 2014 11:46:15 PM (10 years ago)
Author:
vboxsync
Message:

VBoxDrv-win.cpp: Keep the error info string from failed VBoxDrv and VBoxDrvStub open operations so userland can give us better messages to work on. Fixeds a couple of odd bugs.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r52618 r53002  
    6161# define SUP_NT_STATUS_IS_VBOX(a_rcNt)          ( ((uint32_t)(a_rcNt) & 0xffff0000) == SUP_NT_STATUS_BASE )
    6262# define SUP_NT_STATUS_TO_VBOX(a_rcNt)          ( (int)((uint32_t)(a_rcNt) | UINT32_C(0xffff0000)) )
     63
     64/** NT device name for system access. */
     65# define SUPDRV_NT_DEVICE_NAME_SYS              L"\\Device\\VBoxDrv"
     66/** NT device name for user access. */
     67# define SUPDRV_NT_DEVICE_NAME_USR              L"\\Device\\VBoxDrvU"
     68# ifdef VBOX_WITH_HARDENING
     69/** NT device name for hardened stub access. */
     70#  define SUPDRV_NT_DEVICE_NAME_STUB            L"\\Device\\VBoxDrvStub"
     71/** NT device name for getting error information for failed VBoxDrv or
     72 * VBoxDrvStub open. */
     73#  define SUPDRV_NT_DEVICE_NAME_ERROR_INFO      L"\\Device\\VBoxDrvErrorInfo"
     74# endif
     75
    6376
    6477#elif defined(RT_OS_SOLARIS)
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r52618 r53002  
    262262     * Open the support driver.
    263263     */
    264     int rc = suplibOsInit(&g_supLibData, g_fPreInited, fUnrestricted);
     264    SUPINITOP enmWhat = kSupInitOp_Driver;
     265    int rc = suplibOsInit(&g_supLibData, g_fPreInited, fUnrestricted, &enmWhat, NULL);
    265266    if (RT_SUCCESS(rc))
    266267    {
  • trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h

    r52969 r53002  
    352352int     suplibOsInstall(void);
    353353int     suplibOsUninstall(void);
    354 int     suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted);
     354int     suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo);
    355355int     suplibOsTerm(PSUPLIBDATA pThis);
    356356int     suplibOsHardenedVerifyInit(void);
     
    471471DECLHIDDEN(void)    supR3HardenedWinCompactHeaps(void);
    472472DECLHIDDEN(void)    supR3HardenedMainOpenDevice(void);
     473DECLHIDDEN(char *)  supR3HardenedWinReadErrorInfoDevice(char *pszErrorInfo, size_t cbErrorInfo, const char *pszPrefix);
    473474DECLHIDDEN(void)    supR3HardenedWinReportErrorToParent(const char *pszWhere, SUPINITOP enmWhat, int rc,
    474475                                                        const char *pszFormat, va_list va);
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r52971 r53002  
    12321232DECLHIDDEN(void) supR3HardenedMainOpenDevice(void)
    12331233{
    1234     int rc = suplibOsInit(&g_SupPreInitData.Data, false /*fPreInit*/, true /*fUnrestricted*/);
     1234    RTERRINFOSTATIC ErrInfo;
     1235    SUPINITOP       enmWhat = kSupInitOp_Driver;
     1236    int rc = suplibOsInit(&g_SupPreInitData.Data, false /*fPreInit*/, true /*fUnrestricted*/,
     1237                          &enmWhat, RTErrInfoInitStatic(&ErrInfo));
    12351238    if (RT_SUCCESS(rc))
    12361239        return;
    12371240
     1241    if (RTErrInfoIsSet(&ErrInfo.Core))
     1242        supR3HardenedFatalMsg("suplibOsInit", enmWhat, rc, "%s", ErrInfo.szMsg);
     1243
    12381244    switch (rc)
    12391245    {
    12401246        /** @todo better messages! */
    12411247        case VERR_VM_DRIVER_NOT_INSTALLED:
    1242             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1243                                   "Kernel driver not installed");
     1248            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "Kernel driver not installed");
    12441249        case VERR_VM_DRIVER_NOT_ACCESSIBLE:
    1245             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1246                                   "Kernel driver not accessible");
     1250            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "Kernel driver not accessible");
    12471251        case VERR_VM_DRIVER_LOAD_ERROR:
    1248             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1249                                   "VERR_VM_DRIVER_LOAD_ERROR");
     1252            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_VM_DRIVER_LOAD_ERROR");
    12501253        case VERR_VM_DRIVER_OPEN_ERROR:
    1251             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1252                                   "VERR_VM_DRIVER_OPEN_ERROR");
     1254            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_VM_DRIVER_OPEN_ERROR");
    12531255        case VERR_VM_DRIVER_VERSION_MISMATCH:
    1254             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1255                                   "Kernel driver version mismatch");
     1256            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "Kernel driver version mismatch");
    12561257        case VERR_ACCESS_DENIED:
    1257             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1258                                   "VERR_ACCESS_DENIED");
     1258            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "VERR_ACCESS_DENIED");
    12591259        case VERR_NO_MEMORY:
    1260             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1261                                   "Kernel memory allocation/mapping failed");
     1260            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "Kernel memory allocation/mapping failed");
    12621261        case VERR_SUPDRV_HARDENING_EVIL_HANDLE:
    12631262            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Integrity, rc, "VERR_SUPDRV_HARDENING_EVIL_HANDLE");
     
    12691268            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Integrity, rc, "VERR_SUPLIB_NT_PROCESS_UNTRUSTED_2");
    12701269        default:
    1271             supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc,
    1272                                   "Unknown rc=%d", rc);
     1270            supR3HardenedFatalMsg("suplibOsInit", kSupInitOp_Driver, rc, "Unknown rc=%d (%Rrc)", rc, rc);
    12731271    }
    12741272}
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPLib-darwin.cpp

    r51488 r53002  
    186186
    187187
    188 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
     188int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
    189189{
    190190    /*
  • trunk/src/VBox/HostDrivers/Support/freebsd/SUPLib-freebsd.cpp

    r44528 r53002  
    6868
    6969
    70 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
     70int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
    7171{
    7272    /*
  • trunk/src/VBox/HostDrivers/Support/linux/SUPLib-linux.cpp

    r46002 r53002  
    7575
    7676
    77 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
     77int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
    7878{
    7979    /*
  • trunk/src/VBox/HostDrivers/Support/os2/SUPLib-os2.cpp

    r44528 r53002  
    6666
    6767
    68 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
     68int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
    6969{
    7070    /*
  • trunk/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp

    r49840 r53002  
    7878
    7979
    80 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
     80int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
    8181{
    8282    /*
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r52962 r53002  
    4242#include <iprt/power.h>
    4343#include <iprt/rand.h>
     44#include <iprt/semaphore.h>
    4445#include <iprt/spinlock.h>
    4546#include <iprt/string.h>
     
    6263#define SUPDRV_NT_POOL_TAG  'xoBV'
    6364
    64 /** NT device name for system access. */
    65 #define DEVICE_NAME_NT_SYS      L"\\Device\\VBoxDrv"
    6665/** NT device name for user access. */
    67 #define DEVICE_NAME_NT_USR      L"\\Device\\VBoxDrvU"
     66#define DEVICE_NAME_NT_USR          L"\\Device\\VBoxDrvU"
    6867#ifdef VBOX_WITH_HARDENING
    69 /** NT device name for hardened stub access. */
    70 # define DEVICE_NAME_NT_STUB    L"\\Device\\VBoxDrvStub"
    71 
    7268/** Macro for checking for deflecting calls to the stub device. */
    7369# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) \
    74     do { if ((a_pDevObj) == g_pDevObjStub) supdrvNtCompleteRequest(STATUS_ACCESS_DENIED, a_pIrp); } while (0)
     70    do { if ((a_pDevObj) == g_pDevObjStub) \
     71            return supdrvNtCompleteRequest(STATUS_ACCESS_DENIED, a_pIrp); \
     72    } while (0)
     73/** Macro for checking for deflecting calls to the stub and error info
     74 *  devices. */
     75# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_OR_ERROR_INFO_DEV(a_pDevObj, a_pIrp) \
     76    do { if ((a_pDevObj) == g_pDevObjStub || (a_pDevObj) == g_pDevObjErrorInfo) \
     77            return supdrvNtCompleteRequest(STATUS_ACCESS_DENIED, a_pIrp); \
     78    } while (0)
    7579#else
    76 # define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp) do {} while (0)
     80# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(a_pDevObj, a_pIrp)                 do {} while (0)
     81# define VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_OR_ERROR_INFO_DEV(a_pDevObj, a_pIrp)   do {} while (0)
    7782#endif
    7883
     
    109114
    110115/**
    111  * Device extension used by VBoxDrvS.
     116 * Device extension used by VBoxDrvStub.
    112117 */
    113118typedef struct SUPDRVDEVEXTSTUB
     
    116121    SUPDRVDEVEXTUSR     Common;
    117122} SUPDRVDEVEXTSTUB;
    118 /** Pointer to the VBoxDrvS device extension. */
     123/** Pointer to the VBoxDrvStub device extension. */
    119124typedef SUPDRVDEVEXTSTUB *PSUPDRVDEVEXTSTUB;
    120125/** Value of SUPDRVDEVEXTSTUB::Common.u32Cookie. */
    121126#define SUPDRVDEVEXTSTUB_COOKIE      UINT32_C(0x90abcdef)
     127
     128
     129/**
     130 * Device extension used by VBoxDrvErrorInfo.
     131 */
     132typedef struct SUPDRVDEVEXTERRORINFO
     133{
     134    /** Common header. */
     135    SUPDRVDEVEXTUSR     Common;
     136} SUPDRVDEVEXTERRORINFO;
     137/** Pointer to the VBoxDrvErrorInfo device extension. */
     138typedef SUPDRVDEVEXTERRORINFO *PSUPDRVDEVEXTERRORINFO;
     139/** Value of SUPDRVDEVEXTERRORINFO::Common.u32Cookie. */
     140#define SUPDRVDEVEXTERRORINFO_COOKIE      UINT32_C(0xBadC0ca0)
     141
     142/**
     143 * Error info for a failed VBoxDrv or VBoxDrvStub open attempt.
     144 */
     145typedef struct SUPDRVNTERRORINFO
     146{
     147    /** The list entry (in g_ErrorInfoHead). */
     148    RTLISTNODE      ListEntry;
     149    /** The ID of the process this error info belongs to.  */
     150    HANDLE          hProcessId;
     151    /** The ID of the thread owning this info. */
     152    HANDLE          hThreadId;
     153    /** Milliseconds createion timestamp (for cleaning up).  */
     154    uint64_t        uCreatedMsTs;
     155    /** Number of bytes of valid info. */
     156    uint32_t        cchErrorInfo;
     157    /** The error info. */
     158    char            szErrorInfo[2048];
     159} SUPDRVNTERRORINFO;
     160/** Pointer to error info. */
     161typedef SUPDRVNTERRORINFO *PSUPDRVNTERRORINFO;
    122162
    123163
     
    247287static NTSTATUS _stdcall   VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    248288static VOID     _stdcall   VBoxPowerDispatchCallback(PVOID pCallbackContext, PVOID pArgument1, PVOID pArgument2);
     289static NTSTATUS _stdcall   VBoxDrvNtRead(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    249290static NTSTATUS _stdcall   VBoxDrvNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    250291static NTSTATUS            VBoxDrvNtErr2NtStatus(int rc);
     
    260301
    261302static bool                 supdrvNtIsDebuggerAttached(void);
     303static void                 supdrvNtErrorInfoCleanupProcess(HANDLE hProcessId);
     304
    262305#endif
    263306
     
    355398static POBJECT_TYPE volatile        g_pAlpcPortObjectType2 = NULL;
    356399
     400/** Pointer to the error information device instance. */
     401static PDEVICE_OBJECT               g_pDevObjErrorInfo = NULL;
     402/** Fast mutex semaphore protecting the error info list. */
     403static RTSEMMUTEX                   g_hErrorInfoLock = NIL_RTSEMMUTEX;
     404/** Head of the error info (SUPDRVNTERRORINFO). */
     405static RTLISTANCHOR                 g_ErrorInfoHead;
     406
    357407#endif
    358408
     
    370420     */
    371421    UNICODE_STRING DevName;
    372     RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_SYS);
     422    RtlInitUnicodeString(&DevName, SUPDRV_NT_DEVICE_NAME_SYS);
    373423    NTSTATUS rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXT), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjSys);
    374424    if (NT_SUCCESS(rcNt))
     
    377427         * User device.
    378428         */
    379         RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_USR);
     429        RtlInitUnicodeString(&DevName, SUPDRV_NT_DEVICE_NAME_USR);
    380430        rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTUSR), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjUsr);
    381431        if (NT_SUCCESS(rcNt))
     
    389439             * Hardened stub device.
    390440             */
    391             RtlInitUnicodeString(&DevName, DEVICE_NAME_NT_STUB);
     441            RtlInitUnicodeString(&DevName, SUPDRV_NT_DEVICE_NAME_STUB);
    392442            rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTSTUB), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_pDevObjStub);
    393443            if (NT_SUCCESS(rcNt))
     
    398448                    pDevExtStub->Common.pMainDrvExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
    399449                    pDevExtStub->Common.u32Cookie   = SUPDRVDEVEXTSTUB_COOKIE;
     450
     451                    /*
     452                     * Hardened error information device.
     453                     */
     454                    RtlInitUnicodeString(&DevName, SUPDRV_NT_DEVICE_NAME_ERROR_INFO);
     455                    rcNt = IoCreateDevice(pDrvObj, sizeof(SUPDRVDEVEXTERRORINFO), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE,
     456                                          &g_pDevObjErrorInfo);
     457                    if (NT_SUCCESS(rcNt))
     458                    {
     459                        g_pDevObjErrorInfo->Flags |= DO_BUFFERED_IO;
     460
     461                        if (NT_SUCCESS(rcNt))
     462                        {
     463                            PSUPDRVDEVEXTERRORINFO pDevExtStub = (PSUPDRVDEVEXTERRORINFO)g_pDevObjStub->DeviceExtension;
     464                            pDevExtStub->Common.pMainDrvExt = (PSUPDRVDEVEXT)g_pDevObjSys->DeviceExtension;
     465                            pDevExtStub->Common.u32Cookie   = SUPDRVDEVEXTERRORINFO_COOKIE;
     466
    400467#endif
    401 
    402                     /* Done. */
    403                     return rcNt;
     468                            /* Done. */
     469                            return rcNt;
    404470#ifdef VBOX_WITH_HARDENING
     471                        }
     472
     473                        /* Bail out. */
     474                        IoDeleteDevice(g_pDevObjErrorInfo);
     475                        g_pDevObjErrorInfo = NULL;
     476                    }
    405477                }
    406478
     
    435507        pDevExtStub->Common.pMainDrvExt = NULL;
    436508    }
     509    if (g_pDevObjErrorInfo)
     510    {
     511        PSUPDRVDEVEXTERRORINFO pDevExtErrorInfo = (PSUPDRVDEVEXTERRORINFO)g_pDevObjStub->DeviceExtension;
     512        pDevExtErrorInfo->Common.pMainDrvExt = NULL;
     513    }
    437514#endif
    438515
    439516#ifdef VBOX_WITH_HARDENING
     517    IoDeleteDevice(g_pDevObjErrorInfo);
     518    g_pDevObjErrorInfo = NULL;
    440519    IoDeleteDevice(g_pDevObjStub);
    441520    g_pDevObjStub = NULL;
     
    512591                    pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = VBoxDrvNtDeviceControl;
    513592                    pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]  = VBoxDrvNtInternalDeviceControl;
    514                     pDrvObj->MajorFunction[IRP_MJ_READ]                     = VBoxDrvNtNotSupportedStub;
     593                    pDrvObj->MajorFunction[IRP_MJ_READ]                     = VBoxDrvNtRead;
    515594                    pDrvObj->MajorFunction[IRP_MJ_WRITE]                    = VBoxDrvNtNotSupportedStub;
    516595
     
    663742        rcNt = STATUS_ACCESS_DENIED;
    664743    }
     744#ifdef VBOX_WITH_HARDENING
     745    /*
     746     * Anyone can open the error device.
     747     */
     748    else if (pDevObj == g_pDevObjErrorInfo)
     749    {
     750        pFileObj->FsContext = NULL;
     751        return supdrvNtCompleteRequestEx(STATUS_SUCCESS, FILE_OPENED, pIrp);
     752    }
     753#endif
    665754    else
    666755    {
     
    838927        }
    839928    }
     929    else if (pDevObj == g_pDevObjErrorInfo)
     930        supdrvNtErrorInfoCleanupProcess(PsGetCurrentProcessId());
    840931    else
    841932#endif
     
    878969        }
    879970    }
     971    else if (pDevObj == g_pDevObjErrorInfo)
     972        supdrvNtErrorInfoCleanupProcess(PsGetCurrentProcessId());
    880973    else
    881974#endif
     
    9171010                                                     PIO_STATUS_BLOCK pIoStatus, PDEVICE_OBJECT pDevObj)
    9181011{
    919     PSUPDRVDEVEXT   pDevExt  = SUPDRVNT_GET_DEVEXT(pDevObj);
     1012    /*
     1013     * Only the normal devices, not the stub or error info ones.
     1014     */
     1015    if (pDevObj != g_pDevObjSys && pDevObj != g_pDevObjUsr)
     1016    {
     1017        pIoStatus->Status      = STATUS_NOT_SUPPORTED;
     1018        pIoStatus->Information = 0;
     1019        return TRUE;
     1020    }
    9201021
    9211022    /*
    9221023     * Check the input a little bit and get a the session references.
    9231024     */
    924     PSUPDRVSESSION  pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(),
    925                                                           (PSUPDRVSESSION *)&pFileObj->FsContext);
     1025    PSUPDRVDEVEXT  pDevExt  = SUPDRVNT_GET_DEVEXT(pDevObj);
     1026    PSUPDRVSESSION pSession = supdrvSessionHashTabLookup(pDevExt, RTProcSelf(), RTR0ProcHandleSelf(),
     1027                                                         (PSUPDRVSESSION *)&pFileObj->FsContext);
    9261028    if (!pSession)
    9271029    {
     
    11021204NTSTATUS _stdcall VBoxDrvNtDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    11031205{
    1104     VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(pDevObj, pIrp);
     1206    VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_OR_ERROR_INFO_DEV(pDevObj, pIrp);
    11051207
    11061208    PSUPDRVDEVEXT       pDevExt  = SUPDRVNT_GET_DEVEXT(pDevObj);
     
    12441346NTSTATUS _stdcall VBoxDrvNtInternalDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    12451347{
    1246     VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_DEV(pDevObj, pIrp);
     1348    VBOXDRV_COMPLETE_IRP_AND_RETURN_IF_STUB_OR_ERROR_INFO_DEV(pDevObj, pIrp);
    12471349
    12481350    PSUPDRVDEVEXT       pDevExt  = SUPDRVNT_GET_DEVEXT(pDevObj);
     
    13221424    pIrp->IoStatus.Status = rcNt;
    13231425    pIrp->IoStatus.Information = cbOut;
     1426    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
     1427    return rcNt;
     1428}
     1429
     1430
     1431/**
     1432 * Implementation of the read major function for VBoxDrvErrorInfo.
     1433 *
     1434 * This is a stub function for the other devices.
     1435 *
     1436 * @returns NT status code.
     1437 * @param   pDevObj             The device object.
     1438 * @param   pIrp                The I/O request packet.
     1439 */
     1440NTSTATUS _stdcall VBoxDrvNtRead(PDEVICE_OBJECT pDevObj, PIRP pIrp)
     1441{
     1442    Log(("VBoxDrvNtRead\n"));
     1443
     1444    NTSTATUS rcNt;
     1445    pIrp->IoStatus.Information = 0;
     1446
     1447#ifdef VBOX_WITH_HARDENING
     1448    /*
     1449     * VBoxDrvErrorInfo?
     1450     */
     1451    if (pDevObj == g_pDevObjErrorInfo)
     1452    {
     1453        PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
     1454        if (   pStack
     1455            && (pIrp->Flags & IRP_BUFFERED_IO))
     1456        {
     1457            /*
     1458             * Look up the process error information.
     1459             */
     1460            HANDLE hCurThreadId  = PsGetCurrentThreadId();
     1461            HANDLE hCurProcessId = PsGetCurrentProcessId();
     1462            int rc = RTSemMutexRequestNoResume(g_hErrorInfoLock, RT_INDEFINITE_WAIT);
     1463            if (RT_SUCCESS(rc))
     1464            {
     1465                PSUPDRVNTERRORINFO  pCur;
     1466                RTListForEach(&g_ErrorInfoHead, pCur, SUPDRVNTERRORINFO, ListEntry)
     1467                {
     1468                    if (   pCur->hProcessId == hCurProcessId
     1469                        && pCur->hThreadId  == hCurThreadId)
     1470                        break;
     1471                }
     1472
     1473                /*
     1474                 * Did we find error info and is the caller requesting data within it?
     1475                 * If so, cehck the destination buffer and copy the data into it.
     1476                 */
     1477                if (   pCur
     1478                    && pStack->Parameters.Read.ByteOffset.QuadPart < pCur->cchErrorInfo
     1479                    && pStack->Parameters.Read.ByteOffset.QuadPart >= 0)
     1480                {
     1481                    PVOID pvDstBuf = pIrp->AssociatedIrp.SystemBuffer;
     1482                    if (pvDstBuf)
     1483                    {
     1484                        uint32_t offRead  = (uint32_t)pStack->Parameters.Read.ByteOffset.QuadPart;
     1485                        uint32_t cbToRead = pCur->cchErrorInfo - (uint32_t)offRead;
     1486                        if (cbToRead > pStack->Parameters.Read.Length)
     1487                        {
     1488                            cbToRead = pStack->Parameters.Read.Length;
     1489                            RT_BZERO((uint8_t *)pvDstBuf + cbToRead, pStack->Parameters.Read.Length - cbToRead);
     1490                        }
     1491                        memcpy(pvDstBuf, &pCur->szErrorInfo[offRead], cbToRead);
     1492                        pIrp->IoStatus.Information = cbToRead;
     1493
     1494                        rcNt = STATUS_SUCCESS;
     1495                    }
     1496                    else
     1497                        rcNt = STATUS_INVALID_ADDRESS;
     1498                }
     1499                /*
     1500                 * End of file. Free the info.
     1501                 */
     1502                else if (pCur)
     1503                {
     1504                    RTListNodeRemove(&pCur->ListEntry);
     1505                    RTMemFree(pCur);
     1506                    rcNt = STATUS_END_OF_FILE;
     1507                }
     1508                /*
     1509                 * We found no error info. Return EOF.
     1510                 */
     1511                else
     1512                    rcNt = STATUS_END_OF_FILE;
     1513
     1514                RTSemMutexRelease(g_hErrorInfoLock);
     1515            }
     1516            else
     1517                rcNt = STATUS_UNSUCCESSFUL;
     1518        }
     1519        else
     1520            rcNt = STATUS_INVALID_PARAMETER;
     1521    }
     1522    else
     1523#endif /* VBOX_WITH_HARDENING */
     1524    {
     1525        /*
     1526         * Stub.
     1527         */
     1528        rcNt = STATUS_NOT_SUPPORTED;
     1529    }
     1530
     1531    /*
     1532     * Complete the request.
     1533     */
     1534    pIrp->IoStatus.Status = rcNt;
    13241535    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    13251536    return rcNt;
     
    25912802 * @{ */
    25922803
     2804
     2805/**
     2806 * Cleans up VBoxDrv or VBoxDrvStub error info not collected by the dead process.
     2807 *
     2808 * @param   hProcessId          The ID of the dead process.
     2809 */
     2810static void supdrvNtErrorInfoCleanupProcess(HANDLE hProcessId)
     2811{
     2812    int rc = RTSemMutexRequestNoResume(g_hErrorInfoLock, RT_INDEFINITE_WAIT);
     2813    if (RT_SUCCESS(rc))
     2814    {
     2815        PSUPDRVNTERRORINFO pCur, pNext;
     2816        RTListForEachSafe(&g_ErrorInfoHead, pCur, pNext, SUPDRVNTERRORINFO, ListEntry)
     2817        {
     2818            if (pCur->hProcessId == hProcessId)
     2819            {
     2820                RTListNodeRemove(&pCur->ListEntry);
     2821                RTMemFree(pCur);
     2822            }
     2823        }
     2824        RTSemMutexRelease(g_hErrorInfoLock);
     2825    }
     2826}
     2827
     2828
    25932829/**
    25942830 * Common worker used by the process creation hooks as well as the process
     
    28373073     */
    28383074    else
     3075    {
    28393076        supdrvNtProtectUnprotectDeadProcess(hNewPid);
     3077        supdrvNtErrorInfoCleanupProcess(hNewPid);
     3078    }
    28403079}
    28413080
     
    28933132     */
    28943133    else
     3134    {
    28953135        supdrvNtProtectUnprotectDeadProcess(hNewPid);
     3136        supdrvNtErrorInfoCleanupProcess(hNewPid);
     3137    }
    28963138}
    28973139
     
    36143856 * @param   pNtProtect          The NT protect structure for getting information
    36153857 *                              about special processes.
    3616  */
    3617 static int supdrvNtProtectRestrictHandlesToProcessAndThread(PSUPDRVNTPROTECT pNtProtect)
     3858 * @param   pErrInfo            Where to return additional error details.
     3859 */
     3860static int supdrvNtProtectRestrictHandlesToProcessAndThread(PSUPDRVNTPROTECT pNtProtect, PRTERRINFO pErrInfo)
    36183861{
    36193862    /*
     
    36443887            pbBuf = (uint8_t *)RTMemAlloc(cbBuf);
    36453888            if (!pbBuf)
    3646                 return VERR_NO_MEMORY;
     3889                return RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "Error allocating %zu bytes for querying handles.", cbBuf);
    36473890            rcNt = NtQuerySystemInformation(SystemExtendedHandleInformation, pbBuf, cbBuf, &cbNeeded);
    36483891        }
     
    36503893        {
    36513894            RTMemFree(pbBuf);
    3652             return RTErrConvertFromNtStatus(rcNt);
     3895            return RTErrInfoSetF(pErrInfo, RTErrConvertFromNtStatus(rcNt),
     3896                                 "NtQuerySystemInformation/SystemExtendedHandleInformation failed: %#x\n", rcNt);
    36533897        }
    36543898    }
     
    37644008                    pHandleInfo->UniqueProcessId, pHandleInfo->HandleValue,
    37654009                    pHandleInfo->GrantedAccess, pHandleInfo->HandleAttributes, pszType));
    3766             rc = VERR_SUPDRV_HARDENING_EVIL_HANDLE;
     4010            rc = RTErrInfoAddF(pErrInfo, VERR_SUPDRV_HARDENING_EVIL_HANDLE,
     4011                               *pErrInfo->pszMsg
     4012                               ? "\nFound evil handle to budding VM process: pid=%p h=%p acc=%#x attr=%#x type=%s"
     4013                               : "Found evil handle to budding VM process: pid=%p h=%p acc=%#x attr=%#x type=%s",
     4014                               pHandleInfo->UniqueProcessId, pHandleInfo->HandleValue,
     4015                               pHandleInfo->GrantedAccess, pHandleInfo->HandleAttributes, pszType);
     4016
     4017            /* Try add the process name. */
     4018            PEPROCESS pOffendingProcess;
     4019            rcNt = PsLookupProcessByProcessId(pHandleInfo->UniqueProcessId, &pOffendingProcess);
     4020            if (NT_SUCCESS(rcNt))
     4021            {
     4022                const char *pszName = (const char *)PsGetProcessImageFileName(pOffendingProcess);
     4023                if (pszName && *pszName)
     4024                    rc = RTErrInfoAddF(pErrInfo, rc, " [%s]", pszName);
     4025
     4026                ObDereferenceObject(pOffendingProcess);
     4027            }
    37674028        }
    37684029    }
     
    37894050     */
    37904051    int rc = VINF_SUCCESS;
    3791     if (pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
    3792         rc = supdrvNtProtectRestrictHandlesToProcessAndThread(pNtProtect);
     4052    PSUPDRVNTERRORINFO pErrorInfo = (PSUPDRVNTERRORINFO)RTMemAllocZ(sizeof(*pErrorInfo));
    37934053    if (RT_SUCCESS(rc))
    37944054    {
    3795         char szErr[256];
    3796         RT_ZERO(szErr);
     4055        pErrorInfo->hProcessId = PsGetCurrentProcessId();
     4056        pErrorInfo->hThreadId  = PsGetCurrentThreadId();
    37974057        RTERRINFO ErrInfo;
    3798         RTErrInfoInit(&ErrInfo, szErr, sizeof(szErr));
    3799 
    3800         rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
    3801                                          NULL /*pcFixes*/, &ErrInfo);
    3802         if (RT_SUCCESS(rc) && pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
    3803             rc = supdrvNtProtectVerifyStubForVmProcess(pNtProtect, &ErrInfo);
    3804         if (RT_FAILURE(rc))
    3805             RTLogWriteDebugger(szErr, strlen(szErr));
    3806     }
     4058        RTErrInfoInit(&ErrInfo, pErrorInfo->szErrorInfo, sizeof(pErrorInfo->szErrorInfo));
     4059
     4060        if (pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
     4061            rc = supdrvNtProtectRestrictHandlesToProcessAndThread(pNtProtect, &ErrInfo);
     4062        if (RT_SUCCESS(rc))
     4063        {
     4064            rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
     4065                                             NULL /*pcFixes*/, &ErrInfo);
     4066            if (RT_SUCCESS(rc) && pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
     4067                rc = supdrvNtProtectVerifyStubForVmProcess(pNtProtect, &ErrInfo);
     4068        }
     4069    }
     4070    else
     4071        rc = VERR_NO_MEMORY;
    38074072
    38084073    /*
     
    38634128
    38644129    RTSpinlockRelease(g_hNtProtectLock);
     4130
     4131    /*
     4132     * Free error info on success, keep it on failure.
     4133     */
     4134    if (RT_SUCCESS(rc))
     4135        RTMemFree(pErrorInfo);
     4136    else if (pErrorInfo)
     4137    {
     4138        pErrorInfo->cchErrorInfo = (uint32_t)strlen(pErrorInfo->szErrorInfo);
     4139        if (!pErrorInfo->cchErrorInfo)
     4140            pErrorInfo->cchErrorInfo = (uint32_t)RTStrPrintf(pErrorInfo->szErrorInfo, sizeof(pErrorInfo->szErrorInfo),
     4141                                                             "supdrvNtProtectVerifyProcess: rc=%d", rc);
     4142        if (RT_FAILURE(rc))
     4143            RTLogWriteDebugger(pErrorInfo->szErrorInfo, pErrorInfo->cchErrorInfo);
     4144
     4145        int rc2 = RTSemMutexRequest(g_hErrorInfoLock, RT_INDEFINITE_WAIT);
     4146        if (RT_SUCCESS(rc2))
     4147        {
     4148            pErrorInfo->uCreatedMsTs = RTTimeMilliTS();
     4149
     4150            /* Free old entries. */
     4151            PSUPDRVNTERRORINFO pCur;
     4152            while (   (pCur = RTListGetFirst(&g_ErrorInfoHead, SUPDRVNTERRORINFO, ListEntry)) != NULL
     4153                   && (int64_t)(pErrorInfo->uCreatedMsTs - pCur->uCreatedMsTs) > 60000 /*60sec*/)
     4154            {
     4155                RTListNodeRemove(&pCur->ListEntry);
     4156                RTMemFree(pCur);
     4157            }
     4158
     4159            /* Insert our new entry. */
     4160            RTListAppend(&g_ErrorInfoHead, &pErrorInfo->ListEntry);
     4161
     4162            RTSemMutexRelease(g_hErrorInfoLock);
     4163        }
     4164        else
     4165            RTMemFree(pErrorInfo);
     4166    }
     4167
    38654168    return rc;
    38664169}
     
    39124215    RTSpinlockDestroy(g_hNtProtectLock);
    39134216    g_NtProtectTree = NIL_RTSPINLOCK;
     4217
     4218    RTSemMutexDestroy(g_hErrorInfoLock);
     4219    g_hErrorInfoLock = NIL_RTSEMMUTEX;
     4220
     4221    PSUPDRVNTERRORINFO pCur;
     4222    while ((pCur = RTListGetFirst(&g_ErrorInfoHead, SUPDRVNTERRORINFO, ListEntry)) != NULL)
     4223    {
     4224        RTListNodeRemove(&pCur->ListEntry);
     4225        RTMemFree(pCur);
     4226    }
    39144227
    39154228    supHardenedWinTermImageVerifier();
     
    40814394    g_NtProtectTree = NULL;
    40824395
    4083     /* Image stuff + certificates. */
    40844396    NTSTATUS rcNt;
    4085     rc = supHardenedWinInitImageVerifier(NULL);
     4397
     4398    /* The mutex protecting the error information. */
     4399    RTListInit(&g_ErrorInfoHead);
     4400    rc = RTSemMutexCreate(&g_hErrorInfoLock);
    40864401    if (RT_SUCCESS(rc))
    40874402    {
    4088         /*
    4089          * Intercept process creation and termination.
    4090          */
    4091         if (g_pfnPsSetCreateProcessNotifyRoutineEx)
    4092             rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, FALSE /*fRemove*/);
    4093         else
    4094             rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, FALSE /*fRemove*/);
    4095         if (NT_SUCCESS(rcNt))
     4403        /* Image stuff + certificates. */
     4404        rc = supHardenedWinInitImageVerifier(NULL);
     4405        if (RT_SUCCESS(rc))
    40964406        {
    40974407            /*
    4098              * Intercept process and thread handle creation calls.
    4099              * The preferred method is only available on Vista SP1+.
     4408             * Intercept process creation and termination.
    41004409             */
    4101             if (g_pfnObRegisterCallbacks && g_pfnObUnRegisterCallbacks)
    4102             {
    4103                 static OB_OPERATION_REGISTRATION s_aObOperations[] =
     4410            if (g_pfnPsSetCreateProcessNotifyRoutineEx)
     4411                rcNt = g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, FALSE /*fRemove*/);
     4412            else
     4413                rcNt = PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, FALSE /*fRemove*/);
     4414            if (NT_SUCCESS(rcNt))
     4415            {
     4416                /*
     4417                 * Intercept process and thread handle creation calls.
     4418                 * The preferred method is only available on Vista SP1+.
     4419                 */
     4420                if (g_pfnObRegisterCallbacks && g_pfnObUnRegisterCallbacks)
    41044421                {
     4422                    static OB_OPERATION_REGISTRATION s_aObOperations[] =
    41054423                    {
    4106                         PsProcessType,
    4107                         OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE,
    4108                         supdrvNtProtectCallback_ProcessHandlePre,
    4109                         supdrvNtProtectCallback_ProcessHandlePost,
    4110                     },
     4424                        {
     4425                            PsProcessType,
     4426                            OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE,
     4427                            supdrvNtProtectCallback_ProcessHandlePre,
     4428                            supdrvNtProtectCallback_ProcessHandlePost,
     4429                        },
     4430                        {
     4431                            PsThreadType,
     4432                            OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE,
     4433                            supdrvNtProtectCallback_ThreadHandlePre,
     4434                            supdrvNtProtectCallback_ThreadHandlePost,
     4435                        },
     4436                    };
     4437                    static OB_CALLBACK_REGISTRATION s_ObCallbackReg =
    41114438                    {
    4112                         PsThreadType,
    4113                         OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE,
    4114                         supdrvNtProtectCallback_ThreadHandlePre,
    4115                         supdrvNtProtectCallback_ThreadHandlePost,
    4116                     },
    4117                 };
    4118                 static OB_CALLBACK_REGISTRATION s_ObCallbackReg =
    4119                 {
    4120                     /* .Version                     = */ OB_FLT_REGISTRATION_VERSION,
    4121                     /* .OperationRegistrationCount  = */ RT_ELEMENTS(s_aObOperations),
    4122                     /* .Altitude.Length             = */ 0,
    4123                     /* .Altitude.MaximumLength      = */ 0,
    4124                     /* .Altitude.Buffer             = */ NULL,
    4125                     /* .RegistrationContext         = */ NULL,
    4126                     /* .OperationRegistration       = */ &s_aObOperations[0]
    4127                 };
    4128                 static WCHAR const *s_apwszAltitudes[] = /** @todo get a valid number */
    4129                 {
    4130                      L"48596.98940",  L"46935.19485",  L"49739.39704",  L"40334.74976",
    4131                      L"66667.98940",  L"69888.19485",  L"69889.39704",  L"60364.74976",
    4132                      L"85780.98940",  L"88978.19485",  L"89939.39704",  L"80320.74976",
    4133                      L"329879.98940", L"326787.19485", L"328915.39704", L"320314.74976",
    4134                 };
    4135 
    4136                 rcNt = STATUS_FLT_INSTANCE_ALTITUDE_COLLISION;
    4137                 for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszAltitudes) && rcNt == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION; i++)
    4138                 {
    4139                     s_ObCallbackReg.Altitude.Buffer = (WCHAR *)s_apwszAltitudes[i];
    4140                     s_ObCallbackReg.Altitude.Length = (uint16_t)RTUtf16Len(s_apwszAltitudes[i]) * sizeof(WCHAR);
    4141                     s_ObCallbackReg.Altitude.MaximumLength = s_ObCallbackReg.Altitude.Length + sizeof(WCHAR);
    4142 
    4143                     rcNt = g_pfnObRegisterCallbacks(&s_ObCallbackReg, &g_pvObCallbacksCookie);
    4144                     if (NT_SUCCESS(rcNt))
     4439                        /* .Version                     = */ OB_FLT_REGISTRATION_VERSION,
     4440                        /* .OperationRegistrationCount  = */ RT_ELEMENTS(s_aObOperations),
     4441                        /* .Altitude.Length             = */ 0,
     4442                        /* .Altitude.MaximumLength      = */ 0,
     4443                        /* .Altitude.Buffer             = */ NULL,
     4444                        /* .RegistrationContext         = */ NULL,
     4445                        /* .OperationRegistration       = */ &s_aObOperations[0]
     4446                    };
     4447                    static WCHAR const *s_apwszAltitudes[] = /** @todo get a valid number */
    41454448                    {
    4146                         /*
    4147                          * Happy ending.
    4148                          */
    4149                         return STATUS_SUCCESS;
     4449                         L"48596.98940",  L"46935.19485",  L"49739.39704",  L"40334.74976",
     4450                         L"66667.98940",  L"69888.19485",  L"69889.39704",  L"60364.74976",
     4451                         L"85780.98940",  L"88978.19485",  L"89939.39704",  L"80320.74976",
     4452                         L"329879.98940", L"326787.19485", L"328915.39704", L"320314.74976",
     4453                    };
     4454
     4455                    rcNt = STATUS_FLT_INSTANCE_ALTITUDE_COLLISION;
     4456                    for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszAltitudes) && rcNt == STATUS_FLT_INSTANCE_ALTITUDE_COLLISION; i++)
     4457                    {
     4458                        s_ObCallbackReg.Altitude.Buffer = (WCHAR *)s_apwszAltitudes[i];
     4459                        s_ObCallbackReg.Altitude.Length = (uint16_t)RTUtf16Len(s_apwszAltitudes[i]) * sizeof(WCHAR);
     4460                        s_ObCallbackReg.Altitude.MaximumLength = s_ObCallbackReg.Altitude.Length + sizeof(WCHAR);
     4461
     4462                        rcNt = g_pfnObRegisterCallbacks(&s_ObCallbackReg, &g_pvObCallbacksCookie);
     4463                        if (NT_SUCCESS(rcNt))
     4464                        {
     4465                            /*
     4466                             * Happy ending.
     4467                             */
     4468                            return STATUS_SUCCESS;
     4469                        }
    41504470                    }
    4151                 }
    4152                 LogRel(("vboxdrv: ObRegisterCallbacks failed with rcNt=%#x\n", rcNt));
    4153                 g_pvObCallbacksCookie = NULL;
    4154             }
    4155             else
    4156             {
    4157                 /*
    4158                  * For the time being, we do not implement extra process
    4159                  * protection on pre-Vista-SP1 systems as they are lacking
    4160                  * necessary KPIs.  XP is end of life, we do not wish to
    4161                  * spend more time on it, so we don't put up a fuss there.
    4162                  * Vista users without SP1 can install SP1 (or later), darn it,
    4163                  * so refuse to load.
    4164                  */
    4165                 /** @todo Hack up an XP solution - will require hooking kernel APIs or doing bad
    4166                  *        stuff to a couple of object types. */
    4167 # ifndef VBOX_WITH_VISTA_NO_SP
    4168                 if (g_uNtVerCombined >= SUP_NT_VER_VISTA)
    4169 # else
    4170                 if (g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0))
    4171 # endif
    4172                 {
    4173                     DbgPrint("vboxdrv: ObRegisterCallbacks was not found. Please make sure you got the latest updates and service packs installed\n");
    4174                     rcNt = STATUS_SXS_VERSION_CONFLICT;
     4471                    LogRel(("vboxdrv: ObRegisterCallbacks failed with rcNt=%#x\n", rcNt));
     4472                    g_pvObCallbacksCookie = NULL;
    41754473                }
    41764474                else
    41774475                {
    4178                     Log(("vboxdrv: ObRegisterCallbacks was not found; ignored pre-Vista\n"));
    4179                     return rcNt = STATUS_SUCCESS;
     4476                    /*
     4477                     * For the time being, we do not implement extra process
     4478                     * protection on pre-Vista-SP1 systems as they are lacking
     4479                     * necessary KPIs.  XP is end of life, we do not wish to
     4480                     * spend more time on it, so we don't put up a fuss there.
     4481                     * Vista users without SP1 can install SP1 (or later), darn it,
     4482                     * so refuse to load.
     4483                     */
     4484                    /** @todo Hack up an XP solution - will require hooking kernel APIs or doing bad
     4485                     *        stuff to a couple of object types. */
     4486# ifndef VBOX_WITH_VISTA_NO_SP
     4487                    if (g_uNtVerCombined >= SUP_NT_VER_VISTA)
     4488# else
     4489                    if (g_uNtVerCombined >= SUP_MAKE_NT_VER_COMBINED(6, 0, 6001, 0, 0))
     4490# endif
     4491                    {
     4492                        DbgPrint("vboxdrv: ObRegisterCallbacks was not found. Please make sure you got the latest updates and service packs installed\n");
     4493                        rcNt = STATUS_SXS_VERSION_CONFLICT;
     4494                    }
     4495                    else
     4496                    {
     4497                        Log(("vboxdrv: ObRegisterCallbacks was not found; ignored pre-Vista\n"));
     4498                        return rcNt = STATUS_SUCCESS;
     4499                    }
     4500                    g_pvObCallbacksCookie = NULL;
    41804501                }
    4181                 g_pvObCallbacksCookie = NULL;
    4182             }
    4183 
    4184             /*
    4185              * Drop process create/term notifications.
    4186              */
    4187             if (g_pfnPsSetCreateProcessNotifyRoutineEx)
    4188                 g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/);
     4502
     4503                /*
     4504                 * Drop process create/term notifications.
     4505                 */
     4506                if (g_pfnPsSetCreateProcessNotifyRoutineEx)
     4507                    g_pfnPsSetCreateProcessNotifyRoutineEx(supdrvNtProtectCallback_ProcessCreateNotifyEx, TRUE /*fRemove*/);
     4508                else
     4509                    PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/);
     4510            }
    41894511            else
    4190                 PsSetCreateProcessNotifyRoutine(supdrvNtProtectCallback_ProcessCreateNotify, TRUE /*fRemove*/);
     4512                LogRel(("vboxdrv: PsSetCreateProcessNotifyRoutine%s failed with rcNt=%#x\n",
     4513                        g_pfnPsSetCreateProcessNotifyRoutineEx ? "Ex" : "", rcNt));
     4514            supHardenedWinTermImageVerifier();
    41914515        }
    41924516        else
    4193             LogRel(("vboxdrv: PsSetCreateProcessNotifyRoutine%s failed with rcNt=%#x\n",
    4194                     g_pfnPsSetCreateProcessNotifyRoutineEx ? "Ex" : "", rcNt));
    4195         supHardenedWinTermImageVerifier();
     4517            rcNt = VBoxDrvNtErr2NtStatus(rc);
     4518
     4519        RTSemMutexDestroy(g_hErrorInfoLock);
     4520        g_hErrorInfoLock = NIL_RTSEMMUTEX;
    41964521    }
    41974522    else
  • trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp

    r52844 r53002  
    110110
    111111
    112 int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
     112int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
    113113{
    114114    /*
     
    117117    int rc = suplibOsHardenedVerifyInit();
    118118    if (RT_FAILURE(rc))
    119         return rc;
     119        return RTErrInfoSetF(pErrInfo, rc, "suplibOsHardenedVerifyInit failed: %Rrc", rc);
    120120
    121121    /*
     
    170170        if (NT_SUCCESS(rcNt))
    171171            rcNt = Ios.Status;
    172         if (!NT_SUCCESS(rcNt))
    173         {
     172        if (NT_SUCCESS(rcNt))
     173        {
     174            /*
     175             * We're good.
     176             */
     177            pThis->hDevice       = hDevice;
     178            pThis->fUnrestricted = fUnrestricted;
     179            return VINF_SUCCESS;
     180        }
     181
    174182#ifndef IN_SUP_HARDENED_R3
    175             /*
    176              * Failed to open, try starting the service and reopen the device
    177              * exactly once.
    178              */
    179             if (cTry == 0 && !NT_SUCCESS(rcNt))
    180             {
    181                 cTry++;
    182                 suplibOsStartService();
    183                 continue;
    184             }
    185 #endif
    186             switch (rcNt)
    187             {
    188                 /** @todo someone must test what is actually returned. */
    189                 case STATUS_DEVICE_DOES_NOT_EXIST:
    190                 case STATUS_DEVICE_NOT_CONNECTED:
    191                 //case ERROR_BAD_DEVICE:
    192                 case STATUS_DEVICE_REMOVED:
    193                 //case ERROR_DEVICE_NOT_AVAILABLE:
    194                     return VERR_VM_DRIVER_LOAD_ERROR;
    195                 case STATUS_OBJECT_PATH_NOT_FOUND:
    196                 case STATUS_NO_SUCH_DEVICE:
    197                 case STATUS_NO_SUCH_FILE:
    198                 case STATUS_OBJECT_NAME_NOT_FOUND:
    199                     return VERR_VM_DRIVER_NOT_INSTALLED;
    200                 case STATUS_ACCESS_DENIED:
    201                 case STATUS_SHARING_VIOLATION:
    202                     return VERR_VM_DRIVER_NOT_ACCESSIBLE;
    203                 case STATUS_UNSUCCESSFUL:
    204                     return VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0;
    205                 case STATUS_TRUST_FAILURE:
    206                     return VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1;
    207                 case STATUS_TOO_LATE:
    208                     return VERR_SUPDRV_HARDENING_EVIL_HANDLE;
    209                 default:
    210                     if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */
    211                         return SUP_NT_STATUS_TO_VBOX(rcNt);
    212                     return VERR_VM_DRIVER_OPEN_ERROR;
    213             }
    214         }
    215         break;
    216     }
    217 
    218     /*
    219      * We're done.
    220      */
    221     pThis->hDevice       = hDevice;
    222     pThis->fUnrestricted = fUnrestricted;
    223     return VINF_SUCCESS;
     183        /*
     184         * Failed to open, try starting the service and reopen the device
     185         * exactly once.
     186         */
     187        if (cTry == 0 && !NT_SUCCESS(rcNt))
     188        {
     189            cTry++;
     190            suplibOsStartService();
     191            continue;
     192        }
     193#endif
     194
     195        /*
     196         * Translate the error code.
     197         */
     198        switch (rcNt)
     199        {
     200            /** @todo someone must test what is actually returned. */
     201            case STATUS_DEVICE_DOES_NOT_EXIST:
     202            case STATUS_DEVICE_NOT_CONNECTED:
     203            //case ERROR_BAD_DEVICE:
     204            case STATUS_DEVICE_REMOVED:
     205            //case ERROR_DEVICE_NOT_AVAILABLE:
     206                rc = VERR_VM_DRIVER_LOAD_ERROR;
     207                break;
     208            case STATUS_OBJECT_PATH_NOT_FOUND:
     209            case STATUS_NO_SUCH_DEVICE:
     210            case STATUS_NO_SUCH_FILE:
     211            case STATUS_OBJECT_NAME_NOT_FOUND:
     212                rc = VERR_VM_DRIVER_NOT_INSTALLED;
     213                break;
     214            case STATUS_ACCESS_DENIED:
     215            case STATUS_SHARING_VIOLATION:
     216                rc = VERR_VM_DRIVER_NOT_ACCESSIBLE;
     217                break;
     218            case STATUS_UNSUCCESSFUL:
     219                rc = VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0;
     220                break;
     221            case STATUS_TRUST_FAILURE:
     222                rc = VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1;
     223                break;
     224            case STATUS_TOO_LATE:
     225                rc = VERR_SUPDRV_HARDENING_EVIL_HANDLE;
     226                break;
     227            default:
     228                if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */
     229                    rc = SUP_NT_STATUS_TO_VBOX(rcNt);
     230                else
     231                    rc = VERR_VM_DRIVER_OPEN_ERROR;
     232                break;
     233        }
     234
     235#ifdef IN_SUP_HARDENED_R3
     236        /*
     237         * Get more details from VBoxDrvErrorInfo if present.
     238         */
     239        if (pErrInfo && pErrInfo->cbMsg > 32)
     240        {
     241            /* Prefix. */
     242            size_t      cchPrefix;
     243            const char *pszDefine = RTErrGetDefine(rc);
     244            if (strncmp(pszDefine, RT_STR_TUPLE("Unknown")))
     245                cchPrefix = RTStrPrintf(pErrInfo->pszMsg, pErrInfo->cbMsg / 2, "Integrity error (%#x/%s): ", rcNt, pszDefine);
     246            else
     247                cchPrefix = RTStrPrintf(pErrInfo->pszMsg, pErrInfo->cbMsg / 2, "Integrity error (%#x/%d): ", rcNt, rc);
     248
     249            /* Get error info. */
     250            supR3HardenedWinReadErrorInfoDevice(pErrInfo->pszMsg + cchPrefix, pErrInfo->cbMsg - cchPrefix, "");
     251            if (pErrInfo->pszMsg[cchPrefix] != '\0')
     252            {
     253                pErrInfo->fFlags |= RTERRINFO_FLAGS_SET;
     254                pErrInfo->rc      = rc;
     255                *penmWhat = kSupInitOp_Integrity;
     256            }
     257            else
     258                pErrInfo->pszMsg[0] = '\0';
     259        }
     260#endif
     261        return rc;
     262    }
    224263}
    225264
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52975 r53002  
    41864186
    41874187/**
     4188 * Tries to open VBoxDrvErrorInfo and read extra error info from it.
     4189 *
     4190 * @returns pszErrorInfo.
     4191 * @param   pszErrorInfo        The destination buffer.  Will always be
     4192 *                              terminated.
     4193 * @param   cbErrorInfo         The size of the destination buffer.
     4194 * @param   pszPrefix           What to prefix the error info with, if we got
     4195 *                              anything.
     4196 */
     4197DECLHIDDEN(char *) supR3HardenedWinReadErrorInfoDevice(char *pszErrorInfo, size_t cbErrorInfo, const char *pszPrefix)
     4198{
     4199    RT_BZERO(pszErrorInfo, cbErrorInfo);
     4200
     4201    /*
     4202     * Try open the device.
     4203     */
     4204    HANDLE              hFile  = RTNT_INVALID_HANDLE_VALUE;
     4205    IO_STATUS_BLOCK     Ios    = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     4206    UNICODE_STRING      NtName = RTNT_CONSTANT_UNISTR(SUPDRV_NT_DEVICE_NAME_ERROR_INFO);
     4207    OBJECT_ATTRIBUTES   ObjAttr;
     4208    InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
     4209    NTSTATUS rcNt = NtCreateFile(&hFile,
     4210                                 GENERIC_READ,
     4211                                 &ObjAttr,
     4212                                 &Ios,
     4213                                 NULL /* Allocation Size*/,
     4214                                 FILE_ATTRIBUTE_NORMAL,
     4215                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
     4216                                 FILE_OPEN,
     4217                                 FILE_NON_DIRECTORY_FILE,
     4218                                 NULL /*EaBuffer*/,
     4219                                 0 /*EaLength*/);
     4220    if (NT_SUCCESS(rcNt))
     4221        rcNt = Ios.Status;
     4222    if (NT_SUCCESS(rcNt))
     4223    {
     4224        /*
     4225         * Try read error info.
     4226         */
     4227        size_t cchPrefix = strlen(pszPrefix);
     4228        if (cchPrefix + 3 < cbErrorInfo)
     4229        {
     4230            LARGE_INTEGER offRead;
     4231            offRead.QuadPart = 0;
     4232            rcNt = NtReadFile(hFile, NULL /*hEvent*/, NULL /*ApcRoutine*/, NULL /*ApcContext*/, &Ios,
     4233                              &pszErrorInfo[cchPrefix], (ULONG)(cbErrorInfo - cchPrefix - 1), &offRead, NULL);
     4234            if (NT_SUCCESS(rcNt))
     4235            {
     4236                memcpy(pszErrorInfo, pszPrefix, cchPrefix);
     4237                pszErrorInfo[cbErrorInfo - 1] = '\0';
     4238            }
     4239            else
     4240                *pszErrorInfo = '\0';
     4241        }
     4242        else
     4243            RTStrCopy(pszErrorInfo, cbErrorInfo, "error info buffer too small");
     4244        NtClose(hFile);
     4245    }
     4246    return pszErrorInfo;
     4247}
     4248
     4249
     4250
     4251/**
    41884252 * Checks if the driver exists.
    41894253 *
     
    42704334     * Retry if we think driver might still be initializing (STATUS_NO_SUCH_DEVICE + \Drivers\VBoxDrv).
    42714335     */
    4272     static const WCHAR  s_wszName[] = L"\\Device\\VBoxDrvStub";
     4336    static const WCHAR  s_wszName[] = SUPDRV_NT_DEVICE_NAME_STUB;
    42734337    uint64_t const      uMsTsStart = supR3HardenedWinGetMilliTS();
    42744338    NTSTATUS            rcNt;
     
    43344398         * better chance resolving the issue.
    43354399         */
     4400        char szErrorInfo[_4K];
    43364401        int rc = VERR_OPEN_FAILED;
    43374402        if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */
     
    43594424                supR3HardenedWinLogObjDir("\\Windows");
    43604425                supR3HardenedWinLogObjDir("\\Sessions");
     4426
    43614427                supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, rc,
    43624428                                      "NtCreateFile(%ls) failed: VERR_SUPDRV_APIPORT_OPEN_ERROR\n"
     
    43664432                                      "Could be due to security software is redirecting access to it, so please include full "
    43674433                                      "details of such software in a bug report. VBoxStartup.log may contain details important "
    4368                                       "to resolving the issue."
    4369                                       , s_wszName, szDir);
     4434                                      "to resolving the issue.%s"
     4435                                      , s_wszName, szDir,
     4436                                      supR3HardenedWinReadErrorInfoDevice(szErrorInfo, sizeof(szErrorInfo),
     4437                                                                          "\n\nVBoxDrvStub error: "));
    43704438            }
    43714439
     
    43744442             */
    43754443            supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, rc,
    4376                                   "NtCreateFile(%ls) failed: %Rrc (rcNt=%#x)\n", s_wszName, rc, rcNt);
     4444                                  "NtCreateFile(%ls) failed: %Rrc (rcNt=%#x)%s", s_wszName, rc, rcNt,
     4445                                  supR3HardenedWinReadErrorInfoDevice(szErrorInfo, sizeof(szErrorInfo),
     4446                                                                    "\nVBoxDrvStub error: "));
    43774447        }
    43784448        else
     
    44034473                                          "\n"
    44044474                                          "Driver is probably stuck stopping/starting. Try 'sc.exe query vboxdrv' to get more "
    4405                                           "information about its state. Rebooting may actually help.\n"
    4406                                           , s_wszName, rcNt, pszDefine, iTry);
     4475                                          "information about its state. Rebooting may actually help.%s"
     4476                                          , s_wszName, rcNt, pszDefine, iTry,
     4477                                          supR3HardenedWinReadErrorInfoDevice(szErrorInfo, sizeof(szErrorInfo),
     4478                                                                              "\nVBoxDrvStub error: "));
    44074479                else
    44084480                    supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, VERR_OPEN_FAILED,
     
    44104482                                          "\n"
    44114483                                          "Driver is does not appear to be loaded. Try 'sc.exe start vboxdrv', reinstall "
    4412                                           "VirtualBox or reboot.\n"
    4413                                           , s_wszName, rcNt, pszDefine, iTry);
     4484                                          "VirtualBox or reboot.%s"
     4485                                          , s_wszName, rcNt, pszDefine, iTry,
     4486                                          supR3HardenedWinReadErrorInfoDevice(szErrorInfo, sizeof(szErrorInfo),
     4487                                                                              "\nVBoxDrvStub error: "));
    44144488            }
    44154489
    44164490            /* Generic NT failure message. */
    44174491            supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Driver, VERR_OPEN_FAILED,
    4418                                   "NtCreateFile(%ls) failed: %#x%s (%u retries)\n", s_wszName, rcNt, pszDefine, iTry);
     4492                                  "NtCreateFile(%ls) failed: %#x%s (%u retries)%s",
     4493                                  s_wszName, rcNt, pszDefine, iTry,
     4494                                  supR3HardenedWinReadErrorInfoDevice(szErrorInfo, sizeof(szErrorInfo),
     4495                                                                      "\nVBoxDrvStub error: "));
    44194496        }
    44204497    }
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