@@ -29,6 +29,7 @@ import (
29
29
"go.uber.org/atomic"
30
30
31
31
"github.com/DataDog/datadog-agent/pkg/process/procutil"
32
+ "github.com/DataDog/datadog-agent/pkg/security/ebpf"
32
33
"github.com/DataDog/datadog-agent/pkg/security/metrics"
33
34
"github.com/DataDog/datadog-agent/pkg/security/probe/config"
34
35
"github.com/DataDog/datadog-agent/pkg/security/probe/managerhelper"
@@ -77,9 +78,9 @@ type EBPFResolver struct {
77
78
pathResolver spath.ResolverInterface
78
79
envVarsResolver * envvars.Resolver
79
80
80
- inodeFileMap * lib .Map
81
- procCacheMap * lib .Map
82
- pidCacheMap * lib .Map
81
+ inodeFileMap ebpf .Map
82
+ procCacheMap ebpf .Map
83
+ pidCacheMap ebpf .Map
83
84
opts ResolverOpts
84
85
85
86
// stats
@@ -564,15 +565,16 @@ func (p *EBPFResolver) RetrieveFileFieldsFromProcfs(filename string) (*model.Fil
564
565
return & fileFields , nil
565
566
}
566
567
567
- func (p * EBPFResolver ) insertEntry (entry , prev * model.ProcessCacheEntry , source uint64 ) {
568
+ func (p * EBPFResolver ) insertEntry (entry * model.ProcessCacheEntry , source uint64 ) {
568
569
entry .Source = source
569
- p .entryCache [entry .Pid ] = entry
570
- entry .Retain ()
571
570
572
- if prev != nil {
571
+ if prev := p . entryCache [ entry . Pid ]; prev != nil {
573
572
prev .Release ()
574
573
}
575
574
575
+ p .entryCache [entry .Pid ] = entry
576
+ entry .Retain ()
577
+
576
578
if p .cgroupResolver != nil && entry .CGroup .CGroupID != "" {
577
579
// add the new PID in the right cgroup_resolver bucket
578
580
p .cgroupResolver .AddPID (entry )
@@ -591,7 +593,6 @@ func (p *EBPFResolver) insertEntry(entry, prev *model.ProcessCacheEntry, source
591
593
}
592
594
593
595
func (p * EBPFResolver ) insertForkEntry (entry * model.ProcessCacheEntry , inode uint64 , source uint64 , newEntryCb func (* model.ProcessCacheEntry , error )) {
594
-
595
596
if entry .Pid == 0 {
596
597
return
597
598
}
@@ -619,7 +620,7 @@ func (p *EBPFResolver) insertForkEntry(entry *model.ProcessCacheEntry, inode uin
619
620
}
620
621
}
621
622
622
- p .insertEntry (entry , prev , source )
623
+ p .insertEntry (entry , source )
623
624
}
624
625
625
626
func (p * EBPFResolver ) insertExecEntry (entry * model.ProcessCacheEntry , inode uint64 , source uint64 ) {
@@ -634,7 +635,7 @@ func (p *EBPFResolver) insertExecEntry(entry *model.ProcessCacheEntry, inode uin
634
635
p .inodeErrStats .Inc ()
635
636
}
636
637
637
- // check exec bomb
638
+ // check exec bomb, keep the prev entry and update it
638
639
if prev .Equals (entry ) {
639
640
prev .ApplyExecTimeOf (entry )
640
641
return
@@ -644,7 +645,7 @@ func (p *EBPFResolver) insertExecEntry(entry *model.ProcessCacheEntry, inode uin
644
645
entry .IsParentMissing = true
645
646
}
646
647
647
- p .insertEntry (entry , prev , source )
648
+ p .insertEntry (entry , source )
648
649
}
649
650
650
651
func (p * EBPFResolver ) deleteEntry (pid uint32 , exitTime time.Time ) {
@@ -706,7 +707,7 @@ func (p *EBPFResolver) resolve(pid, tid uint32, inode uint64, useProcFS bool, ne
706
707
707
708
if p .procFallbackLimiter .Allow (pid ) {
708
709
// fallback to /proc, the in-kernel LRU may have deleted the entry
709
- if entry := p .resolveFromProcfs (pid , procResolveMaxDepth , newEntryCb ); entry != nil {
710
+ if entry := p .resolveFromProcfs (pid , inode , procResolveMaxDepth , newEntryCb ); entry != nil {
710
711
p .hitsStats [metrics .ProcFSTag ].Inc ()
711
712
return entry
712
713
}
@@ -950,13 +951,13 @@ func (p *EBPFResolver) resolveFromKernelMaps(pid, tid uint32, inode uint64, newE
950
951
}
951
952
952
953
// ResolveFromProcfs resolves the entry from procfs
953
- func (p * EBPFResolver ) ResolveFromProcfs (pid uint32 , newEntryCb func (* model.ProcessCacheEntry , error )) * model.ProcessCacheEntry {
954
+ func (p * EBPFResolver ) ResolveFromProcfs (pid uint32 , inode uint64 , newEntryCb func (* model.ProcessCacheEntry , error )) * model.ProcessCacheEntry {
954
955
p .Lock ()
955
956
defer p .Unlock ()
956
- return p .resolveFromProcfs (pid , procResolveMaxDepth , newEntryCb )
957
+ return p .resolveFromProcfs (pid , inode , procResolveMaxDepth , newEntryCb )
957
958
}
958
959
959
- func (p * EBPFResolver ) resolveFromProcfs (pid uint32 , maxDepth int , newEntryCb func (* model.ProcessCacheEntry , error )) * model.ProcessCacheEntry {
960
+ func (p * EBPFResolver ) resolveFromProcfs (pid uint32 , inode uint64 , maxDepth int , newEntryCb func (* model.ProcessCacheEntry , error )) * model.ProcessCacheEntry {
960
961
if maxDepth < 1 {
961
962
seclog .Tracef ("max depth reached during procfs resolution: %d" , pid )
962
963
return nil
@@ -986,10 +987,12 @@ func (p *EBPFResolver) resolveFromProcfs(pid uint32, maxDepth int, newEntryCb fu
986
987
987
988
ppid := uint32 (filledProc .Ppid )
988
989
if ppid != 0 && p .entryCache [ppid ] == nil {
989
- p .resolveFromProcfs (ppid , maxDepth - 1 , newEntryCb )
990
+ // do not use the inode from the pid context on the parent
991
+ // it may be a different process
992
+ p .resolveFromProcfs (ppid , 0 , maxDepth - 1 , newEntryCb )
990
993
}
991
994
992
- return p .newEntryFromProcfsAndSyncKernelMaps (proc , filledProc , model .ProcessCacheEntryFromProcFS , newEntryCb )
995
+ return p .newEntryFromProcfsAndSyncKernelMaps (proc , filledProc , inode , model .ProcessCacheEntryFromProcFS , newEntryCb )
993
996
}
994
997
995
998
// SetProcessArgs set arguments to cache entry
@@ -1284,7 +1287,7 @@ func (p *EBPFResolver) SyncCache(proc *process.Process) {
1284
1287
return
1285
1288
}
1286
1289
1287
- p .newEntryFromProcfsAndSyncKernelMaps (proc , filledProc , model .ProcessCacheEntryFromSnapshot , nil )
1290
+ p .newEntryFromProcfsAndSyncKernelMaps (proc , filledProc , 0 , model .ProcessCacheEntryFromSnapshot , nil )
1288
1291
}
1289
1292
1290
1293
func (p * EBPFResolver ) setAncestor (pce * model.ProcessCacheEntry ) {
@@ -1294,20 +1297,52 @@ func (p *EBPFResolver) setAncestor(pce *model.ProcessCacheEntry) {
1294
1297
}
1295
1298
}
1296
1299
1300
+ func (p * EBPFResolver ) syncKernelMaps (entry * model.ProcessCacheEntry ) {
1301
+ bootTime := p .timeResolver .GetBootTime ()
1302
+
1303
+ // insert new entry in kernel maps
1304
+ procCacheEntryB := make ([]byte , 248 )
1305
+ _ , err := entry .Process .MarshalProcCache (procCacheEntryB , bootTime )
1306
+ if err != nil {
1307
+ seclog .Errorf ("couldn't marshal proc_cache entry: %s" , err )
1308
+ } else {
1309
+ if err = p .procCacheMap .Put (entry .Cookie , procCacheEntryB ); err != nil {
1310
+ seclog .Errorf ("couldn't push proc_cache entry to kernel space: %s" , err )
1311
+ }
1312
+ }
1313
+ pidCacheEntryB := make ([]byte , 88 )
1314
+ _ , err = entry .Process .MarshalPidCache (pidCacheEntryB , bootTime )
1315
+ if err != nil {
1316
+ seclog .Errorf ("couldn't marshal pid_cache entry: %s" , err )
1317
+ } else {
1318
+ if err = p .pidCacheMap .Put (entry .PIDContext .Pid , pidCacheEntryB ); err != nil {
1319
+ seclog .Errorf ("couldn't push pid_cache entry to kernel space: %s" , err )
1320
+ }
1321
+ }
1322
+ }
1323
+
1297
1324
// newEntryFromProcfsAndSyncKernelMaps snapshots /proc for the provided pid and sync the kernel maps
1298
- func (p * EBPFResolver ) newEntryFromProcfsAndSyncKernelMaps (proc * process.Process , filledProc * utils.FilledProcess , source uint64 , newEntryCb func (* model.ProcessCacheEntry , error )) * model.ProcessCacheEntry {
1325
+ func (p * EBPFResolver ) newEntryFromProcfsAndSyncKernelMaps (proc * process.Process , filledProc * utils.FilledProcess , inode uint64 , source uint64 , newEntryCb func (* model.ProcessCacheEntry , error )) * model.ProcessCacheEntry {
1299
1326
pid := uint32 (proc .Pid )
1300
1327
1301
1328
entry := p .NewProcessCacheEntry (model.PIDContext {Pid : pid , Tid : pid })
1302
1329
1303
1330
// update the cache entry
1304
1331
if err := p .enrichEventFromProcfs (entry , proc , filledProc ); err != nil {
1305
- entry .Release ()
1306
-
1307
1332
seclog .Trace (err )
1308
1333
return nil
1309
1334
}
1310
1335
1336
+ // use the inode from the pid context if set so that we don't propagate a potentially wrong inode
1337
+ if inode != 0 {
1338
+ if entry .FileEvent .Inode != inode {
1339
+ seclog .Errorf ("inode mismatch, using inode from pid context %d: %d != %d" , pid , entry .FileEvent .Inode , inode )
1340
+
1341
+ entry .FileEvent .Inode = inode
1342
+ entry .IsParentMissing = true
1343
+ }
1344
+ }
1345
+
1311
1346
entry .IsKworker = filledProc .Ppid == 0 && filledProc .Pid != 1
1312
1347
1313
1348
parent := p .entryCache [entry .PPid ]
@@ -1325,29 +1360,9 @@ func (p *EBPFResolver) newEntryFromProcfsAndSyncKernelMaps(proc *process.Process
1325
1360
seclog .Debugf ("unable to set the type of process, not pid 1, no parent in cache: %+v" , entry )
1326
1361
}
1327
1362
1328
- p .insertEntry (entry , p . entryCache [ pid ], source )
1363
+ p .insertEntry (entry , source )
1329
1364
1330
- bootTime := p .timeResolver .GetBootTime ()
1331
-
1332
- // insert new entry in kernel maps
1333
- procCacheEntryB := make ([]byte , 248 )
1334
- _ , err := entry .Process .MarshalProcCache (procCacheEntryB , bootTime )
1335
- if err != nil {
1336
- seclog .Errorf ("couldn't marshal proc_cache entry: %s" , err )
1337
- } else {
1338
- if err = p .procCacheMap .Put (entry .Cookie , procCacheEntryB ); err != nil {
1339
- seclog .Errorf ("couldn't push proc_cache entry to kernel space: %s" , err )
1340
- }
1341
- }
1342
- pidCacheEntryB := make ([]byte , 88 )
1343
- _ , err = entry .Process .MarshalPidCache (pidCacheEntryB , bootTime )
1344
- if err != nil {
1345
- seclog .Errorf ("couldn't marshal pid_cache entry: %s" , err )
1346
- } else {
1347
- if err = p .pidCacheMap .Put (pid , pidCacheEntryB ); err != nil {
1348
- seclog .Errorf ("couldn't push pid_cache entry to kernel space: %s" , err )
1349
- }
1350
- }
1365
+ p .syncKernelMaps (entry )
1351
1366
1352
1367
seclog .Tracef ("New process cache entry added: %s %s %d/%d" , entry .Comm , entry .FileEvent .PathnameStr , pid , entry .FileEvent .Inode )
1353
1368
0 commit comments