From 6bd196546c8c1659df45358053962e030a545d8b Mon Sep 17 00:00:00 2001 From: Sylvain Baubeau Date: Tue, 3 Dec 2024 11:56:25 +0100 Subject: [PATCH] Index workload per cgroup ID --- pkg/security/resolvers/cgroup/model/model.go | 9 ++-- pkg/security/resolvers/cgroup/resolver.go | 49 ++++++++++++------- .../resolvers/process/resolver_ebpf.go | 2 +- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/pkg/security/resolvers/cgroup/model/model.go b/pkg/security/resolvers/cgroup/model/model.go index acb18c9922601..c916e45477876 100644 --- a/pkg/security/resolvers/cgroup/model/model.go +++ b/pkg/security/resolvers/cgroup/model/model.go @@ -29,18 +29,19 @@ type CacheEntry struct { } // NewCacheEntry returns a new instance of a CacheEntry -func NewCacheEntry(containerID containerutils.ContainerID, cgroupFlags uint64, pids ...uint32) (*CacheEntry, error) { +func NewCacheEntry(containerID containerutils.ContainerID, cgroupContext *model.CGroupContext, pids ...uint32) (*CacheEntry, error) { newCGroup := CacheEntry{ Deleted: atomic.NewBool(false), - CGroupContext: model.CGroupContext{ - CGroupFlags: containerutils.CGroupFlags(cgroupFlags), - }, ContainerContext: model.ContainerContext{ ContainerID: containerID, }, PIDs: make(map[uint32]bool, 10), } + if cgroupContext != nil { + newCGroup.CGroupContext = *cgroupContext + } + for _, pid := range pids { newCGroup.PIDs[pid] = true } diff --git a/pkg/security/resolvers/cgroup/resolver.go b/pkg/security/resolvers/cgroup/resolver.go index 0e7b7b07b1cd2..825d7cc92cf42 100644 --- a/pkg/security/resolvers/cgroup/resolver.go +++ b/pkg/security/resolvers/cgroup/resolver.go @@ -37,9 +37,9 @@ const ( type ResolverInterface interface { Start(context.Context) AddPID(*model.ProcessCacheEntry) - GetWorkload(string) (*cgroupModel.CacheEntry, bool) + GetWorkload(containerutils.ContainerID) (*cgroupModel.CacheEntry, bool) DelPID(uint32) - DelPIDWithID(string, uint32) + DelPIDWithID(containerutils.ContainerID, uint32) Len() int RegisterListener(Event, utils.Listener[*cgroupModel.CacheEntry]) error } @@ -48,7 +48,7 @@ type ResolverInterface interface { type Resolver struct { *utils.Notifier[Event, *cgroupModel.CacheEntry] sync.RWMutex - workloads *simplelru.LRU[containerutils.ContainerID, *cgroupModel.CacheEntry] + workloads *simplelru.LRU[containerutils.CGroupID, *cgroupModel.CacheEntry] } // NewResolver returns a new cgroups monitor @@ -56,7 +56,7 @@ func NewResolver() (*Resolver, error) { cr := &Resolver{ Notifier: utils.NewNotifier[Event, *cgroupModel.CacheEntry](), } - workloads, err := simplelru.NewLRU(1024, func(_ containerutils.ContainerID, value *cgroupModel.CacheEntry) { + workloads, err := simplelru.NewLRU(1024, func(_ containerutils.CGroupID, value *cgroupModel.CacheEntry) { value.CallReleaseCallback() value.Deleted.Store(true) @@ -78,7 +78,7 @@ func (cr *Resolver) AddPID(process *model.ProcessCacheEntry) { cr.Lock() defer cr.Unlock() - entry, exists := cr.workloads.Get(process.ContainerID) + entry, exists := cr.workloads.Get(process.CGroup.CGroupID) if exists { entry.AddPID(process.Pid) return @@ -86,7 +86,7 @@ func (cr *Resolver) AddPID(process *model.ProcessCacheEntry) { var err error // create new entry now - newCGroup, err := cgroupModel.NewCacheEntry(process.ContainerID, uint64(process.CGroup.CGroupFlags), process.Pid) + newCGroup, err := cgroupModel.NewCacheEntry(process.ContainerID, &process.CGroup, process.Pid) if err != nil { seclog.Errorf("couldn't create new cgroup_resolver cache entry: %v", err) return @@ -94,17 +94,33 @@ func (cr *Resolver) AddPID(process *model.ProcessCacheEntry) { newCGroup.CreatedAt = uint64(process.ProcessContext.ExecTime.UnixNano()) // add the new CGroup to the cache - cr.workloads.Add(process.ContainerID, newCGroup) + cr.workloads.Add(process.CGroup.CGroupID, newCGroup) cr.NotifyListeners(CGroupCreated, newCGroup) } +// Get returns the workload referenced by the provided ID +func (cr *Resolver) Get(id containerutils.CGroupID) (*cgroupModel.CacheEntry, bool) { + cr.RLock() + defer cr.RUnlock() + + return cr.workloads.Get(id) +} + // GetWorkload returns the workload referenced by the provided ID func (cr *Resolver) GetWorkload(id containerutils.ContainerID) (*cgroupModel.CacheEntry, bool) { cr.RLock() defer cr.RUnlock() - return cr.workloads.Get(id) + if id != "" { + for _, workload := range cr.workloads.Values() { + if workload.ContainerID == id { + return workload, true + } + } + } + + return nil, false } // DelPID removes a PID from the cgroup resolver @@ -112,11 +128,8 @@ func (cr *Resolver) DelPID(pid uint32) { cr.Lock() defer cr.Unlock() - for _, id := range cr.workloads.Keys() { - entry, exists := cr.workloads.Get(id) - if exists { - cr.deleteWorkloadPID(pid, entry) - } + for _, workload := range cr.workloads.Values() { + cr.deleteWorkloadPID(pid, workload) } } @@ -125,9 +138,11 @@ func (cr *Resolver) DelPIDWithID(id containerutils.ContainerID, pid uint32) { cr.Lock() defer cr.Unlock() - entry, exists := cr.workloads.Get(id) - if exists { - cr.deleteWorkloadPID(pid, entry) + for _, workload := range cr.workloads.Values() { + if workload.ContainerID == id { + cr.deleteWorkloadPID(pid, workload) + return + } } } @@ -140,7 +155,7 @@ func (cr *Resolver) deleteWorkloadPID(pid uint32, workload *cgroupModel.CacheEnt // check if the workload should be deleted if len(workload.PIDs) <= 0 { - cr.workloads.Remove(workload.ContainerID) + cr.workloads.Remove(workload.CGroupID) } } diff --git a/pkg/security/resolvers/process/resolver_ebpf.go b/pkg/security/resolvers/process/resolver_ebpf.go index 8803cc978f7ba..c9a3fd4f8ad7e 100644 --- a/pkg/security/resolvers/process/resolver_ebpf.go +++ b/pkg/security/resolvers/process/resolver_ebpf.go @@ -502,7 +502,7 @@ func (p *EBPFResolver) insertEntry(entry, prev *model.ProcessCacheEntry, source prev.Release() } - if p.cgroupResolver != nil && entry.ContainerID != "" { + if p.cgroupResolver != nil && entry.CGroup.CGroupID != "" { // add the new PID in the right cgroup_resolver bucket p.cgroupResolver.AddPID(entry) }