Skip to content

Commit 8fa17d6

Browse files
committed
fix(processor): Correct unbounded registry values slice growth
1 parent a669db0 commit 8fa17d6

File tree

2 files changed

+24
-35
lines changed

2 files changed

+24
-35
lines changed

internal/etw/processors/registry_windows.go

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ package processors
2121
import (
2222
"expvar"
2323
"fmt"
24-
"github.com/rabbitstack/fibratus/pkg/util/key"
25-
"golang.org/x/sys/windows"
26-
"golang.org/x/sys/windows/registry"
2724
"os"
2825
"path/filepath"
2926
"strings"
3027
"sync"
3128
"sync/atomic"
3229
"time"
3330

31+
"github.com/rabbitstack/fibratus/pkg/util/key"
32+
"golang.org/x/sys/windows"
33+
"golang.org/x/sys/windows/registry"
34+
3435
"github.com/rabbitstack/fibratus/pkg/event"
3536
"github.com/rabbitstack/fibratus/pkg/event/params"
3637
"github.com/rabbitstack/fibratus/pkg/handle"
@@ -68,7 +69,8 @@ type registryProcessor struct {
6869
keys map[uint64]string
6970
hsnap handle.Snapshotter
7071

71-
values map[uint32][]*event.Event
72+
// values keeps temporarily RegSetValue internal events by pid and base registry path.
73+
values map[uint32]map[string]*event.Event
7274
mu sync.Mutex
7375

7476
purger *time.Ticker
@@ -89,7 +91,7 @@ func newRegistryProcessor(hsnap handle.Snapshotter) Processor {
8991
r := &registryProcessor{
9092
keys: make(map[uint64]string),
9193
hsnap: hsnap,
92-
values: make(map[uint32][]*event.Event),
94+
values: make(map[uint32]map[string]*event.Event),
9395
purger: time.NewTicker(valuePurgerInterval),
9496
quit: make(chan struct{}, 1),
9597
}
@@ -252,35 +254,22 @@ func (r *registryProcessor) findMatchingKey(pid uint32, relativeKeyName string)
252254
func (r *registryProcessor) pushSetValue(e *event.Event) {
253255
r.mu.Lock()
254256
defer r.mu.Unlock()
255-
vals, ok := r.values[e.PID]
256-
if !ok {
257-
r.values[e.PID] = []*event.Event{e}
258-
} else {
259-
r.values[e.PID] = append(vals, e)
260-
}
257+
r.values[e.PID] = map[string]*event.Event{filepath.Base(e.GetParamAsString(params.RegPath)): e}
261258
}
262259

263260
// popSetValue traverses the internal RegSetValue queue
264-
// and pops the event if the suffixes match.
261+
// and pops the event if the base paths match.
265262
func (r *registryProcessor) popSetValue(e *event.Event) *event.Event {
266263
r.mu.Lock()
267264
defer r.mu.Unlock()
268-
vals, ok := r.values[e.PID]
265+
key := filepath.Base(e.GetParamAsString(params.RegPath))
266+
evt, ok := r.values[e.PID][key]
269267
if !ok {
270268
return nil
271269
}
270+
delete(r.values[e.PID], key)
272271

273-
var v *event.Event
274-
for i := len(vals) - 1; i >= 0; i-- {
275-
val := vals[i]
276-
if strings.HasSuffix(e.GetParamAsString(params.RegPath), val.GetParamAsString(params.RegPath)) {
277-
v = val
278-
r.values[e.PID] = append(vals[:i], vals[i+1:]...)
279-
break
280-
}
281-
}
282-
283-
return v
272+
return evt
284273
}
285274

286275
func (r *registryProcessor) valuesSize(pid uint32) int {
@@ -294,14 +283,13 @@ func (r *registryProcessor) housekeep() {
294283
select {
295284
case <-r.purger.C:
296285
r.mu.Lock()
297-
for pid, vals := range r.values {
298-
for i, val := range vals {
299-
if time.Since(val.Timestamp) < valueTTL {
300-
continue
286+
for pid, bucket := range r.values {
287+
for key, ev := range bucket {
288+
if time.Since(ev.Timestamp) > valueTTL {
289+
delete(bucket, key)
301290
}
302-
r.values[pid] = append(vals[:i], vals[i+1:]...)
303291
}
304-
if len(vals) == 0 {
292+
if len(bucket) == 0 {
305293
delete(r.values, pid)
306294
}
307295
}

internal/etw/processors/registry_windows_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@
1919
package processors
2020

2121
import (
22+
"testing"
23+
"time"
24+
2225
"github.com/rabbitstack/fibratus/pkg/event"
2326
"github.com/rabbitstack/fibratus/pkg/event/params"
2427
"github.com/rabbitstack/fibratus/pkg/handle"
2528
htypes "github.com/rabbitstack/fibratus/pkg/handle/types"
2629
"github.com/rabbitstack/fibratus/pkg/util/key"
2730
"github.com/stretchr/testify/assert"
2831
"github.com/stretchr/testify/require"
29-
"testing"
30-
"time"
3132
)
3233

3334
func init() {
@@ -183,8 +184,8 @@ func TestRegistryProcessor(t *testing.T) {
183184
},
184185
},
185186
func(p Processor) {
186-
p.(*registryProcessor).values[23234] = []*event.Event{
187-
{
187+
p.(*registryProcessor).values[23234] = map[string]*event.Event{
188+
"SessionId": {
188189
Type: event.RegSetValueInternal,
189190
Timestamp: time.Now(),
190191
Params: event.Params{
@@ -193,7 +194,7 @@ func TestRegistryProcessor(t *testing.T) {
193194
params.RegValueType: {Name: params.RegValueType, Type: params.Enum, Value: uint32(1), Enum: key.RegistryValueTypes},
194195
params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(0)}},
195196
},
196-
{
197+
"Directory": {
197198
Type: event.RegSetValueInternal,
198199
Timestamp: time.Now(),
199200
Params: event.Params{

0 commit comments

Comments
 (0)