From 26ca52d1274f08fd7637daba50200b7e8535aebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20I=C3=B1iguez=20Goia?= Date: Sun, 22 Nov 2020 01:00:43 +0100 Subject: [PATCH] audit: schedule deletion of old events Instead of check for old events every time we add a new one, do it every 5 minutes. This improves the performance significantly. --- daemon/procmon/audit/client.go | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/daemon/procmon/audit/client.go b/daemon/procmon/audit/client.go index c2e8596de0..16d382099c 100644 --- a/daemon/procmon/audit/client.go +++ b/daemon/procmon/audit/client.go @@ -83,8 +83,11 @@ var ( // Lock holds a mutex Lock sync.RWMutex ourPid = os.Getpid() - events []*Event - // EventChan is an output channel where incoming auditd events will be written. + // cache of events + events []*Event + eventsCleaner *time.Ticker + eventsCleanerChan = make(chan bool) + // TODO: EventChan is an output channel where incoming auditd events will be written. // If a client opens it. EventChan = (chan Event)(nil) auditConn net.Conn @@ -131,12 +134,15 @@ func sortEvents() { }) } -// CleanoldEvents deletes the PIDs which do not exist or that are too old to +// cleanOldEvents deletes the PIDs which do not exist or that are too old to // live. // We start searching from the oldest to the newest. // If the last network activity of a PID has been greater than MaxEventAge, // then it'll be deleted. func cleanOldEvents() { + Lock.Lock() + defer Lock.Unlock() + for n := len(events) - 1; n >= 0; n-- { now := time.Now() elapsedTime := now.Sub(events[n].LastSeen) @@ -176,7 +182,6 @@ func AddEvent(aevent *Event) { Lock.Lock() defer Lock.Unlock() - cleanOldEvents() for n := 0; n < len(events); n++ { if events[n].Pid == aevent.Pid && events[n].Syscall == aevent.Syscall { if aevent.ProcCmdLine != "" || (aevent.ProcCmdLine == events[n].ProcCmdLine) { @@ -192,6 +197,21 @@ func AddEvent(aevent *Event) { events = append([]*Event{aevent}, events...) } +// startEventsCleaner will review if the events in the cache need to be cleaned +// every 5 minutes. +func startEventsCleaner() { + for { + select { + case <-eventsCleanerChan: + goto Exit + case <-eventsCleaner.C: + cleanOldEvents() + } + } +Exit: + log.Info("cleanerRoutine stopped") +} + func addRules() bool { r64 := append([]string{"-A"}, rule64...) r32 := append([]string{"-A"}, rule32...) @@ -244,6 +264,7 @@ func Reader(r io.Reader, eventChan chan<- Event) { return } reader := bufio.NewReader(r) + go startEventsCleaner() for { buf, _, err := reader.ReadLine() @@ -286,6 +307,9 @@ func connect() (net.Conn, error) { // Stop stops listening for events from auditd and delete the auditd rules. func Stop() { + eventsCleanerChan <- true + eventsCleaner.Stop() + if auditConn != nil { if err := auditConn.Close(); err != nil { log.Warning("audit.Stop() error closing socket: %v", err) @@ -308,5 +332,6 @@ func Start() (net.Conn, error) { } configureSyscalls() + eventsCleaner = time.NewTicker(time.Minute * 5) return auditConn, err }