diff --git a/cmd/cws-instrumentation/subcommands/tracecmd/trace.go b/cmd/cws-instrumentation/subcommands/tracecmd/trace.go index f9fede9ce19104..4741281d341965 100644 --- a/cmd/cws-instrumentation/subcommands/tracecmd/trace.go +++ b/cmd/cws-instrumentation/subcommands/tracecmd/trace.go @@ -24,7 +24,7 @@ const ( // envDisableStats defines the environment variable to set to disable avoidable stats envDisableStats = "DD_CWS_INSTRUMENTATION_DISABLE_STATS" // envDisableProcScan defines the environment variable to disable procfs scan - // envDisableProcScan = "DD_CWS_INSTRUMENTATION_DISABLE_PROC_SCAN" + envDisableProcScan = "DD_CWS_INSTRUMENTATION_DISABLE_PROC_SCAN" // envProcScanRate defines the rate of the prodfs scan envProcScanRate = "DD_CWS_INSTRUMENTATION_PROC_SCAN_RATE" ) @@ -103,7 +103,7 @@ func Command() []*cobra.Command { traceCmd.Flags().Int32Var(¶ms.GID, gid, -1, "gid used to start the tracee") traceCmd.Flags().BoolVar(¶ms.Async, async, false, "enable async GRPC connection") traceCmd.Flags().BoolVar(¶ms.DisableStats, disableStats, os.Getenv(envDisableStats) != "", "disable use of stats") - traceCmd.Flags().BoolVar(¶ms.DisableProcScan, disableProcScan, true, "disable proc scan") + traceCmd.Flags().BoolVar(¶ms.DisableProcScan, disableProcScan, os.Getenv(envDisableProcScan) != "", "disable proc scan") traceCmd.Flags().StringVar(¶ms.ScanProcEvery, scanProcEvery, os.Getenv(envProcScanRate), "proc scan rate") traceCmd.AddCommand(selftestscmd.Command()...) diff --git a/pkg/security/probe/probe_ebpfless.go b/pkg/security/probe/probe_ebpfless.go index 5b54eb0d6bce9e..d0a6c07f6ca5d5 100644 --- a/pkg/security/probe/probe_ebpfless.go +++ b/pkg/security/probe/probe_ebpfless.go @@ -131,16 +131,20 @@ func (p *EBPFLessProbe) handleSyscallMsg(cl *client, syscallMsg *ebpfless.Syscal switch syscallMsg.Type { case ebpfless.SyscallTypeExec: event.Type = uint32(model.ExecEventType) - var source uint64 + + var entry *model.ProcessCacheEntry if syscallMsg.Exec.FromProcFS { - source = model.ProcessCacheEntryFromProcFS + entry = p.Resolvers.ProcessResolver.AddProcFSEntry( + process.CacheResolverKey{Pid: syscallMsg.PID, NSID: cl.nsID}, syscallMsg.Exec.PPID, syscallMsg.Exec.File.Filename, + syscallMsg.Exec.Args, syscallMsg.Exec.ArgsTruncated, syscallMsg.Exec.Envs, syscallMsg.Exec.EnvsTruncated, + syscallMsg.ContainerID, syscallMsg.Timestamp, syscallMsg.Exec.TTY) } else { - source = model.ProcessCacheEntryFromEvent + entry = p.Resolvers.ProcessResolver.AddExecEntry( + process.CacheResolverKey{Pid: syscallMsg.PID, NSID: cl.nsID}, syscallMsg.Exec.PPID, syscallMsg.Exec.File.Filename, + syscallMsg.Exec.Args, syscallMsg.Exec.ArgsTruncated, syscallMsg.Exec.Envs, syscallMsg.Exec.EnvsTruncated, + syscallMsg.ContainerID, syscallMsg.Timestamp, syscallMsg.Exec.TTY) } - entry := p.Resolvers.ProcessResolver.AddExecEntry( - process.CacheResolverKey{Pid: syscallMsg.PID, NSID: cl.nsID}, syscallMsg.Exec.PPID, syscallMsg.Exec.File.Filename, - syscallMsg.Exec.Args, syscallMsg.Exec.ArgsTruncated, syscallMsg.Exec.Envs, syscallMsg.Exec.EnvsTruncated, - syscallMsg.ContainerID, syscallMsg.Timestamp, syscallMsg.Exec.TTY, source) + if syscallMsg.Exec.Credentials != nil { entry.Credentials.UID = syscallMsg.Exec.Credentials.UID entry.Credentials.EUID = syscallMsg.Exec.Credentials.EUID diff --git a/pkg/security/probe/selftests/tester.go b/pkg/security/probe/selftests/tester.go index 29713d631c0d84..fe6bfb7e05fd9c 100644 --- a/pkg/security/probe/selftests/tester.go +++ b/pkg/security/probe/selftests/tester.go @@ -217,7 +217,7 @@ func (t *SelfTester) IsExpectedEvent(rule *rules.Rule, event eval.Event, _ *prob select { case t.eventChan <- selfTestEvent: default: - log.Errorf("self test channel is full, discarding event.\n") + log.Debug("self test channel is full, discarding event.") } return true diff --git a/pkg/security/probe/selftests/tester_linux.go b/pkg/security/probe/selftests/tester_linux.go index fb9283cfa0badc..7e2f8ab57d94ac 100644 --- a/pkg/security/probe/selftests/tester_linux.go +++ b/pkg/security/probe/selftests/tester_linux.go @@ -43,7 +43,7 @@ func NewSelfTester(cfg *config.RuntimeSecurityConfig, probe *probe.Probe) (*Self s := &SelfTester{ waitingForEvent: atomic.NewBool(cfg.EBPFLessEnabled), - eventChan: make(chan selfTestEvent, 10), + eventChan: make(chan selfTestEvent, len(selfTests)), selfTestRunning: make(chan time.Duration, 10), probe: probe, selfTests: selfTests, diff --git a/pkg/security/ptracer/cws.go b/pkg/security/ptracer/cws.go index f3bb3ddfffbe68..b53fec1a4cb25e 100644 --- a/pkg/security/ptracer/cws.go +++ b/pkg/security/ptracer/cws.go @@ -302,6 +302,9 @@ func StartCWSPtracer(args []string, envs []string, probeAddr string, opts Opts) go func() { defer wg.Done() + // introduce a delay before starting to scan procfs to let the tracer event first + time.Sleep(2 * time.Second) + scanProcfs(ctx, tracer.PID, send, every, logger) }() } diff --git a/pkg/security/resolvers/process/resolver_ebpfless.go b/pkg/security/resolvers/process/resolver_ebpfless.go index 496459e7ed87ee..2f81c573ca4f51 100644 --- a/pkg/security/resolvers/process/resolver_ebpfless.go +++ b/pkg/security/resolvers/process/resolver_ebpfless.go @@ -98,9 +98,10 @@ func (p *EBPFLessResolver) AddForkEntry(key CacheResolverKey, ppid uint32, ts ui return entry } -// AddExecEntry adds an entry to the local cache and returns the newly created entry -func (p *EBPFLessResolver) AddExecEntry(key CacheResolverKey, ppid uint32, file string, argv []string, argsTruncated bool, +// NewEntry returns a new entry +func (p *EBPFLessResolver) NewEntry(key CacheResolverKey, ppid uint32, file string, argv []string, argsTruncated bool, envs []string, envsTruncated bool, ctrID string, ts uint64, tty string, source uint64) *model.ProcessCacheEntry { + entry := p.processCacheEntryPool.Get() entry.PIDContext.Pid = key.Pid entry.PPid = ppid @@ -136,6 +137,14 @@ func (p *EBPFLessResolver) AddExecEntry(key CacheResolverKey, ppid uint32, file entry.ExecTime = time.Unix(0, int64(ts)) + return entry +} + +// AddExecEntry adds an entry to the local cache and returns the newly created entry +func (p *EBPFLessResolver) AddExecEntry(key CacheResolverKey, ppid uint32, file string, argv []string, argsTruncated bool, + envs []string, envsTruncated bool, ctrID string, ts uint64, tty string) *model.ProcessCacheEntry { + entry := p.NewEntry(key, ppid, file, argv, argsTruncated, envs, envsTruncated, ctrID, ts, tty, model.ProcessCacheEntryFromEvent) + p.Lock() defer p.Unlock() @@ -144,6 +153,27 @@ func (p *EBPFLessResolver) AddExecEntry(key CacheResolverKey, ppid uint32, file return entry } +// AddProcFSEntry add a procfs entry +func (p *EBPFLessResolver) AddProcFSEntry(key CacheResolverKey, ppid uint32, file string, argv []string, argsTruncated bool, + envs []string, envsTruncated bool, ctrID string, ts uint64, tty string) *model.ProcessCacheEntry { + entry := p.NewEntry(key, ppid, file, argv, argsTruncated, envs, envsTruncated, ctrID, ts, tty, model.ProcessCacheEntryFromProcFS) + + p.Lock() + defer p.Unlock() + + parentKey := CacheResolverKey{NSID: key.NSID, Pid: ppid} + if parent := p.entryCache[parentKey]; parent != nil { + if parent.Equals(entry) { + entry.SetParentOfForkChild(parent) + } else { + entry.SetAncestor(parent) + } + } + p.insertEntry(key, entry, p.entryCache[key]) + + return entry +} + func (p *EBPFLessResolver) insertEntry(key CacheResolverKey, entry, prev *model.ProcessCacheEntry) { p.entryCache[key] = entry entry.Retain()