diff --git a/cmd/tarian_detector/k8s.go b/cmd/tarian_detector/k8s.go deleted file mode 100644 index 6b1c82a..0000000 --- a/cmd/tarian_detector/k8s.go +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Authors of Tarian & the Organization created Tarian - -package main - -import ( - "github.com/intelops/tarian-detector/pkg/err" - "github.com/intelops/tarian-detector/pkg/k8s" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" -) - -var k8sErr = err.New("main.k8s") - -const ( - // NotInClusterErrMsg is an error message for when the Kubernetes environment is not detected. - NotInClusterErrMsg string = "Kubernetes environment not detected. The Kubernetes context has been disabled." -) - -// K8Watcher initializes and returns a new PodWatcher for the current Kubernetes cluster. -func K8Watcher() (*k8s.PodWatcher, error) { - // Get the in-cluster configuration. - config, err := rest.InClusterConfig() - if err != nil { - return nil, k8sErr.Throwf("%v. %s", err, NotInClusterErrMsg) - } - - // Create a new Kubernetes client set. - clientSet := kubernetes.NewForConfigOrDie(config) - - // Return a new PodWatcher for the current Kubernetes cluster. - return k8s.NewPodWatcher(clientSet) -} - -// K8sContext holds the Kubernetes context for a given process. -type K8sContext struct { - // pod information - PodUid string - PodName string - PodGeneratedName string - PodKind string - PodAPIVersion string - PodLabels map[string]string - PodAnnotations map[string]string - - // container information - ContainerID string - - // namespace information - Namespace string -} - -// GetK8sContext returns the Kubernetes context for a given process ID. -func GetK8sContext(watcher *k8s.PodWatcher, processId uint32) (K8sContext, error) { - k8sCtx := K8sContext{} - - if watcher == nil { - return k8sCtx, k8sErr.Throw("kubernetes watcher is not enabled. This might not be the kubernetes environment.") - } - - // Get the container ID for the given process ID. - containerId, err := k8s.ProcsContainerID(processId) - if err != nil { - return k8sCtx, k8sErr.Throwf("%v", err) - } - - // If the container ID is missing, return an error. - if len(containerId) == 0 { - return k8sCtx, k8sErr.Throw("missing container id") - } - - // Find the pod associated with the container ID. - pod, err := watcher.FindPod(containerId) - if err != nil { - return k8sCtx, k8sErr.Throwf("%v: unable to find the pod associated with the container ID: %s", err, containerId) - } - - // Set the pod information in the Kubernetes context. - k8sCtx.PodUid = string(pod.ObjectMeta.UID) - k8sCtx.PodName = pod.ObjectMeta.Name - k8sCtx.PodGeneratedName = pod.ObjectMeta.GenerateName - k8sCtx.PodKind = pod.Kind - k8sCtx.PodAPIVersion = pod.APIVersion - k8sCtx.PodLabels = pod.ObjectMeta.Labels - k8sCtx.PodAnnotations = pod.ObjectMeta.Annotations - - // Set the container information in the Kubernetes context. - k8sCtx.ContainerID = containerId - - // Set the namespace information in the Kubernetes context. - k8sCtx.Namespace = pod.ObjectMeta.Namespace - - return k8sCtx, nil -} diff --git a/cmd/tarian_detector/main.go b/cmd/tarian_detector/main.go index 28872eb..e732bb5 100644 --- a/cmd/tarian_detector/main.go +++ b/cmd/tarian_detector/main.go @@ -12,8 +12,15 @@ import ( "time" "github.com/intelops/tarian-detector/pkg/detector" - "github.com/intelops/tarian-detector/pkg/utils" + "github.com/intelops/tarian-detector/pkg/k8s" "github.com/intelops/tarian-detector/tarian" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +const ( + // NotInClusterErrMsg is an error message for when the Kubernetes environment is not detected. + NotInClusterErrMsg string = "Kubernetes environment not detected. The Kubernetes context has been disabled." ) // main is the entry point of the application. It sets up the necessary components @@ -27,8 +34,6 @@ func main() { watcher, err := K8Watcher() if err != nil { log.Print(err) - } else { - watcher.Start() } // Initialize Tarian eBPF module @@ -48,6 +53,7 @@ func main() { // Add the eBPF module to the detectors eventsDetector.Add(tarianDetector) + eventsDetector.SetPodWatcher(watcher) // Start the event detectors and defer their closure err = eventsDetector.Start() @@ -86,17 +92,7 @@ func main() { continue } - // Retrieve Kubernetes context based on host process ID - k8sCtx, err := GetK8sContext(watcher, e["hostProcessId"].(uint32)) - if err != nil { - // Log the error as the Kubernetes context if an error is - e["kubernetes"] = err.Error() - } else { - // Set the Kubernetes context if no error is encountered - e["kubernetes"] = k8sCtx - } - - utils.PrintEvent(e, eventsDetector.GetTotalCount()) + fmt.Println(e) } }() @@ -105,3 +101,18 @@ func main() { time.Sleep(1 * time.Minute) } } + +// K8Watcher initializes and returns a new PodWatcher for the current Kubernetes cluster. +func K8Watcher() (*k8s.PodWatcher, error) { + // Get the in-cluster configuration. + config, err := rest.InClusterConfig() + if err != nil { + return nil, fmt.Errorf("%v. %s", err, NotInClusterErrMsg) + } + + // Create a new Kubernetes client set. + clientSet := kubernetes.NewForConfigOrDie(config) + + // Return a new PodWatcher for the current Kubernetes cluster. + return k8s.NewPodWatcher(clientSet) +} diff --git a/go.mod b/go.mod index 6606926..73ad650 100644 --- a/go.mod +++ b/go.mod @@ -28,11 +28,11 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/protobuf v1.33.0 // indirect @@ -40,7 +40,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20240403164606-bc84c2ddaf99 // indirect + k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 // indirect k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/go.sum b/go.sum index 6c3bfe5..0b40cbf 100644 --- a/go.sum +++ b/go.sum @@ -73,6 +73,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -81,6 +83,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -93,6 +97,8 @@ golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -105,6 +111,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -131,6 +138,8 @@ k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240403164606-bc84c2ddaf99 h1:w6nThEmGo9zcL+xH1Tu6pjxJ3K1jXFW+V0u4peqN8ks= k8s.io/kube-openapi v0.0.0-20240403164606-bc84c2ddaf99/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 h1:SbdLaI6mM6ffDSJCadEaD4IkuPzepLDGlkd2xV0t1uA= +k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/pkg/detector/detector.go b/pkg/detector/detector.go index 2b0c751..770ed23 100644 --- a/pkg/detector/detector.go +++ b/pkg/detector/detector.go @@ -6,6 +6,7 @@ package detector import ( "github.com/intelops/tarian-detector/pkg/err" "github.com/intelops/tarian-detector/pkg/eventparser" + "github.com/intelops/tarian-detector/pkg/k8s" ) var detectorErr = err.New("detector.detector") @@ -32,6 +33,7 @@ type EventsDetector struct { totalRecordsCount int // totalRecordsCount is the total count of records. totalDetectors int // totalDetectors is the total number of detectors. probeRecordsCount map[string]int // probeRecordsCount is a map of probe names to their respective counts + watcher *k8s.PodWatcher // watcher is a pointer to a PodWatcher instance } // NewEventsDetector creates a new EventsDetector instance @@ -79,6 +81,11 @@ func (t *EventsDetector) GetProbeCount() map[string]int { return t.probeRecordsCount } +// SetPodWatcher sets the pod watcher. +func (t *EventsDetector) SetPodWatcher(w *k8s.PodWatcher) { + t.watcher = w +} + // Start initiates the event detection process. It iterates over the map of each detector, // starts a goroutine for each map. These goroutines continuously read events from the maps // and send them to the event queue. If the detector is closed, the goroutines stop reading events. @@ -112,6 +119,10 @@ func (t *EventsDetector) Start() error { t.started = true + if t.watcher != nil { + t.watcher.Start() + } + return nil } @@ -131,23 +142,20 @@ func (t *EventsDetector) Close() error { // ReadAsInterface reads a byte array from the event queue, parses it, and increments the total count. // It also checks for the presence of an event ID and increments the probe count if found. -func (t *EventsDetector) ReadAsInterface() (map[string]any, error) { +func (t *EventsDetector) ReadAsInterface() (eventparser.TarianDetectorEvent, error) { eventparser.LoadTarianEvents() r := <-t.eventQueue if r.err != nil { - return map[string]any{}, detectorErr.Throwf("%v", r.err) + return eventparser.TarianDetectorEvent{}, detectorErr.Throwf("%v", r.err) } t.incrementTotalCount() - data, err := eventparser.ParseByteArray(r.eventData) + data, err := eventparser.ParseByteArray(t.watcher, r.eventData) if err != nil { return data, detectorErr.Throwf("%v", err) } - probe, ok := data["eventId"] - if ok { - t.probeCount(probe.(string)) - } + t.probeCount(data.EventId) return data, nil } diff --git a/pkg/eBPF/handler.go b/pkg/eBPF/handler.go index 226b330..ae9efac 100644 --- a/pkg/eBPF/handler.go +++ b/pkg/eBPF/handler.go @@ -12,9 +12,10 @@ var handlerErr = err.New("ebpf.handler") // Handler represents an eBPF handler. It includes the name of the handler, a list of map readers, and a list of probe links. type Handler struct { - name string // Name of the handler - mapReaders []any // List of map readers - probeLinks []link.Link // List of probe links + name string // Name of the handler + mapReaders []any // List of map readers + probeLinks []link.Link // List of probe links + countPrograms int } // NewHandler creates a new eBPF handler with the given name. @@ -43,7 +44,7 @@ func (h *Handler) ReadAsInterface() ([]func() ([]byte, error), error) { // Count returns the number of probe links in the handler. func (h *Handler) Count() int { - return len(h.probeLinks) + return h.countPrograms } // Close detaches probes and closes map readers. diff --git a/pkg/eBPF/handler_test.go b/pkg/eBPF/handler_test.go index 962a326..cee4a29 100644 --- a/pkg/eBPF/handler_test.go +++ b/pkg/eBPF/handler_test.go @@ -147,9 +147,10 @@ func TestHandler_Count(t *testing.T) { l, _ := link.Kprobe("vprintk", prog, nil) type fields struct { - name string - mapReaders []any - probeLinks []link.Link + name string + mapReaders []any + probeLinks []link.Link + countPrograms int } tests := []struct { name string @@ -159,18 +160,20 @@ func TestHandler_Count(t *testing.T) { { name: "valid values", fields: fields{ - name: "test", - mapReaders: make([]any, 0), - probeLinks: make([]link.Link, 0), + name: "test", + mapReaders: make([]any, 0), + probeLinks: make([]link.Link, 0), + countPrograms: 0, }, want: 0, }, { name: "add an item to the probelink", fields: fields{ - name: "test", - mapReaders: nil, - probeLinks: []link.Link{l, l, l}, + name: "test", + mapReaders: nil, + probeLinks: []link.Link{l, l, l}, + countPrograms: 3, }, want: 3, }, @@ -179,9 +182,10 @@ func TestHandler_Count(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := &Handler{ - name: tt.fields.name, - mapReaders: tt.fields.mapReaders, - probeLinks: tt.fields.probeLinks, + name: tt.fields.name, + mapReaders: tt.fields.mapReaders, + probeLinks: tt.fields.probeLinks, + countPrograms: tt.fields.countPrograms, } if got := h.Count(); got != tt.want { t.Errorf("Handler.Count() = %v, want %v", got, tt.want) diff --git a/pkg/eBPF/module.go b/pkg/eBPF/module.go index cd30bc0..9e2bd69 100644 --- a/pkg/eBPF/module.go +++ b/pkg/eBPF/module.go @@ -59,6 +59,7 @@ func (m *Module) Prepare() (*Handler, error) { handler.AddMapReaders(mrs) } + handler.countPrograms = m.Count() return handler, nil } @@ -83,6 +84,20 @@ func (m *Module) Attach(handler *Handler) error { return nil } +// Count returns the number of programs that are set to be attached. +// +// Programs that are not set to be attached are not included in the count. +func (m *Module) Count() int { + count := 0 + for _, p := range m.programs { + if p.shouldAttach { + count++ + } + } + + return count +} + // GetName returns the name of the Module. func (m *Module) GetName() string { return m.name diff --git a/pkg/eventparser/context.go b/pkg/eventparser/context.go deleted file mode 100644 index a09e305..0000000 --- a/pkg/eventparser/context.go +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024 Authors of Tarian & the Organization created Tarian - -package eventparser - -// TarianMetaData represents the metadata associated with a event being received from the kernel. -// The first 755 bytes received from kernel in form of []byte are of type TarianMetaData -type TarianMetaData struct { - MetaData struct { - Event int32 // Event identifier - Nparams uint8 // Number of parameters - Syscall int32 // System call i - Ts uint64 // Timestamp - Processor uint16 // Processor number - Task struct { // Task information - StartTime uint64 // Start time - HostPid uint32 // Host process ID - HostTgid uint32 // Host thread group ID - HostPpid uint32 // Host parent process ID - Pid uint32 // Process ID of a namespace - Tgid uint32 // Thread group ID of a namespace - Ppid uint32 // Parent process ID of a namespace - Uid uint32 // User ID - Gid uint32 // Group ID - CgroupId uint64 // Cgroup ID - MountNsId uint64 // Mount namespace ID - PidNsId uint64 // Process namespace ID - ExecId uint64 // Execution ID - ParentExecId uint64 // Parent execution ID - Comm [16]uint8 // Command - Cwd [256]uint8 // Current working directory - } - } - SystemInfo struct { - Sysname [65]uint8 // System name - Nodename [65]uint8 // Node name - Release [65]uint8 // Release - Version [65]uint8 // Version - Machine [65]uint8 // Machine - Domainname [65]uint8 // Domain name - } -} - -// TarianParamType represents the type of Tarian parameter -type TarianParamType uint32 - -const ( - TDT_NONE TarianParamType = 0 // TDT_NONE represents the absence of a Tarian parameter - TDT_U8 TarianParamType = 1 // TDT_U8 represents an 8-bit unsigned integer Tarian parameter - TDT_U16 TarianParamType = 2 // TDT_U16 represents a 16-bit unsigned integer Tarian parameter - TDT_U32 TarianParamType = 3 // TDT_U32 represents a 32-bit unsigned integer Tarian parameter - TDT_U64 TarianParamType = 4 // TDT_U64 represents a 64-bit unsigned integer Tarian parameter - TDT_S8 TarianParamType = 5 // TDT_S8 represents an 8-bit signed integer Tarian parameter - TDT_S16 TarianParamType = 6 // TDT_S16 represents a 16-bit signed integer Tarian parameter - TDT_S32 TarianParamType = 7 // TDT_S32 represents a 32-bit signed integer Tarian parameter - TDT_S64 TarianParamType = 8 // TDT_S64 represents a 64-bit signed integer Tarian parameter - TDT_IPV6 TarianParamType = 9 // TDT_IPV6 represents an IPv6 Tarian parameter - TDT_STR TarianParamType = 10 // TDT_STR represents a string Tarian parameter - TDT_STR_ARR TarianParamType = 11 // TDT_STR_ARR represents an array of strings Tarian parameter - TDT_BYTE_ARR TarianParamType = 12 // TDT_BYTE_ARR represents an array of bytes Tarian parameter - TDT_IOVEC_ARR TarianParamType = 15 // TDT_IOVEC_ARR represents an array of I/O vectors Tarian parameter - TDT_SOCKADDR TarianParamType = 14 // TDT_SOCKADDR represents a socket address Tarian parameter -) - -// TarianEventsE represents the type for Tarian events enumeration. -type TarianEventsE int - -const ( - TDE_SYSCALL_EXECVE_E TarianEventsE = 2 // TDE_SYSCALL_EXECVE_E represents the start of an execve syscall - TDE_SYSCALL_EXECVE_R TarianEventsE = 3 // TDE_SYSCALL_EXECVE_R represents the return of an execve syscall - - TDE_SYSCALL_EXECVEAT_E TarianEventsE = 4 // TDE_SYSCALL_EXECVEAT_E represents the start of an execveat syscall - TDE_SYSCALL_EXECVEAT_R TarianEventsE = 5 // TDE_SYSCALL_EXECVEAT_R represents the return of an execveat syscall - - TDE_SYSCALL_CLONE_E TarianEventsE = 6 // TDE_SYSCALL_CLONE_E represents the start of a clone syscall - TDE_SYSCALL_CLONE_R TarianEventsE = 7 // TDE_SYSCALL_CLONE_R represents the return of a clone syscall - - TDE_SYSCALL_CLOSE_E TarianEventsE = 8 // TDE_SYSCALL_CLOSE_E represents the start of a close syscall - TDE_SYSCALL_CLOSE_R TarianEventsE = 9 // TDE_SYSCALL_CLOSE_R represents the return of a close syscall - - TDE_SYSCALL_READ_E TarianEventsE = 10 // TDE_SYSCALL_READ_E represents the start of a read syscall - TDE_SYSCALL_READ_R TarianEventsE = 11 // TDE_SYSCALL_READ_R represents the return of a read syscall - - TDE_SYSCALL_WRITE_E TarianEventsE = 12 // TDE_SYSCALL_WRITE_E represents the start of a write syscall - TDE_SYSCALL_WRITE_R TarianEventsE = 13 // TDE_SYSCALL_WRITE_R represents the return of a write syscall - - TDE_SYSCALL_OPEN_E TarianEventsE = 14 // TDE_SYSCALL_OPEN_E represents the start of an open syscall - TDE_SYSCALL_OPEN_R TarianEventsE = 15 // TDE_SYSCALL_OPEN_R represents the return of an open syscall - - TDE_SYSCALL_READV_E TarianEventsE = 16 // TDE_SYSCALL_READV_E represents the start of a readv syscall - TDE_SYSCALL_READV_R TarianEventsE = 17 // TDE_SYSCALL_READV_R represents the return of a readv syscall - - TDE_SYSCALL_WRITEV_E TarianEventsE = 18 // TDE_SYSCALL_WRITEV_E represents the start of a writev syscall - TDE_SYSCALL_WRITEV_R TarianEventsE = 19 // TDE_SYSCALL_WRITEV_R represents the return of a writev syscall - - TDE_SYSCALL_OPENAT_E TarianEventsE = 20 // TDE_SYSCALL_OPENAT_E represents the start of an openat syscall - TDE_SYSCALL_OPENAT_R TarianEventsE = 21 // TDE_SYSCALL_OPENAT_R represents the return of an openat syscall - - TDE_SYSCALL_OPENAT2_E TarianEventsE = 22 // TDE_SYSCALL_OPENAT2_E represents the start of an openat2 syscall - TDE_SYSCALL_OPENAT2_R TarianEventsE = 23 // TDE_SYSCALL_OPENAT2_R represents the return of an openat2 syscall - - TDE_SYSCALL_LISTEN_E TarianEventsE = 24 // TDE_SYSCALL_LISTEN_E represents the start of a listen syscall - TDE_SYSCALL_LISTEN_R TarianEventsE = 25 // TDE_SYSCALL_LISTEN_R represents the return of a listen syscall - - TDE_SYSCALL_SOCKET_E TarianEventsE = 26 // TDE_SYSCALL_SOCKET_E represents the start of a socket syscall - TDE_SYSCALL_SOCKET_R TarianEventsE = 27 // TDE_SYSCALL_SOCKET_R represents the return of a socket syscall - - TDE_SYSCALL_ACCEPT_E TarianEventsE = 28 // TDE_SYSCALL_ACCEPT_E represents the start of an accept syscall - TDE_SYSCALL_ACCEPT_R TarianEventsE = 29 // TDE_SYSCALL_ACCEPT_R represents the return of an accept syscall - - TDE_SYSCALL_BIND_E TarianEventsE = 30 // TDE_SYSCALL_BIND_E represents the start of a bind syscall - TDE_SYSCALL_BIND_R TarianEventsE = 31 // TDE_SYSCALL_BIND_R represents the return of a bind syscall - - TDE_SYSCALL_CONNECT_E TarianEventsE = 32 // TDE_SYSCALL_CONNECT_E represents the start of a connect syscall - TDE_SYSCALL_CONNECT_R TarianEventsE = 33 // TDE_SYSCALL_CONNECT_R represents the return of a connect syscall -) diff --git a/pkg/eventparser/enricher.go b/pkg/eventparser/enricher.go new file mode 100644 index 0000000..ff6c709 --- /dev/null +++ b/pkg/eventparser/enricher.go @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Authors of Tarian & the Organization created Tarian + +package eventparser + +import ( + "github.com/intelops/tarian-detector/pkg/err" + "github.com/intelops/tarian-detector/pkg/k8s" +) + +var enricherErr = err.New("kubernetes") + +// GetK8sContext returns the Kubernetes context for a given process ID. +func GetK8sContext(watcher *k8s.PodWatcher, processId uint32) (Kubernetes, error) { + k8sCtx := Kubernetes{} + // Get the container ID for the given process ID. + containerId, err := k8s.ProcsContainerID(processId) + if err != nil { + return k8sCtx, enricherErr.Throwf("%v", err) + } + + // If the container ID is missing, return an error. + if len(containerId) == 0 { + return k8sCtx, enricherErr.Throw("missing container id") + } + + // Find the pod associated with the container ID. + pod, err := watcher.FindPod(containerId) + if err != nil { + return k8sCtx, enricherErr.Throwf("%v: unable to find the pod associated with the container ID: %s", err, containerId) + } + + // Set the pod information in the Kubernetes context. + k8sCtx.PodUid = string(pod.ObjectMeta.UID) + k8sCtx.PodName = pod.ObjectMeta.Name + k8sCtx.PodGeneratedName = pod.ObjectMeta.GenerateName + k8sCtx.PodKind = pod.Kind + k8sCtx.PodAPIVersion = pod.APIVersion + k8sCtx.PodLabels = pod.ObjectMeta.Labels + k8sCtx.PodAnnotations = pod.ObjectMeta.Annotations + + // Set the container information in the Kubernetes context. + k8sCtx.ContainerID = containerId + + // Set the namespace information in the Kubernetes context. + k8sCtx.Namespace = pod.ObjectMeta.Namespace + + return k8sCtx, nil +} diff --git a/pkg/eventparser/parser.go b/pkg/eventparser/parser.go index be5d283..d1c92eb 100644 --- a/pkg/eventparser/parser.go +++ b/pkg/eventparser/parser.go @@ -9,6 +9,7 @@ import ( "fmt" "github.com/intelops/tarian-detector/pkg/err" + "github.com/intelops/tarian-detector/pkg/k8s" "github.com/intelops/tarian-detector/pkg/utils" ) @@ -37,41 +38,53 @@ func NewByteStream(inputData []byte, n uint8) *ByteStream { // It first retrieves the eventId from the input data, then checks if the event exists in the Events map. // It then reads the TarianMetaData from the data, updates the Syscall if needed, and parses the parameters. // Finally, it returns the parsed record and any error encountered during parsing. -func ParseByteArray(data []byte) (map[string]any, error) { +func ParseByteArray(watcher *k8s.PodWatcher, data []byte) (TarianDetectorEvent, error) { // Assuming a specific byte pattern within the byte array: - // tarianmetadata + params + // tarianmetadata + directory + executable + params + var metaData TarianMetaData + lenMetaData := binary.Size(metaData) + err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &metaData) + if err != nil { + return TarianDetectorEvent{}, parserErr.Throwf("%v", err) + } - eventId, err := getEventId(data) + event, err := GetTarianEvent(TarianEventsE(metaData.Event())) if err != nil { - return nil, parserErr.Throwf("%v", err) + return TarianDetectorEvent{}, parserErr.Throwf("%v", err) } - event, noEvent := Events[TarianEventsE(eventId)] - if !noEvent { - return nil, parserErr.Throwf("missing event from 'var Events TarianEventMap' for key: %v", eventId) + if metaData.Syscall() != int32(event.syscallId) { + (&metaData).SetSyscall(int32(event.syscallId)) } - var metaData TarianMetaData - lenMetaData := binary.Size(metaData) - err = binary.Read(bytes.NewReader(data), binary.LittleEndian, &metaData) + record := initDetectorEvent(metaData) + record.EventId = event.name + + bs := NewByteStream(data[lenMetaData:], metaData.Nparams()) + + record.Directory, err = bs.parseString() if err != nil { - return nil, parserErr.Throwf("%v", err) + return TarianDetectorEvent{}, parserErr.Throwf("%v", err) } - if metaData.MetaData.Syscall != int32(event.syscallId) { - metaData.MetaData.Syscall = int32(event.syscallId) + record.Executable, err = bs.parseString() + if err != nil { + return TarianDetectorEvent{}, parserErr.Throwf("%v", err) } - record := toMap(metaData) - record["eventId"] = event.name + if watcher != nil { + record.Kubernetes, err = GetK8sContext(watcher, uint32(metaData.HostPid())) + if err != nil { + return TarianDetectorEvent{}, parserErr.Throwf("%v", err) + } + } - bs := NewByteStream(data[lenMetaData:], metaData.MetaData.Nparams) ps, err := bs.parseParams(event) if err != nil { - return nil, parserErr.Throwf("%v", err) + return TarianDetectorEvent{}, parserErr.Throwf("%v", err) } - record["context"] = ps + record.Context = ps return record, nil } @@ -340,49 +353,34 @@ func (bs *ByteStream) parseSocketAddress() (any, error) { } } -// getEventId reads the eventId from the data and returns it as an int. -func getEventId(data []byte) (int, error) { - id, err := utils.Int32(data, 0) - if err != nil { - return 0, parserErr.Throwf("failed to read eventId from data: %v", err) +// initDetectorEvent converts the TarianMetaData struct to a map[string]any. +func initDetectorEvent(t TarianMetaData) TarianDetectorEvent { + return TarianDetectorEvent{ + Timestamp: t.Ts(), + SyscallId: t.Syscall(), + ProcessorId: t.Processor(), + ThreadStartTime: t.StartTime(), + HostProcessId: t.HostPid(), + HostThreadId: t.HostTgid(), + HostParentProcessId: t.HostPpid(), + ProcessId: t.Pid(), + ThreadId: t.Tgid(), + ParentProcessId: t.Ppid(), + UserId: t.Uid(), + GroupId: t.Gid(), + CgroupId: t.CgroupId(), + MountNamespaceId: t.MountNsId(), + PidNamespaceId: t.PidNsId(), + ExecId: t.ExecId(), + ParentExecId: t.ParentExecId(), + ProcessName: t.Comm(), + HostDetails: HostDetails{ + Sysname: t.Sysname(), + Hostname: t.Nodename(), + Release: t.Release(), + KernelVersion: t.Version(), + Machine: t.Machine(), + Domainname: t.Domainname(), + }, } - - return int(id), nil -} - -// toMap converts the TarianMetaData struct to a map[string]any. -func toMap(t TarianMetaData) map[string]any { - m := make(map[string]any) - - m["timestamp"] = t.MetaData.Ts - m["syscallId"] = t.MetaData.Syscall - m["processor"] = t.MetaData.Processor - - // task fields - m["threadStartTime"] = t.MetaData.Task.StartTime - m["hostProcessId"] = t.MetaData.Task.HostPid - m["hostThreadId"] = t.MetaData.Task.HostTgid - m["hostParentProcessId"] = t.MetaData.Task.HostPpid - m["processId"] = t.MetaData.Task.Pid - m["threadId"] = t.MetaData.Task.Tgid - m["parentProcessId"] = t.MetaData.Task.Ppid - m["userId"] = t.MetaData.Task.Uid - m["groupId"] = t.MetaData.Task.Gid - m["cgroupId"] = t.MetaData.Task.CgroupId - m["mountNamespace"] = t.MetaData.Task.MountNsId - m["pidNamespace"] = t.MetaData.Task.PidNsId - m["execId"] = t.MetaData.Task.ExecId - m["parentExecId"] = t.MetaData.Task.ParentExecId - m["processName"] = utils.ToString(t.MetaData.Task.Comm[:], 0, len(t.MetaData.Task.Comm)) - m["directory"] = utils.ToString(t.MetaData.Task.Cwd[:], 0, len(t.MetaData.Task.Cwd)) - - // SystemInfo fields - m["sysname"] = utils.ToString(t.SystemInfo.Sysname[:], 0, len(t.SystemInfo.Sysname)) - m["nodename"] = utils.ToString(t.SystemInfo.Nodename[:], 0, len(t.SystemInfo.Nodename)) - m["release"] = utils.ToString(t.SystemInfo.Release[:], 0, len(t.SystemInfo.Release)) - m["version"] = utils.ToString(t.SystemInfo.Version[:], 0, len(t.SystemInfo.Version)) - m["machine"] = utils.ToString(t.SystemInfo.Machine[:], 0, len(t.SystemInfo.Machine)) - m["domainname"] = utils.ToString(t.SystemInfo.Domainname[:], 0, len(t.SystemInfo.Domainname)) - - return m } diff --git a/pkg/eventparser/parser_test.go b/pkg/eventparser/parser_test.go index 266db65..a8f4548 100644 --- a/pkg/eventparser/parser_test.go +++ b/pkg/eventparser/parser_test.go @@ -4,7 +4,6 @@ package eventparser import ( - "fmt" "reflect" "testing" ) @@ -52,391 +51,35 @@ func TestParseByteArray(t *testing.T) { name string args args loadEvents bool - want map[string]any + want TarianDetectorEvent wantErr bool }{ { - name: "buffer size lessthan 4", + name: "short data buffer", args: args{ - data: []byte{1, 2, 3}, + data: []byte{1, 2, 3, 4, 5, 6, 7, 8}, }, loadEvents: false, - want: nil, + want: TarianDetectorEvent{}, wantErr: true, }, { name: "invalid event id", - args: args{ - data: []byte{1, 2, 3, 4}, - }, - loadEvents: false, - want: nil, - wantErr: true, - }, - { - name: "invalid buffer", - args: args{ - data: []byte{12, 0, 0, 0, 5, 6, 7, 8, 9}, - }, - loadEvents: true, - want: nil, - wantErr: true, - }, - { - name: "error parse params", args: args{ data: func() []byte { - data := make([]byte, 764) - - data[0] = 12 // eventId - data[4] = 2 // nparams + data := make([]byte, 1000) + data[0] = 1 + data[1] = 2 + data[2] = 3 + data[3] = 4 return data }(), }, - loadEvents: true, - want: nil, + loadEvents: false, + want: TarianDetectorEvent{}, wantErr: true, }, - { - name: "error nparams > actual written params", - args: args{ - data: func() []byte { - data := make([]byte, 765+7) - - data[0] = 12 // eventId - data[4] = 4 // nparams - - return data - }(), - }, - loadEvents: true, - want: map[string]any{ - "eventId": "sys_write_entry", - "timestamp": uint64(0), - "syscallId": int32(1), - "processor": uint16(0), - "threadStartTime": uint64(0), - "hostProcessId": uint32(0), - "hostThreadId": uint32(0), - "hostParentProcessId": uint32(0), - "processId": uint32(0), - "threadId": uint32(0), - "parentProcessId": uint32(0), - "userId": uint32(0), - "groupId": uint32(0), - "cgroupId": uint64(0), - "mountNamespace": uint64(0), - "pidNamespace": uint64(0), - "execId": uint64(0), - "parentExecId": uint64(0), - "processName": "", - "directory": "", - "sysname": "", - "nodename": "", - "release": "", - "version": "", - "machine": "", - "domainname": "", - "context": []Arg{ - { - Name: "fd", - Value: "0", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "buf", - Value: fmt.Sprintf("%v", []byte{}), - TarianType: 12, - LinuxType: "const char *", - }, - { - Name: "count", - Value: "0", - TarianType: 3, - LinuxType: "size_t", - }, - }, - }, - wantErr: false, - }, - { - name: "valid sys_write_entry record parsing", - args: args{ - data: []byte{12, 0, 0, 0, 3, 1, 0, 0, 0, 19, 2, 55, 188, 204, 13, 0, 0, 0, 0, 85, 79, 20, 171, 7, 0, 0, 0, 170, 12, 0, 0, 170, 12, 0, 0, 66, 7, 0, 0, 170, 12, 0, 0, 170, 12, 0, 0, 66, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 240, 0, 0, 0, 0, 252, 255, 255, 239, 0, 0, 0, 0, 85, 79, 20, 171, 175, 12, 0, 0, 17, 97, 89, 157, 70, 7, 0, 0, 102, 114, 111, 110, 116, 101, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 47, 104, 111, 109, 101, 47, 99, 114, 97, 118, 101, 108, 97, 64, 97, 112, 112, 115, 116, 101, 107, 99, 111, 114, 112, 46, 108, 111, 99, 97, 108, 0, 47, 101, 109, 98, 101, 100, 100, 101, 100, 45, 49, 100, 49, 56, 49, 101, 99, 100, 101, 102, 51, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 105, 110, 117, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 67, 76, 80, 84, 68, 65, 76, 48, 54, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 46, 49, 53, 46, 48, 45, 57, 55, 45, 103, 101, 110, 101, 114, 105, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 49, 48, 55, 126, 50, 48, 46, 48, 52, 46, 49, 45, 85, 98, 117, 110, 116, 117, 32, 83, 77, 80, 32, 70, 114, 105, 32, 70, 101, 98, 32, 57, 32, 49, 52, 58, 50, 48, 58, 49, 49, 32, 85, 84, 67, 32, 50, 48, 50, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 56, 54, 95, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 110, 111, 110, 101, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 73, 110, 118, 97, 108, 105, 100, 32, 112, 97, 115, 115, 119, 111, 114, 100, 0, 17, 0, 0, 0}, - }, - loadEvents: true, - want: map[string]any{ - "eventId": "sys_write_entry", - "timestamp": uint64(15172982211091), - "syscallId": int32(1), - "processor": uint16(0), - "threadStartTime": uint64(32935006037), - "hostProcessId": uint32(3242), - "hostThreadId": uint32(3242), - "hostParentProcessId": uint32(1858), - "processId": uint32(3242), - "threadId": uint32(3242), - "parentProcessId": uint32(1858), - "userId": uint32(0), - "groupId": uint32(0), - "cgroupId": uint64(1366), - "mountNamespace": uint64(4026531841), - "pidNamespace": uint64(4026531836), - "execId": uint64(13948629045077), - "parentExecId": uint64(7999868985617), - "processName": "frontend", - "directory": string([]byte{47, 104, 111, 109, 101, 47, 99, 114, 97, 118, 101, 108, 97, 64, 97, 112, 112, 115, 116, 101, 107, 99, 111, 114, 112, 46, 108, 111, 99, 97, 108, 0, 47, 101, 109, 98, 101, 100, 100, 101, 100, 45, 49, 100, 49, 56, 49, 101, 99, 100, 101, 102, 51, 102}), - "sysname": "Linux", - "nodename": "ACLPTDAL0631", - "release": "5.15.0-97-generic", - "version": "#107~20.04.1-Ubuntu SMP Fri Feb 9 14:20:11 UTC 2024", - "machine": "x86_64", - "domainname": "(none)", - "context": []Arg{ - { - Name: "fd", - Value: "1", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "buf", - Value: fmt.Sprintf("%v", []byte{73, 110, 118, 97, 108, 105, 100, 32, 112, 97, 115, 115, 119, 111, 114, 100, 0}), - TarianType: 12, - LinuxType: "const char *", - }, - { - Name: "count", - Value: "17", - TarianType: 3, - LinuxType: "size_t", - }, - }, - }, - wantErr: false, - }, - { - name: "valid sys_socket_entry record parsing", - loadEvents: true, - wantErr: false, - args: args{ - data: []byte{26, 0, 0, 0, 3, 41, 0, 0, 0, 81, 74, 169, 30, 184, 30, 0, 0, 15, 0, 69, 7, 11, 28, 5, 1, 0, 0, 191, 227, 36, 0, 191, 227, 36, 0, 173, 200, 0, 0, 191, 227, 36, 0, 191, 227, 36, 0, 10, 205, 0, 0, 24, 197, 143, 36, 193, 191, 143, 36, 182, 14, 0, 0, 0, 0, 0, 0, 1, 0, 0, 240, 0, 0, 0, 0, 252, 255, 255, 239, 0, 0, 0, 0, 69, 7, 11, 28, 191, 227, 36, 0, 51, 160, 181, 22, 173, 200, 0, 0, 99, 111, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 104, 111, 109, 101, 47, 99, 114, 97, 118, 101, 108, 97, 64, 97, 112, 112, 115, 116, 101, 107, 99, 111, 114, 112, 46, 108, 111, 99, 97, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 105, 110, 117, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 67, 76, 80, 84, 68, 65, 76, 48, 54, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 46, 49, 53, 46, 48, 45, 57, 55, 45, 103, 101, 110, 101, 114, 105, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 49, 48, 55, 126, 50, 48, 46, 48, 52, 46, 49, 45, 85, 98, 117, 110, 116, 117, 32, 83, 77, 80, 32, 70, 114, 105, 32, 70, 101, 98, 32, 57, 32, 49, 52, 58, 50, 48, 58, 49, 49, 32, 85, 84, 67, 32, 50, 48, 50, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 56, 54, 95, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 110, 111, 110, 101, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - }, - want: map[string]any{ - "eventId": "sys_socket_entry", - "timestamp": uint64(33776137226833), - "syscallId": int32(41), - "processor": uint16(15), - "threadStartTime": uint64(1121456949061), - "hostProcessId": uint32(2417599), - "hostThreadId": uint32(2417599), - "hostParentProcessId": uint32(51373), - "processId": uint32(2417599), - "threadId": uint32(2417599), - "parentProcessId": uint32(52490), - "userId": uint32(613401880), - "groupId": uint32(613400513), - "cgroupId": uint64(3766), - "mountNamespace": uint64(4026531841), - "pidNamespace": uint64(4026531836), - "execId": uint64(10383509110327109), - "parentExecId": uint64(220645735899187), - "processName": "code", - "directory": "/home/cravela@appstekcorp.local", - "sysname": "Linux", - "nodename": "ACLPTDAL0631", - "release": "5.15.0-97-generic", - "version": "#107~20.04.1-Ubuntu SMP Fri Feb 9 14:20:11 UTC 2024", - "machine": "x86_64", - "domainname": "(none)", - "context": []Arg{ - { - Name: "family", - Value: "AF_INET", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "type", - Value: "SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "protocol", - Value: "IPPROTO_IP", - TarianType: 7, - LinuxType: "int", - }, - }, - }, - }, - { - name: "valid sys_bind_entry record parsing family AF_INET6", - loadEvents: true, - wantErr: false, - args: args{ - data: []byte{30, 0, 0, 0, 3, 49, 0, 0, 0, 34, 193, 57, 22, 40, 33, 0, 0, 4, 0, 71, 195, 17, 22, 40, 33, 0, 0, 199, 125, 41, 0, 199, 125, 41, 0, 72, 45, 1, 0, 199, 125, 41, 0, 199, 125, 41, 0, 72, 45, 1, 0, 24, 197, 143, 36, 193, 191, 143, 36, 246, 14, 0, 0, 0, 0, 0, 0, 1, 0, 0, 240, 0, 0, 0, 0, 252, 255, 255, 239, 0, 0, 0, 0, 71, 195, 17, 22, 239, 125, 41, 0, 250, 174, 10, 131, 89, 45, 1, 0, 98, 105, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 104, 111, 109, 101, 47, 99, 114, 97, 118, 101, 108, 97, 64, 97, 112, 112, 115, 116, 101, 107, 99, 111, 114, 112, 46, 108, 111, 99, 97, 108, 47, 80, 114, 111, 106, 101, 99, 116, 115, 47, 68, 79, 85, 66, 76, 69, 47, 68, 69, 76, 69, 84, 69, 47, 68, 69, 76, 69, 84, 69, 47, 116, 97, 114, 105, 97, 110, 45, 100, 101, 116, 101, 99, 116, 111, 114, 47, 112, 107, 103, 47, 101, 66, 80, 70, 47, 99, 47, 98, 112, 102, 47, 110, 101, 116, 119, 111, 114, 107, 95, 98, 105, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 105, 110, 117, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 67, 76, 80, 84, 68, 65, 76, 48, 54, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 46, 49, 53, 46, 48, 45, 57, 55, 45, 103, 101, 110, 101, 114, 105, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 49, 48, 55, 126, 50, 48, 46, 48, 52, 46, 49, 45, 85, 98, 117, 110, 116, 117, 32, 83, 77, 80, 32, 70, 114, 105, 32, 70, 101, 98, 32, 57, 32, 49, 52, 58, 50, 48, 58, 49, 49, 32, 85, 84, 67, 32, 50, 48, 50, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 56, 54, 95, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 110, 111, 110, 101, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 31, 144, 28, 0, 0, 0}, - }, - want: map[string]any{ - "eventId": "sys_bind_entry", - "timestamp": uint64(36456055292194), - "syscallId": int32(49), - "processor": uint16(4), - "threadStartTime": uint64(36456052671303), - "hostProcessId": uint32(2719175), - "hostThreadId": uint32(2719175), - "hostParentProcessId": uint32(77128), - "processId": uint32(2719175), - "threadId": uint32(2719175), - "parentProcessId": uint32(77128), - "userId": uint32(613401880), - "groupId": uint32(613400513), - "cgroupId": uint64(3830), - "mountNamespace": uint64(4026531841), - "pidNamespace": uint64(4026531836), - "execId": uint64(11678939866055495), - "parentExecId": uint64(331337450565370), - "processName": "bind", - "directory": "/home/cravela@appstekcorp.local/Projects/DOUBLE/DELETE/DELETE/tarian-detector/pkg/eBPF/c/bpf/network_bind", - "sysname": "Linux", - "nodename": "ACLPTDAL0631", - "release": "5.15.0-97-generic", - "version": "#107~20.04.1-Ubuntu SMP Fri Feb 9 14:20:11 UTC 2024", - "machine": "x86_64", - "domainname": "(none)", - "context": []Arg{ - { - Name: "fd", - Value: "3", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "umyaddr", - Value: fmt.Sprintf("%+v", struct { - Family string - Sa_addr string - Sa_port uint16 - }{Family: "AF_INET6", Sa_addr: "::1", Sa_port: 8080}), - TarianType: 14, - LinuxType: "struct sockaddr *", - }, - {Name: "addrlen", Value: "28", TarianType: 7, LinuxType: "int"}, - }, - }, - }, - { - name: "valid sys_bind_entry record parsing family AF_INET", - loadEvents: true, - wantErr: false, - args: args{ - data: []byte{30, 0, 0, 0, 3, 49, 0, 0, 0, 176, 136, 54, 5, 54, 34, 0, 0, 6, 0, 114, 61, 18, 5, 54, 34, 0, 0, 157, 39, 17, 0, 157, 39, 17, 0, 72, 45, 1, 0, 157, 39, 17, 0, 157, 39, 17, 0, 72, 45, 1, 0, 24, 197, 143, 36, 193, 191, 143, 36, 246, 14, 0, 0, 0, 0, 0, 0, 1, 0, 0, 240, 0, 0, 0, 0, 252, 255, 255, 239, 0, 0, 0, 0, 114, 61, 18, 5, 191, 39, 17, 0, 250, 174, 10, 131, 89, 45, 1, 0, 98, 105, 110, 100, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 104, 111, 109, 101, 47, 99, 114, 97, 118, 101, 108, 97, 64, 97, 112, 112, 115, 116, 101, 107, 99, 111, 114, 112, 46, 108, 111, 99, 97, 108, 47, 80, 114, 111, 106, 101, 99, 116, 115, 47, 68, 79, 85, 66, 76, 69, 47, 68, 69, 76, 69, 84, 69, 47, 68, 69, 76, 69, 84, 69, 47, 116, 97, 114, 105, 97, 110, 45, 100, 101, 116, 101, 99, 116, 111, 114, 47, 112, 107, 103, 47, 101, 66, 80, 70, 47, 99, 47, 98, 112, 102, 47, 110, 101, 116, 119, 111, 114, 107, 95, 98, 105, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 105, 110, 117, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 67, 76, 80, 84, 68, 65, 76, 48, 54, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 46, 49, 53, 46, 48, 45, 57, 55, 45, 103, 101, 110, 101, 114, 105, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 49, 48, 55, 126, 50, 48, 46, 48, 52, 46, 49, 45, 85, 98, 117, 110, 116, 117, 32, 83, 77, 80, 32, 70, 114, 105, 32, 70, 101, 98, 32, 57, 32, 49, 52, 58, 50, 48, 58, 49, 49, 32, 85, 84, 67, 32, 50, 48, 50, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 56, 54, 95, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 110, 111, 110, 101, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 31, 144, 16, 0, 0, 0, 0, 0, 0, 0}, - }, - want: map[string]any{ - "eventId": "sys_bind_entry", - "timestamp": uint64(37615411038384), - "syscallId": int32(49), - "processor": uint16(6), - "threadStartTime": uint64(37615408659826), - "hostProcessId": uint32(1124253), - "hostThreadId": uint32(1124253), - "hostParentProcessId": uint32(77128), - "processId": uint32(1124253), - "threadId": uint32(1124253), - "parentProcessId": uint32(77128), - "userId": uint32(613401880), - "groupId": uint32(613400513), - "cgroupId": uint64(3830), - "mountNamespace": uint64(4026531841), - "pidNamespace": uint64(4026531836), - "execId": uint64(4828775981399410), - "parentExecId": uint64(331337450565370), - "processName": "bind4", - "directory": "/home/cravela@appstekcorp.local/Projects/DOUBLE/DELETE/DELETE/tarian-detector/pkg/eBPF/c/bpf/network_bind", - "sysname": "Linux", - "nodename": "ACLPTDAL0631", - "release": "5.15.0-97-generic", - "version": "#107~20.04.1-Ubuntu SMP Fri Feb 9 14:20:11 UTC 2024", - "machine": "x86_64", - "domainname": "(none)", - "context": []Arg{ - { - Name: "fd", - Value: "3", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "umyaddr", - Value: fmt.Sprintf("%+v", struct { - Family string - Sa_addr string - Sa_port uint16 - }{Family: "AF_INET", Sa_addr: "0.0.0.0", Sa_port: 8080}), - TarianType: 14, - LinuxType: "struct sockaddr *", - }, - {Name: "addrlen", Value: "16", TarianType: 7, LinuxType: "int"}, - }, - }, - }, - { - name: "valid sys_bind_entry record parsing family AF_UNIX", - loadEvents: true, - wantErr: false, - args: args{ - data: []byte{30, 0, 0, 0, 3, 49, 0, 0, 0, 85, 21, 60, 167, 192, 34, 0, 0, 2, 0, 146, 158, 19, 167, 192, 34, 0, 0, 7, 172, 37, 0, 7, 172, 37, 0, 16, 221, 29, 0, 7, 172, 37, 0, 7, 172, 37, 0, 16, 221, 29, 0, 24, 197, 143, 36, 193, 191, 143, 36, 198, 31, 0, 0, 0, 0, 0, 0, 1, 0, 0, 240, 0, 0, 0, 0, 252, 255, 255, 239, 0, 0, 0, 0, 146, 158, 19, 167, 199, 174, 37, 0, 39, 14, 153, 126, 157, 255, 29, 0, 117, 110, 105, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 104, 111, 109, 101, 47, 99, 114, 97, 118, 101, 108, 97, 64, 97, 112, 112, 115, 116, 101, 107, 99, 111, 114, 112, 46, 108, 111, 99, 97, 108, 47, 80, 114, 111, 106, 101, 99, 116, 115, 47, 68, 79, 85, 66, 76, 69, 47, 68, 69, 76, 69, 84, 69, 47, 68, 69, 76, 69, 84, 69, 47, 116, 97, 114, 105, 97, 110, 45, 100, 101, 116, 101, 99, 116, 111, 114, 47, 112, 107, 103, 47, 101, 66, 80, 70, 47, 99, 47, 98, 112, 102, 47, 110, 101, 116, 119, 111, 114, 107, 95, 98, 105, 110, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 105, 110, 117, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 67, 76, 80, 84, 68, 65, 76, 48, 54, 51, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 46, 49, 53, 46, 48, 45, 57, 55, 45, 103, 101, 110, 101, 114, 105, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 49, 48, 55, 126, 50, 48, 46, 48, 52, 46, 49, 45, 85, 98, 117, 110, 116, 117, 32, 83, 77, 80, 32, 70, 114, 105, 32, 70, 101, 98, 32, 57, 32, 49, 52, 58, 50, 48, 58, 49, 49, 32, 85, 84, 67, 32, 50, 48, 50, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 56, 54, 95, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 110, 111, 110, 101, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 21, 0, 47, 116, 109, 112, 47, 109, 121, 95, 117, 110, 105, 120, 95, 115, 111, 99, 107, 101, 116, 50, 0, 110, 0, 0, 0, 0, 0, 0}, - }, - want: map[string]any{ - "eventId": "sys_bind_entry", - "timestamp": uint64(38210834797909), - "syscallId": int32(49), - "processor": uint16(2), - "threadStartTime": uint64(38210832146066), - "hostProcessId": uint32(2468871), - "hostThreadId": uint32(2468871), - "hostParentProcessId": uint32(1957136), - "processId": uint32(2468871), - "threadId": uint32(2468871), - "parentProcessId": uint32(1957136), - "userId": uint32(613401880), - "groupId": uint32(613400513), - "cgroupId": uint64(8134), - "mountNamespace": uint64(4026531841), - "pidNamespace": uint64(4026531836), - "execId": uint64(10606746663100050), - "parentExecId": uint64(8443826223517223), - "processName": "unix", - "directory": "/home/cravela@appstekcorp.local/Projects/DOUBLE/DELETE/DELETE/tarian-detector/pkg/eBPF/c/bpf/network_bind", - "sysname": "Linux", - "nodename": "ACLPTDAL0631", - "release": "5.15.0-97-generic", - "version": "#107~20.04.1-Ubuntu SMP Fri Feb 9 14:20:11 UTC 2024", - "machine": "x86_64", - "domainname": "(none)", - "context": []Arg{ - { - Name: "fd", - Value: "3", - TarianType: 7, - LinuxType: "int", - }, - { - Name: "umyaddr", - Value: fmt.Sprintf("%+v", struct { - Family string - Sun_path string - }{Family: "AF_UNIX", Sun_path: "/tmp/my_unix_socket2"}), - TarianType: 14, - LinuxType: "struct sockaddr *", - }, - {Name: "addrlen", Value: "110", TarianType: 7, LinuxType: "int"}, - }, - }, - }, } for _, tt := range tests { @@ -445,7 +88,7 @@ func TestParseByteArray(t *testing.T) { } t.Run(tt.name, func(t *testing.T) { - got, err := ParseByteArray(tt.args.data) + got, err := ParseByteArray(nil, tt.args.data) if (err != nil) != tt.wantErr { t.Errorf("ParseByteArray() error = %v, wantErr %v", err, tt.wantErr) return @@ -484,7 +127,7 @@ func TestByteStream_parseParams(t *testing.T) { syscallId: 0, eventSize: 783, params: []Param{ - Param{}, Param{}, + {}, {}, }, }, }, @@ -541,7 +184,7 @@ func TestByteStream_parseParam(t *testing.T) { want: Arg{ Name: "test", Value: "1", - TarianType: 1, + TarianType: "TDT_U8", LinuxType: "uint8_t", }, wantErr: false, @@ -563,7 +206,7 @@ func TestByteStream_parseParam(t *testing.T) { want: Arg{ Name: "test", Value: "513", - TarianType: 2, + TarianType: "TDT_U16", LinuxType: "uint16_t", }, wantErr: false, @@ -585,7 +228,7 @@ func TestByteStream_parseParam(t *testing.T) { want: Arg{ Name: "test", Value: "578437695752307201", - TarianType: 4, + TarianType: "TDT_U64", LinuxType: "uint64_t", }, wantErr: false, @@ -604,7 +247,7 @@ func TestByteStream_parseParam(t *testing.T) { linuxType: "int8_t", }, }, - want: Arg{"test", "1", 5, "int8_t"}, + want: Arg{"test", "1", "TDT_S8", "int8_t"}, wantErr: false, }, { @@ -621,7 +264,7 @@ func TestByteStream_parseParam(t *testing.T) { linuxType: "int16_t", }, }, - want: Arg{"test", "513", 6, "int16_t"}, + want: Arg{"test", "513", "TDT_S16", "int16_t"}, wantErr: false, }, { @@ -638,7 +281,7 @@ func TestByteStream_parseParam(t *testing.T) { linuxType: "int64_t", }, }, - want: Arg{"test", "578437695752307201", 8, "int64_t"}, + want: Arg{"test", "578437695752307201", "TDT_S64", "int64_t"}, wantErr: false, }, { @@ -655,7 +298,7 @@ func TestByteStream_parseParam(t *testing.T) { linuxType: "string", }, }, - want: Arg{"test", "ABCD", 10, "string"}, + want: Arg{"test", "ABCD", "TDT_STR", "string"}, wantErr: false, }, } diff --git a/pkg/eventparser/probes.go b/pkg/eventparser/probes.go index 834ae3b..74936e8 100644 --- a/pkg/eventparser/probes.go +++ b/pkg/eventparser/probes.go @@ -11,14 +11,6 @@ import ( var probesErr = err.New("eventparser.probes") -// Arg represents an argument with its name, value, and types for Tarian and Linux. -type Arg struct { - Name string // Name is the name of the argument - Value string // Value is the value of the argument - TarianType uint32 // TarianType is the Tarian type of the argument - LinuxType string // LinuxType is the Linux type of the argumen -} - // Param represents a parameter with its name, type, Linux type, and processing function type Param struct { name string // name of the parameter @@ -62,19 +54,19 @@ func LoadTarianEvents() { func GenerateTarianEvents() TarianEventMap { events := make(TarianEventMap) - execve_e := NewTarianEvent(59, "sys_execve_entry", 8957, + execve_e := NewTarianEvent(59, "sys_execve_entry", 16897, Param{name: "filename", paramType: TDT_STR, linuxType: "const char *"}, Param{name: "argv", paramType: TDT_STR_ARR, linuxType: "const char **"}, Param{name: "envp", paramType: TDT_STR_ARR, linuxType: "const char **"}, ) events.AddTarianEvent(TDE_SYSCALL_EXECVE_E, execve_e) - execve_r := NewTarianEvent(59, "sys_execve_exit", 765, + execve_r := NewTarianEvent(59, "sys_execve_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_EXECVE_R, execve_r) - execveat_e := NewTarianEvent(322, "sys_execveat_entry", 8965, + execveat_e := NewTarianEvent(322, "sys_execveat_entry", 16905, Param{name: "fd", paramType: TDT_S32, linuxType: "int", function: parseExecveatDird}, Param{name: "filename", paramType: TDT_STR, linuxType: "const char *"}, Param{name: "argv", paramType: TDT_STR_ARR, linuxType: "char const **"}, @@ -83,12 +75,12 @@ func GenerateTarianEvents() TarianEventMap { ) events.AddTarianEvent(TDE_SYSCALL_EXECVEAT_E, execveat_e) - execveat_r := NewTarianEvent(322, "sys_execveat_exit", 765, + execveat_r := NewTarianEvent(322, "sys_execveat_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_EXECVEAT_R, execveat_r) - clone_e := NewTarianEvent(56, "sys_clone_entry", 793, + clone_e := NewTarianEvent(56, "sys_clone_entry", 8733, Param{name: "clone_flags", paramType: TDT_U64, linuxType: "unsigned long", function: parseCloneFlags}, Param{name: "newsp", paramType: TDT_S64, linuxType: "unsigned long"}, Param{name: "parent_tid", paramType: TDT_S32, linuxType: "int *"}, @@ -97,82 +89,82 @@ func GenerateTarianEvents() TarianEventMap { ) events.AddTarianEvent(TDE_SYSCALL_CLONE_E, clone_e) - clone_r := NewTarianEvent(56, "sys_clone_exit", 765, + clone_r := NewTarianEvent(56, "sys_clone_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_CLONE_R, clone_r) - close_e := NewTarianEvent(3, "sys_close_entry", 765, + close_e := NewTarianEvent(3, "sys_close_entry", 8705, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_CLOSE_E, close_e) - close_r := NewTarianEvent(3, "sys_close_exit", 765, + close_r := NewTarianEvent(3, "sys_close_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_CLOSE_R, close_r) - read_e := NewTarianEvent(0, "sys_read_entry", 4867, + read_e := NewTarianEvent(0, "sys_read_entry", 12807, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "buf", paramType: TDT_BYTE_ARR, linuxType: "char *"}, Param{name: "count", paramType: TDT_U32, linuxType: "size_t"}, ) events.AddTarianEvent(TDE_SYSCALL_READ_E, read_e) - read_r := NewTarianEvent(0, "sys_read_exit", 769, + read_r := NewTarianEvent(0, "sys_read_exit", 8709, Param{name: "return", paramType: TDT_S64, linuxType: "ssize_t"}, ) events.AddTarianEvent(TDE_SYSCALL_READ_R, read_r) - write_e := NewTarianEvent(1, "sys_write_entry", 4867, + write_e := NewTarianEvent(1, "sys_write_entry", 12807, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "buf", paramType: TDT_BYTE_ARR, linuxType: "const char *"}, Param{name: "count", paramType: TDT_U32, linuxType: "size_t"}, ) events.AddTarianEvent(TDE_SYSCALL_WRITE_E, write_e) - write_r := NewTarianEvent(1, "sys_write_exit", 769, + write_r := NewTarianEvent(1, "sys_write_exit", 8709, Param{name: "return", paramType: TDT_S64, linuxType: "ssize_t"}, ) events.AddTarianEvent(TDE_SYSCALL_WRITE_R, write_r) - open_e := NewTarianEvent(2, "sys_open_entry", 4867, + open_e := NewTarianEvent(2, "sys_open_entry", 12807, Param{name: "filename", paramType: TDT_STR, linuxType: "const char *"}, Param{name: "flags", paramType: TDT_S32, linuxType: "int", function: parseOpenFlags}, Param{name: "mode", paramType: TDT_U32, linuxType: "umode_t", function: parseOpenMode}, ) events.AddTarianEvent(TDE_SYSCALL_OPEN_E, open_e) - open_r := NewTarianEvent(2, "sys_open_exit", 765, + open_r := NewTarianEvent(2, "sys_open_exit", 8705, Param{name: "return", paramType: TDT_U32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_OPEN_R, open_r) - readv_e := NewTarianEvent(19, "sys_readv_entry", 4867, + readv_e := NewTarianEvent(19, "sys_readv_entry", 12807, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "vec", paramType: TDT_BYTE_ARR, linuxType: "const struct iovec *"}, Param{name: "vlen", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_READV_E, readv_e) - readv_r := NewTarianEvent(19, "sys_readv_exit", 769, + readv_r := NewTarianEvent(19, "sys_readv_exit", 8709, Param{name: "return", paramType: TDT_S64, linuxType: "ssize_t"}, ) events.AddTarianEvent(TDE_SYSCALL_READV_R, readv_r) - writev_e := NewTarianEvent(20, "sys_writev_entry", 4867, + writev_e := NewTarianEvent(20, "sys_writev_entry", 12807, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "vec", paramType: TDT_BYTE_ARR, linuxType: "const struct iovec *"}, Param{name: "vlen", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_WRITEV_E, writev_e) - writev_r := NewTarianEvent(20, "sys_writev_exit", 769, + writev_r := NewTarianEvent(20, "sys_writev_exit", 8709, Param{name: "return", paramType: TDT_S64, linuxType: "ssize_t"}, ) events.AddTarianEvent(TDE_SYSCALL_WRITEV_R, writev_r) - openat_e := NewTarianEvent(257, "sys_openat_entry", 4871, + openat_e := NewTarianEvent(257, "sys_openat_entry", 12811, Param{name: "dfd", paramType: TDT_S32, linuxType: "int", function: parseExecveatDird}, Param{name: "filename", paramType: TDT_STR, linuxType: "const char *"}, Param{name: "flags", paramType: TDT_S32, linuxType: "int", function: parseOpenFlags}, @@ -180,12 +172,12 @@ func GenerateTarianEvents() TarianEventMap { ) events.AddTarianEvent(TDE_SYSCALL_OPENAT_E, openat_e) - openat_r := NewTarianEvent(257, "sys_openat_exit", 765, + openat_r := NewTarianEvent(257, "sys_openat_exit", 8705, Param{name: "return", paramType: TDT_U32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_OPENAT_R, openat_r) - openat2_e := NewTarianEvent(437, "sys_openat2_entry", 4891, + openat2_e := NewTarianEvent(437, "sys_openat2_entry", 12831, Param{name: "dfd", paramType: TDT_S32, linuxType: "int", function: parseExecveatDird}, Param{name: "filename", paramType: TDT_STR, linuxType: "const char *"}, Param{name: "flags", paramType: TDT_S64, linuxType: "unsigned long", function: parseOpenat2Flags}, @@ -195,66 +187,66 @@ func GenerateTarianEvents() TarianEventMap { ) events.AddTarianEvent(TDE_SYSCALL_OPENAT2_E, openat2_e) - openat2_r := NewTarianEvent(437, "sys_openat2_exit", 769, + openat2_r := NewTarianEvent(437, "sys_openat2_exit", 8709, Param{name: "return", paramType: TDT_S64, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_OPENAT2_R, openat2_r) - listen_e := NewTarianEvent(50, "sys_listen_entry", 769, + listen_e := NewTarianEvent(50, "sys_listen_entry", 8709, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "backlog", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_LISTEN_E, listen_e) - listen_r := NewTarianEvent(50, "sys_listen_exit", 765, + listen_r := NewTarianEvent(50, "sys_listen_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_LISTEN_R, listen_r) - socket_e := NewTarianEvent(41, "sys_socket_entry", 773, + socket_e := NewTarianEvent(41, "sys_socket_entry", 8713, Param{name: "family", paramType: TDT_S32, linuxType: "int", function: parseSocketFamily}, Param{name: "type", paramType: TDT_S32, linuxType: "int", function: parseSocketType}, Param{name: "protocol", paramType: TDT_S32, linuxType: "int", function: parseSocketProtocol}, ) events.AddTarianEvent(TDE_SYSCALL_SOCKET_E, socket_e) - socket_r := NewTarianEvent(41, "sys_socket_exit", 765, + socket_r := NewTarianEvent(41, "sys_socket_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_SOCKET_R, socket_r) - accept_e := NewTarianEvent(43, "sys_accept_entry", 880, + accept_e := NewTarianEvent(43, "sys_accept_entry", 8820, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "upeer_sockaddr", paramType: TDT_SOCKADDR, linuxType: "struct sockaddr *"}, Param{name: "upper_addrlen", paramType: TDT_S32, linuxType: "int *"}, ) events.AddTarianEvent(TDE_SYSCALL_ACCEPT_E, accept_e) - accept_r := NewTarianEvent(43, "sys_accept_exit", 765, + accept_r := NewTarianEvent(43, "sys_accept_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_ACCEPT_R, accept_r) - bind_e := NewTarianEvent(49, "sys_bind_entry", 880, + bind_e := NewTarianEvent(49, "sys_bind_entry", 8820, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "umyaddr", paramType: TDT_SOCKADDR, linuxType: "struct sockaddr *"}, Param{name: "addrlen", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_BIND_E, bind_e) - bind_r := NewTarianEvent(49, "sys_bind_exit", 765, + bind_r := NewTarianEvent(49, "sys_bind_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_BIND_R, bind_r) - connect_e := NewTarianEvent(42, "sys_connect_entry", 880, + connect_e := NewTarianEvent(42, "sys_connect_entry", 8820, Param{name: "fd", paramType: TDT_S32, linuxType: "int"}, Param{name: "uservaddr", paramType: TDT_SOCKADDR, linuxType: "struct sockaddr *"}, Param{name: "addrlen", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_CONNECT_E, connect_e) - connect_r := NewTarianEvent(42, "sys_connect_exit", 765, + connect_r := NewTarianEvent(42, "sys_connect_exit", 8705, Param{name: "return", paramType: TDT_S32, linuxType: "int"}, ) events.AddTarianEvent(TDE_SYSCALL_CONNECT_R, connect_r) @@ -262,6 +254,15 @@ func GenerateTarianEvents() TarianEventMap { return events } +func GetTarianEvent(idx TarianEventsE) (TarianEvent, error) { + event, noEvent := Events[idx] + if !noEvent { + return event, probesErr.Throwf("missing event from 'var Events TarianEventMap' for key: %v", idx) + } + + return event, nil +} + // processValue processes the value and returns the argument and an error, if any. func (p *Param) processValue(val interface{}) (Arg, error) { arg := Arg{} @@ -279,7 +280,7 @@ func (p *Param) processValue(val interface{}) (Arg, error) { arg.Name = p.name arg.LinuxType = p.linuxType - arg.TarianType = uint32(p.paramType) + arg.TarianType = p.paramType.String() return arg, nil } diff --git a/pkg/eventparser/types.go b/pkg/eventparser/types.go new file mode 100644 index 0000000..30fdbae --- /dev/null +++ b/pkg/eventparser/types.go @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Authors of Tarian & the Organization created Tarian + +package eventparser + +import ( + "fmt" + + "github.com/intelops/tarian-detector/pkg/utils" +) + +// Arg represents an argument with its name, value, and types for Tarian and Linux. +type Arg struct { + Name string // Name is the name of the argument + Value string // Value is the value of the argument + TarianType string // TarianType is the Tarian type of the argument + LinuxType string // LinuxType is the Linux type of the argumen +} + +// String returns a string representation of the Arg struct. +func (arg Arg) String() string { + str := "" + + str += fmt.Sprintf("Name: %v\n", arg.Name) + str += fmt.Sprintf("Value: %v\n", arg.Value) + str += fmt.Sprintf("TarianType: %v\n", arg.TarianType) + str += fmt.Sprintf("LinuxType: %v\n", arg.LinuxType) + + return str +} + +// HostDetails represents information about the host system. +type HostDetails struct { + // Sysname is the name of the operating system. + Sysname string `json:"sysname"` + // Hostname is the name of the host system. + Hostname string `json:"hostname"` + // Release is the release level of the operating system. + Release string `json:"release"` + // KernelVersion is the version of the kernel. + KernelVersion string `json:"kernelversion"` + // Machine is the machine architecture. + Machine string `json:"machine"` + // Domainname is the domain name of the host. + Domainname string `json:"domainname"` +} + +// String returns a string representation of the HostDetails struct. +func (h HostDetails) String() string { + str := "" + + str += fmt.Sprintf("Sysname: %v\n", h.Sysname) + str += fmt.Sprintf("Hostname: %v\n", h.Hostname) + str += fmt.Sprintf("Release: %v\n", h.Release) + str += fmt.Sprintf("KernelVersion: %v\n", h.KernelVersion) + str += fmt.Sprintf("Machine: %v\n", h.Machine) + str += fmt.Sprintf("Domainname: %v\n", h.Domainname) + + return str +} + +// Kubernetes represents information about a Kubernetes pod and container. +type Kubernetes struct { + // pod information + // PodUid is the unique ID for the pod. + PodUid string `json:"pod_uid"` + // PodName is the name of the pod. + PodName string `json:"pod_name"` + // PodGeneratedName is the generated name of the pod. + PodGeneratedName string `json:"pod_generated_name"` + // PodKind is the kind of the pod (e.g. Pod). + PodKind string `json:"pod_kind"` + // PodAPIVersion is the API version of the pod. + PodAPIVersion string `json:"pod_api_version"` + // PodLabels is a map of labels applied to the pod. + PodLabels map[string]string `json:"pod_labels"` + // PodAnnotations is a map of annotations applied to the pod. + PodAnnotations map[string]string `json:"pod_annotations"` + + // ContainerID is the ID of the container. + ContainerID string `json:"container_id"` + + // Namespace is the name of the namespace that the pod is in. + Namespace string `json:"namespace"` +} + +// String returns a string representation of the Kubernetes struct. +func (k Kubernetes) String() string { + str := "" + + str += fmt.Sprintf("PodUid: %v\n", k.PodUid) + str += fmt.Sprintf("PodName: %v\n", k.PodName) + str += fmt.Sprintf("PodGeneratedName: %v\n", k.PodGeneratedName) + str += fmt.Sprintf("PodKind: %v\n", k.PodKind) + str += fmt.Sprintf("PodAPIVersion: %v\n", k.PodAPIVersion) + str += fmt.Sprintf("PodLabels: %v\n", k.PodLabels) + str += fmt.Sprintf("PodAnnotations: %v\n", k.PodAnnotations) + str += fmt.Sprintf("ContainerID: %v\n", k.ContainerID) + str += fmt.Sprintf("Namespace: %v\n", k.Namespace) + + return str +} + +// TarianDetectorEvent represents an event that has been received from the +// kernel and parsed. +type TarianDetectorEvent struct { + // EventId is a unique identifier represents what kind of event it is. + EventId string `json:"event_id"` + // SyscallId is the identifier of the system call that event is generated from. + SyscallId int32 `json:"syscall_id"` + // Timestamp is the timestamp of when the event started by kernel. + Timestamp uint64 `json:"timestamp"` + // ProcessorId is the identifier of the processor that recorded the event. + ProcessorId uint16 `json:"processor_id"` + // ThreadStartTime is the timestamp of when the thread that recorded the + // event started. + ThreadStartTime uint64 `json:"thread_start_time"` + // HostProcessId is the ID of the process in the host's context. + HostProcessId uint32 `json:"host_process_id"` + // HostThreadId is the ID of the thread in the host's context. + HostThreadId uint32 `json:"host_thread_id"` + // HostParentProcessId is the ID of the parent process in the host's + // context. + HostParentProcessId uint32 `json:"host_parent_process_id"` + // ProcessId is the ID of the process in the container's context. + ProcessId uint32 `json:"process_id"` + // ThreadId is the ID of the thread in the container's context. + ThreadId uint32 `json:"thread_id"` + // ParentProcessId is the ID of the parent process in the container's + // context. + ParentProcessId uint32 `json:"parent_process_id"` + // UserId is the user ID of the user running the process. + UserId uint32 `json:"user_id"` + // GroupId is the group ID of the group that the user belongs to. + GroupId uint32 `json:"group_id"` + // CgroupId is the control group ID of the process. + CgroupId uint64 `json:"cgroup_id"` + // MountNamespaceId is the ID of the mount namespace of the process. + MountNamespaceId uint64 `json:"mount_namespace_id"` + // PidNamespaceId is the ID of the PID namespace of the process. + PidNamespaceId uint64 `json:"pid_namespace_id"` + // ExecId is the execution ID of the process. + ExecId uint64 `json:"exec_id"` + // ParentExecId is the execution ID of the parent process. + ParentExecId uint64 `json:"parent_exec_id"` + // ProcessName is the name of the process. + ProcessName string `json:"process_name"` + // Directory is the working directory of the process. + Directory string `json:"directory"` + // Executable is the executable path of the process. + Executable string `json:"executable"` + // HostDetails contains information about the host system. + HostDetails HostDetails `json:"host_details"` + // Kubernetes contains information about the Kubernetes pod and + // container. + Kubernetes Kubernetes `json:"kubernetes,omitempty"` + // Context is the list of arguments that were passed to the system call. + Context []Arg `json:"context"` +} + +// String returns a string representation of the TarianDetectorEvent. +func (t TarianDetectorEvent) String() string { + str := "" + + str += fmt.Sprintf("EventId: %v\n", t.EventId) + str += fmt.Sprintf("SyscallId: %v\n", t.SyscallId) + str += fmt.Sprintf("Timestamp: %v\n", t.Timestamp) + str += fmt.Sprintf("ProcessorId: %v\n", t.ProcessorId) + str += fmt.Sprintf("ThreadStartTime: %v\n", t.ThreadStartTime) + str += fmt.Sprintf("HostProcessId: %v\n", t.HostProcessId) + str += fmt.Sprintf("HostThreadId: %v\n", t.HostThreadId) + str += fmt.Sprintf("HostParentProcessId: %v\n", t.HostParentProcessId) + str += fmt.Sprintf("ProcessId: %v\n", t.ProcessId) + str += fmt.Sprintf("ThreadId: %v\n", t.ThreadId) + str += fmt.Sprintf("ParentProcessId: %v\n", t.ParentProcessId) + str += fmt.Sprintf("UserId: %v\n", t.UserId) + str += fmt.Sprintf("GroupId: %v\n", t.GroupId) + str += fmt.Sprintf("CgroupId: %v\n", t.CgroupId) + str += fmt.Sprintf("MountNamespaceId: %v\n", t.MountNamespaceId) + str += fmt.Sprintf("PidNamespaceId: %v\n", t.PidNamespaceId) + str += fmt.Sprintf("ExecId: %v\n", t.ExecId) + str += fmt.Sprintf("ParentExecId: %v\n", t.ParentExecId) + str += fmt.Sprintf("ProcessName: %v\n", t.ProcessName) + str += fmt.Sprintf("Directory: %v\n", t.Directory) + str += fmt.Sprintf("Executable: %v\n", t.Executable) + str += fmt.Sprintf("HostDetails: {\n\n%s\n}\n", t.HostDetails) + str += fmt.Sprintf("Kubernetes: {\n\n%s\n}\n", t.Kubernetes) + str += fmt.Sprintf("Context: {\n\n%s\n}\n", t.Context) + + return str +} + +// TarianMetaData represents the metadata associated with a event being received from the kernel. +// The first 755 bytes received from kernel in form of []byte are of type TarianMetaData +type TarianMetaData struct { + MetaData struct { + Event int32 // Event identifier + Nparams uint8 // Number of parameters + Syscall int32 // System call id + Ts uint64 // Timestamp + Processor uint16 // Processor number + Task struct { // Task information + StartTime uint64 // Start time + HostPid uint32 // Host process ID + HostTgid uint32 // Host thread group ID + HostPpid uint32 // Host parent process ID + Pid uint32 // Process ID of a namespace + Tgid uint32 // Thread group ID of a namespace + Ppid uint32 // Parent process ID of a namespace + Uid uint32 // User ID + Gid uint32 // Group ID + CgroupId uint64 // Cgroup ID + MountNsId uint64 // Mount namespace ID + PidNsId uint64 // Process namespace ID + ExecId uint64 // Execution ID + ParentExecId uint64 // Parent execution ID + Comm [16]uint8 // Command + } + } + SystemInfo struct { + Sysname [65]uint8 // System name + Nodename [65]uint8 // Node name + Release [65]uint8 // Release + Version [65]uint8 // Version + Machine [65]uint8 // Machine + Domainname [65]uint8 // Domain name + } +} + +// Event returns the Event field of TarianMetaData +func (t TarianMetaData) Event() int32 { + return t.MetaData.Event +} + +// Nparams returns the Nparams field of TarianMetaData +func (t TarianMetaData) Nparams() uint8 { + return t.MetaData.Nparams +} + +// Syscall returns the Syscall field of TarianMetaData +func (t TarianMetaData) Syscall() int32 { + return t.MetaData.Syscall +} + +func (t *TarianMetaData) SetSyscall(syscallId int32) { + t.MetaData.Syscall = syscallId +} + +// Ts returns the Ts field of TarianMetaData +func (t TarianMetaData) Ts() uint64 { + return t.MetaData.Ts +} + +// Processor returns the Processor field of TarianMetaData +func (t TarianMetaData) Processor() uint16 { + return t.MetaData.Processor +} + +// StartTime returns the StartTime field of TarianMetaData +func (t TarianMetaData) StartTime() uint64 { + return t.MetaData.Task.StartTime +} + +// Hostpid returns the Hostpid field of TarianMetaData +func (t TarianMetaData) HostPid() uint32 { + return t.MetaData.Task.HostPid +} + +// HostTgid returns the HostTgid field of TarianMetaData +func (t TarianMetaData) HostTgid() uint32 { + return t.MetaData.Task.HostTgid +} + +// HostPpid returns the HostPpid field of TarianMetaData +func (t TarianMetaData) HostPpid() uint32 { + return t.MetaData.Task.HostPpid +} + +// Pid returns the Pid field of TarianMetaData +func (t TarianMetaData) Pid() uint32 { + return t.MetaData.Task.Pid +} + +// Tgid returns the Tgid field of TarianMetaData +func (t TarianMetaData) Tgid() uint32 { + return t.MetaData.Task.Tgid +} + +// Ppid returns the Ppid field of TarianMetaData +func (t TarianMetaData) Ppid() uint32 { + return t.MetaData.Task.Ppid +} + +// Uid returns the Uid field of TarianMetaData +func (t TarianMetaData) Uid() uint32 { + return t.MetaData.Task.Uid +} + +// Gid returns the Gid field of TarianMetaData +func (t TarianMetaData) Gid() uint32 { + return t.MetaData.Task.Gid +} + +// CgroupId returns the CgroupId field of TarianMetaData +func (t TarianMetaData) CgroupId() uint64 { + return t.MetaData.Task.CgroupId +} + +// MountNsId returns the MountNsId field of TarianMetaData +func (t TarianMetaData) MountNsId() uint64 { + return t.MetaData.Task.MountNsId +} + +// PidNsId returns the PidNsId field of TarianMetaData +func (t TarianMetaData) PidNsId() uint64 { + return t.MetaData.Task.PidNsId +} + +// ExecId returns the ExecId field of TarianMetaData +func (t TarianMetaData) ExecId() uint64 { + return t.MetaData.Task.ExecId +} + +// ParentExecId returns the ParentExecId field of TarianMetaData +func (t TarianMetaData) ParentExecId() uint64 { + return t.MetaData.Task.ParentExecId +} + +// Comm returns the Comm field of TarianMetaData +func (t TarianMetaData) Comm() string { + return utils.ToString(t.MetaData.Task.Comm[:], 0, len(t.MetaData.Task.Comm)) +} + +// Sysname returns the Sysname field of TarianMetaData +func (t TarianMetaData) Sysname() string { + return utils.ToString(t.SystemInfo.Sysname[:], 0, len(t.SystemInfo.Sysname)) +} + +// Nodename returns the Nodename field of TarianMetaData +func (t TarianMetaData) Nodename() string { + return utils.ToString(t.SystemInfo.Nodename[:], 0, len(t.SystemInfo.Nodename)) +} + +// Release returns the Release field of TarianMetaData +func (t TarianMetaData) Release() string { + return utils.ToString(t.SystemInfo.Release[:], 0, len(t.SystemInfo.Release)) +} + +// Version returns the Version field of TarianMetaData +func (t TarianMetaData) Version() string { + return utils.ToString(t.SystemInfo.Version[:], 0, len(t.SystemInfo.Version)) +} + +// Machine returns the Machine field of TarianMetaData +func (t TarianMetaData) Machine() string { + return utils.ToString(t.SystemInfo.Machine[:], 0, len(t.SystemInfo.Machine)) +} + +// Domainname returns the Domainname field of TarianMetaData +func (t TarianMetaData) Domainname() string { + return utils.ToString(t.SystemInfo.Domainname[:], 0, len(t.SystemInfo.Domainname)) +} + +// TarianParamType represents the type of Tarian parameter +type TarianParamType uint32 + +const ( + TDT_NONE TarianParamType = 0 // TDT_NONE represents the absence of a Tarian parameter + TDT_U8 TarianParamType = 1 // TDT_U8 represents an 8-bit unsigned integer Tarian parameter + TDT_U16 TarianParamType = 2 // TDT_U16 represents a 16-bit unsigned integer Tarian parameter + TDT_U32 TarianParamType = 3 // TDT_U32 represents a 32-bit unsigned integer Tarian parameter + TDT_U64 TarianParamType = 4 // TDT_U64 represents a 64-bit unsigned integer Tarian parameter + TDT_S8 TarianParamType = 5 // TDT_S8 represents an 8-bit signed integer Tarian parameter + TDT_S16 TarianParamType = 6 // TDT_S16 represents a 16-bit signed integer Tarian parameter + TDT_S32 TarianParamType = 7 // TDT_S32 represents a 32-bit signed integer Tarian parameter + TDT_S64 TarianParamType = 8 // TDT_S64 represents a 64-bit signed integer Tarian parameter + TDT_IPV6 TarianParamType = 9 // TDT_IPV6 represents an IPv6 Tarian parameter + TDT_STR TarianParamType = 10 // TDT_STR represents a string Tarian parameter + TDT_STR_ARR TarianParamType = 11 // TDT_STR_ARR represents an array of strings Tarian parameter + TDT_BYTE_ARR TarianParamType = 12 // TDT_BYTE_ARR represents an array of bytes Tarian parameter + TDT_IOVEC_ARR TarianParamType = 15 // TDT_IOVEC_ARR represents an array of I/O vectors Tarian parameter + TDT_SOCKADDR TarianParamType = 14 // TDT_SOCKADDR represents a socket address Tarian parameter +) + +// String returns the string representation of the TarianParamType +func (t TarianParamType) String() string { + switch t { + case TDT_NONE: + return "TDT_NONE" + case TDT_U8: + return "TDT_U8" + case TDT_U16: + return "TDT_U16" + case TDT_U32: + return "TDT_U32" + case TDT_U64: + return "TDT_U64" + case TDT_S8: + return "TDT_S8" + case TDT_S16: + return "TDT_S16" + case TDT_S32: + return "TDT_S32" + case TDT_S64: + return "TDT_S64" + case TDT_IPV6: + return "TDT_IPV6" + case TDT_STR: + return "TDT_STR" + case TDT_STR_ARR: + return "TDT_STR_ARR" + case TDT_BYTE_ARR: + return "TDT_BYTE_ARR" + case TDT_IOVEC_ARR: + return "TDT_IOVEC_ARR" + case TDT_SOCKADDR: + return "TDT_SOCKADDR" + default: + return fmt.Sprintf("unknown TarianParamType(%d)", int(t)) + } +} + +// TarianEventsE represents the type for Tarian events enumeration. +type TarianEventsE int + +const ( + TDE_SYSCALL_EXECVE_E TarianEventsE = 2 // TDE_SYSCALL_EXECVE_E represents the start of an execve syscall + TDE_SYSCALL_EXECVE_R TarianEventsE = 3 // TDE_SYSCALL_EXECVE_R represents the return of an execve syscall + + TDE_SYSCALL_EXECVEAT_E TarianEventsE = 4 // TDE_SYSCALL_EXECVEAT_E represents the start of an execveat syscall + TDE_SYSCALL_EXECVEAT_R TarianEventsE = 5 // TDE_SYSCALL_EXECVEAT_R represents the return of an execveat syscall + + TDE_SYSCALL_CLONE_E TarianEventsE = 6 // TDE_SYSCALL_CLONE_E represents the start of a clone syscall + TDE_SYSCALL_CLONE_R TarianEventsE = 7 // TDE_SYSCALL_CLONE_R represents the return of a clone syscall + + TDE_SYSCALL_CLOSE_E TarianEventsE = 8 // TDE_SYSCALL_CLOSE_E represents the start of a close syscall + TDE_SYSCALL_CLOSE_R TarianEventsE = 9 // TDE_SYSCALL_CLOSE_R represents the return of a close syscall + + TDE_SYSCALL_READ_E TarianEventsE = 10 // TDE_SYSCALL_READ_E represents the start of a read syscall + TDE_SYSCALL_READ_R TarianEventsE = 11 // TDE_SYSCALL_READ_R represents the return of a read syscall + + TDE_SYSCALL_WRITE_E TarianEventsE = 12 // TDE_SYSCALL_WRITE_E represents the start of a write syscall + TDE_SYSCALL_WRITE_R TarianEventsE = 13 // TDE_SYSCALL_WRITE_R represents the return of a write syscall + + TDE_SYSCALL_OPEN_E TarianEventsE = 14 // TDE_SYSCALL_OPEN_E represents the start of an open syscall + TDE_SYSCALL_OPEN_R TarianEventsE = 15 // TDE_SYSCALL_OPEN_R represents the return of an open syscall + + TDE_SYSCALL_READV_E TarianEventsE = 16 // TDE_SYSCALL_READV_E represents the start of a readv syscall + TDE_SYSCALL_READV_R TarianEventsE = 17 // TDE_SYSCALL_READV_R represents the return of a readv syscall + + TDE_SYSCALL_WRITEV_E TarianEventsE = 18 // TDE_SYSCALL_WRITEV_E represents the start of a writev syscall + TDE_SYSCALL_WRITEV_R TarianEventsE = 19 // TDE_SYSCALL_WRITEV_R represents the return of a writev syscall + + TDE_SYSCALL_OPENAT_E TarianEventsE = 20 // TDE_SYSCALL_OPENAT_E represents the start of an openat syscall + TDE_SYSCALL_OPENAT_R TarianEventsE = 21 // TDE_SYSCALL_OPENAT_R represents the return of an openat syscall + + TDE_SYSCALL_OPENAT2_E TarianEventsE = 22 // TDE_SYSCALL_OPENAT2_E represents the start of an openat2 syscall + TDE_SYSCALL_OPENAT2_R TarianEventsE = 23 // TDE_SYSCALL_OPENAT2_R represents the return of an openat2 syscall + + TDE_SYSCALL_LISTEN_E TarianEventsE = 24 // TDE_SYSCALL_LISTEN_E represents the start of a listen syscall + TDE_SYSCALL_LISTEN_R TarianEventsE = 25 // TDE_SYSCALL_LISTEN_R represents the return of a listen syscall + + TDE_SYSCALL_SOCKET_E TarianEventsE = 26 // TDE_SYSCALL_SOCKET_E represents the start of a socket syscall + TDE_SYSCALL_SOCKET_R TarianEventsE = 27 // TDE_SYSCALL_SOCKET_R represents the return of a socket syscall + + TDE_SYSCALL_ACCEPT_E TarianEventsE = 28 // TDE_SYSCALL_ACCEPT_E represents the start of an accept syscall + TDE_SYSCALL_ACCEPT_R TarianEventsE = 29 // TDE_SYSCALL_ACCEPT_R represents the return of an accept syscall + + TDE_SYSCALL_BIND_E TarianEventsE = 30 // TDE_SYSCALL_BIND_E represents the start of a bind syscall + TDE_SYSCALL_BIND_R TarianEventsE = 31 // TDE_SYSCALL_BIND_R represents the return of a bind syscall + + TDE_SYSCALL_CONNECT_E TarianEventsE = 32 // TDE_SYSCALL_CONNECT_E represents the start of a connect syscall + TDE_SYSCALL_CONNECT_R TarianEventsE = 33 // TDE_SYSCALL_CONNECT_R represents the return of a connect syscall +) + +// String returns the string representation of TarianEventsE +func (t TarianEventsE) String() string { + switch t { + case TDE_SYSCALL_EXECVE_E: + return "TDE_SYSCALL_EXECVE_E" + case TDE_SYSCALL_EXECVE_R: + return "TDE_SYSCALL_EXECVE_R" + case TDE_SYSCALL_CLONE_E: + return "TDE_SYSCALL_CLONE_E" + case TDE_SYSCALL_CLONE_R: + return "TDE_SYSCALL_CLONE_R" + case TDE_SYSCALL_CLOSE_E: + return "TDE_SYSCALL_CLOSE_E" + case TDE_SYSCALL_CLOSE_R: + return "TDE_SYSCALL_CLOSE_R" + case TDE_SYSCALL_READ_E: + return "TDE_SYSCALL_READ_E" + case TDE_SYSCALL_READ_R: + return "TDE_SYSCALL_READ_R" + case TDE_SYSCALL_WRITE_E: + return "TDE_SYSCALL_WRITE_E" + case TDE_SYSCALL_WRITE_R: + return "TDE_SYSCALL_WRITE_R" + case TDE_SYSCALL_OPEN_E: + return "TDE_SYSCALL_OPEN_E" + case TDE_SYSCALL_OPEN_R: + return "TDE_SYSCALL_OPEN_R" + case TDE_SYSCALL_READV_E: + return "TDE_SYSCALL_READV_E" + case TDE_SYSCALL_READV_R: + return "TDE_SYSCALL_READV_R" + case TDE_SYSCALL_WRITEV_E: + return "TDE_SYSCALL_WRITEV_E" + case TDE_SYSCALL_WRITEV_R: + return "TDE_SYSCALL_WRITEV_R" + case TDE_SYSCALL_OPENAT_E: + return "TDE_SYSCALL_OPENAT_E" + case TDE_SYSCALL_OPENAT_R: + return "TDE_SYSCALL_OPENAT_R" + case TDE_SYSCALL_OPENAT2_E: + return "TDE_SYSCALL_OPENAT2_E" + case TDE_SYSCALL_OPENAT2_R: + return "TDE_SYSCALL_OPENAT2_R" + case TDE_SYSCALL_LISTEN_E: + return "TDE_SYSCALL_LISTEN_E" + case TDE_SYSCALL_LISTEN_R: + return "TDE_SYSCALL_LISTEN_R" + case TDE_SYSCALL_SOCKET_E: + return "TDE_SYSCALL_SOCKET_E" + case TDE_SYSCALL_SOCKET_R: + return "TDE_SYSCALL_SOCKET_R" + case TDE_SYSCALL_ACCEPT_E: + return "TDE_SYSCALL_ACCEPT_E" + case TDE_SYSCALL_ACCEPT_R: + return "TDE_SYSCALL_ACCEPT_R" + case TDE_SYSCALL_BIND_E: + return "TDE_SYSCALL_BIND_E" + case TDE_SYSCALL_BIND_R: + return "TDE_SYSCALL_BIND_R" + case TDE_SYSCALL_CONNECT_E: + return "TDE_SYSCALL_CONNECT_E" + case TDE_SYSCALL_CONNECT_R: + return "TDE_SYSCALL_CONNECT_R" + default: + return fmt.Sprintf("unknown TarianEventsE(%d)", int(t)) + } +} diff --git a/pkg/eventparser/types_test.go b/pkg/eventparser/types_test.go new file mode 100644 index 0000000..be4648f --- /dev/null +++ b/pkg/eventparser/types_test.go @@ -0,0 +1,794 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Authors of Tarian & the Organization created Tarian + +package eventparser + +import ( + "testing" +) + +// TestTarianMetaData_Event tests the Event function. +func TestTarianMetaData_Event(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want int32 + }{ + { + name: "default values", + fields: TarianMetaData{}, + want: 0, + }, + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Event = 29 + return t + }(), + want: 29, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Event(); got != tt.want { + t.Errorf("TarianMetaData.Event() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Nparams tests the Nparams function. +func TestTarianMetaData_Nparams(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint8 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Nparams = 4 + return t + }(), + want: 4, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Nparams(); got != tt.want { + t.Errorf("TarianMetaData.Nparams() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Syscall tests the Syscall function. +func TestTarianMetaData_Syscall(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want int32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Syscall = 29 + return t + }(), + want: 29, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Syscall(); got != tt.want { + t.Errorf("TarianMetaData.Syscall() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Ts tests the Ts function. +func TestTarianMetaData_Ts(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Ts = 2932984232342 + return t + }(), + want: 2932984232342, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Ts(); got != tt.want { + t.Errorf("TarianMetaData.Ts() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Processor tests the Processor function. +func TestTarianMetaData_Processor(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint16 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Processor = 15 + return t + }(), + want: 15, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Processor(); got != tt.want { + t.Errorf("TarianMetaData.Processor() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_StartTime tests the StartTime function. +func TestTarianMetaData_StartTime(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.StartTime = 7423975270240932424 + return t + }(), + want: 7423975270240932424, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.StartTime(); got != tt.want { + t.Errorf("TarianMetaData.StartTime() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_HostPid tests the HostPid function. +func TestTarianMetaData_HostPid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.HostPid = 344532 + return t + }(), + want: 344532, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.HostPid(); got != tt.want { + t.Errorf("TarianMetaData.HostPid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_HostTgid tests the HostTgid function. +func TestTarianMetaData_HostTgid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.HostTgid = 32342 + return t + }(), + want: 32342, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.HostTgid(); got != tt.want { + t.Errorf("TarianMetaData.HostTgid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_HostPpid tests the HostPpid function. +func TestTarianMetaData_HostPpid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.HostPpid = 54354345 + return t + }(), + want: 54354345, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.HostPpid(); got != tt.want { + t.Errorf("TarianMetaData.HostPpid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Pid tests the Pid function. +func TestTarianMetaData_Pid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.Pid = 232543534 + return t + }(), + want: 232543534, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Pid(); got != tt.want { + t.Errorf("TarianMetaData.Pid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Tgid tests the Tgid function. +func TestTarianMetaData_Tgid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.Tgid = 345252 + return t + }(), + want: 345252, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Tgid(); got != tt.want { + t.Errorf("TarianMetaData.Tgid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Ppid tests the Ppid function. +func TestTarianMetaData_Ppid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.Ppid = 257435 + return t + }(), + want: 257435, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Ppid(); got != tt.want { + t.Errorf("TarianMetaData.Ppid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Uid tests the Uid function. +func TestTarianMetaData_Uid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.Uid = 12345 + return t + }(), + want: 12345, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Uid(); got != tt.want { + t.Errorf("TarianMetaData.Uid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Gid tests the Gid function. +func TestTarianMetaData_Gid(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint32 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.Gid = 9876543 + return t + }(), + want: 9876543, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Gid(); got != tt.want { + t.Errorf("TarianMetaData.Gid() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_CgroupId tests the CgroupId function. +func TestTarianMetaData_CgroupId(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.CgroupId = 9342795229 + return t + }(), + want: 9342795229, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.CgroupId(); got != tt.want { + t.Errorf("TarianMetaData.CgroupId() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_MountNsId tests the MountNsId function. +func TestTarianMetaData_MountNsId(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.MountNsId = 432543253 + return t + }(), + want: 432543253, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.MountNsId(); got != tt.want { + t.Errorf("TarianMetaData.MountNsId() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_PidNsId tests the PidNsId function. +func TestTarianMetaData_PidNsId(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.PidNsId = 7425928524 + return t + }(), + want: 7425928524, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.PidNsId(); got != tt.want { + t.Errorf("TarianMetaData.PidNsId() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_ExecId tests the ExecId function. +func TestTarianMetaData_ExecId(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.ExecId = 12432543632652652632 + return t + }(), + want: 12432543632652652632, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.ExecId(); got != tt.want { + t.Errorf("TarianMetaData.ExecId() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_ParentExecId tests the ParentExecId function. +func TestTarianMetaData_ParentExecId(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want uint64 + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.ParentExecId = 4358723423092423121 + return t + }(), + want: 4358723423092423121, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.ParentExecId(); got != tt.want { + t.Errorf("TarianMetaData.ParentExecId() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Comm tests the Comm function. +func TestTarianMetaData_Comm(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.MetaData.Task.Comm = [16]byte{99, 111, 109, 109, 0} + return t + }(), + want: "comm", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Comm(); got != tt.want { + t.Errorf("TarianMetaData.Comm() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Sysname tests the Sysname function. +func TestTarianMetaData_Sysname(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.SystemInfo.Sysname = [65]byte{0, 0, 115, 121, 115, 0} + return t + }(), + want: "sys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Sysname(); got != tt.want { + t.Errorf("TarianMetaData.Sysname() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Nodename tests the Nodename function. +func TestTarianMetaData_Nodename(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.SystemInfo.Nodename = [65]byte{115, 121, 115, 0} + return t + }(), + want: "sys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Nodename(); got != tt.want { + t.Errorf("TarianMetaData.Nodename() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Release tests the Release function. +func TestTarianMetaData_Release(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.SystemInfo.Release = [65]byte{115, 121, 115} + return t + }(), + want: "sys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Release(); got != tt.want { + t.Errorf("TarianMetaData.Release() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Version tests the Version function. +func TestTarianMetaData_Version(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.SystemInfo.Version = [65]byte{115, 121, 115} + return t + }(), + want: "sys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Version(); got != tt.want { + t.Errorf("TarianMetaData.Version() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Machine tests the Machine function. +func TestTarianMetaData_Machine(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.SystemInfo.Machine = [65]byte{115, 121, 115} + return t + }(), + want: "sys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Machine(); got != tt.want { + t.Errorf("TarianMetaData.Machine() = %v, want %v", got, tt.want) + } + }) + } +} + +// TestTarianMetaData_Domainname tests the Domainname function. +func TestTarianMetaData_Domainname(t *testing.T) { + tests := []struct { + name string + fields TarianMetaData + want string + }{ + { + name: "valid values", + fields: func() TarianMetaData { + var t TarianMetaData + t.SystemInfo.Domainname = [65]byte{115, 121, 115} + return t + }(), + want: "sys", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tr := TarianMetaData{ + MetaData: tt.fields.MetaData, + SystemInfo: tt.fields.SystemInfo, + } + if got := tr.Domainname(); got != tt.want { + t.Errorf("TarianMetaData.Domainname() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 3650d87..8755a0c 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -4,8 +4,6 @@ package utils import ( - "fmt" - "log" "os" "strconv" @@ -58,24 +56,3 @@ func CurrentKernelVersion() (int, error) { return KernelVersion(a, b, c), nil } - -// PrintEvent prints the given data map along with a total captured count and a divider. -// It uses a predefined set of keys to extract values from the data map. -func PrintEvent(data map[string]any, t int) { - keys := []string{ - "eventId", "timestamp", "syscallId", "processor", - "threadStartTime", "hostProcessId", "hostThreadId", - "hostParentProcessId", "processId", "threadId", "parentProcessId", - "userId", "groupId", "cgroupId", "mountNamespace", "pidNamespace", - "execId", "parentExecId", "processName", "directory", - "sysname", "nodename", "release", "version", "machine", "domainname", - "context", - } - div := "==================================" - msg := "" - for _, ky := range keys { - msg += fmt.Sprintf("%s: %+v\n", ky, data[ky]) - } - - log.Printf("Total captured %d.\n%s\n%s%s\n", t, div, msg, div) -} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 6692736..6a79154 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -152,36 +152,3 @@ func TestCurrentKernelVersion(t *testing.T) { }) } } - -// TestPrintEvent is a Go function for testing the PrintEvent function. -func TestPrintEvent(t *testing.T) { - type args struct { - data map[string]any - t int - } - tests := []struct { - name string - args args - }{ - { - name: "empty map", - args: args{ - data: map[string]any{}, - t: 0, - }, - }, { - name: "non empty map", - args: args{ - data: map[string]any{ - "eventId": "sys_test", - "syscallId": -1, - }, - t: 0, - }, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - PrintEvent(tt.args.data, tt.args.t) - }) - } -} diff --git a/tarian/c/utils/meta.h b/tarian/c/utils/meta.h index aac0b9c..61d480c 100644 --- a/tarian/c/utils/meta.h +++ b/tarian/c/utils/meta.h @@ -7,6 +7,7 @@ stain int new_event(void *, int, tarian_event_t *, enum allocation_type,int); stain int init_tarian_meta_data_t(tarian_event_t *, int); stain int init_task_meta_data_t(tarian_event_t *); stain int init_event_meta_data_t(tarian_event_t *, int); +stain int init_cwd_and_exe(tarian_event_t *); stain int read_node_info_into(node_meta_data_t *ni, struct task_struct *t); stain int new_event(void *ctx, int tarian_event, tarian_event_t *te, enum allocation_type at,int req_buf_sz) { @@ -18,9 +19,6 @@ stain int new_event(void *ctx, int tarian_event, tarian_event_t *te, enum alloca te->ctx = ctx; te->task = (struct task_struct *)bpf_get_current_task(); - scratch_space_t *ss = get__scratch_space(); - if (!ss) return TDCE_SCRATCH_SPACE_ALLOCATION; - int resp = tdf_reserve_space(te, at , req_buf_sz); if (resp != TDC_SUCCESS) return resp; @@ -32,20 +30,10 @@ stain int new_event(void *ctx, int tarian_event, tarian_event_t *te, enum alloca resp = init_tarian_meta_data_t(te, tarian_event); if (resp != TDC_SUCCESS) return resp; - - uint32_t len = 0; - u8 *filepath = get__cwd_d_path(&len, ss, te->task); - - if (len > 255) { - stats__add_buffer(); - } - resp = flush(te->tarian->meta_data.task.cwd, sizeof(te->tarian->meta_data.task.cwd)); - if (resp != TDC_SUCCESS) { - return resp; - } - bpf_probe_read_kernel_str(te->tarian->meta_data.task.cwd, len & (MAX_TARIAN_PATH - 1), filepath); - + resp = init_cwd_and_exe(te); + if (resp != TDC_SUCCESS) return resp; + return TDC_SUCCESS; }; @@ -81,12 +69,20 @@ stain int init_task_meta_data_t(tarian_event_t *te) { tm->start_time = get_task_start_time(te->task); + /* + Just for reference + https://github.com/aquasecurity/tracee/blob/935ad012f0a040bb04b7f3b0c574a36a4e9cc909/pkg/ebpf/c/common/context.h#L125C1-L127C48 + */ u64 ptid = bpf_get_current_pid_tgid(); tm->host_tgid = ptid; tm->host_pid = ptid >> 32; tm->host_ppid = get_task_ppid(te->task); + /* + This is not a mistake. Followed this from tracee. + https://github.com/aquasecurity/tracee/blob/935ad012f0a040bb04b7f3b0c574a36a4e9cc909/pkg/ebpf/c/common/context.h#L33C1-L34C43 + */ tm->pid = get_task_ns_tgid(te->task); tm->tgid = get_task_ns_pid(te->task); @@ -109,6 +105,27 @@ stain int init_task_meta_data_t(tarian_event_t *te) { return TDC_SUCCESS; }; +stain int init_cwd_and_exe(tarian_event_t *te) { + scratch_space_t *ss = get__scratch_space(); + if (!ss) return TDCE_SCRATCH_SPACE_ALLOCATION; + + uint32_t len = 0; + struct path path = get_task_directory(te->task); + u8 *filepath = get__d_path(&len, ss, &path); + + // filepath + write_str(te->buf.data, &te->buf.pos, (unsigned long)filepath, len & (MAX_TARIAN_PATH - 1), KERNEL); + + uint32_t exe_len = 0; + struct path exe_path = get_task_executable(te->task); + u8 *executable = get__d_path(&exe_len, ss, &exe_path); + + // executable + write_str(te->buf.data, &te->buf.pos, (unsigned long)executable, exe_len & (MAX_TARIAN_PATH - 1), KERNEL); + + return TDC_SUCCESS; +} + stain int read_node_info_into(node_meta_data_t *nm, struct task_struct *t) { if (nm == NULL) return TDCE_NULL_POINTER; diff --git a/tarian/c/utils/shared.h b/tarian/c/utils/shared.h index f97b3d2..114b032 100644 --- a/tarian/c/utils/shared.h +++ b/tarian/c/utils/shared.h @@ -91,12 +91,11 @@ stain void print_event(tarian_event_t *te) { bpf_printk("19. parent_exec %ld 20. sysname %s 21. nodename %s ", te->tarian->meta_data.task.parent_exec_id, te->tarian->system_info.sysname, te->tarian->system_info.nodename); bpf_printk("22. release %s 23. version %s", te->tarian->system_info.release, te->tarian->system_info.version); bpf_printk("24. machine %s 25. domainname %s 26. nparams %d", te->tarian->system_info.machine, te->tarian->system_info.domainname, te->tarian->meta_data.nparams); - bpf_printk("27. cwd %s", te->tarian->meta_data.task.cwd); }; #define SCRATCH_SAFE_ACCESS(x) (x) & (MAX_STRING_SIZE - 1) -stain uint8_t *get__cwd_d_path(uint32_t *slen, scratch_space_t *s, struct task_struct *task) { - struct path path = BPF_CORE_READ(task, fs, pwd); +stain uint8_t *get__d_path(uint32_t *slen, scratch_space_t *s, struct path *p) { + struct path path = *p; struct dentry *dentry = path.dentry; struct vfsmount *vfsmnt = path.mnt; diff --git a/tarian/c/utils/shared/constants.h b/tarian/c/utils/shared/constants.h index c0fcfef..c51d5bd 100644 --- a/tarian/c/utils/shared/constants.h +++ b/tarian/c/utils/shared/constants.h @@ -4,7 +4,7 @@ #define MAX_PATH_LOOP 20 #define MAX_NODE_FIELD_SIZE 65 /* 65B */ #define MAX_STRING_SIZE 4096 -#define MAX_TARIAN_PATH 256 +#define MAX_TARIAN_PATH 4096 #define MAX_SCRATCH_SPACE 8192 #define MAX_BUFFER_SIZE 1024 * 128 /* 128kB */ #define MAX_EVENT_SIZE 64 * 1024 /* 64kB */ @@ -115,8 +115,9 @@ typedef enum tarian_events_e{ } tarian_event_code; /*****Event Data Size - START****/ -#define MD_SIZE sizeof(tarian_meta_data_t) /* sizeof tarian meta data for each event*/ -#define PARAM_SIZE sizeof(uint16_t) +/* sizeof tarian meta data for each event*/ +#define MD_SIZE sizeof(tarian_meta_data_t) + MAX_TARIAN_PATH * 2 + PARAM_SIZE * 2 /* for directory and executable*/ +#define PARAM_SIZE sizeof(uint16_t) /* appended before an variable length argument represents size of the argument data*/ #define TDS_EXECVE_E (MD_SIZE + MAX_STRING_SIZE*2 + PARAM_SIZE*2) #define TDS_EXECVE_R (MD_SIZE + sizeof(int32_t)) diff --git a/tarian/c/utils/shared/maps.h b/tarian/c/utils/shared/maps.h index 790cfb9..f474b4e 100644 --- a/tarian/c/utils/shared/maps.h +++ b/tarian/c/utils/shared/maps.h @@ -77,6 +77,7 @@ stain void *get__scratch_space() { uint32_t index = 0; return bpf_map_lookup_elem(&scratch_space, &index); } + /* * * PER_CPU_ARRAY diff --git a/tarian/c/utils/shared/task.h b/tarian/c/utils/shared/task.h index 47bef55..bd67fe1 100644 --- a/tarian/c/utils/shared/task.h +++ b/tarian/c/utils/shared/task.h @@ -64,4 +64,10 @@ stain struct task_struct *get_task_parent(struct task_struct *task) { return BPF_CORE_READ(task, parent); } +stain struct path get_task_directory(struct task_struct *task) { + return BPF_CORE_READ(task, fs, pwd); +} +stain struct path get_task_executable(struct task_struct *task) { + return BPF_CORE_READ(task, mm, exe_file, f_path); +} #endif diff --git a/tarian/c/utils/shared/types.h b/tarian/c/utils/shared/types.h index 8a1c4db..4e10580 100644 --- a/tarian/c/utils/shared/types.h +++ b/tarian/c/utils/shared/types.h @@ -57,8 +57,7 @@ typedef struct __attribute__((__packed__)) task_meta_data { u64 parent_exec_id; /* user defined: parent execution id*/ u8 comm[TASK_COMM_LEN]; /* task's process name*/ - u8 cwd[MAX_TARIAN_PATH]; -} task_meta_data_t; /* 352B */ +} task_meta_data_t; /* 96B */ typedef struct __attribute__((__packed__)) event_meta_data { s32 event; /* event id associated with the event */ @@ -67,12 +66,12 @@ typedef struct __attribute__((__packed__)) event_meta_data { u64 ts; /* event timestamp */ u16 processor; /* processor id where the event was processed */ task_meta_data_t task; /* event's task meta data */ -} event_meta_data_t; /* 371B */ +} event_meta_data_t; /* 115B */ typedef struct __attribute__((__packed__)) tarian_meta_data { event_meta_data_t meta_data; node_meta_data_t system_info; /* system information */ -} tarian_meta_data_t; /* 761B */ +} tarian_meta_data_t; /* 505B */ typedef struct event { /* 1 - buf on per cpu array for perf event 2 - ringbuf map 3 - buf on per cpu @@ -112,6 +111,6 @@ typedef struct tarian_stats { /* count of untracked scenarios */ u64 n_trgs_unknown; -} tarian_stats_t; /* 48B */ +} tarian_stats_t; /* 64B */ #endif \ No newline at end of file diff --git a/tarian/tarian.go b/tarian/tarian.go index 8902df1..241c3d4 100644 --- a/tarian/tarian.go +++ b/tarian/tarian.go @@ -30,8 +30,8 @@ func GetModule() (*ebpf.Module, error) { return nil, tarianErr.Throwf("%v", err) } - // update_application_pid updates the application pid to the kernel - err = update_application_pid(bpfObjs.TarianDetectorApplicationPid) + // updateApplicationPid updates the application pid to the kernel + err = updateApplicationPid(bpfObjs.TarianDetectorApplicationPid) if err != nil { return nil, err } @@ -126,7 +126,7 @@ func getBpfObject() (*tarianObjects, error) { return &bpfObj, nil } -// update_application_pid updates the application pid to the kernel +// updateApplicationPid updates the application pid to the kernel // // This function updates the application pid to the kernel through a map. // The map is declared in the eBPF spec and its name is `tarian_detector_application_pid`. @@ -135,7 +135,7 @@ func getBpfObject() (*tarianObjects, error) { // // The function uses `ebpf.Map.Update` with `ebpf.UpdateAny` option to update the map. // If there is an error, it returns a formatted error from the tarianErr package. -func update_application_pid(m *cilium_ebpf.Map) error { +func updateApplicationPid(m *cilium_ebpf.Map) error { var key uint32 = 0 var value uint32 = uint32(os.Getpid()) diff --git a/tarian/tarian_x86_bpfel.o b/tarian/tarian_x86_bpfel.o index fae3ee7..6568f98 100644 Binary files a/tarian/tarian_x86_bpfel.o and b/tarian/tarian_x86_bpfel.o differ