Skip to content

Commit

Permalink
fix(promtail): windows forward event crash (#16155)
Browse files Browse the repository at this point in the history
  • Loading branch information
wildum authored Feb 10, 2025
1 parent be047cb commit 82cfaea
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 16 deletions.
45 changes: 29 additions & 16 deletions clients/pkg/promtail/targets/windows/win_eventlog/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,41 @@ package win_eventlog
// More info on schema, if there will be need to add more:
// https://docs.microsoft.com/en-us/windows/win32/wes/eventschema-elements
type Event struct {
Source Provider `xml:"System>Provider"`
EventID int `xml:"System>EventID"`
Version int `xml:"System>Version"`
Level int `xml:"System>Level"`
Task int `xml:"System>Task"`
Opcode int `xml:"System>Opcode"`
Keywords string `xml:"System>Keywords"`
TimeCreated TimeCreated `xml:"System>TimeCreated"`
EventRecordID int `xml:"System>EventRecordID"`
Correlation Correlation `xml:"System>Correlation"`
Execution Execution `xml:"System>Execution"`
Channel string `xml:"System>Channel"`
Computer string `xml:"System>Computer"`
Security Security `xml:"System>Security"`
UserData UserData `xml:"UserData"`
EventData EventData `xml:"EventData"`
Source Provider `xml:"System>Provider"`
EventID int `xml:"System>EventID"`
Version int `xml:"System>Version"`
Level int `xml:"System>Level"`
Task int `xml:"System>Task"`
Opcode int `xml:"System>Opcode"`
Keywords string `xml:"System>Keywords"`
TimeCreated TimeCreated `xml:"System>TimeCreated"`
EventRecordID int `xml:"System>EventRecordID"`
Correlation Correlation `xml:"System>Correlation"`
Execution Execution `xml:"System>Execution"`
Channel string `xml:"System>Channel"`
Computer string `xml:"System>Computer"`
Security Security `xml:"System>Security"`
UserData UserData `xml:"UserData"`
EventData EventData `xml:"EventData"`
RenderingInfo *RenderingInfo `xml:"RenderingInfo"`
Message string
LevelText string
TaskText string
OpcodeText string
}

// RenderingInfo is provided for events forwarded by Windows Event Collector
// see https://learn.microsoft.com/en-us/windows/win32/api/winevt/nf-winevt-evtformatmessage#parameters
type RenderingInfo struct {
Message string `xml:"Message"`
Level string `xml:"Level"`
Task string `xml:"Task"`
Opcode string `xml:"Opcode"`
Channel string `xml:"Channel"`
Provider string `xml:"Provider"`
Keywords []string `xml:"Keywords>Keyword"`
}

// UserData Application-provided XML data
type UserData struct {
InnerXML []byte `xml:",innerxml"`
Expand Down
38 changes: 38 additions & 0 deletions clients/pkg/promtail/targets/windows/win_eventlog/win_eventlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,39 @@ func (w *EventFetcher) renderEvent(eventHandle EvtHandle, lang uint32) (Event, e
return event, nil
}

// Do resolve local messages the usual way, while using built-in information for events forwarded by WEC.
// This is a safety measure as the underlying Windows-internal EvtFormatMessage might segfault in cases
// where the publisher (i.e. the remote machine which forwared the event) is unavailable e.g. due to
// a reboot. See https://github.com/influxdata/telegraf/issues/12328 for the full story.
if event.RenderingInfo == nil {
return w.renderLocalMessage(event, eventHandle, lang)
}

// We got 'RenderInfo' elements, so try to apply them in the following function
return w.renderRemoteMessage(event)
}

func (w *EventFetcher) renderRemoteMessage(event Event) (Event, error) {
// Populating text values from RenderingInfo part of the XML
if len(event.RenderingInfo.Keywords) > 0 {
event.Keywords = strings.Join(event.RenderingInfo.Keywords, ",")
}
if event.RenderingInfo.Message != "" {
event.Message = event.RenderingInfo.Message
}
if event.RenderingInfo.Level != "" {
event.LevelText = event.RenderingInfo.Level
}
if event.RenderingInfo.Task != "" {
event.TaskText = event.RenderingInfo.Task
}
if event.RenderingInfo.Opcode != "" {
event.OpcodeText = event.RenderingInfo.Opcode
}
return event, nil
}

func (w *EventFetcher) renderLocalMessage(event Event, eventHandle EvtHandle, lang uint32) (Event, error) {
publisherHandle, err := openPublisherMetadata(0, event.Source.Name, lang)
if err != nil {
return event, nil
Expand Down Expand Up @@ -525,6 +558,11 @@ func formatEventString(
return "", err
}

// Handle empty elements
if bufferUsed < 1 {
return "", nil
}

bufferUsed *= 2
buffer := make([]byte, bufferUsed)
bufferUsed = 0
Expand Down

0 comments on commit 82cfaea

Please sign in to comment.