From db54e653f3bb8cc1ca9a2cc3ca1dfa4d65eebf42 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Mon, 13 May 2024 11:53:46 -0700 Subject: [PATCH 1/6] Rename UpdateDB to SyncDB --- .../processors/sessionmd/add_session_metadata.go | 2 +- .../sessionmd/provider/ebpf_provider/ebpf_provider.go | 8 ++++---- .../provider/procfs_provider/procfs_provider.go | 4 ++-- .../provider/procfs_provider/procfs_provider_test.go | 10 +++++----- .../processors/sessionmd/provider/provider.go | 3 ++- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/x-pack/auditbeat/processors/sessionmd/add_session_metadata.go b/x-pack/auditbeat/processors/sessionmd/add_session_metadata.go index 766e9623b9ea..4fa86c25d029 100644 --- a/x-pack/auditbeat/processors/sessionmd/add_session_metadata.go +++ b/x-pack/auditbeat/processors/sessionmd/add_session_metadata.go @@ -113,7 +113,7 @@ func (p *addSessionMetadata) Run(ev *beat.Event) (*beat.Event, error) { return ev, nil //nolint:nilerr // Running on events with a different PID type is not a processor error } - err = p.provider.UpdateDB(ev, pid) + err = p.provider.SyncDB(ev, pid) if err != nil { return ev, err } diff --git a/x-pack/auditbeat/processors/sessionmd/provider/ebpf_provider/ebpf_provider.go b/x-pack/auditbeat/processors/sessionmd/provider/ebpf_provider/ebpf_provider.go index f1b8bae0b671..8c08ae199a73 100644 --- a/x-pack/auditbeat/processors/sessionmd/provider/ebpf_provider/ebpf_provider.go +++ b/x-pack/auditbeat/processors/sessionmd/provider/ebpf_provider/ebpf_provider.go @@ -153,9 +153,9 @@ func NewProvider(ctx context.Context, logger *logp.Logger, db *processdb.DB) (pr } const ( - maxWaitLimit = 200 * time.Millisecond // Maximum time UpdateDB will wait for process - combinedWaitLimit = 2 * time.Second // Multiple UpdateDB calls will wait up to this amount within resetDuration - backoffDuration = 10 * time.Second // UpdateDB will stop waiting for processes for this time + maxWaitLimit = 200 * time.Millisecond // Maximum time SyncDB will wait for process + combinedWaitLimit = 2 * time.Second // Multiple SyncDB calls will wait up to this amount within resetDuration + backoffDuration = 10 * time.Second // SyncDB will stop waiting for processes for this time resetDuration = 5 * time.Second // After this amount of times with no backoffs, the combinedWait will be reset ) @@ -176,7 +176,7 @@ var ( // If for some reason a lot of time has been spent waiting for missing processes, this also has a backoff timer during // which it will continue without waiting for missing events to arrive, so the processor doesn't become overly backed-up // waiting for these processes, at the cost of possibly not enriching some processes. -func (s prvdr) UpdateDB(ev *beat.Event, pid uint32) error { +func (s prvdr) SyncDB(ev *beat.Event, pid uint32) error { if s.db.HasProcess(pid) { return nil } diff --git a/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider.go b/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider.go index 6525b860b6d2..1578e89f915e 100644 --- a/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider.go +++ b/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider.go @@ -40,8 +40,8 @@ func NewProvider(ctx context.Context, logger *logp.Logger, db *processdb.DB, rea }, nil } -// UpdateDB will update the process DB with process info from procfs or the event itself -func (s prvdr) UpdateDB(ev *beat.Event, pid uint32) error { +// SyncDB will update the process DB with process info from procfs or the event itself +func (s prvdr) SyncDB(ev *beat.Event, pid uint32) error { syscall, err := ev.GetValue(syscallField) if err != nil { return fmt.Errorf("event not supported, no syscall data") diff --git a/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider_test.go b/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider_test.go index c438efcfe1ae..455cb3c0433a 100644 --- a/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider_test.go +++ b/x-pack/auditbeat/processors/sessionmd/provider/procfs_provider/procfs_provider_test.go @@ -124,7 +124,7 @@ func TestExecveEvent(t *testing.T) { provider, err := NewProvider(context.TODO(), &logger, db, reader, "process.pid") require.Nil(t, err, "error creating provider") - err = provider.UpdateDB(&event, expected.PIDs.Tgid) + err = provider.SyncDB(&event, expected.PIDs.Tgid) require.Nil(t, err) actual, err := db.GetProcess(pid) @@ -234,7 +234,7 @@ func TestExecveatEvent(t *testing.T) { provider, err := NewProvider(context.TODO(), &logger, db, reader, "process.pid") require.Nil(t, err, "error creating provider") - err = provider.UpdateDB(&event, expected.PIDs.Tgid) + err = provider.SyncDB(&event, expected.PIDs.Tgid) require.Nil(t, err) actual, err := db.GetProcess(pid) @@ -317,7 +317,7 @@ func TestSetSidEvent(t *testing.T) { provider, err := NewProvider(context.TODO(), &logger, db, reader, "process.pid") require.Nil(t, err, "error creating provider") - err = provider.UpdateDB(&event, expected.PIDs.Tgid) + err = provider.SyncDB(&event, expected.PIDs.Tgid) require.Nil(t, err) actual, err := db.GetProcess(pid) @@ -399,7 +399,7 @@ func TestSetSidEventFailed(t *testing.T) { provider, err := NewProvider(context.TODO(), &logger, db, reader, "process.pid") require.Nil(t, err, "error creating provider") - err = provider.UpdateDB(&event, expected.PIDs.Tgid) + err = provider.SyncDB(&event, expected.PIDs.Tgid) require.Nil(t, err) actual, err := db.GetProcess(pid) @@ -470,7 +470,7 @@ func TestSetSidSessionLeaderNotScraped(t *testing.T) { provider, err := NewProvider(context.TODO(), &logger, db, reader, "process.pid") require.Nil(t, err, "error creating provider") - err = provider.UpdateDB(&event, expected.PIDs.Tgid) + err = provider.SyncDB(&event, expected.PIDs.Tgid) require.Nil(t, err) actual, err := db.GetProcess(pid) diff --git a/x-pack/auditbeat/processors/sessionmd/provider/provider.go b/x-pack/auditbeat/processors/sessionmd/provider/provider.go index 6452eb9e2bf7..e95da3ec2006 100644 --- a/x-pack/auditbeat/processors/sessionmd/provider/provider.go +++ b/x-pack/auditbeat/processors/sessionmd/provider/provider.go @@ -10,6 +10,7 @@ import ( "github.com/elastic/beats/v7/libbeat/beat" ) +// SyncDB should ensure the DB is in a state to handle the event before returning. type Provider interface { - UpdateDB(*beat.Event, uint32) error + SyncDB(event *beat.Event, pid uint32) error } From 47b6a042f5365129f57d907be19ebab5fc5ddc73 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Mon, 13 May 2024 14:27:07 -0700 Subject: [PATCH 2/6] [add_session_metadata processor] Populate events with user/group names Enrich process events with user and group names for the process, and related processes (parent, session leader, group leader, entry leader). A new cache for user and group names is added to the process DB, so that the names only need to be read once, and not on every process event that's received. --- .../processors/sessionmd/processdb/db.go | 62 ++++++++++++--- .../processors/sessionmd/processdb/names.go | 75 +++++++++++++++++++ 2 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 x-pack/auditbeat/processors/sessionmd/processdb/names.go diff --git a/x-pack/auditbeat/processors/sessionmd/processdb/db.go b/x-pack/auditbeat/processors/sessionmd/processdb/db.go index b8c624abe00a..cb48ec09d631 100644 --- a/x-pack/auditbeat/processors/sessionmd/processdb/db.go +++ b/x-pack/auditbeat/processors/sessionmd/processdb/db.go @@ -189,6 +189,7 @@ type DB struct { procfs procfs.Reader stopChan chan struct{} removalCandidates rcHeap + namesCache *namesCache } func NewDB(reader procfs.Reader, logger logp.Logger) (*DB, error) { @@ -204,6 +205,7 @@ func NewDB(reader procfs.Reader, logger logp.Logger) (*DB, error) { procfs: reader, stopChan: make(chan struct{}), removalCandidates: make(rcHeap, 0), + namesCache: newNamesCache(), } db.startReaper() return &db, nil @@ -430,7 +432,7 @@ func interactiveFromTTY(tty types.TTYDev) bool { return TTYUnknown != getTTYType(tty.Major, tty.Minor) } -func fullProcessFromDBProcess(p Process) types.Process { +func (db *DB) fullProcessFromDBProcess(p Process) types.Process { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(p.PIDs.StartTimeNS) interactive := interactiveFromTTY(p.CTTY) @@ -447,7 +449,15 @@ func fullProcessFromDBProcess(p Process) types.Process { euid := p.Creds.Euid egid := p.Creds.Egid ret.User.ID = strconv.FormatUint(uint64(euid), 10) + username, ok := db.namesCache.getUserName(ret.User.ID) + if ok { + ret.User.Name = username + } ret.Group.ID = strconv.FormatUint(uint64(egid), 10) + groupname, ok := db.namesCache.getGroupName(ret.Group.ID) + if ok { + ret.Group.Name = groupname + } ret.Thread.Capabilities.Permitted, _ = capabilities.FromUint64(p.Creds.CapPermitted) ret.Thread.Capabilities.Effective, _ = capabilities.FromUint64(p.Creds.CapEffective) ret.TTY.CharDevice.Major = p.CTTY.Major @@ -457,7 +467,7 @@ func fullProcessFromDBProcess(p Process) types.Process { return ret } -func fillParent(process *types.Process, parent Process) { +func (db *DB) fillParent(process *types.Process, parent Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(parent.PIDs.StartTimeNS) interactive := interactiveFromTTY(parent.CTTY) @@ -471,10 +481,18 @@ func fillParent(process *types.Process, parent Process) { process.Parent.WorkingDirectory = parent.Cwd process.Parent.Interactive = &interactive process.Parent.User.ID = strconv.FormatUint(uint64(euid), 10) + username, ok := db.namesCache.getUserName(process.Parent.User.ID) + if ok { + process.Parent.User.Name = username + } process.Parent.Group.ID = strconv.FormatUint(uint64(egid), 10) + groupname, ok := db.namesCache.getGroupName(process.Parent.Group.ID) + if ok { + process.Parent.Group.Name = groupname + } } -func fillGroupLeader(process *types.Process, groupLeader Process) { +func (db *DB) fillGroupLeader(process *types.Process, groupLeader Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(groupLeader.PIDs.StartTimeNS) interactive := interactiveFromTTY(groupLeader.CTTY) @@ -488,10 +506,18 @@ func fillGroupLeader(process *types.Process, groupLeader Process) { process.GroupLeader.WorkingDirectory = groupLeader.Cwd process.GroupLeader.Interactive = &interactive process.GroupLeader.User.ID = strconv.FormatUint(uint64(euid), 10) + username, ok := db.namesCache.getUserName(process.GroupLeader.User.ID) + if ok { + process.GroupLeader.User.Name = username + } process.GroupLeader.Group.ID = strconv.FormatUint(uint64(egid), 10) + groupname, ok := db.namesCache.getGroupName(process.GroupLeader.Group.ID) + if ok { + process.GroupLeader.Group.Name = groupname + } } -func fillSessionLeader(process *types.Process, sessionLeader Process) { +func (db *DB) fillSessionLeader(process *types.Process, sessionLeader Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(sessionLeader.PIDs.StartTimeNS) interactive := interactiveFromTTY(sessionLeader.CTTY) @@ -505,10 +531,18 @@ func fillSessionLeader(process *types.Process, sessionLeader Process) { process.SessionLeader.WorkingDirectory = sessionLeader.Cwd process.SessionLeader.Interactive = &interactive process.SessionLeader.User.ID = strconv.FormatUint(uint64(euid), 10) + username, ok := db.namesCache.getUserName(process.SessionLeader.User.ID) + if ok { + process.SessionLeader.User.Name = username + } process.SessionLeader.Group.ID = strconv.FormatUint(uint64(egid), 10) + groupname, ok := db.namesCache.getGroupName(process.SessionLeader.Group.ID) + if ok { + process.SessionLeader.Group.Name = groupname + } } -func fillEntryLeader(process *types.Process, entryType EntryType, entryLeader Process) { +func (db *DB) fillEntryLeader(process *types.Process, entryType EntryType, entryLeader Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(entryLeader.PIDs.StartTimeNS) interactive := interactiveFromTTY(entryLeader.CTTY) @@ -522,7 +556,15 @@ func fillEntryLeader(process *types.Process, entryType EntryType, entryLeader Pr process.EntryLeader.WorkingDirectory = entryLeader.Cwd process.EntryLeader.Interactive = &interactive process.EntryLeader.User.ID = strconv.FormatUint(uint64(euid), 10) + username, ok := db.namesCache.getUserName(process.EntryLeader.User.ID) + if ok { + process.EntryLeader.User.Name = username + } process.EntryLeader.Group.ID = strconv.FormatUint(uint64(egid), 10) + groupname, ok := db.namesCache.getGroupName(process.EntryLeader.Group.ID) + if ok { + process.EntryLeader.Group.Name = groupname + } process.EntryLeader.EntryMeta.Type = string(entryType) } @@ -583,12 +625,12 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { return types.Process{}, errors.New("process not found") } - ret := fullProcessFromDBProcess(process) + ret := db.fullProcessFromDBProcess(process) if process.PIDs.Ppid != 0 { for i := 0; i < retryCount; i++ { if parent, ok := db.processes[process.PIDs.Ppid]; ok { - fillParent(&ret, parent) + db.fillParent(&ret, parent) break } } @@ -597,7 +639,7 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { if process.PIDs.Pgid != 0 { for i := 0; i < retryCount; i++ { if groupLeader, ok := db.processes[process.PIDs.Pgid]; ok { - fillGroupLeader(&ret, groupLeader) + db.fillGroupLeader(&ret, groupLeader) break } } @@ -606,7 +648,7 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { if process.PIDs.Sid != 0 { for i := 0; i < retryCount; i++ { if sessionLeader, ok := db.processes[process.PIDs.Sid]; ok { - fillSessionLeader(&ret, sessionLeader) + db.fillSessionLeader(&ret, sessionLeader) break } } @@ -615,7 +657,7 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { if entryLeaderPID, foundEntryLeaderPID := db.entryLeaderRelationships[process.PIDs.Tgid]; foundEntryLeaderPID { if entryLeader, foundEntryLeader := db.processes[entryLeaderPID]; foundEntryLeader { // if there is an entry leader then there is a matching member in the entryLeaders table - fillEntryLeader(&ret, db.entryLeaders[entryLeaderPID], entryLeader) + db.fillEntryLeader(&ret, db.entryLeaders[entryLeaderPID], entryLeader) } else { db.logger.Debugf("failed to find entry leader entry %d for %d (%s)", entryLeaderPID, pid, db.processes[pid].Filename) } diff --git a/x-pack/auditbeat/processors/sessionmd/processdb/names.go b/x-pack/auditbeat/processors/sessionmd/processdb/names.go new file mode 100644 index 000000000000..05936a852c48 --- /dev/null +++ b/x-pack/auditbeat/processors/sessionmd/processdb/names.go @@ -0,0 +1,75 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +//go:build linux + +package processdb + +import ( + "os/user" + "sync" +) + +type cval struct { + name string + found bool +} + +type namesCache struct { + mutex sync.RWMutex + users map[string]cval + groups map[string]cval +} + +// newNamesCache will return a new namesCache, which can be used to get mappings +// of user and group IDs to names. +func newNamesCache() *namesCache { + u := namesCache{ + users: make(map[string]cval), + groups: make(map[string]cval), + } + return &u +} + +// getUserName will return the name associated with the user ID, if it exists +func (u *namesCache) getUserName(id string) (string, bool) { + u.mutex.Lock() + defer u.mutex.Unlock() + + val, ok := u.users[id] + if ok { + return val.name, val.found + } + user, err := user.LookupId(id) + cval := cval{} + if err != nil { + cval.name = "" + cval.found = false + } else { + cval.name = user.Username + cval.found = true + } + return cval.name, cval.found +} + +// getGroupName will return the name associated with the group ID, if it exists +func (u *namesCache) getGroupName(id string) (string, bool) { + u.mutex.Lock() + defer u.mutex.Unlock() + + val, ok := u.groups[id] + if ok { + return val.name, val.found + } + group, err := user.LookupGroupId(id) + cval := cval{} + if err != nil { + cval.name = "" + cval.found = false + } else { + cval.name = group.Name + cval.found = true + } + return cval.name, cval.found +} From 58a614b5ed778f5b8b0af35f80613b796d6757cb Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Mon, 13 May 2024 15:05:02 -0700 Subject: [PATCH 3/6] Add user and group names to tests --- .../sessionmd/add_session_metadata_test.go | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/x-pack/auditbeat/processors/sessionmd/add_session_metadata_test.go b/x-pack/auditbeat/processors/sessionmd/add_session_metadata_test.go index 602f80f58367..95892482f80e 100644 --- a/x-pack/auditbeat/processors/sessionmd/add_session_metadata_test.go +++ b/x-pack/auditbeat/processors/sessionmd/add_session_metadata_test.go @@ -43,6 +43,14 @@ var ( Pgid: uint32(100), Sid: uint32(40), }, + Creds: types.CredInfo{ + Ruid: 0, + Euid: 0, + Suid: 0, + Rgid: 0, + Egid: 0, + Sgid: 0, + }, CWD: "/", Filename: "/bin/ls", }, @@ -78,12 +86,24 @@ var ( "pid": uint32(100), "parent": mapstr.M{ "pid": uint32(50), + "user": mapstr.M{ + "id": "0", + "name": "root", + }, }, "session_leader": mapstr.M{ "pid": uint32(40), + "user": mapstr.M{ + "id": "0", + "name": "root", + }, }, "group_leader": mapstr.M{ "pid": uint32(100), + "user": mapstr.M{ + "id": "0", + "name": "root", + }, }, }, }, @@ -318,33 +338,35 @@ var ( func TestEnrich(t *testing.T) { for _, tt := range enrichTests { - reader := procfs.NewMockReader() - db, err := processdb.NewDB(reader, *logger) - require.Nil(t, err) + t.Run(tt.testName, func(t *testing.T) { + reader := procfs.NewMockReader() + db, err := processdb.NewDB(reader, *logger) + require.Nil(t, err) - for _, ev := range tt.mockProcesses { - db.InsertExec(ev) - } - s := addSessionMetadata{ - logger: logger, - db: db, - config: tt.config, - } + for _, ev := range tt.mockProcesses { + db.InsertExec(ev) + } + s := addSessionMetadata{ + logger: logger, + db: db, + config: tt.config, + } - // avoid taking address of loop variable - i := tt.input - actual, err := s.enrich(&i) - if tt.expect_error { - require.Error(t, err, "%s: error unexpectedly nil", tt.testName) - } else { - require.Nil(t, err, "%s: enrich error: %w", tt.testName, err) - require.NotNil(t, actual, "%s: returned nil event", tt.testName) + // avoid taking address of loop variable + i := tt.input + actual, err := s.enrich(&i) + if tt.expect_error { + require.Error(t, err, "%s: error unexpectedly nil", tt.testName) + } else { + require.Nil(t, err, "%s: enrich error: %w", tt.testName, err) + require.NotNil(t, actual, "%s: returned nil event", tt.testName) - //Validate output - if diff := cmp.Diff(tt.expected.Fields, actual.Fields, ignoreMissingFrom(tt.expected.Fields)); diff != "" { - t.Errorf("field mismatch:\n%s", diff) + //Validate output + if diff := cmp.Diff(tt.expected.Fields, actual.Fields, ignoreMissingFrom(tt.expected.Fields)); diff != "" { + t.Errorf("field mismatch:\n%s", diff) + } } - } + }) } } @@ -364,8 +386,10 @@ func ignoreMissingFrom(m mapstr.M) cmp.Option { // Note: This validates test code only func TestFilter(t *testing.T) { for _, tt := range filterTests { - if eq := cmp.Equal(tt.mx, tt.my, ignoreMissingFrom(tt.mx)); eq != tt.expected { - t.Errorf("%s: unexpected comparator result", tt.testName) - } + t.Run(tt.testName, func(t *testing.T) { + if eq := cmp.Equal(tt.mx, tt.my, ignoreMissingFrom(tt.mx)); eq != tt.expected { + t.Errorf("%s: unexpected comparator result", tt.testName) + } + }) } } From 43fe82ab9e32bfee3cf2d1c2293b382caa0e6785 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Mon, 13 May 2024 15:14:55 -0700 Subject: [PATCH 4/6] Update changelog --- CHANGELOG.next.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 2b571875e347..a9103cfeadc0 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -206,6 +206,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] - Add procfs backend to the `add_session_metadata` processor. {pull}38799[38799] - Add process.entity_id, process.group.name and process.group.id in add_process_metadata processor. Make fim module with kprobes backend to always add an appropriately configured add_process_metadata processor to enrich file events {pull}38776[38776] - Reduce data size for add_session_metadata processor by removing unneeded fields {pull}39500[39500] +- Enrich process events with user and group names, with add_session_metadata processor {pull}39537[39537] *Auditbeat* From 2da9c7d094a684c3d7525f61a8538cdfbd5e4fd0 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Wed, 15 May 2024 15:40:35 -0700 Subject: [PATCH 5/6] Remove caching from getUserName Profiling has shown that `user.LookupId(id)` is already very fast, and there's no need to add a cache for this data. --- .../processors/sessionmd/processdb/db.go | 22 ++++--- .../processors/sessionmd/processdb/names.go | 58 ++----------------- 2 files changed, 16 insertions(+), 64 deletions(-) diff --git a/x-pack/auditbeat/processors/sessionmd/processdb/db.go b/x-pack/auditbeat/processors/sessionmd/processdb/db.go index cb48ec09d631..d316bf41d2b9 100644 --- a/x-pack/auditbeat/processors/sessionmd/processdb/db.go +++ b/x-pack/auditbeat/processors/sessionmd/processdb/db.go @@ -189,7 +189,6 @@ type DB struct { procfs procfs.Reader stopChan chan struct{} removalCandidates rcHeap - namesCache *namesCache } func NewDB(reader procfs.Reader, logger logp.Logger) (*DB, error) { @@ -205,7 +204,6 @@ func NewDB(reader procfs.Reader, logger logp.Logger) (*DB, error) { procfs: reader, stopChan: make(chan struct{}), removalCandidates: make(rcHeap, 0), - namesCache: newNamesCache(), } db.startReaper() return &db, nil @@ -449,12 +447,12 @@ func (db *DB) fullProcessFromDBProcess(p Process) types.Process { euid := p.Creds.Euid egid := p.Creds.Egid ret.User.ID = strconv.FormatUint(uint64(euid), 10) - username, ok := db.namesCache.getUserName(ret.User.ID) + username, ok := getUserName(ret.User.ID) if ok { ret.User.Name = username } ret.Group.ID = strconv.FormatUint(uint64(egid), 10) - groupname, ok := db.namesCache.getGroupName(ret.Group.ID) + groupname, ok := getGroupName(ret.Group.ID) if ok { ret.Group.Name = groupname } @@ -481,12 +479,12 @@ func (db *DB) fillParent(process *types.Process, parent Process) { process.Parent.WorkingDirectory = parent.Cwd process.Parent.Interactive = &interactive process.Parent.User.ID = strconv.FormatUint(uint64(euid), 10) - username, ok := db.namesCache.getUserName(process.Parent.User.ID) + username, ok := getUserName(process.Parent.User.ID) if ok { process.Parent.User.Name = username } process.Parent.Group.ID = strconv.FormatUint(uint64(egid), 10) - groupname, ok := db.namesCache.getGroupName(process.Parent.Group.ID) + groupname, ok := getGroupName(process.Parent.Group.ID) if ok { process.Parent.Group.Name = groupname } @@ -506,12 +504,12 @@ func (db *DB) fillGroupLeader(process *types.Process, groupLeader Process) { process.GroupLeader.WorkingDirectory = groupLeader.Cwd process.GroupLeader.Interactive = &interactive process.GroupLeader.User.ID = strconv.FormatUint(uint64(euid), 10) - username, ok := db.namesCache.getUserName(process.GroupLeader.User.ID) + username, ok := getUserName(process.GroupLeader.User.ID) if ok { process.GroupLeader.User.Name = username } process.GroupLeader.Group.ID = strconv.FormatUint(uint64(egid), 10) - groupname, ok := db.namesCache.getGroupName(process.GroupLeader.Group.ID) + groupname, ok := getGroupName(process.GroupLeader.Group.ID) if ok { process.GroupLeader.Group.Name = groupname } @@ -531,12 +529,12 @@ func (db *DB) fillSessionLeader(process *types.Process, sessionLeader Process) { process.SessionLeader.WorkingDirectory = sessionLeader.Cwd process.SessionLeader.Interactive = &interactive process.SessionLeader.User.ID = strconv.FormatUint(uint64(euid), 10) - username, ok := db.namesCache.getUserName(process.SessionLeader.User.ID) + username, ok := getUserName(process.SessionLeader.User.ID) if ok { process.SessionLeader.User.Name = username } process.SessionLeader.Group.ID = strconv.FormatUint(uint64(egid), 10) - groupname, ok := db.namesCache.getGroupName(process.SessionLeader.Group.ID) + groupname, ok := getGroupName(process.SessionLeader.Group.ID) if ok { process.SessionLeader.Group.Name = groupname } @@ -556,12 +554,12 @@ func (db *DB) fillEntryLeader(process *types.Process, entryType EntryType, entry process.EntryLeader.WorkingDirectory = entryLeader.Cwd process.EntryLeader.Interactive = &interactive process.EntryLeader.User.ID = strconv.FormatUint(uint64(euid), 10) - username, ok := db.namesCache.getUserName(process.EntryLeader.User.ID) + username, ok := getUserName(process.EntryLeader.User.ID) if ok { process.EntryLeader.User.Name = username } process.EntryLeader.Group.ID = strconv.FormatUint(uint64(egid), 10) - groupname, ok := db.namesCache.getGroupName(process.EntryLeader.Group.ID) + groupname, ok := getGroupName(process.EntryLeader.Group.ID) if ok { process.EntryLeader.Group.Name = groupname } diff --git a/x-pack/auditbeat/processors/sessionmd/processdb/names.go b/x-pack/auditbeat/processors/sessionmd/processdb/names.go index 05936a852c48..77ff99de6596 100644 --- a/x-pack/auditbeat/processors/sessionmd/processdb/names.go +++ b/x-pack/auditbeat/processors/sessionmd/processdb/names.go @@ -8,68 +8,22 @@ package processdb import ( "os/user" - "sync" ) -type cval struct { - name string - found bool -} - -type namesCache struct { - mutex sync.RWMutex - users map[string]cval - groups map[string]cval -} - -// newNamesCache will return a new namesCache, which can be used to get mappings -// of user and group IDs to names. -func newNamesCache() *namesCache { - u := namesCache{ - users: make(map[string]cval), - groups: make(map[string]cval), - } - return &u -} - // getUserName will return the name associated with the user ID, if it exists -func (u *namesCache) getUserName(id string) (string, bool) { - u.mutex.Lock() - defer u.mutex.Unlock() - - val, ok := u.users[id] - if ok { - return val.name, val.found - } +func getUserName(id string) (string, bool) { user, err := user.LookupId(id) - cval := cval{} if err != nil { - cval.name = "" - cval.found = false - } else { - cval.name = user.Username - cval.found = true + return "", false } - return cval.name, cval.found + return user.Username, true } // getGroupName will return the name associated with the group ID, if it exists -func (u *namesCache) getGroupName(id string) (string, bool) { - u.mutex.Lock() - defer u.mutex.Unlock() - - val, ok := u.groups[id] - if ok { - return val.name, val.found - } +func getGroupName(id string) (string, bool) { group, err := user.LookupGroupId(id) - cval := cval{} if err != nil { - cval.name = "" - cval.found = false - } else { - cval.name = group.Name - cval.found = true + return "", false } - return cval.name, cval.found + return group.Name, true } From 0b5885c6d07d9ede307457a2eef56aba0a73588d Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Wed, 15 May 2024 15:51:02 -0700 Subject: [PATCH 6/6] remove unneeded methods --- .../processors/sessionmd/processdb/db.go | 20 +++++++++---------- .../processors/sessionmd/processdb/names.go | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/x-pack/auditbeat/processors/sessionmd/processdb/db.go b/x-pack/auditbeat/processors/sessionmd/processdb/db.go index d316bf41d2b9..28c848ddfdbc 100644 --- a/x-pack/auditbeat/processors/sessionmd/processdb/db.go +++ b/x-pack/auditbeat/processors/sessionmd/processdb/db.go @@ -430,7 +430,7 @@ func interactiveFromTTY(tty types.TTYDev) bool { return TTYUnknown != getTTYType(tty.Major, tty.Minor) } -func (db *DB) fullProcessFromDBProcess(p Process) types.Process { +func fullProcessFromDBProcess(p Process) types.Process { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(p.PIDs.StartTimeNS) interactive := interactiveFromTTY(p.CTTY) @@ -465,7 +465,7 @@ func (db *DB) fullProcessFromDBProcess(p Process) types.Process { return ret } -func (db *DB) fillParent(process *types.Process, parent Process) { +func fillParent(process *types.Process, parent Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(parent.PIDs.StartTimeNS) interactive := interactiveFromTTY(parent.CTTY) @@ -490,7 +490,7 @@ func (db *DB) fillParent(process *types.Process, parent Process) { } } -func (db *DB) fillGroupLeader(process *types.Process, groupLeader Process) { +func fillGroupLeader(process *types.Process, groupLeader Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(groupLeader.PIDs.StartTimeNS) interactive := interactiveFromTTY(groupLeader.CTTY) @@ -515,7 +515,7 @@ func (db *DB) fillGroupLeader(process *types.Process, groupLeader Process) { } } -func (db *DB) fillSessionLeader(process *types.Process, sessionLeader Process) { +func fillSessionLeader(process *types.Process, sessionLeader Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(sessionLeader.PIDs.StartTimeNS) interactive := interactiveFromTTY(sessionLeader.CTTY) @@ -540,7 +540,7 @@ func (db *DB) fillSessionLeader(process *types.Process, sessionLeader Process) { } } -func (db *DB) fillEntryLeader(process *types.Process, entryType EntryType, entryLeader Process) { +func fillEntryLeader(process *types.Process, entryType EntryType, entryLeader Process) { reducedPrecisionStartTime := timeutils.ReduceTimestampPrecision(entryLeader.PIDs.StartTimeNS) interactive := interactiveFromTTY(entryLeader.CTTY) @@ -623,12 +623,12 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { return types.Process{}, errors.New("process not found") } - ret := db.fullProcessFromDBProcess(process) + ret := fullProcessFromDBProcess(process) if process.PIDs.Ppid != 0 { for i := 0; i < retryCount; i++ { if parent, ok := db.processes[process.PIDs.Ppid]; ok { - db.fillParent(&ret, parent) + fillParent(&ret, parent) break } } @@ -637,7 +637,7 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { if process.PIDs.Pgid != 0 { for i := 0; i < retryCount; i++ { if groupLeader, ok := db.processes[process.PIDs.Pgid]; ok { - db.fillGroupLeader(&ret, groupLeader) + fillGroupLeader(&ret, groupLeader) break } } @@ -646,7 +646,7 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { if process.PIDs.Sid != 0 { for i := 0; i < retryCount; i++ { if sessionLeader, ok := db.processes[process.PIDs.Sid]; ok { - db.fillSessionLeader(&ret, sessionLeader) + fillSessionLeader(&ret, sessionLeader) break } } @@ -655,7 +655,7 @@ func (db *DB) GetProcess(pid uint32) (types.Process, error) { if entryLeaderPID, foundEntryLeaderPID := db.entryLeaderRelationships[process.PIDs.Tgid]; foundEntryLeaderPID { if entryLeader, foundEntryLeader := db.processes[entryLeaderPID]; foundEntryLeader { // if there is an entry leader then there is a matching member in the entryLeaders table - db.fillEntryLeader(&ret, db.entryLeaders[entryLeaderPID], entryLeader) + fillEntryLeader(&ret, db.entryLeaders[entryLeaderPID], entryLeader) } else { db.logger.Debugf("failed to find entry leader entry %d for %d (%s)", entryLeaderPID, pid, db.processes[pid].Filename) } diff --git a/x-pack/auditbeat/processors/sessionmd/processdb/names.go b/x-pack/auditbeat/processors/sessionmd/processdb/names.go index 77ff99de6596..6584e6e9986f 100644 --- a/x-pack/auditbeat/processors/sessionmd/processdb/names.go +++ b/x-pack/auditbeat/processors/sessionmd/processdb/names.go @@ -14,7 +14,7 @@ import ( func getUserName(id string) (string, bool) { user, err := user.LookupId(id) if err != nil { - return "", false + return "", false } return user.Username, true } @@ -23,7 +23,7 @@ func getUserName(id string) (string, bool) { func getGroupName(id string) (string, bool) { group, err := user.LookupGroupId(id) if err != nil { - return "", false + return "", false } return group.Name, true }