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.

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 committed Apr 27, 2016
1 parent 2a7ba04 commit 16738a0
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 16738a0

Please sign in to comment.