From b0ebc8b332b042cab5f582e88d278a267f84257f Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Sat, 15 Aug 2020 20:37:15 +0100 Subject: [PATCH] kernel: avoid potential buffer overflow on DbgPrint --- src/core/kernel/exports/EmuKrnlDbg.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlDbg.cpp b/src/core/kernel/exports/EmuKrnlDbg.cpp index 93fe00477..18893828e 100644 --- a/src/core/kernel/exports/EmuKrnlDbg.cpp +++ b/src/core/kernel/exports/EmuKrnlDbg.cpp @@ -106,16 +106,31 @@ XBSYSAPI EXPORTNUM(8) xboxkrnl::ULONG _cdecl xboxkrnl::DbgPrint LOG_FUNC_END; if (Format != NULL) { - char szBuffer[MAX_PATH]; - - va_list argp; + va_list argp, argp_copy; va_start(argp, Format); - vsprintf(szBuffer, Format, argp); + // Allocate a sufficient buffer to hold the formatted string + // We make a copy of the argument structure, this prevents issues + // as the call to vsnprintf will modify the va_list. + va_copy(argp_copy, argp); + auto size = vsnprintf(nullptr, 0, Format, argp_copy); + va_end(argp_copy); + + auto buffer = (char*)malloc(size); + if (buffer == nullptr) { + // Prevent a crash if we can't allocate enough memory + // We want this to be transparent to the running Xbox application + // Hence, we return success. + return STATUS_SUCCESS; + } + + // Perform the actual print operation + vsnprintf(buffer, size, Format, argp); va_end(argp); // Allow DbgPrint to be disabled - EmuLog(LOG_LEVEL::INFO, "%s", szBuffer); + EmuLog(LOG_LEVEL::INFO, "%s", buffer); + free(buffer); fflush(stdout); }