diff --git a/pkg/security/ebpf/c/include/helpers/activity_dump.h b/pkg/security/ebpf/c/include/helpers/activity_dump.h index e4440703711951..dee1fce2bc2147 100644 --- a/pkg/security/ebpf/c/include/helpers/activity_dump.h +++ b/pkg/security/ebpf/c/include/helpers/activity_dump.h @@ -46,12 +46,7 @@ __attribute__((always_inline)) struct activity_dump_config *lookup_or_delete_tra __attribute__((always_inline)) struct cgroup_tracing_event_t *get_cgroup_tracing_event() { u32 key = bpf_get_current_pid_tgid() % EVENT_GEN_SIZE; - struct cgroup_tracing_event_t *evt = bpf_map_lookup_elem(&cgroup_tracing_event_gen, &key); - if (evt == NULL) { - return 0; - } - evt->container.container_id[0] = 0; - return evt; + return bpf_map_lookup_elem(&cgroup_tracing_event_gen, &key); } __attribute__((always_inline)) u32 is_cgroup_activity_dumps_supported(struct cgroup_context_t *cgroup) { @@ -113,11 +108,6 @@ __attribute__((always_inline)) u64 trace_new_cgroup(void *ctx, u64 now, struct c return 0; } - if ((container->cgroup_context.cgroup_flags&CGROUP_MANAGER_MASK) != CGROUP_MANAGER_SYSTEMD) { - copy_container_id(container->container_id, evt->container.container_id); - } else { - evt->container.container_id[0] = '\0'; - } evt->container.cgroup_context = container->cgroup_context; evt->cookie = cookie; evt->config = config; diff --git a/pkg/security/ebpf/c/include/helpers/container.h b/pkg/security/ebpf/c/include/helpers/container.h index c75de85ba6a347..a5bc665f2b6c2b 100644 --- a/pkg/security/ebpf/c/include/helpers/container.h +++ b/pkg/security/ebpf/c/include/helpers/container.h @@ -12,7 +12,6 @@ static __attribute__((always_inline)) void copy_container_id(const container_id_ static void __attribute__((always_inline)) fill_container_context(struct proc_cache_t *entry, struct container_context_t *context) { if (entry) { - copy_container_id(entry->container.container_id, context->container_id); context->cgroup_context = entry->container.cgroup_context; } } diff --git a/pkg/security/ebpf/c/include/helpers/dns.h b/pkg/security/ebpf/c/include/helpers/dns.h index f6e394fbc08db7..9e7532dc5c0bd6 100644 --- a/pkg/security/ebpf/c/include/helpers/dns.h +++ b/pkg/security/ebpf/c/include/helpers/dns.h @@ -33,10 +33,7 @@ __attribute__((always_inline)) struct dns_event_t *reset_dns_event(struct __sk_b fill_network_context(&evt->network, skb, pkt); struct proc_cache_t *entry = get_proc_cache(evt->process.pid); - if (entry == NULL) { - evt->container.container_id[0] = 0; - } else { - copy_container_id_no_tracing(entry->container.container_id, &evt->container.container_id); + if (entry != NULL) { evt->container.cgroup_context = entry->container.cgroup_context; } diff --git a/pkg/security/ebpf/c/include/helpers/imds.h b/pkg/security/ebpf/c/include/helpers/imds.h index c53b53c15f9e0f..d5b9f45df1ffeb 100644 --- a/pkg/security/ebpf/c/include/helpers/imds.h +++ b/pkg/security/ebpf/c/include/helpers/imds.h @@ -29,13 +29,6 @@ __attribute__((always_inline)) struct imds_event_t *reset_imds_event(struct __sk // network context fill_network_context(&evt->network, skb, pkt); - struct proc_cache_t *entry = get_proc_cache(evt->process.pid); - if (entry == NULL) { - evt->container.container_id[0] = 0; - } else { - copy_container_id_no_tracing(entry->container.container_id, &evt->container.container_id); - } - // should we sample this event for activity dumps ? struct activity_dump_config *config = lookup_or_delete_traced_pid(evt->process.pid, bpf_ktime_get_ns(), NULL); if (config) { diff --git a/pkg/security/ebpf/c/include/helpers/process.h b/pkg/security/ebpf/c/include/helpers/process.h index eeefb2359685dd..99e7134eb20673 100644 --- a/pkg/security/ebpf/c/include/helpers/process.h +++ b/pkg/security/ebpf/c/include/helpers/process.h @@ -39,7 +39,6 @@ void __attribute__((always_inline)) copy_proc_entry(struct process_entry_t *src, } void __attribute__((always_inline)) copy_proc_cache(struct proc_cache_t *src, struct proc_cache_t *dst) { - copy_container_id(src->container.container_id, dst->container.container_id); dst->container.cgroup_context.cgroup_flags = src->container.cgroup_context.cgroup_flags; copy_proc_entry(&src->entry, &dst->entry); } diff --git a/pkg/security/ebpf/c/include/hooks/cgroup.h b/pkg/security/ebpf/c/include/hooks/cgroup.h index e6856337759a36..7599ca36f42093 100644 --- a/pkg/security/ebpf/c/include/hooks/cgroup.h +++ b/pkg/security/ebpf/c/include/hooks/cgroup.h @@ -72,10 +72,6 @@ static __attribute__((always_inline)) int trace__cgroup_write(ctx_t *ctx) { // Select the old cache entry old_entry = get_proc_from_cookie(cookie); if (old_entry) { - if ((old_entry->container.container_id[0] != '\0') && old_entry->container.cgroup_context.cgroup_flags && (old_entry->container.cgroup_context.cgroup_flags != CGROUP_MANAGER_SYSTEMD)) { - return 0; - } - // copy cache data copy_proc_cache(old_entry, &new_entry); } @@ -196,8 +192,6 @@ static __attribute__((always_inline)) int trace__cgroup_write(ctx_t *ctx) { } else if (length >= 7 && (*prefix)[length-7] == '.' && (*prefix)[length-6] == 's' && (*prefix)[length-5] == 'c' && (*prefix)[length-4] == 'o' && (*prefix)[length-3] == 'p' && (*prefix)[length-2] == 'e') { cgroup_flags = CGROUP_MANAGER_SYSTEMD | CGROUP_SYSTEMD_SCOPE; } - } else { - bpf_probe_read(&new_entry.container.container_id, sizeof(new_entry.container.container_id), container_id); } new_entry.container.cgroup_context.cgroup_flags = cgroup_flags; diff --git a/pkg/security/ebpf/c/include/hooks/network/raw.h b/pkg/security/ebpf/c/include/hooks/network/raw.h index 6f46f6b4eb1a2e..21c7331839767a 100644 --- a/pkg/security/ebpf/c/include/hooks/network/raw.h +++ b/pkg/security/ebpf/c/include/hooks/network/raw.h @@ -26,13 +26,6 @@ int classifier_raw_packet_sender(struct __sk_buff *skb) { // process context fill_network_process_context(&evt->process, pkt); - struct proc_cache_t *entry = get_proc_cache(evt->process.pid); - if (entry == NULL) { - evt->container.container_id[0] = 0; - } else { - copy_container_id_no_tracing(entry->container.container_id, &evt->container.container_id); - } - fill_network_device_context(&evt->device, skb, pkt); u32 len = evt->len; diff --git a/pkg/security/ebpf/c/include/hooks/raw_syscalls.h b/pkg/security/ebpf/c/include/hooks/raw_syscalls.h index 50e9e456287325..d02a79c5c63317 100644 --- a/pkg/security/ebpf/c/include/hooks/raw_syscalls.h +++ b/pkg/security/ebpf/c/include/hooks/raw_syscalls.h @@ -20,7 +20,7 @@ int sys_enter(struct _tracepoint_raw_syscalls_sys_enter *args) { fill_container_context(proc_cache_entry, &event.container); // check if this event should trigger a syscall drift event - if (is_anomaly_syscalls_enabled() && event.container.container_id[0] != 0) { + if (is_anomaly_syscalls_enabled() && (event.container.cgroup_context.cgroup_flags != 0)) { // fetch the profile for the current container struct security_profile_t *profile = bpf_map_lookup_elem(&security_profiles, &event.container); if (profile) { diff --git a/pkg/security/ebpf/c/include/structs/events_context.h b/pkg/security/ebpf/c/include/structs/events_context.h index 476f08a0e7c89d..98feaa4281e84d 100644 --- a/pkg/security/ebpf/c/include/structs/events_context.h +++ b/pkg/security/ebpf/c/include/structs/events_context.h @@ -65,7 +65,6 @@ struct cgroup_context_t { }; struct container_context_t { - container_id_t container_id; struct cgroup_context_t cgroup_context; }; diff --git a/pkg/security/probe/probe_ebpf.go b/pkg/security/probe/probe_ebpf.go index 075d9e4171c8af..c78859583fe58b 100644 --- a/pkg/security/probe/probe_ebpf.go +++ b/pkg/security/probe/probe_ebpf.go @@ -638,7 +638,7 @@ func (p *EBPFProbe) EventMarshallerCtor(event *model.Event) func() events.EventM } func (p *EBPFProbe) unmarshalContexts(data []byte, event *model.Event) (int, error) { - read, err := model.UnmarshalBinary(data, &event.PIDContext, &event.SpanContext, event.ContainerContext, &event.CGroupContext) + read, err := model.UnmarshalBinary(data, &event.PIDContext, &event.SpanContext, &event.CGroupContext) if err != nil { return 0, err } @@ -732,25 +732,31 @@ func (p *EBPFProbe) zeroEvent() *model.Event { return p.event } -func (p *EBPFProbe) resolveCGroup(pid uint32, cgroupPathKey model.PathKey, cgroupFlags containerutils.CGroupFlags, newEntryCb func(entry *model.ProcessCacheEntry, err error)) (*model.CGroupContext, error) { +func (p *EBPFProbe) resolveCGroup(pid uint32, cgroupPathKey model.PathKey, cgroupFlags containerutils.CGroupFlags, newEntryCb func(entry *model.ProcessCacheEntry, err error)) (*model.CGroupContext, containerutils.ContainerID, error) { pce := p.Resolvers.ProcessResolver.Resolve(pid, pid, 0, false, newEntryCb) - if pce != nil { - cgroupContext, err := p.Resolvers.ResolveCGroupContext(cgroupPathKey, cgroupFlags) - if err != nil { - return nil, fmt.Errorf("failed to resorve cgroup for pid %d: %w", pid, err) - } + if pce == nil { + return nil, "", fmt.Errorf("entry not found for pid %d", pid) + } + + cgroupContext, err := p.Resolvers.ResolveCGroupContext(cgroupPathKey, cgroupFlags) + if err != nil { + return nil, "", fmt.Errorf("failed to reserve cgroup for pid %d: %w", pid, err) + } - pce.Process.CGroup = *cgroupContext - pce.CGroup = *cgroupContext - if cgroupContext.CGroupFlags.IsContainer() { - containerID, _ := containerutils.FindContainerID(cgroupContext.CGroupID) - pce.ContainerID = containerID - pce.Process.ContainerID = containerID + pce.Process.CGroup = *cgroupContext + pce.CGroup = *cgroupContext + + if cgroupContext.CGroupFlags.IsContainer() || cgroupContext.CGroupFlags == 0 { + containerID, parsedCgroupFlags := containerutils.FindContainerID(cgroupContext.CGroupID) + pce.ContainerID = containerID + pce.Process.ContainerID = containerID + if parsedCgroupFlags != 0 && parsedCgroupFlags != uint64(cgroupFlags) { + pce.Process.CGroup.CGroupFlags = containerutils.CGroupFlags(parsedCgroupFlags) + pce.CGroup.CGroupFlags = containerutils.CGroupFlags(parsedCgroupFlags) } - } else { - return nil, fmt.Errorf("entry not found for pid %d", pid) } - return &pce.CGroup, nil + + return &pce.CGroup, pce.ContainerID, nil } func (p *EBPFProbe) handleEvent(CPU int, data []byte) { @@ -836,7 +842,7 @@ func (p *EBPFProbe) handleEvent(CPU int, data []byte) { seclog.Errorf("failed to decode cgroup tracing event: %s (offset %d, len %d)", err, offset, dataLen) return } - if cgroupContext, err := p.resolveCGroup(event.CgroupTracing.Pid, event.CgroupTracing.CGroupContext.CGroupFile, event.CgroupTracing.CGroupContext.CGroupFlags, newEntryCb); err != nil { + if cgroupContext, _, err := p.resolveCGroup(event.CgroupTracing.Pid, event.CgroupTracing.CGroupContext.CGroupFile, event.CgroupTracing.CGroupContext.CGroupFlags, newEntryCb); err != nil { seclog.Debugf("Failed to resolve cgroup: %s", err.Error()) } else { event.CgroupTracing.CGroupContext = *cgroupContext @@ -845,10 +851,10 @@ func (p *EBPFProbe) handleEvent(CPU int, data []byte) { return case model.CgroupWriteEventType: if _, err = event.CgroupWrite.UnmarshalBinary(data[offset:]); err != nil { - seclog.Errorf("failed to decode cgroup write released event: %s (offset %d, len %d)", err, offset, dataLen) + seclog.Errorf("failed to decode cgroup write event: %s (offset %d, len %d)", err, offset, dataLen) return } - if _, err := p.resolveCGroup(event.CgroupWrite.Pid, event.CgroupWrite.File.PathKey, containerutils.CGroupFlags(event.CgroupWrite.CGroupFlags), newEntryCb); err != nil { + if _, _, err := p.resolveCGroup(event.CgroupWrite.Pid, event.CgroupWrite.File.PathKey, containerutils.CGroupFlags(event.CgroupWrite.CGroupFlags), newEntryCb); err != nil { seclog.Debugf("Failed to resolve cgroup: %s", err.Error()) } return @@ -899,7 +905,16 @@ func (p *EBPFProbe) handleEvent(CPU int, data []byte) { seclog.Errorf("failed to insert exec event: %s (pid %d, offset %d, len %d)", err, event.PIDContext.Pid, offset, len(data)) return } - + default: + if !event.CGroupContext.CGroupFile.IsNull() { + cgroupContext, containerID, err := p.resolveCGroup(event.PIDContext.Pid, event.CGroupContext.CGroupFile, event.CGroupContext.CGroupFlags, newEntryCb) + if err != nil { + seclog.Errorf("failed to resolve cgroup context for event %s: %s", err, eventType.String()) + } else { + event.CGroupContext.Merge(cgroupContext) + event.ContainerContext.ContainerID = containerID + } + } } if !p.setProcessContext(eventType, event, newEntryCb) { diff --git a/pkg/security/resolvers/process/resolver_ebpf.go b/pkg/security/resolvers/process/resolver_ebpf.go index 638c03b51b791a..ba5fe708d9fe05 100644 --- a/pkg/security/resolvers/process/resolver_ebpf.go +++ b/pkg/security/resolvers/process/resolver_ebpf.go @@ -862,17 +862,12 @@ func (p *EBPFResolver) resolveFromKernelMaps(pid, tid uint32, inode uint64, newE entry := p.NewProcessCacheEntry(model.PIDContext{Pid: pid, Tid: tid, ExecInode: inode}) var ctrCtx model.ContainerContext - read, err := ctrCtx.UnmarshalBinary(procCache) - if err != nil { - return nil - } - cgroupRead, err := entry.CGroup.UnmarshalBinary(procCache) if err != nil { return nil } - if _, err := entry.UnmarshalProcEntryBinary(procCache[read+cgroupRead:]); err != nil { + if _, err := entry.UnmarshalProcEntryBinary(procCache[cgroupRead:]); err != nil { return nil } @@ -1295,7 +1290,7 @@ func (p *EBPFResolver) newEntryFromProcfsAndSyncKernelMaps(proc *process.Process bootTime := p.timeResolver.GetBootTime() // insert new entry in kernel maps - procCacheEntryB := make([]byte, 248) + procCacheEntryB := make([]byte, 184) _, err := entry.Process.MarshalProcCache(procCacheEntryB, bootTime) if err != nil { seclog.Errorf("couldn't marshal proc_cache entry: %s", err) diff --git a/pkg/security/secl/model/marshallers_linux.go b/pkg/security/secl/model/marshallers_linux.go index 4ea841cd8fc3bd..5950ae3e041a63 100644 --- a/pkg/security/secl/model/marshallers_linux.go +++ b/pkg/security/secl/model/marshallers_linux.go @@ -72,14 +72,12 @@ func (e *FileFields) MarshalBinary(data []byte) (int, error) { // MarshalProcCache marshals a binary representation of itself func (e *Process) MarshalProcCache(data []byte, bootTime time.Time) (int, error) { // Marshal proc_cache_t - if len(data) < ContainerIDLen { + if len(data) < 8 { return 0, ErrNotEnoughSpace } - copy(data[0:ContainerIDLen], []byte(e.ContainerID)) - binary.NativeEndian.PutUint64(data[ContainerIDLen:ContainerIDLen+8], uint64(e.CGroup.CGroupFlags)) - - written := ContainerIDLen + 8 + binary.NativeEndian.PutUint64(data[0:8], uint64(e.CGroup.CGroupFlags)) + written := 8 toAdd, err := e.CGroup.CGroupFile.MarshalBinary() if err != nil { diff --git a/pkg/security/secl/model/unmarshallers_linux.go b/pkg/security/secl/model/unmarshallers_linux.go index d5c392d1c20a21..4965be2795574e 100644 --- a/pkg/security/secl/model/unmarshallers_linux.go +++ b/pkg/security/secl/model/unmarshallers_linux.go @@ -56,18 +56,6 @@ func (e *CGroupContext) UnmarshalBinary(data []byte) (int, error) { return 8 + n, nil } -// UnmarshalBinary unmarshalls a binary representation of itself -func (e *ContainerContext) UnmarshalBinary(data []byte) (int, error) { - id, err := UnmarshalString(data, ContainerIDLen) - if err != nil { - return 0, err - } - - e.ContainerID = containerutils.ContainerID(id) - - return ContainerIDLen, nil -} - // UnmarshalBinary unmarshalls a binary representation of itself func (e *ChmodEvent) UnmarshalBinary(data []byte) (int, error) { n, err := UnmarshalBinary(data, &e.SyscallEvent, &e.SyscallContext, &e.File) @@ -967,18 +955,12 @@ func (e *SpliceEvent) UnmarshalBinary(data []byte) (int, error) { // UnmarshalBinary unmarshals a binary representation of itself func (e *CgroupTracingEvent) UnmarshalBinary(data []byte) (int, error) { - read, err := UnmarshalBinary(data, &e.ContainerContext) + read, err := UnmarshalBinary(data, &e.CGroupContext) if err != nil { return 0, err } cursor := read - read, err = UnmarshalBinary(data[cursor:], &e.CGroupContext) - if err != nil { - return 0, err - } - cursor += read - read, err = e.Config.EventUnmarshalBinary(data[cursor:]) if err != nil { return 0, err