From 2797a0476181fd01afc1e0d5e61009a66be3f090 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Mon, 14 Aug 2023 14:09:56 +0930 Subject: [PATCH 1/4] auditbeat/module/file_integrity: add support for selinux and posix_acl_access xattrs --- CHANGELOG.next.asciidoc | 1 + NOTICE.txt | 35 +++++++++++++++ auditbeat/module/file_integrity/event.go | 44 ++++++++++--------- .../module/file_integrity/fileinfo_posix.go | 22 ++++++++++ .../module/file_integrity/flatbuffers.go | 15 ++++++- auditbeat/module/file_integrity/schema.fbs | 2 + .../module/file_integrity/schema/Metadata.go | 24 +++++++++- go.mod | 1 + go.sum | 3 ++ 9 files changed, 123 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index ba94ca31247..9a020a63438 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -221,6 +221,7 @@ automatic splitting at root level, if root level element is an array. {pull}3415 *Auditbeat* +- Add support for `security.selinux` and `system.posix_acl_access` extended attributes to FIM. {issue}36265[36265] {pull}36310[36310] *Filebeat* diff --git a/NOTICE.txt b/NOTICE.txt index 0b69efaec93..b3759a6814d 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -21270,6 +21270,41 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------------------- +Dependency : github.com/pkg/xattr +Version: v0.4.9 +Licence type (autodetected): BSD-2-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/pkg/xattr@v0.4.9/LICENSE: + +Copyright (c) 2012 Dave Cheney. All rights reserved. +Copyright (c) 2014 Kuba Podgórski. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + -------------------------------------------------------------------------------- Dependency : github.com/pmezard/go-difflib Version: v1.0.0 diff --git a/auditbeat/module/file_integrity/event.go b/auditbeat/module/file_integrity/event.go index 67615efd4a9..d26ca24c484 100644 --- a/auditbeat/module/file_integrity/event.go +++ b/auditbeat/module/file_integrity/event.go @@ -127,20 +127,22 @@ type Event struct { // Metadata contains file metadata. type Metadata struct { - Inode uint64 `json:"inode"` - UID uint32 `json:"uid"` - GID uint32 `json:"gid"` - SID string `json:"sid"` - Owner string `json:"owner"` - Group string `json:"group"` - Size uint64 `json:"size"` - MTime time.Time `json:"mtime"` // Last modification time. - CTime time.Time `json:"ctime"` // Last metadata change time. - Type Type `json:"type"` // File type (dir, file, symlink). - Mode os.FileMode `json:"mode"` // Permissions - SetUID bool `json:"setuid"` // setuid bit (POSIX only) - SetGID bool `json:"setgid"` // setgid bit (POSIX only) - Origin []string `json:"origin"` // External origin info for the file (MacOS only) + Inode uint64 `json:"inode"` + UID uint32 `json:"uid"` + GID uint32 `json:"gid"` + SID string `json:"sid"` + Owner string `json:"owner"` + Group string `json:"group"` + Size uint64 `json:"size"` + MTime time.Time `json:"mtime"` // Last modification time. + CTime time.Time `json:"ctime"` // Last metadata change time. + Type Type `json:"type"` // File type (dir, file, symlink). + Mode os.FileMode `json:"mode"` // Permissions + SetUID bool `json:"setuid"` // setuid bit (POSIX only) + SetGID bool `json:"setgid"` // setgid bit (POSIX only) + Origin []string `json:"origin"` // External origin info for the file (MacOS only) + SELinux string `json:"selinux"` // security.selinux xattr value (Linux only) + POSIXACLAccess string `json:"posix_acl_access"` // system.posix_acl_access xattr value (Linux only) } // NewEventFromFileInfo creates a new Event based on data from a os.FileInfo @@ -332,14 +334,14 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event { file[k] = v } - out.MetricSetFields.Put("event.kind", "event") //nolint:errcheck // Will not error. - out.MetricSetFields.Put("event.category", []string{"file"}) //nolint:errcheck // Will not error. + out.MetricSetFields.Put("event.kind", "event") + out.MetricSetFields.Put("event.category", []string{"file"}) if e.Action > 0 { actions := e.Action.InOrder(existedBefore, e.Info != nil) - out.MetricSetFields.Put("event.type", actions.ECSTypes()) //nolint:errcheck // Will not error. - out.MetricSetFields.Put("event.action", actions.StringArray()) //nolint:errcheck // Will not error. + out.MetricSetFields.Put("event.type", actions.ECSTypes()) + out.MetricSetFields.Put("event.action", actions.StringArray()) } else { - out.MetricSetFields.Put("event.type", None.ECSTypes()) //nolint:errcheck // Will not error. + out.MetricSetFields.Put("event.type", None.ECSTypes()) } if n := len(e.errors); n > 0 { @@ -348,9 +350,9 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event { errors[idx] = err.Error() } if n == 1 { - out.MetricSetFields.Put("error.message", errors[0]) //nolint:errcheck // Will not error. + out.MetricSetFields.Put("error.message", errors[0]) } else { - out.MetricSetFields.Put("error.message", errors) //nolint:errcheck // Will not error. + out.MetricSetFields.Put("error.message", errors) } } return out diff --git a/auditbeat/module/file_integrity/fileinfo_posix.go b/auditbeat/module/file_integrity/fileinfo_posix.go index 576d71b20b6..d0845f36369 100644 --- a/auditbeat/module/file_integrity/fileinfo_posix.go +++ b/auditbeat/module/file_integrity/fileinfo_posix.go @@ -27,6 +27,7 @@ import ( "syscall" "github.com/joeshaw/multierror" + "github.com/pkg/xattr" ) // NewMetadata returns a new Metadata object. If an error is returned it is @@ -67,6 +68,11 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) { fileInfo.Owner = owner.Username } + getExtendedAttributes(path, map[string]*string{ + "security.selinux": &fileInfo.SELinux, + "system.posix_acl_access": &fileInfo.POSIXACLAccess, + }) + group, err := user.LookupGroupId(strconv.Itoa(int(fileInfo.GID))) if err != nil { errs = append(errs, err) @@ -78,3 +84,19 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) { } return fileInfo, errs.Err() } + +func getExtendedAttributes(path string, dst map[string]*string) { + f, err := os.Open(path) + if err != nil { + return + } + defer f.Close() + + for n, d := range dst { + att, err := xattr.FGet(f, n) + if err != nil { + continue + } + *d = string(att) + } +} diff --git a/auditbeat/module/file_integrity/flatbuffers.go b/auditbeat/module/file_integrity/flatbuffers.go index 3ab173f60e6..21ef24150c9 100644 --- a/auditbeat/module/file_integrity/flatbuffers.go +++ b/auditbeat/module/file_integrity/flatbuffers.go @@ -125,11 +125,16 @@ func fbWriteMetadata(b *flatbuffers.Builder, m *Metadata) flatbuffers.UOffsetT { return 0 } - var sidOffset flatbuffers.UOffsetT + var sidOffset, selinuxOffset, aclAccessOffset flatbuffers.UOffsetT if m.SID != "" { sidOffset = b.CreateString(m.SID) } - + if m.SELinux != "" { + selinuxOffset = b.CreateString(m.SELinux) + } + if m.POSIXACLAccess != "" { + aclAccessOffset = b.CreateString(m.POSIXACLAccess) + } schema.MetadataStart(b) schema.MetadataAddInode(b, m.Inode) schema.MetadataAddUid(b, m.UID) @@ -160,6 +165,12 @@ func fbWriteMetadata(b *flatbuffers.Builder, m *Metadata) flatbuffers.UOffsetT { case SymlinkType: schema.MetadataAddType(b, schema.TypeSymlink) } + if selinuxOffset > 0 { + schema.MetadataAddSelinux(b, selinuxOffset) + } + if aclAccessOffset > 0 { + schema.MetadataAddPosixAclAccess(b, aclAccessOffset) + } return schema.MetadataEnd(b) } diff --git a/auditbeat/module/file_integrity/schema.fbs b/auditbeat/module/file_integrity/schema.fbs index b22efd5e5ae..a32c6bfe52f 100644 --- a/auditbeat/module/file_integrity/schema.fbs +++ b/auditbeat/module/file_integrity/schema.fbs @@ -31,6 +31,8 @@ table Metadata { mtime_ns:long; ctime_ns:long; type:Type = 1; + selinux:string; + posix_acl_access:string; } table Hash { diff --git a/auditbeat/module/file_integrity/schema/Metadata.go b/auditbeat/module/file_integrity/schema/Metadata.go index a9f08378913..890a14210f8 100644 --- a/auditbeat/module/file_integrity/schema/Metadata.go +++ b/auditbeat/module/file_integrity/schema/Metadata.go @@ -154,8 +154,24 @@ func (rcv *Metadata) MutateType(n Type) bool { return rcv._tab.MutateByteSlot(20, byte(n)) } +func (rcv *Metadata) Selinux() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(22)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + +func (rcv *Metadata) PosixAclAccess() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(24)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + func MetadataStart(builder *flatbuffers.Builder) { - builder.StartObject(9) + builder.StartObject(11) } func MetadataAddInode(builder *flatbuffers.Builder, inode uint64) { builder.PrependUint64Slot(0, inode, 0) @@ -184,6 +200,12 @@ func MetadataAddCtimeNs(builder *flatbuffers.Builder, ctimeNs int64) { func MetadataAddType(builder *flatbuffers.Builder, type_ Type) { builder.PrependByteSlot(8, byte(type_), 1) } +func MetadataAddSelinux(builder *flatbuffers.Builder, selinux flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(9, flatbuffers.UOffsetT(selinux), 0) +} +func MetadataAddPosixAclAccess(builder *flatbuffers.Builder, posixAclAccess flatbuffers.UOffsetT) { + builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(posixAclAccess), 0) +} func MetadataEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } diff --git a/go.mod b/go.mod index 328869b6bc1..de1a5bb7953 100644 --- a/go.mod +++ b/go.mod @@ -215,6 +215,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/lestrrat-go/jwx/v2 v2.0.11 github.com/pierrec/lz4/v4 v4.1.15 + github.com/pkg/xattr v0.4.9 github.com/shirou/gopsutil/v3 v3.22.10 go.elastic.co/apm/module/apmelasticsearch/v2 v2.0.0 go.elastic.co/apm/module/apmhttp/v2 v2.0.0 diff --git a/go.sum b/go.sum index 0065058f7c5..ff2057f8357 100644 --- a/go.sum +++ b/go.sum @@ -1359,6 +1359,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE= +github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -1974,6 +1976,7 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 4303194ea18e6e77a7457cc8bfcc7f0661dcdbf5 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Tue, 15 Aug 2023 10:36:20 +0930 Subject: [PATCH 2/4] address pr comments --- auditbeat/module/file_integrity/event.go | 87 ++++++++++++++++++- auditbeat/module/file_integrity/event_test.go | 39 +++++++++ .../module/file_integrity/fileinfo_posix.go | 8 +- 3 files changed, 132 insertions(+), 2 deletions(-) diff --git a/auditbeat/module/file_integrity/event.go b/auditbeat/module/file_integrity/event.go index d26ca24c484..be4d701f2a3 100644 --- a/auditbeat/module/file_integrity/event.go +++ b/auditbeat/module/file_integrity/event.go @@ -23,12 +23,15 @@ import ( "crypto/sha1" "crypto/sha256" "crypto/sha512" + "encoding/base64" + "encoding/binary" "encoding/hex" "fmt" "hash" "io" "math" "os" + "os/user" "path/filepath" "runtime" "strconv" @@ -321,6 +324,15 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event { if len(info.Origin) > 0 { file["origin"] = info.Origin } + if info.SELinux != "" { + file["selinux"] = info.SELinux + } + if info.POSIXACLAccess != "" { + a, err := aclText(info.POSIXACLAccess) + if err == nil { + file["posix_acl_access"] = a + } + } } if len(e.Hashes) > 0 { @@ -358,6 +370,78 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event { return out } +func aclText(s string) ([]string, error) { + b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(s, "0s")) + if err != nil { + return nil, err + } + if (len(b)-4)%8 != 0 { + return nil, fmt.Errorf("unexpected ACL length: %d", len(b)) + } + b = b[4:] // The first four bytes is the version, discard it. + a := make([]string, 0, len(b)/8) + for len(b) != 0 { + tag := binary.LittleEndian.Uint16(b) + perm := binary.LittleEndian.Uint16(b[2:]) + qual := binary.LittleEndian.Uint32(b[4:]) + a = append(a, fmt.Sprintf("%s:%s:%s", tags[tag], qualString(qual, tag), modeString(perm))) + b = b[8:] + } + return a, nil +} + +var tags = map[uint16]string{ + 0x00: "undefined", + 0x01: "user", + 0x02: "user", + 0x04: "group", + 0x08: "group", + 0x10: "mask", + 0x20: "other", +} + +func qualString(qual uint32, tag uint16) string { + if qual == math.MaxUint32 { + // 0xffffffff is undefined ID, so return zero. + return "" + } + const ( + tagUser = 0x02 + tagGroup = 0x08 + ) + id := strconv.Itoa(int(qual)) + switch tag { + case tagUser: + u, err := user.LookupId(id) + if err == nil { + return u.Username + } + case tagGroup: + g, err := user.LookupGroupId(id) + if err == nil { + return g.Name + } + } + // Fallback to the numeric ID if we can't get a name + // or the tag is other than user/group. + return id +} + +func modeString(perm uint16) string { + var buf [3]byte + w := 0 + const rwx = "rwx" + for i, c := range rwx { + if perm&(1< Date: Wed, 16 Aug 2023 06:56:35 +0930 Subject: [PATCH 3/4] address pr comment --- auditbeat/module/file_integrity/event.go | 9 ++------- auditbeat/module/file_integrity/event_test.go | 13 ++++++++++++- auditbeat/module/file_integrity/fileinfo_posix.go | 15 ++++++++------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/auditbeat/module/file_integrity/event.go b/auditbeat/module/file_integrity/event.go index be4d701f2a3..8d1fd54b7b8 100644 --- a/auditbeat/module/file_integrity/event.go +++ b/auditbeat/module/file_integrity/event.go @@ -23,7 +23,6 @@ import ( "crypto/sha1" "crypto/sha256" "crypto/sha512" - "encoding/base64" "encoding/binary" "encoding/hex" "fmt" @@ -328,7 +327,7 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event { file["selinux"] = info.SELinux } if info.POSIXACLAccess != "" { - a, err := aclText(info.POSIXACLAccess) + a, err := aclText([]byte(info.POSIXACLAccess)) if err == nil { file["posix_acl_access"] = a } @@ -370,11 +369,7 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event { return out } -func aclText(s string) ([]string, error) { - b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(s, "0s")) - if err != nil { - return nil, err - } +func aclText(b []byte) ([]string, error) { if (len(b)-4)%8 != 0 { return nil, fmt.Errorf("unexpected ACL length: %d", len(b)) } diff --git a/auditbeat/module/file_integrity/event_test.go b/auditbeat/module/file_integrity/event_test.go index 2777a427d34..e587b8e25f6 100644 --- a/auditbeat/module/file_integrity/event_test.go +++ b/auditbeat/module/file_integrity/event_test.go @@ -19,6 +19,7 @@ package file_integrity import ( "bytes" + "encoding/base64" "encoding/hex" "fmt" "io/ioutil" @@ -27,6 +28,7 @@ import ( "os/user" "reflect" "runtime" + "strings" "testing" "time" @@ -557,6 +559,10 @@ func assertHasKey(t testing.TB, m mapstr.M, key string) bool { } func TestACLText(t *testing.T) { + // The xattr package returns raw bytes, but command line tools such as getfattr + // return a base64-encoded format, so use that here to make test validation + // easier. + // // Depending on the system we are running this test on, we may or may not // have a username associated with the user's UID in the xattr string, so // dynamically determine the username here. @@ -574,7 +580,12 @@ func TestACLText(t *testing.T) { }, } for i, test := range tests { - got, err := aclText(test.encoded) + b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(test.encoded, "0s")) + if err != nil { + t.Errorf("invalid test: unexpected base64 encoding error for test %d: %v", i, err) + continue + } + got, err := aclText(b) if err != nil { t.Errorf("unexpected error for test %d: %v", i, err) continue diff --git a/auditbeat/module/file_integrity/fileinfo_posix.go b/auditbeat/module/file_integrity/fileinfo_posix.go index 27ba9f775e6..93ab2d80457 100644 --- a/auditbeat/module/file_integrity/fileinfo_posix.go +++ b/auditbeat/module/file_integrity/fileinfo_posix.go @@ -20,11 +20,11 @@ package file_integrity import ( - "bytes" "fmt" "os" "os/user" "strconv" + "strings" "syscall" "github.com/joeshaw/multierror" @@ -73,6 +73,12 @@ func NewMetadata(path string, info os.FileInfo) (*Metadata, error) { "security.selinux": &fileInfo.SELinux, "system.posix_acl_access": &fileInfo.POSIXACLAccess, }) + // The selinux attr may be null terminated. It would be cheaper + // to use strings.TrimRight, but absent documentation saying + // that there is only ever a final null terminator, take the + // guaranteed correct path of terminating at the first found + // null byte. + fileInfo.SELinux, _, _ = strings.Cut(fileInfo.SELinux, "\x00") group, err := user.LookupGroupId(strconv.Itoa(int(fileInfo.GID))) if err != nil { @@ -98,11 +104,6 @@ func getExtendedAttributes(path string, dst map[string]*string) { if err != nil { continue } - *d = string(trimNull(att)) + *d = string(att) } } - -func trimNull(b []byte) []byte { - b, _, _ = bytes.Cut(b, []byte{0}) - return b -} From 0f8dccb3fdd087e2913a5d89d4298d8a2eb1571d Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 16 Aug 2023 16:20:18 +0930 Subject: [PATCH 4/4] add missing fbDecodeMetadata accesses --- .../module/file_integrity/flatbuffers.go | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/auditbeat/module/file_integrity/flatbuffers.go b/auditbeat/module/file_integrity/flatbuffers.go index 21ef24150c9..d338ffcedaf 100644 --- a/auditbeat/module/file_integrity/flatbuffers.go +++ b/auditbeat/module/file_integrity/flatbuffers.go @@ -257,16 +257,18 @@ func fbDecodeMetadata(e *schema.Event) *Metadata { } mode := os.FileMode(info.Mode()) rtn := &Metadata{ - Inode: info.Inode(), - UID: info.Uid(), - GID: info.Gid(), - SID: string(info.Sid()), - Mode: mode & ^(os.ModeSetuid | os.ModeSetgid), - Size: info.Size(), - MTime: time.Unix(0, info.MtimeNs()).UTC(), - CTime: time.Unix(0, info.CtimeNs()).UTC(), - SetUID: mode&os.ModeSetuid != 0, - SetGID: mode&os.ModeSetgid != 0, + Inode: info.Inode(), + UID: info.Uid(), + GID: info.Gid(), + SID: string(info.Sid()), + Mode: mode & ^(os.ModeSetuid | os.ModeSetgid), + Size: info.Size(), + MTime: time.Unix(0, info.MtimeNs()).UTC(), + CTime: time.Unix(0, info.CtimeNs()).UTC(), + SetUID: mode&os.ModeSetuid != 0, + SetGID: mode&os.ModeSetgid != 0, + SELinux: string(info.Selinux()), + POSIXACLAccess: string(info.PosixAclAccess()), } switch info.Type() {