VirtualBox

Ignore:
Timestamp:
Oct 21, 2013 2:22:52 PM (11 years ago)
Author:
vboxsync
Message:

SUP: some minor improvements.

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

Legend:

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

    r44528 r49211  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    100100
    101101
     102/** @name CRT function mappings (not using CRT on Windows).
     103 * @{
     104 */
     105#if defined(IN_SUP_HARDENED_R3) && defined(RT_OS_WINDOWS)
     106DECLHIDDEN(void *) suplibHardenedMemCopy(void *pvDst, const void *pvSrc, size_t cbToCopy);
     107DECLHIDDEN(char *) suplibHardenedStrCopy(char *pszDst, const char *pszSrc);
     108DECLHIDDEN(size_t) suplibHardenedStrLen(const char *psz);
     109DECLHIDDEN(char *) suplibHardenedStrCat(char *pszDst, const char *pszSrc);
     110DECLHIDDEN(int)    suplibHardenedStrCmp(const char *psz1, const char *psz2);
     111DECLHIDDEN(int)    suplibHardenedStrNCmp(const char *psz1, const char *psz2, size_t cchMax);
     112DECLHIDDEN(int)    suplibHardenedStrICmp(const char *psz1, const char *psz2);
     113#else
     114# define suplibHardenedMemCopy memcpy
     115# define suplibHardenedStrCopy strcpy
     116# define suplibHardenedStrLen  strlen
     117# define suplibHardenedStrCat  strcat
     118# define suplibHardenedStrCmp  strcmp
     119# define suplibHardenedStrNCmp strncmp
     120# define suplibHardenedStrICmp stricmp
     121#endif
     122DECLNORETURN(void) suplibHardenedExit(RTEXITCODE rcExit);
     123/** @} */
     124
     125
    102126/*******************************************************************************
    103127*   Structures and Typedefs                                                    *
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r44528 r49211  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3838#elif RT_OS_WINDOWS
    3939# include <Windows.h>
    40 # include <stdio.h>
    4140
    4241#else /* UNIXes */
     
    5150# include <sys/stat.h>
    5251# include <sys/time.h>
    53 # include <stdio.h>
    5452# include <sys/types.h>
    5553# if defined(RT_OS_LINUX)
     
    7977#include <VBox/sup.h>
    8078#include <VBox/err.h>
     79#include <iprt/ctype.h>
    8180#include <iprt/string.h>
    8281#include <iprt/initterm.h>
     
    150149
    151150
     151#ifdef RT_OS_WINDOWS
     152/*
     153 * No CRT here, thank you.
     154 */
     155
     156/** memcpy */
     157DECLHIDDEN(void *) suplibHardenedMemCopy(void *pvDst, const void *pvSrc, size_t cbToCopy)
     158{
     159    size_t         *puDst = (size_t *)pvDst;
     160    size_t const   *puSrc = (size_t const *)pvSrc;
     161    while (cbToCopy >= sizeof(size_t))
     162    {
     163        *puDst++ = *puSrc++;
     164        cbToCopy -= sizeof(size_t);
     165    }
     166
     167    uint8_t        *pbDst = (uint8_t *)puDst;
     168    uint8_t const  *pbSrc = (uint8_t const *)puSrc;
     169    while (cbToCopy > 0)
     170    {
     171        *pbDst++ = *pbSrc++;
     172        cbToCopy--;
     173    }
     174
     175    return pvDst;
     176}
     177
     178
     179/** strcpy */
     180DECLHIDDEN(char *) suplibHardenedStrCopy(char *pszDst, const char *pszSrc)
     181{
     182    char *pszRet = pszDst;
     183    char ch;
     184    do
     185    {
     186        ch = *pszSrc++;
     187        *pszDst++ = ch;
     188    } while (ch);
     189    return pszRet;
     190}
     191
     192
     193/** strlen */
     194DECLHIDDEN(size_t) suplibHardenedStrLen(const char *psz)
     195{
     196    const char *pszStart = psz;
     197    while (*psz)
     198        psz++;
     199    return psz - pszStart;
     200}
     201
     202
     203/** strcat */
     204DECLHIDDEN(char *) suplibHardenedStrCat(char *pszDst, const char *pszSrc)
     205{
     206    char *pszRet = pszDst;
     207    while (*pszDst)
     208        pszDst++;
     209    suplibHardenedStrCopy(pszDst, pszSrc);
     210    return pszRet;
     211}
     212
     213
     214# ifdef RT_OS_WINDOWS
     215/** stricmp */
     216DECLHIDDEN(int) suplibHardenedStrICmp(const char *psz1, const char *psz2)
     217{
     218    const char *pszOrg1 = psz1;
     219    const char *pszOrg2 = psz2;
     220
     221    for (;;)
     222    {
     223        char ch1 = *psz1++;
     224        char ch2 = *psz1++;
     225        if (ch1 != ch2)
     226        {
     227            int rc = CompareStringA(LOCALE_USER_DEFAULT, NORM_IGNORECASE, pszOrg1, -1, pszOrg2, -1);
     228#  ifdef VBOX_STRICT
     229            if (rc == 0)
     230                __debugbreak();
     231#  endif
     232            return rc - 2;
     233        }
     234        if (ch1 == 0)
     235            return 0;
     236    }
     237}
     238# endif
     239
     240
     241/** strcmp */
     242DECLHIDDEN(int) suplibHardenedStrCmp(const char *psz1, const char *psz2)
     243{
     244    for (;;)
     245    {
     246        char ch1 = *psz1++;
     247        char ch2 = *psz1++;
     248        if (ch1 != ch2)
     249            return ch1 < ch2 ? -1 : 1;
     250        if (ch1 == 0)
     251            return 0;
     252    }
     253}
     254
     255
     256/** strncmp */
     257DECLHIDDEN(int) suplibHardenedStrNCmp(const char *psz1, const char *psz2, size_t cchMax)
     258{
     259    while (cchMax-- > 0)
     260    {
     261        char ch1 = *psz1++;
     262        char ch2 = *psz1++;
     263        if (ch1 != ch2)
     264            return ch1 < ch2 ? -1 : 1;
     265        if (ch1 == 0)
     266            break;
     267    }
     268    return 0;
     269}
     270
     271#endif /* RT_OS_WINDOWS */
     272
     273
     274/**
     275 * Safely copy one or more strings into the given buffer.
     276 *
     277 * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
     278 * @param   pszDst              The destionation buffer.
     279 * @param   cbDst               The size of the destination buffer.
     280 * @param   ...                 One or more zero terminated strings, ending with
     281 *                              a NULL.
     282 */
     283static int suplibHardenedStrCopyEx(char *pszDst, size_t cbDst, ...)
     284{
     285    int rc = VINF_SUCCESS;
     286
     287    if (cbDst == 0)
     288        return VERR_BUFFER_OVERFLOW;
     289
     290    va_list va;
     291    va_start(va, cbDst);
     292    for (;;)
     293    {
     294        const char *pszSrc = va_arg(va, const char *);
     295        if (!pszSrc)
     296            break;
     297
     298        size_t cchSrc = suplibHardenedStrLen(pszSrc);
     299        if (cchSrc < cbDst)
     300        {
     301            suplibHardenedMemCopy(pszDst, pszSrc, cchSrc);
     302            pszDst += cchSrc;
     303            cbDst  -= cchSrc;
     304        }
     305        else
     306        {
     307            rc = VERR_BUFFER_OVERFLOW;
     308            if (cbDst > 1)
     309            {
     310                suplibHardenedMemCopy(pszDst, pszSrc, cbDst - 1);
     311                pszDst += cbDst - 1;
     312                cbDst   = 1;
     313            }
     314        }
     315        *pszDst = '\0';
     316    }
     317    va_end(va);
     318
     319    return rc;
     320}
     321
     322
     323/**
     324 * Exit current process in the quickest possible fashion.
     325 *
     326 * @param   rcExit      The exit code.
     327 */
     328DECLNORETURN(void) suplibHardenedExit(RTEXITCODE rcExit)
     329{
     330    for (;;)
     331#ifdef RT_OS_WINDOWS
     332        ExitProcess(rcExit);
     333#else
     334        _Exit(rcExit);
     335#endif
     336}
     337
     338
     339/**
     340 * Writes a substring to standard error.
     341 *
     342 * @param   pch                 The start of the substring.
     343 * @param   cch                 The length of the substring.
     344 */
     345static void suplibHardenedPrintStrN(const char *pch, size_t cch)
     346{
     347#ifdef RT_OS_WINDOWS
     348    DWORD cbWrittenIgn;
     349    WriteFile(GetStdHandle(STD_ERROR_HANDLE), pch, (DWORD)cch, &cbWrittenIgn, NULL);
     350#else
     351    write(2, pch, cch);
     352#endif
     353}
     354
     355
     356/**
     357 * Writes a string to standard error.
     358 *
     359 * @param   psz                 The string.
     360 */
     361static void suplibHardenedPrintStr(const char *psz)
     362{
     363    suplibHardenedPrintStrN(psz, suplibHardenedStrLen(psz));
     364}
     365
     366
     367/**
     368 * Writes a char to standard error.
     369 *
     370 * @param   ch                  The character value to write.
     371 */
     372static void suplibHardenedPrintChr(char ch)
     373{
     374    suplibHardenedPrintStrN(&ch, 1);
     375}
     376
     377
     378/**
     379 * Writes a decimal number to stdard error.
     380 *
     381 * @param   uValue              The value.
     382 */
     383static void suplibHardenedPrintDecimal(uint64_t uValue)
     384{
     385    char    szBuf[64];
     386    char   *pszEnd = &szBuf[sizeof(szBuf) - 1];
     387    char   *psz    = pszEnd;
     388
     389    *psz-- = '\0';
     390
     391    do
     392    {
     393        *psz-- = '0' + (uValue % 10);
     394        uValue /= 10;
     395    } while (uValue > 0);
     396
     397    psz++;
     398    suplibHardenedPrintStrN(psz, pszEnd - psz);
     399}
     400
     401
     402/**
     403 * Writes a hexadecimal or octal number to standard error.
     404 *
     405 * @param   uValue              The value.
     406 * @param   uBase               The base (16 or 8).
     407 * @param   fFlags              Format flags.
     408 */
     409static void suplibHardenedPrintHexOctal(uint64_t uValue, unsigned uBase, uint32_t fFlags)
     410{
     411    static char const   s_achDigitsLower[17] = "0123456789abcdef";
     412    static char const   s_achDigitsUpper[17] = "0123456789ABCDEF";
     413    const char         *pchDigits   = !(fFlags & RTSTR_F_CAPITAL) ? s_achDigitsLower : s_achDigitsUpper;
     414    unsigned            cShift      = uBase == 16 ?   4 : 3;
     415    unsigned            fDigitMask  = uBase == 16 ? 0xf : 7;
     416    char                szBuf[64];
     417    char               *pszEnd = &szBuf[sizeof(szBuf) - 1];
     418    char               *psz    = pszEnd;
     419
     420    *psz-- = '\0';
     421
     422    do
     423    {
     424        unsigned iDigit = uValue & fDigitMask;
     425        uValue >>= cShift;
     426
     427        *psz-- = uValue % 10;
     428        uValue /= 10;
     429    } while (uValue > 0);
     430
     431    if ((fFlags & RTSTR_F_SPECIAL) && uBase == 16)
     432    {
     433        *psz-- = 'x';
     434        *psz-- = '0';
     435    }
     436
     437    psz++;
     438    suplibHardenedPrintStrN(psz, pszEnd - psz);
     439}
     440
     441
     442/**
     443 * Simple printf to standard error.
     444 *
     445 * @param   pszFormat   The format string.
     446 * @param   va          Arguments to format.
     447 */
     448DECLHIDDEN(void) suplibHardenedPrintFV(const char *pszFormat, va_list va)
     449{
     450    /*
     451     * Format loop.
     452     */
     453    char ch;
     454    const char *pszLast = pszFormat;
     455    for (;;)
     456    {
     457        ch = *pszFormat;
     458        if (!ch)
     459            break;
     460        pszFormat++;
     461
     462        if (ch == '%')
     463        {
     464            /*
     465             * Format argument.
     466             */
     467
     468            /* Flush unwritten bits. */
     469            if (pszLast != pszFormat - 1)
     470                suplibHardenedPrintStrN(pszLast, pszFormat - pszLast - 1);
     471            pszLast = pszFormat;
     472            ch = *pszFormat++;
     473
     474            /* flags. */
     475            uint32_t fFlags = 0;
     476            for (;;)
     477            {
     478                if (ch == '#')          fFlags |= RTSTR_F_SPECIAL;
     479                else if (ch == '-')     fFlags |= RTSTR_F_LEFT;
     480                else if (ch == '+')     fFlags |= RTSTR_F_PLUS;
     481                else if (ch == ' ')     fFlags |= RTSTR_F_BLANK;
     482                else if (ch == '0')     fFlags |= RTSTR_F_ZEROPAD;
     483                else if (ch == '\'')    fFlags |= RTSTR_F_THOUSAND_SEP;
     484                else                    break;
     485                ch = *pszFormat++;
     486            }
     487
     488            /* Width and precision - ignored. */
     489            while (RT_C_IS_DIGIT(ch))
     490                ch = *pszFormat++;
     491            if (ch == '*')
     492                va_arg(va, int);
     493            if (ch == '.')
     494            {
     495                do ch = *pszFormat++;
     496                while (RT_C_IS_DIGIT(ch));
     497                if (ch == '*')
     498                    va_arg(va, int);
     499            }
     500
     501            /* Size. */
     502            char chArgSize = 0;
     503            switch (ch)
     504            {
     505                case 'z':
     506                case 'L':
     507                case 'j':
     508                case 't':
     509                    chArgSize = ch;
     510                    ch = *pszFormat++;
     511                    break;
     512
     513                case 'l':
     514                    chArgSize = ch;
     515                    ch = *pszFormat++;
     516                    if (ch == 'l')
     517                    {
     518                        chArgSize = 'L';
     519                        ch = *pszFormat++;
     520                    }
     521                    break;
     522
     523                case 'h':
     524                    chArgSize = ch;
     525                    ch = *pszFormat++;
     526                    if (ch == 'h')
     527                    {
     528                        chArgSize = 'H';
     529                        ch = *pszFormat++;
     530                    }
     531                    break;
     532            }
     533
     534            /*
     535             * Do type specific formatting.
     536             */
     537            switch (ch)
     538            {
     539                case 'c':
     540                    ch = (char)va_arg(va, int);
     541                    suplibHardenedPrintChr(ch);
     542                    break;
     543
     544                case 's':
     545                {
     546                    const char *pszStr = va_arg(va, const char *);
     547                    if (!RT_VALID_PTR(pszStr))
     548                        pszStr = "<NULL>";
     549                    suplibHardenedPrintStr(pszStr);
     550                    break;
     551                }
     552
     553                case 'd':
     554                case 'i':
     555                {
     556                    int64_t iValue;
     557                    if (chArgSize == 'L' || chArgSize == 'j')
     558                        iValue = va_arg(va, int64_t);
     559                    else if (chArgSize == 'l')
     560                        iValue = va_arg(va, signed long);
     561                    else if (chArgSize == 'z' || chArgSize == 't')
     562                        iValue = va_arg(va, intptr_t);
     563                    else
     564                        iValue = va_arg(va, signed int);
     565                    if (iValue < 0)
     566                    {
     567                        suplibHardenedPrintChr('-');
     568                        iValue = -iValue;
     569                    }
     570                    suplibHardenedPrintDecimal(iValue);
     571                    break;
     572                }
     573
     574                case 'p':
     575                case 'x':
     576                case 'X':
     577                case 'u':
     578                case 'o':
     579                {
     580                    unsigned uBase = 10;
     581                    uint64_t uValue;
     582
     583                    switch (ch)
     584                    {
     585                        case 'p':
     586                            fFlags |= RTSTR_F_ZEROPAD; /* Note not standard behaviour (but I like it this way!) */
     587                            uBase = 16;
     588                            break;
     589                        case 'X':
     590                            fFlags |= RTSTR_F_CAPITAL;
     591                        case 'x':
     592                            uBase = 16;
     593                            break;
     594                        case 'u':
     595                            uBase = 10;
     596                            break;
     597                        case 'o':
     598                            uBase = 8;
     599                            break;
     600                    }
     601
     602                    if (ch == 'p' || chArgSize == 'z' || chArgSize == 't')
     603                        uValue = va_arg(va, uintptr_t);
     604                    else if (chArgSize == 'L' || chArgSize == 'j')
     605                        uValue = va_arg(va, uint64_t);
     606                    else if (chArgSize == 'l')
     607                        uValue = va_arg(va, unsigned long);
     608                    else
     609                        uValue = va_arg(va, unsigned int);
     610
     611                    if (uBase == 10)
     612                        suplibHardenedPrintDecimal(uValue);
     613                    else
     614                        suplibHardenedPrintHexOctal(uValue, uBase, fFlags);
     615                    break;
     616                }
     617
     618
     619                /*
     620                 * Custom format.
     621                 */
     622                default:
     623                    suplibHardenedPrintStr("[bad format: ");
     624                    suplibHardenedPrintStrN(pszLast, pszFormat - pszLast);
     625                    suplibHardenedPrintChr(']');
     626                    break;
     627            }
     628
     629            /* continue */
     630            pszLast = pszFormat;
     631        }
     632    }
     633
     634    /* Flush the last bits of the string. */
     635    if (pszLast != pszFormat)
     636        suplibHardenedPrintStrN(pszLast, pszFormat - pszLast);
     637}
     638
     639
     640/**
     641 * Prints to standard error.
     642 *
     643 * @param   pszFormat   The format string.
     644 * @param   ...         Arguments to format.
     645 */
     646DECLHIDDEN(void) suplibHardenedPrintF(const char *pszFormat, ...)
     647{
     648    va_list va;
     649    va_start(va, pszFormat);
     650    suplibHardenedPrintFV(pszFormat, va);
     651    va_end(va);
     652}
     653
     654
     655
    152656/**
    153657 * @copydoc RTPathStripFilename.
     
    230734#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE)
    231735    const char *pszSrcPath = RTPATH_APP_PRIVATE;
    232     size_t cchPathPrivateNoArch = strlen(pszSrcPath);
     736    size_t cchPathPrivateNoArch = suplibHardenedStrLen(pszSrcPath);
    233737    if (cchPathPrivateNoArch >= cchPath)
    234         supR3HardenedFatal("supR3HardenedPathAppPrivateNoArch: Buffer overflow, %lu >= %lu\n",
    235                             (unsigned long)cchPathPrivateNoArch, (unsigned long)cchPath);
    236     memcpy(pszPath, pszSrcPath, cchPathPrivateNoArch + 1);
     738        supR3HardenedFatal("supR3HardenedPathAppPrivateNoArch: Buffer overflow, %zu >= %zu\n", cchPathPrivateNoArch, cchPath);
     739    suplibHardenedMemCopy(pszPath, pszSrcPath, cchPathPrivateNoArch + 1);
    237740    return VINF_SUCCESS;
    238741
     
    250753#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_PRIVATE_ARCH)
    251754    const char *pszSrcPath = RTPATH_APP_PRIVATE_ARCH;
    252     size_t cchPathPrivateArch = strlen(pszSrcPath);
     755    size_t cchPathPrivateArch = suplibHardenedStrLen(pszSrcPath);
    253756    if (cchPathPrivateArch >= cchPath)
    254         supR3HardenedFatal("supR3HardenedPathAppPrivateArch: Buffer overflow, %lu >= %lu\n",
    255                             (unsigned long)cchPathPrivateArch, (unsigned long)cchPath);
    256     memcpy(pszPath, pszSrcPath, cchPathPrivateArch + 1);
     757        supR3HardenedFatal("supR3HardenedPathAppPrivateArch: Buffer overflow, %zu >= %zu\n", cchPathPrivateArch, cchPath);
     758    suplibHardenedMemCopy(pszPath, pszSrcPath, cchPathPrivateArch + 1);
    257759    return VINF_SUCCESS;
    258760
     
    270772#if !defined(RT_OS_WINDOWS) && defined(RTPATH_SHARED_LIBS)
    271773    const char *pszSrcPath = RTPATH_SHARED_LIBS;
    272     size_t cchPathSharedLibs = strlen(pszSrcPath);
     774    size_t cchPathSharedLibs = suplibHardenedStrLen(pszSrcPath);
    273775    if (cchPathSharedLibs >= cchPath)
    274         supR3HardenedFatal("supR3HardenedPathSharedLibs: Buffer overflow, %lu >= %lu\n",
    275                             (unsigned long)cchPathSharedLibs, (unsigned long)cchPath);
    276     memcpy(pszPath, pszSrcPath, cchPathSharedLibs + 1);
     776        supR3HardenedFatal("supR3HardenedPathSharedLibs: Buffer overflow, %zu >= %zu\n", cchPathSharedLibs, cchPath);
     777    suplibHardenedMemCopy(pszPath, pszSrcPath, cchPathSharedLibs + 1);
    277778    return VINF_SUCCESS;
    278779
     
    290791#if !defined(RT_OS_WINDOWS) && defined(RTPATH_APP_DOCS)
    291792    const char *pszSrcPath = RTPATH_APP_DOCS;
    292     size_t cchPathAppDocs = strlen(pszSrcPath);
     793    size_t cchPathAppDocs = suplibHardenedStrLen(pszSrcPath);
    293794    if (cchPathAppDocs >= cchPath)
    294         supR3HardenedFatal("supR3HardenedPathAppDocs: Buffer overflow, %lu >= %lu\n",
    295                             (unsigned long)cchPathAppDocs, (unsigned long)cchPath);
    296     memcpy(pszPath, pszSrcPath, cchPathAppDocs + 1);
     795        supR3HardenedFatal("supR3HardenedPathAppDocs: Buffer overflow, %zu >= %zu\n", cchPathAppDocs, cchPath);
     796    suplibHardenedMemCopy(pszPath, pszSrcPath, cchPathAppDocs + 1);
    297797    return VINF_SUCCESS;
    298798
     
    341841        supR3HardenedFatal("supR3HardenedExecDir: sysctl failed\n");
    342842    g_szSupLibHardenedExePath[sizeof(g_szSupLibHardenedExePath) - 1] = '\0';
    343     int cchLink = strlen(g_szSupLibHardenedExePath); /* paranoid? can't we use cbPath? */
     843    int cchLink = suplibHardenedStrLen(g_szSupLibHardenedExePath); /* paranoid? can't we use cbPath? */
    344844
    345845# endif
     
    356856    if (!pszImageName)
    357857        supR3HardenedFatal("supR3HardenedExecDir: _dyld_get_image_name(0) failed\n");
    358     size_t cchImageName = strlen(pszImageName);
     858    size_t cchImageName = suplibHardenedStrLen(pszImageName);
    359859    if (!cchImageName || cchImageName >= sizeof(g_szSupLibHardenedExePath))
    360860        supR3HardenedFatal("supR3HardenedExecDir: _dyld_get_image_name(0) failed, cchImageName=%d\n", cchImageName);
    361     memcpy(g_szSupLibHardenedExePath, pszImageName, cchImageName + 1);
     861    suplibHardenedMemCopy(g_szSupLibHardenedExePath, pszImageName, cchImageName + 1);
    362862
    363863#elif defined(RT_OS_WINDOWS)
     
    372872     * Strip off the filename part (RTPathStripFilename()).
    373873     */
    374     strcpy(g_szSupLibHardenedDirPath, g_szSupLibHardenedExePath);
     874    suplibHardenedStrCopy(g_szSupLibHardenedDirPath, g_szSupLibHardenedExePath);
    375875    suplibHardenedPathStripFilename(g_szSupLibHardenedDirPath);
    376876}
     
    410910     * Calc the length and check if there is space before copying.
    411911     */
    412     size_t cch = strlen(g_szSupLibHardenedDirPath) + 1;
     912    size_t cch = suplibHardenedStrLen(g_szSupLibHardenedDirPath) + 1;
    413913    if (cch <= cchPath)
    414914    {
    415         memcpy(pszPath, g_szSupLibHardenedDirPath, cch + 1);
     915        suplibHardenedMemCopy(pszPath, g_szSupLibHardenedDirPath, cch + 1);
    416916        return VINF_SUCCESS;
    417917    }
     
    422922
    423923
     924/**
     925 * Prints the message prefix.
     926 */
     927static void suplibHardenedPrintPrefix(void)
     928{
     929    suplibHardenedPrintStr(g_pszSupLibHardenedProgName);
     930    suplibHardenedPrintStr(": ");
     931}
     932
     933
    424934DECLHIDDEN(void)   supR3HardenedFatalMsgV(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va)
    425935{
     
    427937     * To the console first, like supR3HardenedFatalV.
    428938     */
    429     fprintf(stderr, "%s: Error %d in %s!\n", g_pszSupLibHardenedProgName, rc, pszWhere);
    430     fprintf(stderr, "%s: ", g_pszSupLibHardenedProgName);
     939    suplibHardenedPrintPrefix();
     940    suplibHardenedPrintF("Error %d in %s!\n", rc, pszWhere);
     941
     942    suplibHardenedPrintPrefix();
    431943    va_list vaCopy;
    432944    va_copy(vaCopy, va);
    433     vfprintf(stderr, pszMsgFmt, vaCopy);
     945    suplibHardenedPrintFV(pszMsgFmt, vaCopy);
    434946    va_end(vaCopy);
    435     fprintf(stderr, "\n");
     947    suplibHardenedPrintChr('\n');
    436948
    437949    switch (enmWhat)
    438950    {
    439951        case kSupInitOp_Driver:
    440             fprintf(stderr,
    441                     "\n"
    442                     "%s: Tip! Make sure the kernel module is loaded. It may also help to reinstall VirtualBox.\n",
    443                     g_pszSupLibHardenedProgName);
     952            suplibHardenedPrintChr('\n');
     953            suplibHardenedPrintPrefix();
     954            suplibHardenedPrintStr("Tip! Make sure the kernel module is loaded. It may also help to reinstall VirtualBox.\n");
    444955            break;
    445956
     
    447958        case kSupInitOp_Integrity:
    448959        case kSupInitOp_RootCheck:
    449             fprintf(stderr,
    450                     "\n"
    451                     "%s: Tip! It may help to reinstall VirtualBox.\n",
    452                     g_pszSupLibHardenedProgName);
     960            suplibHardenedPrintChr('\n');
     961            suplibHardenedPrintPrefix();
     962            suplibHardenedPrintStr("Tip! It may help to reinstall VirtualBox.\n");
    453963            break;
    454964
     
    485995     * Quit
    486996     */
    487     for (;;)
    488 #ifdef _MSC_VER
    489         exit(1);
    490 #else
    491         _Exit(1);
    492 #endif
     997    suplibHardenedExit(RTEXITCODE_FAILURE);
    493998}
    494999
     
    5051010DECLHIDDEN(void) supR3HardenedFatalV(const char *pszFormat, va_list va)
    5061011{
    507     fprintf(stderr, "%s: ", g_pszSupLibHardenedProgName);
    508     vfprintf(stderr, pszFormat, va);
    509     for (;;)
    510 #ifdef _MSC_VER
    511         exit(1);
    512 #else
    513         _Exit(1);
    514 #endif
     1012    suplibHardenedPrintPrefix();
     1013    suplibHardenedPrintFV(pszFormat, va);
     1014    suplibHardenedExit(RTEXITCODE_FAILURE);
    5151015}
    5161016
     
    5301030        supR3HardenedFatalV(pszFormat, va);
    5311031
    532     fprintf(stderr, "%s: ", g_pszSupLibHardenedProgName);
    533     vfprintf(stderr, pszFormat, va);
     1032    suplibHardenedPrintPrefix();
     1033    suplibHardenedPrintFV(pszFormat, va);
    5341034    return rc;
    5351035}
     
    5431043    va_end(va);
    5441044    return rc;
    545 }
    546 
    547 
    548 /**
    549  * Wrapper around snprintf which will throw a fatal error on buffer overflow.
    550  *
    551  * @returns Number of chars in the result string.
    552  * @param   pszDst          The destination buffer.
    553  * @param   cchDst          The size of the buffer.
    554  * @param   pszFormat       The format string.
    555  * @param   ...             Format arguments.
    556  */
    557 static size_t supR3HardenedStrPrintf(char *pszDst, size_t cchDst, const char *pszFormat, ...)
    558 {
    559     va_list va;
    560     va_start(va, pszFormat);
    561 #ifdef _MSC_VER
    562     int cch = _vsnprintf(pszDst, cchDst, pszFormat, va);
    563 #else
    564     int cch = vsnprintf(pszDst, cchDst, pszFormat, va);
    565 #endif
    566     va_end(va);
    567     if ((unsigned)cch >= cchDst || cch < 0)
    568         supR3HardenedFatal("supR3HardenedStrPrintf: buffer overflow, %d >= %lu\n", cch, (long)cchDst);
    569     return cch;
    5701045}
    5711046
     
    8431318    char szPath[RTPATH_MAX];
    8441319    supR3HardenedPathSharedLibs(szPath, sizeof(szPath) - sizeof("/VBoxRT" SUPLIB_DLL_SUFF));
    845     strcat(szPath, "/VBoxRT" SUPLIB_DLL_SUFF);
     1320    suplibHardenedStrCat(szPath, "/VBoxRT" SUPLIB_DLL_SUFF);
    8461321
    8471322    /*
     
    9251400    char szPath[RTPATH_MAX];
    9261401    supR3HardenedPathAppPrivateArch(szPath, sizeof(szPath) - 10);
    927     size_t cch = strlen(szPath);
    928     supR3HardenedStrPrintf(&szPath[cch], sizeof(szPath) - cch, "/%s%s", pszProgName, SUPLIB_DLL_SUFF);
     1402    size_t cch = suplibHardenedStrLen(szPath);
     1403    suplibHardenedStrCopyEx(&szPath[cch], sizeof(szPath) - cch, "/", pszProgName, SUPLIB_DLL_SUFF, NULL);
    9291404
    9301405    /*
     
    9691444    char szPath[RTPATH_MAX];
    9701445    supR3HardenedPathAppPrivateArch(szPath, sizeof(szPath) - 10);
    971     size_t cch = strlen(szPath);
    972     supR3HardenedStrPrintf(&szPath[cch], sizeof(szPath) - cch, "/%s%s", pszProgName, SUPLIB_DLL_SUFF);
     1446    size_t cch = suplibHardenedStrLen(szPath);
     1447    suplibHardenedStrCopyEx(&szPath[cch], sizeof(szPath) - cch, "/", pszProgName, SUPLIB_DLL_SUFF, NULL);
    9731448
    9741449    /*
     
    11021577}
    11031578
     1579
     1580#ifdef RT_OS_WINDOWS
     1581
     1582extern "C" int main(int argc, char **argv, char **envp);
     1583
     1584/**
     1585 * The executable entry point.
     1586 */
     1587extern "C" void __stdcall suplibHardenedWindowsMain(void)
     1588{
     1589    RTEXITCODE  rcExit = RTEXITCODE_FAILURE;
     1590
     1591    /*
     1592     * Convert the arguments to UTF-8.
     1593     */
     1594    int    cArgs;
     1595    PWSTR *papwszArgs = CommandLineToArgvW(GetCommandLineW(), &cArgs); /** @todo fix me! */
     1596    if (papwszArgs)
     1597    {
     1598        char **papszArgs = (char **)HeapAlloc(GetProcessHeap(), 0 /* dwFlags*/, (cArgs + 1) * sizeof(const char **));
     1599        if (papszArgs)
     1600        {
     1601            int iArg;
     1602            for (iArg = 0; iArg < cArgs; iArg++)
     1603            {
     1604                int cbNeeded = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, papwszArgs[iArg], -1, NULL /*pszDst*/, 0 /*cbDst*/,
     1605                                                   NULL /*pchDefChar*/, NULL /* pfUsedDefChar */);
     1606                if (!cbNeeded)
     1607                {
     1608                    suplibHardenedPrintF("CommandLineToArgvW failed on argument %d: %u\n", iArg, GetLastError());
     1609                    break;
     1610                }
     1611
     1612                papszArgs[iArg] = (char *)HeapAlloc(GetProcessHeap(), 0 /*dwFlags*/, cbNeeded);
     1613                if (!papszArgs[iArg])
     1614                {
     1615                    suplibHardenedPrintF("HeapAlloc failed");
     1616                    break;
     1617                }
     1618
     1619                int cbRet = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, papwszArgs[iArg], -1, papszArgs[iArg], cbNeeded,
     1620                                                NULL /*pchDefChar*/, NULL /* pfUsedDefChar */);
     1621                if (!cbRet)
     1622                {
     1623                    suplibHardenedPrintF("CommandLineToArgvW failed on argument %d: %u\n", iArg, GetLastError());
     1624                    break;
     1625                }
     1626            }
     1627            if (iArg == cArgs)
     1628            {
     1629                papszArgs[iArg] = NULL;
     1630
     1631                /*
     1632                 * Call the main function.
     1633                 */
     1634                rcExit = (RTEXITCODE)main(cArgs, papszArgs, NULL);
     1635            }
     1636        }
     1637        else
     1638            suplibHardenedPrintF("HeapAlloc failed\n");
     1639    }
     1640    else
     1641        suplibHardenedPrintF("CommandLineToArgvW failed\n");
     1642
     1643    /*
     1644     * Exit the process (never return).
     1645     */
     1646    for (;;)
     1647        ExitProcess(rcExit);
     1648}
     1649
     1650#endif
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp

    r47894 r49211  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4141#elif defined(RT_OS_WINDOWS)
    4242# include <Windows.h>
    43 # include <stdio.h>
     43# ifndef IN_SUP_HARDENED_R3
     44#  include <stdio.h>
     45# endif
    4446
    4547#else /* UNIXes */
     
    5658# include <sys/time.h>
    5759# include <sys/fcntl.h>
    58 # include <stdio.h>
    5960# include <pwd.h>
    6061# ifdef RT_OS_DARWIN
     
    244245            if (RT_SUCCESS(rc))
    245246            {
    246                 size_t off = strlen(pszDst);
     247                size_t off = suplibHardenedStrLen(pszDst);
    247248                if (cchDst - off >= sizeof("/components"))
    248                     memcpy(&pszDst[off], "/components", sizeof("/components"));
     249                    suplibHardenedMemCopy(&pszDst[off], "/components", sizeof("/components"));
    249250                else
    250251                    rc = VERR_BUFFER_OVERFLOW;
     
    286287    if (RT_SUCCESS(rc) && fWithFilename)
    287288    {
    288         size_t cchFile = strlen(pFile->pszFile);
    289         size_t off = strlen(pszDst);
     289        size_t cchFile = suplibHardenedStrLen(pFile->pszFile);
     290        size_t off = suplibHardenedStrLen(pszDst);
    290291        if (cchDst - off >= cchFile + 2)
    291292        {
    292293            pszDst[off++] = '/';
    293             memcpy(&pszDst[off], pFile->pszFile, cchFile + 1);
     294            suplibHardenedMemCopy(&pszDst[off], pFile->pszFile, cchFile + 1);
    294295        }
    295296        else
     
    581582        return rc;
    582583#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    583     if (stricmp(szName, pszFilename))
     584    if (suplibHardenedStrICmp(szName, pszFilename))
    584585#else
    585     if (strcmp(szName, pszFilename))
     586    if (suplibHardenedStrCmp(szName, pszFilename))
    586587#endif
    587588    {
     
    595596        if (    GetFullPathName(szName, RT_ELEMENTS(szName2), &szName2[0], &pszIgnored)
    596597            &&  GetFullPathName(pszFilename, RT_ELEMENTS(szName), &szName[0], &pszIgnored))
    597             if (!stricmp(szName2, szName))
     598            if (!suplibHardenedStrICmp(szName2, szName))
    598599                rc = VINF_SUCCESS;
    599600#else
     
    602603        if (    realpath(szName, szName2) != NULL
    603604            &&  realpath(pszFilename, szName) != NULL)
    604             if (!strcmp(szName2, szName))
     605            if (!suplibHardenedStrCmp(szName2, szName))
    605606                rc = VINF_SUCCESS;
    606607#endif
     
    644645    const char *pszName = supR3HardenedPathFilename(pszFilename);
    645646    for (unsigned iFile = 0; iFile < RT_ELEMENTS(g_aSupInstallFiles); iFile++)
    646         if (!strcmp(pszName, g_aSupInstallFiles[iFile].pszFile))
     647        if (!suplibHardenedStrCmp(pszName, g_aSupInstallFiles[iFile].pszFile))
    647648        {
    648649            int rc = supR3HardenedVerifySameFile(iFile, pszFilename, fFatal);
     
    671672    bool            fExe = false;
    672673    bool            fDll = false;
    673     size_t const    cchProgName = strlen(pszProgName);
     674    size_t const    cchProgName = suplibHardenedStrLen(pszProgName);
    674675    for (unsigned iFile = 0; iFile < RT_ELEMENTS(g_aSupInstallFiles); iFile++)
    675         if (!strncmp(pszProgName, g_aSupInstallFiles[iFile].pszFile, cchProgName))
     676        if (!suplibHardenedStrNCmp(pszProgName, g_aSupInstallFiles[iFile].pszFile, cchProgName))
    676677        {
    677678            if (    g_aSupInstallFiles[iFile].enmType == kSupIFT_Dll
    678                 &&  !strcmp(&g_aSupInstallFiles[iFile].pszFile[cchProgName], SUPLIB_DLL_SUFF))
     679                &&  !suplibHardenedStrCmp(&g_aSupInstallFiles[iFile].pszFile[cchProgName], SUPLIB_DLL_SUFF))
    679680            {
    680681                /* This only has to be found (once). */
     
    685686            }
    686687            else if (   g_aSupInstallFiles[iFile].enmType == kSupIFT_Exe
    687                      && !strcmp(&g_aSupInstallFiles[iFile].pszFile[cchProgName], SUPLIB_EXE_SUFF))
     688                     && !suplibHardenedStrCmp(&g_aSupInstallFiles[iFile].pszFile[cchProgName], SUPLIB_EXE_SUFF))
    688689            {
    689690                /* Here we'll have to check that the specific program is the same as the entry. */
     
    697698                if (RT_SUCCESS(rc2))
    698699                {
    699                     strcat(szFilename, "/");
    700                     strcat(szFilename, g_aSupInstallFiles[iFile].pszFile);
     700                    suplibHardenedStrCat(szFilename, "/");
     701                    suplibHardenedStrCat(szFilename, g_aSupInstallFiles[iFile].pszFile);
    701702                    supR3HardenedVerifySameFile(iFile, szFilename, fFatal);
    702703                }
     
    786787        {
    787788            const char *pszMsg = va_arg(va,  const char *);
    788             size_t cchMsg = VALID_PTR(pszMsg) ? strlen(pszMsg) : 0;
     789            size_t cchMsg = VALID_PTR(pszMsg) ? suplibHardenedStrLen(pszMsg) : 0;
    789790            if (cchMsg >= cbErr)
    790791                cchMsg = cbErr - 1;
    791             memcpy(pszErr, pszMsg, cchMsg);
     792            suplibHardenedMemCopy(pszErr, pszMsg, cchMsg);
    792793            pszErr[cchMsg] = '\0';
    793794            pszErr += cchMsg;
     
    11971198           permit grand parents and beyond to be group writable by admin. */
    11981199        /** @todo dynamically resolve the admin group? */
    1199         bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 80 /*admin*/ || strcmp(pszPath, "/Applications");
     1200        bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 80 /*admin*/ || suplibHardenedStrCmp(pszPath, "/Applications");
    12001201
    12011202#elif defined(RT_OS_FREEBSD)
     
    12051206           PC-BSD the default user is a member. */
    12061207        /** @todo dynamically resolve the operator group? */
    1207         bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 5 /*operator*/ || strcmp(pszPath, "/usr/pbi");
     1208        bool fBad = !fRelaxed || pFsObjState->Stat.st_gid != 5 /*operator*/ || suplibHardenedStrCmp(pszPath, "/usr/pbi");
    12081209        NOREF(fRelaxed);
    12091210#else
     
    13361337         * stat()'ed.
    13371338         */
    1338         size_t cchName = strlen(pEntry->d_name);
     1339        size_t cchName = suplibHardenedStrLen(pEntry->d_name);
    13391340        if (cchName + cchDirPath > SUPR3HARDENED_MAX_PATH)
    13401341        {
     
    13431344            break;
    13441345        }
    1345         memcpy(&pszDirPath[cchName], pEntry->d_name, cchName + 1);
     1346        suplibHardenedMemCopy(&pszDirPath[cchName], pEntry->d_name, cchName + 1);
    13461347
    13471348        /*
     
    13631364        if (    fRecursive
    13641365            &&  S_ISDIR(pFsObjState->Stat.st_mode)
    1365             &&  strcmp(pEntry->d_name, ".")
    1366             &&  strcmp(pEntry->d_name, ".."))
     1366            &&  suplibHardenedStrCmp(pEntry->d_name, ".")
     1367            &&  suplibHardenedStrCmp(pEntry->d_name, ".."))
    13671368        {
    13681369            pszDirPath[cchDirPath + cchName]     = RTPATH_SLASH;
     
    15281529            ||  g_aSupInstallFiles[iFile].enmType   != paInstallFiles[iFile].enmType
    15291530            ||  g_aSupInstallFiles[iFile].fOptional != paInstallFiles[iFile].fOptional
    1530             ||  strcmp(g_aSupInstallFiles[iFile].pszFile, paInstallFiles[iFile].pszFile))
     1531            ||  suplibHardenedStrCmp(g_aSupInstallFiles[iFile].pszFile, paInstallFiles[iFile].pszFile))
    15311532            return VERR_VERSION_MISMATCH;
    15321533
     
    15421543     * Copy the verification data over.
    15431544     */
    1544     memcpy(&g_aSupVerifiedFiles[0], pPreInitData->paVerifiedFiles, sizeof(g_aSupVerifiedFiles));
    1545     memcpy(&g_aSupVerifiedDirs[0], pPreInitData->paVerifiedDirs, sizeof(g_aSupVerifiedDirs));
    1546     return VINF_SUCCESS;
    1547 }
     1545    suplibHardenedMemCopy(&g_aSupVerifiedFiles[0], pPreInitData->paVerifiedFiles, sizeof(g_aSupVerifiedFiles));
     1546    suplibHardenedMemCopy(&g_aSupVerifiedDirs[0], pPreInitData->paVerifiedDirs, sizeof(g_aSupVerifiedDirs));
     1547    return VINF_SUCCESS;
     1548}
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