Skip to content
165 changes: 138 additions & 27 deletions pkg/security/security_profile/activity_tree/activity_tree.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ import (

// ProtoDecodeActivityTree decodes an ActivityTree structure
func ProtoDecodeActivityTree(dest *ActivityTree, nodes []*adproto.ProcessActivityNode) {
getIDFromTag := func(imageTag string) uint64 {
return dest.GetOrInsertImageTag(imageTag)
}
for _, node := range nodes {
dest.ProcessNodes = append(dest.ProcessNodes, protoDecodeProcessActivityNode(dest, node))
dest.ProcessNodes = append(dest.ProcessNodes, protoDecodeProcessActivityNode(dest, node, getIDFromTag))
}
}

func protoDecodeProcessActivityNode(parent ProcessNodeParent, pan *adproto.ProcessActivityNode) *ProcessNode {
func protoDecodeProcessActivityNode(parent ProcessNodeParent, pan *adproto.ProcessActivityNode, getIDFromImageTag func(string) uint64) *ProcessNode {
if pan == nil {
return nil
}
Expand All @@ -50,7 +53,7 @@ func protoDecodeProcessActivityNode(parent ProcessNodeParent, pan *adproto.Proce
for tag, imageTagTimes := range pan.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
ppan.RecordWithTimestamps(tag, firstSeen, lastSeen)
ppan.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

Expand All @@ -59,51 +62,51 @@ func protoDecodeProcessActivityNode(parent ProcessNodeParent, pan *adproto.Proce
}

for _, child := range pan.Children {
ppan.Children = append(ppan.Children, protoDecodeProcessActivityNode(ppan, child))
ppan.Children = append(ppan.Children, protoDecodeProcessActivityNode(ppan, child, getIDFromImageTag))
}

for _, fan := range pan.Files {
protoDecodedFan := protoDecodeFileActivityNode(fan)
protoDecodedFan := protoDecodeFileActivityNode(fan, getIDFromImageTag)
ppan.Files[protoDecodedFan.Name] = protoDecodedFan
}

for _, dns := range pan.DnsNames {
protoDecodedDNS := protoDecodeDNSNode(dns)
protoDecodedDNS := protoDecodeDNSNode(dns, getIDFromImageTag)
if len(protoDecodedDNS.Requests) != 0 {
name := protoDecodedDNS.Requests[0].Question.Name
ppan.DNSNames[name] = protoDecodedDNS
}
}

for _, imds := range pan.ImdsEvents {
node := protoDecodeIMDSNode(imds)
node := protoDecodeIMDSNode(imds, getIDFromImageTag)
ppan.IMDSEvents[node.Event] = node
}

for _, socket := range pan.Sockets {
ppan.Sockets = append(ppan.Sockets, protoDecodeProtoSocket(socket))
ppan.Sockets = append(ppan.Sockets, protoDecodeProtoSocket(socket, getIDFromImageTag))
}

for _, sysc := range pan.SyscallNodes {
ppan.Syscalls = append(ppan.Syscalls, protoDecodeSyscallNode(sysc))
ppan.Syscalls = append(ppan.Syscalls, protoDecodeSyscallNode(sysc, getIDFromImageTag))
}

for _, networkDevice := range pan.NetworkDevices {
ppan.NetworkDevices[model.NetworkDeviceContext{
NetNS: networkDevice.Netns,
IfIndex: networkDevice.Ifindex,
IfName: networkDevice.Ifname,
}] = protoDecodeNetworkDevice(networkDevice)
}] = protoDecodeNetworkDevice(networkDevice, getIDFromImageTag)
}

for _, capNode := range pan.CapabilityNodes {
ppan.Capabilities = append(ppan.Capabilities, decodeProtoCapabilityNode(capNode))
ppan.Capabilities = append(ppan.Capabilities, decodeProtoCapabilityNode(capNode, getIDFromImageTag))
}

return ppan
}

func protoDecodeSyscallNode(sysc *adproto.SyscallNode) *SyscallNode {
func protoDecodeSyscallNode(sysc *adproto.SyscallNode, getIDFromImageTag func(imageTag string) uint64) *SyscallNode {
if sysc == nil {
return nil
}
Expand All @@ -118,7 +121,7 @@ func protoDecodeSyscallNode(sysc *adproto.SyscallNode) *SyscallNode {
for tag, imageTagTimes := range sysc.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
syscallNode.RecordWithTimestamps(tag, firstSeen, lastSeen)
syscallNode.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

Expand Down Expand Up @@ -223,6 +226,44 @@ func protoDecodeFileEvent(fi *adproto.FileInfo) *model.FileEvent {
return fe
}

func protoDecodeStoredFileEvent(fi *adproto.FileInfo) *storedFileEvent {
if fi == nil {
return nil
}

fe := &storedFileEvent{
FileFields: model.FileFields{
UID: fi.Uid,
User: fi.User,
GID: fi.Gid,
Group: fi.Group,
Mode: uint16(fi.Mode),
CTime: fi.Ctime,
MTime: fi.Mtime,
PathKey: model.PathKey{
MountID: fi.MountId,
Inode: fi.Inode,
},
InUpperLayer: fi.InUpperLayer,
},
PathnameStr: fi.Path,
BasenameStr: fi.Basename,
Filesystem: fi.Filesystem,
PkgName: fi.PackageName,
PkgVersion: fi.PackageVersion,
PkgEpoch: int(ptrOrZero(fi.PackageEpoch)),
PkgRelease: ptrOrZero(fi.PackageRelease),
PkgSrcVersion: fi.PackageSrcVersion,
PkgSrcEpoch: int(ptrOrZero(fi.PackageSrcEpoch)),
PkgSrcRelease: ptrOrZero(fi.PackageSrcRelease),
Hashes: make([]string, len(fi.Hashes)),
HashState: model.HashState(fi.HashState),
}
copy(fe.Hashes, fi.Hashes)

return fe
}

func ptrOrZero[T any](ptr *T) T {
if ptr != nil {
return *ptr
Expand All @@ -231,36 +272,39 @@ func ptrOrZero[T any](ptr *T) T {
return zero
}

func protoDecodeFileActivityNode(fan *adproto.FileActivityNode) *FileNode {
func protoDecodeFileActivityNode(fan *adproto.FileActivityNode, getIDFromImageTag func(string) uint64) *FileNode {
if fan == nil {
return nil
}

pfan := &FileNode{
MatchedRules: make([]*model.MatchedRule, 0, len(fan.MatchedRules)),
Name: fan.Name,
File: protoDecodeFileEvent(fan.File),
File: protoDecodeStoredFileEvent(fan.File),
GenerationType: NodeGenerationType(fan.GenerationType),
Open: protoDecodeOpenNode(fan.Open),
Children: make(map[string]*FileNode, len(fan.Children)),
Children: nil,
NodeBase: NewNodeBase(),
}

if fan.NodeBase != nil {
for tag, imageTagTimes := range fan.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
pfan.RecordWithTimestamps(tag, firstSeen, lastSeen)
pfan.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

for _, rule := range fan.MatchedRules {
pfan.MatchedRules = append(pfan.MatchedRules, protoDecodeProtoMatchedRule(rule))
}

for _, child := range fan.Children {
node := protoDecodeFileActivityNode(child)
pfan.Children[node.Name] = node
if len(fan.Children) > 0 {
pfan.Children = make(map[string]*FileNode, len(fan.Children))
for _, child := range fan.Children {
node := protoDecodeFileActivityNode(child, getIDFromImageTag)
pfan.Children[node.Name] = node
}
}

return pfan
Expand All @@ -282,7 +326,7 @@ func protoDecodeOpenNode(openNode *adproto.OpenNode) *OpenNode {
return pon
}

func protoDecodeDNSNode(dn *adproto.DNSNode) *DNSNode {
func protoDecodeDNSNode(dn *adproto.DNSNode, getIDFromImageTag func(string) uint64) *DNSNode {
if dn == nil {
return nil
}
Expand All @@ -297,7 +341,7 @@ func protoDecodeDNSNode(dn *adproto.DNSNode) *DNSNode {
for tag, imageTagTimes := range dn.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
pdn.RecordWithTimestamps(tag, firstSeen, lastSeen)
pdn.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

Expand All @@ -312,7 +356,7 @@ func protoDecodeDNSNode(dn *adproto.DNSNode) *DNSNode {
return pdn
}

func protoDecodeNetworkDevice(device *adproto.NetworkDeviceNode) *NetworkDeviceNode {
func protoDecodeNetworkDevice(device *adproto.NetworkDeviceNode, getIDFromImageTag func(string) uint64) *NetworkDeviceNode {
if device == nil {
return nil
}
Expand Down Expand Up @@ -343,7 +387,7 @@ func protoDecodeNetworkDevice(device *adproto.NetworkDeviceNode) *NetworkDeviceN
for tag, imageTagTimes := range flow.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
fn.RecordWithTimestamps(tag, firstSeen, lastSeen)
fn.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}
ndn.FlowNodes[f.GetFiveTuple()] = fn
Expand Down Expand Up @@ -380,7 +424,7 @@ func protoDecodeNetworkStats(stats *adproto.NetworkStats) model.NetworkStats {
return ns
}

func protoDecodeIMDSNode(in *adproto.IMDSNode) *IMDSNode {
func protoDecodeIMDSNode(in *adproto.IMDSNode, getIDFromImageTag func(string) uint64) *IMDSNode {
if in == nil {
return nil
}
Expand All @@ -395,7 +439,7 @@ func protoDecodeIMDSNode(in *adproto.IMDSNode) *IMDSNode {
for tag, imageTagTimes := range in.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
node.RecordWithTimestamps(tag, firstSeen, lastSeen)
node.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

Expand Down Expand Up @@ -466,7 +510,7 @@ func protoDecodeAWSSecurityCredentials(creds *adproto.AWSSecurityCredentials) mo
}
}

func protoDecodeProtoSocket(sn *adproto.SocketNode) *SocketNode {
func protoDecodeProtoSocket(sn *adproto.SocketNode, getIDFromImageTag func(string) uint64) *SocketNode {
if sn == nil {
return nil
}
Expand All @@ -489,7 +533,7 @@ func protoDecodeProtoSocket(sn *adproto.SocketNode) *SocketNode {
for tag, imageTagTimes := range bindNode.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
psn.RecordWithTimestamps(tag, firstSeen, lastSeen)
psn.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

Expand Down Expand Up @@ -524,7 +568,7 @@ func ProtoDecodeTimestamp(nanos uint64) time.Time {
return time.Unix(0, int64(nanos))
}

func decodeProtoCapabilityNode(pan *adproto.CapabilityNode) *CapabilityNode {
func decodeProtoCapabilityNode(pan *adproto.CapabilityNode, getIDFromImageTag func(string) uint64) *CapabilityNode {
if pan == nil {
return nil
}
Expand All @@ -540,7 +584,7 @@ func decodeProtoCapabilityNode(pan *adproto.CapabilityNode) *CapabilityNode {
for tag, imageTagTimes := range pan.NodeBase.Seen {
firstSeen := ProtoDecodeTimestamp(imageTagTimes.FirstSeen)
lastSeen := ProtoDecodeTimestamp(imageTagTimes.LastSeen)
capNode.RecordWithTimestamps(tag, firstSeen, lastSeen)
capNode.RecordWithTimestamps(getIDFromImageTag(tag), firstSeen, lastSeen)
}
}

Expand Down
Loading
Loading