Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 616238
Collapse All | Expand All

(-)VirtualBox-5.1.22/src/VBox/HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp (-3 / +42 lines)
Lines 341-346 Link Here
341
     * Patch 64-bit hosts.
341
     * Patch 64-bit hosts.
342
     */
342
     */
343
    uint32_t cRipRelMovs = 0;
343
    uint32_t cRipRelMovs = 0;
344
    uint32_t cRelCalls = 0;
344
345
345
    /* Just use the disassembler to skip 12 bytes or more, we might need to
346
    /* Just use the disassembler to skip 12 bytes or more, we might need to
346
       rewrite mov instructions using RIP relative addressing. */
347
       rewrite mov instructions using RIP relative addressing. */
Lines 349-355 Link Here
349
        cbInstr = 1;
350
        cbInstr = 1;
350
        int rc = DISInstr(pbTarget + offJmpBack, DISCPUMODE_64BIT, &Dis, &cbInstr);
351
        int rc = DISInstr(pbTarget + offJmpBack, DISCPUMODE_64BIT, &Dis, &cbInstr);
351
        if (   RT_FAILURE(rc)
352
        if (   RT_FAILURE(rc)
352
            || (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW)
353
            || (   Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW
354
                && Dis.pCurInstr->uOpcode != OP_CALL)
353
            || (   Dis.ModRM.Bits.Mod == 0
355
            || (   Dis.ModRM.Bits.Mod == 0
354
                && Dis.ModRM.Bits.Rm  == 5 /* wrt RIP */
356
                && Dis.ModRM.Bits.Rm  == 5 /* wrt RIP */
355
                && Dis.pCurInstr->uOpcode != OP_MOV))
357
                && Dis.pCurInstr->uOpcode != OP_MOV))
Lines 357-371 Link Here
357
359
358
        if (Dis.ModRM.Bits.Mod == 0 && Dis.ModRM.Bits.Rm == 5 /* wrt RIP */)
360
        if (Dis.ModRM.Bits.Mod == 0 && Dis.ModRM.Bits.Rm == 5 /* wrt RIP */)
359
            cRipRelMovs++;
361
            cRipRelMovs++;
362
        if (   Dis.pCurInstr->uOpcode == OP_CALL
363
            && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
364
            cRelCalls++;
360
365
361
        offJmpBack += cbInstr;
366
        offJmpBack += cbInstr;
362
        cbPatchMem += cbInstr;
367
        cbPatchMem += cbInstr;
363
    }
368
    }
364
369
370
    /*
371
     * Each relative call requires extra bytes as it is converted to a pushq imm32
372
     * + mov [RSP+4], imm32 + a jmp qword [$+8 wrt RIP] to avoid clobbering registers.
373
     */
374
    cbPatchMem += cRelCalls * RT_ALIGN_32(13 + 6 + 8, 8);
365
    cbPatchMem += 14; /* jmp qword [$+8 wrt RIP] + 8 byte address to jump to. */
375
    cbPatchMem += 14; /* jmp qword [$+8 wrt RIP] + 8 byte address to jump to. */
366
    cbPatchMem = RT_ALIGN_32(cbPatchMem, 8);
376
    cbPatchMem = RT_ALIGN_32(cbPatchMem, 8);
367
377
368
    /* Allocate suitable exectuable memory available. */
378
    /* Allocate suitable executable memory available. */
369
    bool fConvRipRelMovs = false;
379
    bool fConvRipRelMovs = false;
370
    uint8_t *pbPatchMem = supR3HardenedMainPosixExecMemAlloc(cbPatchMem, pbTarget, cRipRelMovs > 0);
380
    uint8_t *pbPatchMem = supR3HardenedMainPosixExecMemAlloc(cbPatchMem, pbTarget, cRipRelMovs > 0);
371
    if (!pbPatchMem)
381
    if (!pbPatchMem)
Lines 396-402 Link Here
396
        cbInstr = 1;
406
        cbInstr = 1;
397
        int rc = DISInstr(pbTarget + offInsn, DISCPUMODE_64BIT, &Dis, &cbInstr);
407
        int rc = DISInstr(pbTarget + offInsn, DISCPUMODE_64BIT, &Dis, &cbInstr);
398
        if (   RT_FAILURE(rc)
408
        if (   RT_FAILURE(rc)
399
            || (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW))
409
            || (   Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW
410
                && Dis.pCurInstr->uOpcode != OP_CALL))
400
            return VERR_SUPLIB_UNEXPECTED_INSTRUCTION;
411
            return VERR_SUPLIB_UNEXPECTED_INSTRUCTION;
401
412
402
        if (   Dis.ModRM.Bits.Mod == 0
413
        if (   Dis.ModRM.Bits.Mod == 0
Lines 439-444 Link Here
439
                pbPatchMem   += sizeof(int32_t);
450
                pbPatchMem   += sizeof(int32_t);
440
            }
451
            }
441
        }
452
        }
453
        else if (   Dis.pCurInstr->uOpcode == OP_CALL
454
                 && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
455
        {
456
            /* Convert to absolute jump. */
457
            uintptr_t uAddr = (uintptr_t)&pbTarget[offInsn + cbInstr] + (intptr_t)Dis.Param1.uValue;
458
459
            /* Skip the push instructions till the return address is known. */
460
            uint8_t *pbPatchMemPush = pbPatchMem;
461
            pbPatchMem += 13;
462
463
            *pbPatchMem++ = 0xff; /* jmp qword [$+8 wrt RIP] */
464
            *pbPatchMem++ = 0x25;
465
            *(uint32_t *)pbPatchMem = (uint32_t)(RT_ALIGN_PT(pbPatchMem + 4, 8, uint8_t *) - (pbPatchMem + 4));
466
            pbPatchMem = RT_ALIGN_PT(pbPatchMem + 4, 8, uint8_t *);
467
            *(uint64_t *)pbPatchMem = uAddr;
468
            pbPatchMem += sizeof(uint64_t);
469
470
            /* Push the return address onto stack. Difficult on amd64 without clobbering registers... */
471
            uintptr_t uAddrReturn = (uintptr_t)pbPatchMem;
472
            *pbPatchMemPush++ = 0x68; /* push imm32 sign-extended as 64-bit*/
473
            *(uint32_t *)pbPatchMemPush = RT_LO_U32(uAddrReturn);
474
            pbPatchMemPush += sizeof(uint32_t);
475
            *pbPatchMemPush++ = 0xc7;
476
            *pbPatchMemPush++ = 0x44;
477
            *pbPatchMemPush++ = 0x24;
478
            *pbPatchMemPush++ = 0x04; /* movl [RSP+4], imm32 */
479
            *(uint32_t *)pbPatchMemPush = RT_HI_U32(uAddrReturn);
480
        }
442
        else
481
        else
443
        {
482
        {
444
            memcpy(pbPatchMem, pbTarget + offInsn, cbInstr);
483
            memcpy(pbPatchMem, pbTarget + offInsn, cbInstr);
(-)VirtualBox-5.1.22/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp (-1 / +27 lines)
Lines 86-91 Link Here
86
/** The max path length acceptable for a trusted path. */
86
/** The max path length acceptable for a trusted path. */
87
#define SUPR3HARDENED_MAX_PATH      260U
87
#define SUPR3HARDENED_MAX_PATH      260U
88
88
89
/** Enable to resolve symlinks using realpath() instead of cooking our own stuff. */
90
#define SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH 1
91
89
#ifdef RT_OS_SOLARIS
92
#ifdef RT_OS_SOLARIS
90
# define dirfd(d) ((d)->d_fd)
93
# define dirfd(d) ((d)->d_fd)
91
#endif
94
#endif
Lines 1091-1097 Link Here
1091
#endif
1094
#endif
1092
1095
1093
1096
1094
#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
1097
#ifndef SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH
1098
# if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
1095
/**
1099
/**
1096
 * Copies the error message to the error buffer and returns @a rc.
1100
 * Copies the error message to the error buffer and returns @a rc.
1097
 *
1101
 *
Lines 1104-1109 Link Here
1104
{
1108
{
1105
    return supR3HardenedSetErrorN(rc, pErrInfo, 1, pszMsg);
1109
    return supR3HardenedSetErrorN(rc, pErrInfo, 1, pszMsg);
1106
}
1110
}
1111
# endif
1107
#endif
1112
#endif
1108
1113
1109
1114
Lines 1893-1899 Link Here
1893
    /*
1898
    /*
1894
     * Verify each component from the root up.
1899
     * Verify each component from the root up.
1895
     */
1900
     */
1901
#ifndef SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH
1896
    uint32_t                iLoops = 0;
1902
    uint32_t                iLoops = 0;
1903
#endif
1897
    SUPR3HARDENEDFSOBJSTATE FsObjState;
1904
    SUPR3HARDENEDFSOBJSTATE FsObjState;
1898
    uint32_t                iComponent = 0;
1905
    uint32_t                iComponent = 0;
1899
    while (iComponent < Info.cComponents)
1906
    while (iComponent < Info.cComponents)
Lines 1915-1920 Link Here
1915
            if (   RT_SUCCESS(rc)
1922
            if (   RT_SUCCESS(rc)
1916
                && S_ISLNK(FsObjState.Stat.st_mode))
1923
                && S_ISLNK(FsObjState.Stat.st_mode))
1917
            {
1924
            {
1925
#if SUP_HARDENED_VERIFY_FOLLOW_SYMLINKS_USE_REALPATH /* Another approach using realpath() and verifying the result when encountering a symlink. */
1926
                char *pszFilenameResolved = realpath(pszFilename, NULL);
1927
                if (pszFilenameResolved)
1928
                {
1929
                    rc = supR3HardenedVerifyFile(pszFilenameResolved, hNativeFile, fMaybe3rdParty, pErrInfo);
1930
                    free(pszFilenameResolved);
1931
                    return rc;
1932
                }
1933
                else
1934
                {
1935
                    int iErr = errno;
1936
                    supR3HardenedError(VERR_ACCESS_DENIED, false /*fFatal*/,
1937
                                       "supR3HardenedVerifyFileFollowSymlinks: Failed to resolve the real path '%s': %s (%d)\n",
1938
                                       pszFilename, strerror(iErr), iErr);
1939
                    return supR3HardenedSetError4(VERR_ACCESS_DENIED, pErrInfo,
1940
                                                  "realpath failed for '", pszFilename, "': ", strerror(iErr));
1941
                }
1942
#else
1918
                /* Don't loop forever. */
1943
                /* Don't loop forever. */
1919
                iLoops++;
1944
                iLoops++;
1920
                if (iLoops < 8)
1945
                if (iLoops < 8)
Lines 1989-1994 Link Here
1989
                else
2014
                else
1990
                    return supR3HardenedSetError3(VERR_TOO_MANY_SYMLINKS, pErrInfo,
2015
                    return supR3HardenedSetError3(VERR_TOO_MANY_SYMLINKS, pErrInfo,
1991
                                                  "Too many symbolic links: '", pszFilename, "'");
2016
                                                  "Too many symbolic links: '", pszFilename, "'");
2017
#endif
1992
            }
2018
            }
1993
        }
2019
        }
1994
        if (RT_FAILURE(rc))
2020
        if (RT_FAILURE(rc))

Return to bug 616238