From 7197c7c8640c42df5c6630bde08df65ef42a439b Mon Sep 17 00:00:00 2001 From: daemon1024 Date: Mon, 11 Jul 2022 16:44:01 +0530 Subject: [PATCH] enforcer: graceful clean up on termination Signed-off-by: daemon1024 --- KubeArmor/enforcer/SELinuxEnforcer.go | 1 + KubeArmor/enforcer/appArmorEnforcer.go | 2 + KubeArmor/enforcer/bpflsm/enforcer.go | 51 ++++++++++++++++---------- KubeArmor/enforcer/runtimeEnforcer.go | 23 +++++++++--- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/KubeArmor/enforcer/SELinuxEnforcer.go b/KubeArmor/enforcer/SELinuxEnforcer.go index 8326653c48..2e233cfddd 100644 --- a/KubeArmor/enforcer/SELinuxEnforcer.go +++ b/KubeArmor/enforcer/SELinuxEnforcer.go @@ -123,6 +123,7 @@ func (se *SELinuxEnforcer) DestroySELinuxEnforcer() error { se.UnregisterSELinuxHostProfile() } + se = nil return nil } diff --git a/KubeArmor/enforcer/appArmorEnforcer.go b/KubeArmor/enforcer/appArmorEnforcer.go index d68aa923e8..13c2ab73f9 100644 --- a/KubeArmor/enforcer/appArmorEnforcer.go +++ b/KubeArmor/enforcer/appArmorEnforcer.go @@ -173,6 +173,8 @@ func (ae *AppArmorEnforcer) DestroyAppArmorEnforcer() error { ae.UnregisterAppArmorHostProfile() } + ae = nil + return nil } diff --git a/KubeArmor/enforcer/bpflsm/enforcer.go b/KubeArmor/enforcer/bpflsm/enforcer.go index ce3d922962..16bae6591c 100644 --- a/KubeArmor/enforcer/bpflsm/enforcer.go +++ b/KubeArmor/enforcer/bpflsm/enforcer.go @@ -4,6 +4,7 @@ package bpflsm import ( + "errors" "sync" "github.com/cilium/ebpf" @@ -36,7 +37,7 @@ type BPFEnforcer struct { } // NewBPFEnforcer instantiates a objects for setting up BPF LSM Enforcement -func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) *BPFEnforcer { +func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) (*BPFEnforcer, error) { be := &BPFEnforcer{} @@ -46,9 +47,13 @@ func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) *BPFEnforcer { if err := rlimit.RemoveMemlock(); err != nil { be.Logger.Errf("Error removing rlimit %v", err) - return nil + return nil, nil // Doesn't require clean up so not returning err } + be.Probes = make(map[string]link.Link) + be.ContainerMap = make(map[string]ContainerKV) + be.ContainerMapLock = new(sync.RWMutex) + be.InnerMapSpec = &ebpf.MapSpec{ Type: ebpf.Hash, KeySize: 512, @@ -69,7 +74,7 @@ func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) *BPFEnforcer { }) if err != nil { be.Logger.Errf("error creating kubearmor_containers map: %s", err) - return nil + return be, err } if err := loadEnforcerObjects(&be.obj, &ebpf.CollectionOptions{ @@ -78,32 +83,28 @@ func NewBPFEnforcer(node tp.Node, logger *fd.Feeder) *BPFEnforcer { }, }); err != nil { be.Logger.Errf("error loading BPF LSM objects: %v", err) - return nil + return be, err } - be.Probes = make(map[string]link.Link) - be.ContainerMap = make(map[string]ContainerKV) - be.ContainerMapLock = new(sync.RWMutex) - be.Probes[be.obj.EnforceProc.String()], err = link.AttachLSM(link.LSMOptions{Program: be.obj.EnforceProc}) if err != nil { be.Logger.Errf("opening kprobe %s: %s", be.obj.EnforceProc.String(), err) - return nil + return be, err } be.Probes[be.obj.EnforceFile.String()], err = link.AttachLSM(link.LSMOptions{Program: be.obj.EnforceFile}) if err != nil { be.Logger.Errf("opening kprobe %s: %s", be.obj.EnforceFile.String(), err) - return nil + return be, err } be.Probes[be.obj.EnforceNet.String()], err = link.AttachLSM(link.LSMOptions{Program: be.obj.EnforceNet}) if err != nil { be.Logger.Errf("opening kprobe %s: %s", be.obj.EnforceNet.String(), err) - return nil + return be, err } - return be + return be, nil } // UpdateSecurityPolicies loops through containers present in the input endpoint and updates rules for each container @@ -126,8 +127,18 @@ func (be *BPFEnforcer) DestroyBPFEnforcer() error { return nil } + errBPFCleanUp := false + if err := be.obj.Close(); err != nil { - return err + be.Logger.Err(err.Error()) + errBPFCleanUp = true + } + + for _, link := range be.Probes { + if err := link.Close(); err != nil { + be.Logger.Err(err.Error()) + errBPFCleanUp = true + } } be.ContainerMapLock.Lock() @@ -135,17 +146,19 @@ func (be *BPFEnforcer) DestroyBPFEnforcer() error { if be.BPFContainerMap != nil { if err := be.BPFContainerMap.Unpin(); err != nil { - return err + be.Logger.Err(err.Error()) + errBPFCleanUp = true } if err := be.BPFContainerMap.Close(); err != nil { - return err + be.Logger.Err(err.Error()) + errBPFCleanUp = true } } - for _, link := range be.Probes { - if err := link.Close(); err != nil { - return err - } + if errBPFCleanUp { + return errors.New("error cleaning up BPF LSM Enforcer Objects") } + + be = nil return nil } diff --git a/KubeArmor/enforcer/runtimeEnforcer.go b/KubeArmor/enforcer/runtimeEnforcer.go index a105226c72..2134a4c157 100644 --- a/KubeArmor/enforcer/runtimeEnforcer.go +++ b/KubeArmor/enforcer/runtimeEnforcer.go @@ -65,13 +65,24 @@ func NewRuntimeEnforcer(node tp.Node, logger *fd.Feeder) *RuntimeEnforcer { re.Logger.Printf("Supported LSMs: %s", lsms) if strings.Contains(lsms, "bpf") { - re.bpfEnforcer = be.NewBPFEnforcer(node, logger) + var err error + re.bpfEnforcer, err = be.NewBPFEnforcer(node, logger) if re.bpfEnforcer != nil { - re.Logger.Print("Initialized BPF LSM Enforcer") - re.EnforcerType = "BPFLSM" - logger.UpdateEnforcer(re.EnforcerType) - return re + if err != nil { + re.Logger.Print("Error Initialising BPF LSM Enforcer, Cleaning Up") + if err := re.bpfEnforcer.DestroyBPFEnforcer(); err != nil { + re.Logger.Err(err.Error()) + } else { + re.Logger.Print("Destroyed BPFLSM Enforcer") + } + } else { + re.Logger.Print("Initialized BPF LSM Enforcer") + re.EnforcerType = "BPFLSM" + logger.UpdateEnforcer(re.EnforcerType) + return re + } } + } // Fallback to Other LSMs if failure during BPF Enforcer initialisation @@ -216,5 +227,7 @@ func (re *RuntimeEnforcer) DestroyRuntimeEnforcer() error { return fmt.Errorf("failed to destroy RuntimeEnforcer (%s)", re.EnforcerType) } + // Reset Enforcer to nil if no errors during clean up + re = nil return nil }