VirtualBox

Changeset 97253 in vbox


Ignore:
Timestamp:
Oct 20, 2022 12:49:06 PM (2 years ago)
Author:
vboxsync
Message:

Shared Clipboard/common: Fixed a bug in ShClConvLatin1LFToUtf16CRLF() where a buffer overflow could happen, when handing-in strings which are bigger than the included string terminator (e.g. text which comes AFTER the string terminator). This caused overwriting areas bigger than the allocated pwszDst UTF-16 string, ultimately leading to a heap corruption.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp

    r96407 r97253  
    636636}
    637637
     638/**
     639 * Converts a Latin-1 string with LF line endings into an UTF-16 string with CRLF endings.
     640 *
     641 * @returns VBox status code.
     642 * @param   pcszSrc             Latin-1 string to convert.
     643 * @param   cbSrc               Size (in bytes) of Latin-1 string to convert.
     644 * @param   ppwszDst            Where to return the converted UTF-16 string on success.
     645 * @param   pcwDst              Where to return the length (in UTF-16 characters) on success.
     646 *
     647 * @note    Only converts the source until the string terminator is found (or length limit is hit).
     648 */
    638649int ShClConvLatin1LFToUtf16CRLF(const char *pcszSrc, size_t cbSrc,
    639650                                PRTUTF16 *ppwszDst, size_t *pcwDst)
     
    644655    AssertPtrReturn(pcwDst,   VERR_INVALID_POINTER);
    645656
    646     int rc = VINF_SUCCESS;
     657    size_t chSrc = 0;
    647658
    648659    PRTUTF16 pwszDst = NULL;
    649660
    650661    /* Calculate the space needed. */
    651     unsigned cwDst = 0;
    652     for (unsigned i = 0; i < cbSrc && pcszSrc[i] != '\0'; ++i)
     662    size_t cwDst = 0;
     663    for (size_t i = 0; i < cbSrc && pcszSrc[i] != '\0'; ++i)
    653664    {
    654665        if (pcszSrc[i] == VBOX_SHCL_LINEFEED)
     
    656667        else
    657668            ++cwDst;
     669        chSrc++;
    658670    }
    659671
    660672    pwszDst = (PRTUTF16)RTMemAlloc((cwDst + 1 /* Leave space for the terminator */) * sizeof(RTUTF16));
    661     if (!pwszDst)
    662         rc = VERR_NO_MEMORY;
     673    AssertPtrReturn(pwszDst, VERR_NO_MEMORY);
    663674
    664675    /* Do the conversion, bearing in mind that Latin-1 expands "naturally" to UTF-16. */
    665     if (RT_SUCCESS(rc))
    666     {
    667         for (unsigned i = 0, j = 0; i < cbSrc; ++i, ++j)
    668         {
    669             if (pcszSrc[i] != VBOX_SHCL_LINEFEED)
    670                 pwszDst[j] = pcszSrc[i];
    671             else
    672             {
    673                 pwszDst[j]     = VBOX_SHCL_CARRIAGERETURN;
    674                 pwszDst[j + 1] = VBOX_SHCL_LINEFEED;
    675                 ++j;
    676             }
    677         }
    678 
    679         pwszDst[cwDst] = '\0';  /* Make sure we are zero-terminated. */
    680     }
    681 
    682     if (RT_SUCCESS(rc))
    683     {
    684         *ppwszDst = pwszDst;
    685         *pcwDst   = cwDst;
    686     }
    687     else
    688         RTMemFree(pwszDst);
    689 
    690     return rc;
     676    for (size_t i = 0, j = 0; i < chSrc; ++i, ++j)
     677    {
     678        AssertMsg(j <= cwDst, ("cbSrc=%zu, j=%u vs. cwDst=%u\n", cbSrc, j, cwDst));
     679        if (pcszSrc[i] != VBOX_SHCL_LINEFEED)
     680            pwszDst[j] = pcszSrc[i];
     681        else
     682        {
     683            pwszDst[j]     = VBOX_SHCL_CARRIAGERETURN;
     684            pwszDst[j + 1] = VBOX_SHCL_LINEFEED;
     685            ++j;
     686        }
     687    }
     688
     689    pwszDst[cwDst] = '\0';  /* Make sure we are zero-terminated. */
     690
     691    *ppwszDst = pwszDst;
     692    *pcwDst   = cwDst;
     693
     694    return VINF_SUCCESS;
    691695}
    692696
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