Skip to content

Commit 155ddb0

Browse files
authored
fix: process ancestor filters stackoverflow (#127)
* mitigate stack overflow when replying caputre with ancestor filters * add comment * the capture should only contain CreateFile events, regenerate test fixture
1 parent d1d0ebe commit 155ddb0

File tree

7 files changed

+42
-35
lines changed

7 files changed

+42
-35
lines changed

pkg/filter/accessor_windows.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -418,47 +418,47 @@ func ancestorFields(field string, kevt *kevent.Kevent) (kparams.Value, error) {
418418

419419
switch key {
420420
case "root":
421-
pstypes.Walk(func(proc *pstypes.PS) {
421+
walk := func(proc *pstypes.PS) {
422422
ps = proc
423-
}, kevt.PS)
424-
423+
}
424+
pstypes.Walk(walk, kevt.PS)
425425
case "any":
426426
values := make([]string, 0)
427-
pstypes.Walk(func(ps *pstypes.PS) {
427+
walk := func(proc *pstypes.PS) {
428428
switch segment {
429429
case fields.ProcessName:
430-
values = append(values, ps.Name)
430+
values = append(values, proc.Name)
431431
case fields.ProcessID:
432-
values = append(values, strconv.Itoa(int(ps.PID)))
432+
values = append(values, strconv.Itoa(int(proc.PID)))
433433
case fields.ProcessSID:
434-
values = append(values, ps.SID)
434+
values = append(values, proc.SID)
435435
case fields.ProcessSessionID:
436-
values = append(values, strconv.Itoa(int(ps.SessionID)))
436+
values = append(values, strconv.Itoa(int(proc.SessionID)))
437437
case fields.ProcessCwd:
438-
values = append(values, ps.Cwd)
438+
values = append(values, proc.Cwd)
439439
case fields.ProcessComm:
440-
values = append(values, ps.Comm)
440+
values = append(values, proc.Comm)
441441
case fields.ProcessArgs:
442-
values = append(values, ps.Args...)
442+
values = append(values, proc.Args...)
443443
case fields.ProcessExe:
444-
values = append(values, ps.Exe)
444+
values = append(values, proc.Exe)
445445
}
446-
}, kevt.PS)
447-
446+
}
447+
pstypes.Walk(walk, kevt.PS)
448448
return values, nil
449-
450449
default:
451450
depth, err := strconv.Atoi(key)
452451
if err != nil {
453452
return nil, err
454453
}
455454
var i int
456-
pstypes.Walk(func(proc *pstypes.PS) {
455+
walk := func(proc *pstypes.PS) {
457456
i++
458457
if i == depth {
459458
ps = proc
460459
}
461-
}, kevt.PS)
460+
}
461+
pstypes.Walk(walk, kevt.PS)
462462
}
463463

464464
if ps == nil {

pkg/kcap/_fixtures/cap.kcap

-882 Bytes
Binary file not shown.

pkg/kcap/_fixtures/cap1.kcap

-691 Bytes
Binary file not shown.

pkg/kcap/reader_windows.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,18 @@ func (r *reader) read(kevt *kevent.Kevent, keventsc chan *kevent.Kevent) {
178178

179179
func (r *reader) updateSnapshotters(kevt *kevent.Kevent) error {
180180
switch kevt.Type {
181-
case ktypes.TerminateThread, ktypes.TerminateProcess, ktypes.UnloadImage:
181+
case ktypes.TerminateThread,
182+
ktypes.TerminateProcess,
183+
ktypes.UnloadImage:
182184
if err := r.psnapshotter.Remove(kevt); err != nil {
183185
return err
184186
}
185187
case ktypes.CreateProcess,
186188
ktypes.CreateThread,
187189
ktypes.LoadImage,
188190
ktypes.EnumImage,
189-
ktypes.EnumProcess, ktypes.EnumThread:
191+
ktypes.EnumProcess,
192+
ktypes.EnumThread:
190193
if err := r.psnapshotter.WriteFromKcap(kevt); err != nil {
191194
return err
192195
}

pkg/kcap/writer_windows_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,8 @@ func TestWrite(t *testing.T) {
6565
errs := make(chan error, 10)
6666

6767
for i := 0; i < 100; i++ {
68-
typ := ktypes.CreateFile
69-
if i%2 == 0 {
70-
typ = ktypes.CreateProcess
71-
}
7268
kevt := &kevent.Kevent{
73-
Type: typ,
69+
Type: ktypes.CreateFile,
7470
Tid: 2484,
7571
PID: 859,
7672
CPU: uint8(i / 2),

pkg/ps/snapshotter_windows.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,6 @@ func NewSnapshotterFromKcap(handleSnap handle.Snapshotter, config *config.Config
9595
capture: true,
9696
}
9797

98-
s.mu.Lock()
99-
defer s.mu.Unlock()
100-
10198
s.handleSnap.RegisterCreateCallback(s.onHandleCreated)
10299
s.handleSnap.RegisterDestroyCallback(s.onHandleDestroyed)
103100

@@ -113,12 +110,24 @@ func (s *snapshotter) WriteFromKcap(kevt *kevent.Kevent) error {
113110
if ps == nil {
114111
return nil
115112
}
116-
if ps.PID == winerrno.InvalidPID {
117-
return nil
113+
pid, err := kevt.Kparams.GetPid()
114+
if err != nil {
115+
return err
118116
}
119-
ps.Parent = s.procs[ps.Ppid]
120-
s.procs[ps.PID] = ps
121-
117+
if kevt.Type == ktypes.EnumProcess {
118+
// invalid process
119+
if ps.PID == ps.Ppid {
120+
return nil
121+
}
122+
s.procs[pid] = ps
123+
} else {
124+
s.procs[pid] = pstypes.FromKevent(unwrapParams(pid, kevt))
125+
}
126+
ppid, err := kevt.Kparams.GetPpid()
127+
if err != nil {
128+
return err
129+
}
130+
ps.Parent = s.procs[ppid]
122131
case ktypes.CreateThread, ktypes.EnumThread:
123132
pid, err := kevt.Kparams.GetPid()
124133
if err != nil {
@@ -130,7 +139,6 @@ func (s *snapshotter) WriteFromKcap(kevt *kevent.Kevent) error {
130139
ps.AddThread(thread)
131140
ps.Parent = s.procs[ps.Ppid]
132141
}
133-
134142
case ktypes.LoadImage, ktypes.EnumImage:
135143
pid, err := kevt.Kparams.GetPid()
136144
if err != nil {
@@ -340,7 +348,7 @@ func (s *snapshotter) findProcess(pid uint32, thread pstypes.Thread) *pstypes.PS
340348
case 0:
341349
return pstypes.NewPS(pid, pid, "idle", "", "idle", thread, nil)
342350
case 4:
343-
return pstypes.NewPS(pid, pid, "System", "", ntoskrnl(), thread, nil)
351+
return pstypes.NewPS(pid, 0, "System", "", ntoskrnl(), thread, nil)
344352
}
345353
flags := process.QueryInformation | process.VMRead
346354
h, err := process.Open(flags, false, pid)

pkg/ps/types/marshaller_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ func (m *Module) Unmarshal(b []byte) (uint16, error) {
314314
// read checksum
315315
m.Checksum = bytes.ReadUint32(b[4:])
316316

317-
// read DLL full path
317+
// read module full path
318318
length := bytes.ReadUint16(b[8:])
319319
buf := b[10:]
320320
offset := length

0 commit comments

Comments
 (0)