Skip to content

Commit

Permalink
Fix panic that occurs when reading a large events on Windows Vista an…
Browse files Browse the repository at this point in the history
…d newer. (#1499)

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.
  • Loading branch information
andrewkroh authored and ruflin committed Apr 27, 2016
1 parent b81a7a2 commit 63c0f44
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.asciidoc
Expand Up @@ -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

Expand Down
8 changes: 6 additions & 2 deletions winlogbeat/sys/wineventlog/wineventlog_windows.go
Expand Up @@ -192,15 +192,19 @@ 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)}
}
if err != nil {
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
}

Expand Down

0 comments on commit 63c0f44

Please sign in to comment.