Skip to content

Commit e01f933

Browse files
rscamposAlonZivony
andcommitted
Enable time normalization for proctree
Co-authored-by: Alon Zivony <[email protected]>
1 parent d27eac1 commit e01f933

File tree

6 files changed

+57
-58
lines changed

6 files changed

+57
-58
lines changed

pkg/ebpf/processor_proctree.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package ebpf
22

33
import (
44
"fmt"
5-
"time"
65

76
"github.com/aquasecurity/tracee/pkg/events/parse"
87
"github.com/aquasecurity/tracee/pkg/logger"
98
"github.com/aquasecurity/tracee/pkg/proctree"
9+
traceetime "github.com/aquasecurity/tracee/pkg/time"
1010
"github.com/aquasecurity/tracee/pkg/utils"
1111
"github.com/aquasecurity/tracee/types/trace"
1212
)
@@ -75,25 +75,25 @@ func (t *Tracee) procTreeForkProcessor(event *trace.Event) error {
7575

7676
return t.processTree.FeedFromFork(
7777
proctree.ForkFeed{
78-
TimeStamp: childStartTime, // event timestamp is the same
78+
TimeStamp: uint64(t.timeNormalizer.NormalizeTime(int(childStartTime))), // event timestamp is the same
7979
ChildHash: childHash,
8080
ParentHash: parentHash,
8181
LeaderHash: leaderHash,
8282
ParentTid: parentTid,
8383
ParentNsTid: parentNsTid,
8484
ParentPid: parentPid,
8585
ParentNsPid: parentNsPid,
86-
ParentStartTime: parentStartTime,
86+
ParentStartTime: uint64(t.timeNormalizer.NormalizeTime(int(parentStartTime))),
8787
LeaderTid: leaderTid,
8888
LeaderNsTid: leaderNsTid,
8989
LeaderPid: leaderPid,
9090
LeaderNsPid: leaderNsPid,
91-
LeaderStartTime: leaderStartTime,
91+
LeaderStartTime: uint64(t.timeNormalizer.NormalizeTime(int(leaderStartTime))),
9292
ChildTid: childTid,
9393
ChildNsTid: childNsTid,
9494
ChildPid: childPid,
9595
ChildNsPid: childNsPid,
96-
ChildStartTime: childStartTime,
96+
ChildStartTime: uint64(t.timeNormalizer.NormalizeTime(int(childStartTime))),
9797
},
9898
)
9999
}
@@ -153,7 +153,7 @@ func (t *Tracee) procTreeExecProcessor(event *trace.Event) error {
153153

154154
return t.processTree.FeedFromExec(
155155
proctree.ExecFeed{
156-
TimeStamp: timestamp,
156+
TimeStamp: uint64(t.timeNormalizer.NormalizeTime(int(timestamp))),
157157
TaskHash: taskHash,
158158
ParentHash: 0, // regular pipeline does not have parent hash
159159
LeaderHash: 0, // regular pipeline does not have leader hash
@@ -204,7 +204,7 @@ func (t *Tracee) procTreeExitProcessor(event *trace.Event) error {
204204

205205
return t.processTree.FeedFromExit(
206206
proctree.ExitFeed{
207-
TimeStamp: timestamp, // time of exit is already a timestamp
207+
TimeStamp: uint64(t.timeNormalizer.NormalizeTime(int(timestamp))), // time of exit is already a timestamp
208208
TaskHash: taskHash,
209209
ParentHash: 0, // regular pipeline does not have parent hash
210210
LeaderHash: 0, // regular pipeline does not have leader hash
@@ -237,7 +237,7 @@ func (t *Tracee) procTreeAddBinInfo(event *trace.Event) error {
237237
}
238238

239239
// Event timestamp is changed to relative (or not) at the end of all processors only.
240-
eventTimestamp := time.Unix(0, int64(event.Timestamp)+int64(t.bootTime))
240+
eventTimestamp := traceetime.NsSinceEpochToTime(uint64(t.timeNormalizer.NormalizeTime(event.Timestamp)))
241241

242242
executable := currentProcess.GetExecutable()
243243

pkg/ebpf/tracee.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ func (t *Tracee) Init(ctx gocontext.Context) error {
564564
proctreeConfig.ProcfsInitialization = false
565565
proctreeConfig.ProcfsQuerying = false
566566
}
567-
t.processTree, err = proctree.NewProcessTree(ctx, proctreeConfig)
567+
t.processTree, err = proctree.NewProcessTree(ctx, proctreeConfig, t.timeNormalizer)
568568
if err != nil {
569569
return errfmt.WrapError(err)
570570
}

pkg/proctree/proctree.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/aquasecurity/tracee/pkg/errfmt"
1111
"github.com/aquasecurity/tracee/pkg/logger"
12+
traceetime "github.com/aquasecurity/tracee/pkg/time"
1213
)
1314

1415
//
@@ -72,17 +73,18 @@ type ProcTreeConfig struct {
7273

7374
// ProcessTree is a tree of processes and threads.
7475
type ProcessTree struct {
75-
processes *lru.Cache[uint32, *Process] // hash -> process
76-
threads *lru.Cache[uint32, *Thread] // hash -> threads
77-
procfsChan chan int // channel of pids to read from procfs
78-
procfsOnce *sync.Once // busy loop debug message throttling
79-
ctx context.Context // context for the process tree
80-
mutex *sync.RWMutex // mutex for the process tree
81-
procfsQuery bool
76+
processes *lru.Cache[uint32, *Process] // hash -> process
77+
threads *lru.Cache[uint32, *Thread] // hash -> threads
78+
procfsChan chan int // channel of pids to read from procfs
79+
procfsOnce *sync.Once // busy loop debug message throttling
80+
ctx context.Context // context for the process tree
81+
mutex *sync.RWMutex // mutex for the process tree
82+
procfsQuery bool
83+
timeNormalizer traceetime.TimeNormalizer
8284
}
8385

8486
// NewProcessTree creates a new process tree.
85-
func NewProcessTree(ctx context.Context, config ProcTreeConfig) (*ProcessTree, error) {
87+
func NewProcessTree(ctx context.Context, config ProcTreeConfig, timeNormalizer traceetime.TimeNormalizer) (*ProcessTree, error) {
8688
procEvited := 0
8789
thrEvicted := 0
8890

@@ -136,11 +138,12 @@ func NewProcessTree(ctx context.Context, config ProcTreeConfig) (*ProcessTree, e
136138
}()
137139

138140
procTree := &ProcessTree{
139-
processes: processes,
140-
threads: threads,
141-
ctx: ctx,
142-
mutex: &sync.RWMutex{},
143-
procfsQuery: config.ProcfsQuerying,
141+
processes: processes,
142+
threads: threads,
143+
ctx: ctx,
144+
mutex: &sync.RWMutex{},
145+
procfsQuery: config.ProcfsQuerying,
146+
timeNormalizer: timeNormalizer,
144147
}
145148

146149
if config.ProcfsInitialization {

pkg/proctree/proctree_feed.go

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55

66
"github.com/aquasecurity/tracee/pkg/errfmt"
77
"github.com/aquasecurity/tracee/pkg/logger"
8-
"github.com/aquasecurity/tracee/pkg/utils"
8+
traceetime "github.com/aquasecurity/tracee/pkg/time"
99
)
1010

1111
//
@@ -42,6 +42,8 @@ func (pt *ProcessTree) FeedFromFork(feed ForkFeed) error {
4242
if feed.ChildTid == 0 || feed.ChildPid == 0 {
4343
return errfmt.Errorf("invalid child task")
4444
}
45+
46+
feedTimeStamp := traceetime.NsSinceEpochToTime(feed.TimeStamp)
4547
// Parent PID or TID might be 0 for init (and docker containers)
4648
// if feed.ParentTid == 0 || feed.ParentPid == 0 {
4749
// return errfmt.Errorf("invalid parent task")
@@ -63,7 +65,7 @@ func (pt *ProcessTree) FeedFromFork(feed ForkFeed) error {
6365
Uid: -1, // do not change the parent uid
6466
Gid: -1, // do not change the parent gid
6567
},
66-
utils.NsSinceBootTimeToTime(feed.TimeStamp),
68+
feedTimeStamp,
6769
)
6870
if pt.procfsQuery {
6971
pt.FeedFromProcFSAsync(int(feed.ParentPid)) // try to enrich ppid and name from procfs
@@ -101,7 +103,7 @@ func (pt *ProcessTree) FeedFromFork(feed ForkFeed) error {
101103
Uid: -1, // do not change the parent ui
102104
Gid: -1, // do not change the parent gid
103105
},
104-
utils.NsSinceBootTimeToTime(feed.TimeStamp),
106+
feedTimeStamp,
105107
)
106108
if pt.procfsQuery {
107109
pt.FeedFromProcFSAsync(int(feed.LeaderPid)) // try to enrich name from procfs if needed
@@ -127,11 +129,11 @@ func (pt *ProcessTree) FeedFromFork(feed ForkFeed) error {
127129
if feed.ChildHash == feed.LeaderHash {
128130
leader.GetExecutable().SetFeedAt(
129131
parent.GetExecutable().GetFeed(),
130-
utils.NsSinceBootTimeToTime(feed.TimeStamp),
132+
feedTimeStamp,
131133
)
132134
leader.GetInterpreter().SetFeedAt(
133135
parent.GetInterpreter().GetFeed(),
134-
utils.NsSinceBootTimeToTime(feed.TimeStamp),
136+
feedTimeStamp,
135137
)
136138
}
137139

@@ -151,7 +153,7 @@ func (pt *ProcessTree) FeedFromFork(feed ForkFeed) error {
151153
Uid: -1, // do not change the thread uid
152154
Gid: -1, // do not change the thread gid
153155
},
154-
utils.NsSinceBootTimeToTime(feed.TimeStamp),
156+
feedTimeStamp,
155157
)
156158
}
157159

@@ -224,7 +226,7 @@ func (pt *ProcessTree) FeedFromExec(feed ExecFeed) error {
224226
process.SetParentHash(feed.ParentHash) // faster than checking if already set
225227
}
226228

227-
execTimestamp := utils.NsSinceBootTimeToTime(feed.TimeStamp)
229+
execTimestamp := traceetime.NsSinceEpochToTime(feed.TimeStamp)
228230
basename := filepath.Base(feed.CmdPath)
229231
comm := basename[:min(len(basename), COMM_LEN)]
230232
process.GetInfo().SetNameAt(
@@ -243,11 +245,6 @@ func (pt *ProcessTree) FeedFromExec(feed ExecFeed) error {
243245
execTimestamp,
244246
)
245247

246-
// The interpreter and interp info are taking a lot of memory.
247-
// As their usage is still unclear in the process tree, it was decided
248-
// to not save their information until it was clear how they would be used.
249-
// TODO: Decide whether remove the interpreter and interp from the tree or add them back.
250-
251248
return nil
252249
}
253250

pkg/proctree/proctree_procfs.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ import (
99

1010
"github.com/aquasecurity/tracee/pkg/errfmt"
1111
"github.com/aquasecurity/tracee/pkg/logger"
12+
traceetime "github.com/aquasecurity/tracee/pkg/time"
1213
"github.com/aquasecurity/tracee/pkg/utils"
1314
"github.com/aquasecurity/tracee/pkg/utils/proc"
1415
)
1516

16-
const debugMsgs = false // debug messages can be too verbose, so they are disabled by default
17+
const debugMsgs = false // debug messages can be too verbose, so they are disabled by default
18+
const ProcfsClockId = traceetime.CLOCK_BOOTTIME // Procfs uses jiffies, which are based on boottime
1719

1820
const (
1921
AllPIDs = 0
@@ -107,7 +109,7 @@ func getProcessByPID(pt *ProcessTree, givenPid int) (*Process, error) {
107109
return nil, errfmt.Errorf("%v", err)
108110
}
109111

110-
startTimeNs := utils.ClockTicksToNsSinceBootTime(stat.StartTime)
112+
startTimeNs := traceetime.ClockTicksToNsSinceBootTime(stat.StartTime)
111113
hash := utils.HashTaskID(uint32(status.GetPid()), startTimeNs) // status pid == tid
112114

113115
return pt.GetOrCreateProcessByHash(hash), nil
@@ -149,7 +151,7 @@ func dealWithProc(pt *ProcessTree, givenPid int) error {
149151
}
150152

151153
// process hash
152-
startTimeNs := utils.ClockTicksToNsSinceBootTime(start)
154+
startTimeNs := traceetime.ClockTicksToNsSinceBootTime(start)
153155
hash := utils.HashTaskID(uint32(pid), startTimeNs)
154156

155157
// update tree for the given process
@@ -165,6 +167,8 @@ func dealWithProc(pt *ProcessTree, givenPid int) error {
165167
}
166168
}
167169

170+
procfsTimeStamp := uint64(pt.timeNormalizer.NormalizeTime(int(startTimeNs)))
171+
168172
procInfo.SetFeedAt(
169173
TaskInfoFeed{
170174
Name: name, // command name (add "procfs+" to debug if needed)
@@ -176,9 +180,9 @@ func dealWithProc(pt *ProcessTree, givenPid int) error {
176180
NsPPid: nsppid, // status: nsppid == nsppid
177181
Uid: -1, // do not change the parent uid
178182
Gid: -1, // do not change the parent gid
179-
StartTimeNS: startTimeNs,
183+
StartTimeNS: procfsTimeStamp,
180184
},
181-
utils.NsSinceBootTimeToTime(uint64(start)), // try to be the first changelog entry
185+
traceetime.NsSinceEpochToTime(procfsTimeStamp), // try to be the first changelog entry
182186
)
183187

184188
// TODO: Update executable with information from /proc/<pid>/exe
@@ -222,7 +226,7 @@ func dealWithThread(pt *ProcessTree, givenPid int, givenTid int) error {
222226
}
223227

224228
// thread hash
225-
startTimeNs := utils.ClockTicksToNsSinceBootTime(start)
229+
startTimeNs := traceetime.ClockTicksToNsSinceBootTime(start)
226230
hash := utils.HashTaskID(uint32(pid), startTimeNs)
227231

228232
// update tree for the given thread
@@ -234,6 +238,8 @@ func dealWithThread(pt *ProcessTree, givenPid int, givenTid int) error {
234238
return nil
235239
}
236240

241+
procfsTimeStamp := uint64(pt.timeNormalizer.NormalizeTime(int(startTimeNs)))
242+
237243
threadInfo.SetFeedAt(
238244
TaskInfoFeed{
239245
Name: name, // command name (add "procfs+" to debug if needed)
@@ -245,9 +251,9 @@ func dealWithThread(pt *ProcessTree, givenPid int, givenTid int) error {
245251
NsPPid: nsppid, // status: nsppid == nsppid
246252
Uid: -1, // do not change the parent uid
247253
Gid: -1, // do not change the parent gid
248-
StartTimeNS: startTimeNs,
254+
StartTimeNS: procfsTimeStamp,
249255
},
250-
utils.NsSinceBootTimeToTime(uint64(start)), // try to be the first changelog entry
256+
traceetime.NsSinceEpochToTime(procfsTimeStamp), // try to be the first changelog entry
251257
)
252258

253259
// thread group leader (leader tid is the same as the thread's pid, so we can find it)

pkg/proctree/taskinfo.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"time"
66

77
ch "github.com/aquasecurity/tracee/pkg/changelog"
8-
"github.com/aquasecurity/tracee/pkg/utils"
8+
traceetime "github.com/aquasecurity/tracee/pkg/time"
99
)
1010

1111
// TaskInfoFeed allows external packages to set/get multiple values of a task at once.
@@ -360,40 +360,33 @@ func (ti *TaskInfo) GetGidAt(targetTime time.Time) int {
360360
return ti.gid.Get(targetTime)
361361
}
362362

363-
// GetStartTimeNS returns the startTimeNS of the task.
363+
// GetStartTimeNS returns the start time of the task in nanoseconds since epoch
364364
func (ti *TaskInfo) GetStartTimeNS() uint64 {
365365
ti.mutex.RLock()
366366
defer ti.mutex.RUnlock()
367367
return ti.startTimeNS
368368
}
369369

370-
// GetStartTime returns the "real" start time of the task.
370+
// GetStartTime returns the start time of the task.
371371
func (ti *TaskInfo) GetStartTime() time.Time {
372372
ti.mutex.RLock()
373373
defer ti.mutex.RUnlock()
374374

375-
// Returns a real "time" to be used for the task.
376-
duration := time.Duration(int64(ti.startTimeNS))
377-
bootTime := utils.GetBootTime()
378-
return bootTime.Add(duration)
375+
return traceetime.NsSinceEpochToTime(ti.startTimeNS)
379376
}
380377

381-
// GetExitTimeNS returns the exitTime of the task.
378+
// GetExitTimeNS returns the exitTime of the task in nanoseconds since epoch
382379
func (ti *TaskInfo) GetExitTimeNS() uint64 {
383380
ti.mutex.RLock()
384381
defer ti.mutex.RUnlock()
385382
return ti.exitTimeNS
386383
}
387384

388-
// GetExitTime returns the "real" exit time of the task.
385+
// GetExitTime returns the exit time of the task.
389386
func (ti *TaskInfo) GetExitTime() time.Time {
390387
ti.mutex.RLock()
391388
defer ti.mutex.RUnlock()
392-
393-
// Returns a real "time" to be used for the task.
394-
duration := time.Duration(int64(ti.exitTimeNS))
395-
bootTime := utils.GetBootTime()
396-
return bootTime.Add(duration)
389+
return traceetime.NsSinceEpochToTime(ti.exitTimeNS)
397390
}
398391

399392
// IsAlive returns true if the task has exited.
@@ -409,13 +402,13 @@ func (ti *TaskInfo) IsAliveAt(targetTime time.Time) bool {
409402
ti.mutex.RLock()
410403
defer ti.mutex.RUnlock()
411404
if ti.exitTimeNS != 0 {
412-
if targetTime.After(utils.NsSinceBootTimeToTime(ti.exitTimeNS)) {
405+
if targetTime.After(traceetime.NsSinceEpochToTime(ti.exitTimeNS)) {
413406
return false
414407
}
415408
}
416409
// If start time is not initialized it will count as 0 ns, meaning it will be before any
417410
// query time given.
418-
if targetTime.Before(utils.NsSinceBootTimeToTime(ti.startTimeNS)) {
411+
if targetTime.Before(traceetime.NsSinceEpochToTime(ti.startTimeNS)) {
419412
return false
420413
}
421414
return true

0 commit comments

Comments
 (0)