Skip to content

Commit

Permalink
Add PCE NSID resolution for ptrace events
Browse files Browse the repository at this point in the history
  • Loading branch information
spikat committed Dec 20, 2024
1 parent c7d1bc8 commit 6fd7cf0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
17 changes: 16 additions & 1 deletion pkg/security/probe/field_handlers_ebpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/DataDog/datadog-agent/pkg/security/resolvers"
sprocess "github.com/DataDog/datadog-agent/pkg/security/resolvers/process"
"github.com/DataDog/datadog-agent/pkg/security/secl/containerutils"
"github.com/DataDog/datadog-agent/pkg/security/utils"

"github.com/DataDog/datadog-agent/pkg/security/secl/args"
"github.com/DataDog/datadog-agent/pkg/security/secl/model"
Expand Down Expand Up @@ -230,7 +231,7 @@ func (fh *EBPFFieldHandlers) ResolveRights(_ *model.Event, e *model.FileFields)
return int(e.Mode) & (syscall.S_ISUID | syscall.S_ISGID | syscall.S_ISVTX | syscall.S_IRWXU | syscall.S_IRWXG | syscall.S_IRWXO)
}

// ResolveChownUID resolves the ResolveProcessCacheEntry id of a chown event to a username
// ResolveChownUID resolves the user id of a chown event to a username
func (fh *EBPFFieldHandlers) ResolveChownUID(ev *model.Event, e *model.ChownEvent) string {
if len(e.User) == 0 {
e.User, _ = fh.resolvers.UserGroupResolver.ResolveUser(int(e.UID), ev.ContainerContext.ContainerID)
Expand Down Expand Up @@ -731,3 +732,17 @@ func (fh *EBPFFieldHandlers) ResolveOnDemandArg4Str(_ *model.Event, e *model.OnD
func (fh *EBPFFieldHandlers) ResolveOnDemandArg4Uint(_ *model.Event, e *model.OnDemandEvent) int {
return int(binary.NativeEndian.Uint64(e.Data[192 : 192+8]))
}

// ResolveProcessNSID resolves the process namespace ID
func (fh *EBPFFieldHandlers) ResolveProcessNSID(e *model.Event) (uint64, error) {
if e.ProcessCacheEntry.Process.NSID != 0 {
return e.ProcessCacheEntry.Process.NSID, nil
}

nsid, err := utils.GetProcessPidNamespace(e.ProcessCacheEntry.Process.Pid)
if err != nil {
return 0, err
}
e.ProcessCacheEntry.Process.NSID = nsid
return nsid, nil
}
9 changes: 8 additions & 1 deletion pkg/security/probe/probe_ebpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,14 @@ func (p *EBPFProbe) handleEvent(CPU int, data []byte) {
if containerID == "" && event.PTrace.Request != unix.PTRACE_ATTACH {
pidToResolve = event.PTrace.NSPID
} else {
pid, err := utils.TryToResolveTraceePid(event.ProcessContext.Process.Pid, event.PTrace.NSPID)
nsid, err := p.fieldHandlers.ResolveProcessNSID(event)
if err != nil {
seclog.Debugf("PTrace NSID resolution error for process %s in container %s: %v",
event.ProcessContext.Process.FileEvent.PathnameStr, containerID, err)
return
}

pid, err := utils.TryToResolveTraceePid(event.ProcessContext.Process.Pid, nsid, event.PTrace.NSPID)
if err != nil {
seclog.Debugf("PTrace tracee resolution error for process %s in container %s: %v",
event.ProcessContext.Process.FileEvent.PathnameStr, containerID, err)
Expand Down
12 changes: 2 additions & 10 deletions pkg/security/utils/proc_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,22 +567,14 @@ var isNsPidAvailable = sync.OnceValue(func() bool {
})

// TryToResolveTraceePid tries to resolve and returnt the HOST tracee PID, given the HOST tracer PID and the namespaced tracee PID.
func TryToResolveTraceePid(hostTracerPID, NsTraceePid uint32) (uint32, error) {
func TryToResolveTraceePid(hostTracerPID uint32, tracerNSID uint64, NsTraceePid uint32) (uint32, error) {
// Look if the NSpid status field is available or not (it should be, except for Centos7).
if isNsPidAvailable() {
/*
If it's available, we will search for an host pid having the same PID namespace as the
tracer, and having the corresponding NS PID in its status field
*/

// 1. get the pid namespace of the tracer
ns, err := GetProcessPidNamespace(hostTracerPID)
if err != nil {
return 0, fmt.Errorf("Failed to resolve PID namespace: %v", err)
}

// 2. find the host pid matching the arg pid with he tracer namespace
pid, err := FindPidNamespace(NsTraceePid, ns)
pid, err := FindPidNamespace(NsTraceePid, tracerNSID)
if err != nil {
return 0, fmt.Errorf("Failed to resolve tracee PID namespace: %v", err)
}
Expand Down

0 comments on commit 6fd7cf0

Please sign in to comment.