Skip to content

[metainfo] Buffer overflow in ConvertToUtf8 when WszWideCharToMultiByte fails #124073

@SnowCoderX

Description

@SnowCoderX

Description

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Description

Buffer overflow in ConvertToUtf8 when WszWideCharToMultiByte returns 0 (conversion error).
The function writes buffer[bufLen] = '\0', which is one byte beyond the allocated array bounds.

Affected code (mdinfo.cpp):

int iLen = 1 + (ULONG32)qSigName.Size();
LPSTR pzSig = (LPSTR)(new char[iLen]);
VWrite(" :: %s", ConvertToUtf8((LPWSTR)qSigName.Ptr(), pzSig, iLen));
delete [] pzSig;


Inside ConvertToUtf8 (approximate):
C++int res = WszWideCharToMultiByte(CP_UTF8, 0, name, -1, buffer, bufLen, NULL, NULL);
if (res == 0)
    buffer[bufLen] = '\0';  // ← out-of-bounds write!

### Reproduction Steps

Trigger DisplayCustomAttributeInfo with metadata where WszWideCharToMultiByte fails (e.g. very long or invalid UTF-16 string).
Hard to reproduce reliably without modifying metadata, but the overflow is clear from static analysis.

### Expected behavior

On conversion failure (res == 0), the buffer should remain safe (e.g. set to empty string without writing beyond bounds).

### Actual behavior

Out-of-bounds write (buffer[bufLen]) → heap corruption / crash / potential security impact.

### Regression?

No 

### Known Workarounds

None practical — requires avoiding conversion failures (not controllable).

### Configuration

.NET Runtime tools (metainfo tool)
Platforms: all — the issue is platform-independent
Found via static analysis (SVACE) in recent versions of dotnet/runtime
No specific runtime version / OS / architecture tested — detected purely by static analysis in mdinfo.cpp

### Other information

Found by Linux Verification Center (linuxtesting.org) with SVACE.
Suggested fix (minimal and safe):
static const char* ConvertToUtf8(LPCWSTR name, char* buffer, ULONG bufLen)
{
    if (bufLen == 0 || buffer == nullptr) {
        return "";
    }

    int res = WszWideCharToMultiByte(CP_UTF8, 0, name, -1, buffer, bufLen, NULL, NULL);

    if (res > 0) {
        // Success — string is already null-terminated inside buffer
    } else {
        // Error — make empty string safely
        buffer[0] = '\0';
    }

    return buffer;
}

Metadata

Metadata

Type

No type

Projects

Status

No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions