From 16738a07bc3163baa8ffbd4b086962c64c6dd5ce Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Tue, 26 Apr 2016 22:56:05 -0400 Subject: [PATCH] Fix panic that occurs when reading a large events on Windows Vista and newer. This occurs in an error recovery path so in order for the panic to occur, first there had to have been an error rendering the event as XML with the event message string. When that error occurs Winlogbeat tries to render the event as XML, but without the message string. If the XML was larger than half the buffer size a panic would occur. The cause was invalid handling of the "BufferUsed [out]" parameter value. The value specifies the number of bytes in this case and it was treated as if it where the number of characters. This is opposite of the behavior of FormatMessage() used in earlier versions of Windows which returns the number of characters rather than bytes. --- CHANGELOG.asciidoc | 2 ++ winlogbeat/sys/wineventlog/wineventlog_windows.go | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index b3893d2c828..c9b8b27683b 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -59,6 +59,8 @@ https://github.com/elastic/beats/compare/v5.0.0-alpha1...master[Check the HEAD d *Winlogbeat* - Fix panic when reading messages larger than 32K characters on Windows XP and 2003. {pull}1498[1498] +- Fix panic that occurs when reading a large events on Windows Vista and newer. {pull}1499[1499] + ==== Added diff --git a/winlogbeat/sys/wineventlog/wineventlog_windows.go b/winlogbeat/sys/wineventlog/wineventlog_windows.go index 45be1edd827..bc5eab1c454 100644 --- a/winlogbeat/sys/wineventlog/wineventlog_windows.go +++ b/winlogbeat/sys/wineventlog/wineventlog_windows.go @@ -192,7 +192,6 @@ func RenderEventNoMessage(eventHandle EvtHandle, renderBuf []byte) (string, erro var bufferUsed, propertyCount uint32 err := _EvtRender(0, eventHandle, EvtRenderEventXml, uint32(len(renderBuf)), &renderBuf[0], &bufferUsed, &propertyCount) - bufferUsed *= 2 // It returns the number of utf-16 chars. if err == ERROR_INSUFFICIENT_BUFFER { return "", sys.InsufficientBufferError{err, int(bufferUsed)} } @@ -200,7 +199,12 @@ func RenderEventNoMessage(eventHandle EvtHandle, renderBuf []byte) (string, erro return "", err } - xml, _, err := sys.UTF16BytesToString(renderBuf[0:bufferUsed]) + if int(bufferUsed) > len(renderBuf) { + return "", fmt.Errorf("Windows EvtRender reported that wrote %d bytes "+ + "to the buffer, but the buffer can only hold %d bytes", + bufferUsed, len(renderBuf)) + } + xml, _, err := sys.UTF16BytesToString(renderBuf[:bufferUsed]) return xml, err }