Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Auditbeat] Package: Close librpm handle #12215

Merged
merged 2 commits into from
May 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Package dataset: Fixed a crash inside librpm after Auditbeat has been running for a while. {issue}12147[12147] {pull}12168[12168]
- Fix formatting of config files on macOS and Windows. {pull}12148[12148]
- Fix direction of incoming IPv6 sockets. {pull}12248[12248]
- Package dataset: Close librpm handle. {pull}12215[12215]

*Filebeat*

Expand Down
10 changes: 8 additions & 2 deletions x-pack/auditbeat/module/system/package/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

"github.com/OneOfOne/xxhash"
"github.com/gofrs/uuid"
"github.com/joeshaw/multierror"
"github.com/pkg/errors"

"github.com/elastic/beats/auditbeat/datastore"
Expand Down Expand Up @@ -255,10 +256,15 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {

// Close cleans up the MetricSet when it finishes.
func (ms *MetricSet) Close() error {
var errs multierror.Errors

errs = append(errs, closeDataset())

if ms.bucket != nil {
return ms.bucket.Close()
errs = append(errs, ms.bucket.Close())
}
return nil

return errs.Err()
}

// Fetch collects data about the host. It is invoked periodically.
Expand Down
113 changes: 68 additions & 45 deletions x-pack/auditbeat/module/system/package/rpm_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,22 @@ const (
RPMTAG_INSTALLTIME = 1008
)

type cFunctions struct {
var openedLibrpm *librpm

// closeDataset performs cleanup when the dataset is closed.
func closeDataset() error {
if openedLibrpm != nil {
err := openedLibrpm.close()
openedLibrpm = nil
return err
}

return nil
}

type librpm struct {
handle *dlopen.LibHandle

rpmtsCreate unsafe.Pointer
rpmReadConfigFiles unsafe.Pointer
rpmtsInitIterator unsafe.Pointer
Expand All @@ -181,9 +196,15 @@ type cFunctions struct {
rpmFreeMacros unsafe.Pointer
}

var cFun *cFunctions
func (lib *librpm) close() error {
if lib.handle != nil {
return lib.handle.Close()
}

return nil
}

func dlopenCFunctions() (*cFunctions, error) {
func openLibrpm() (*librpm, error) {
var librpmNames = []string{
"librpm.so", // with rpm-devel installed
"librpm.so.8", // Fedora 29
Expand All @@ -197,77 +218,79 @@ func dlopenCFunctions() (*cFunctions, error) {
"librpm.so.4",
"librpm.so.2",
}
var cFun cFunctions

librpm, err := dlopen.GetHandle(librpmNames)
var librpm librpm
var err error

librpm.handle, err = dlopen.GetHandle(librpmNames)
if err != nil {
return nil, err
}

cFun.rpmtsCreate, err = librpm.GetSymbolPointer("rpmtsCreate")
librpm.rpmtsCreate, err = librpm.handle.GetSymbolPointer("rpmtsCreate")
if err != nil {
return nil, err
}

cFun.rpmReadConfigFiles, err = librpm.GetSymbolPointer("rpmReadConfigFiles")
librpm.rpmReadConfigFiles, err = librpm.handle.GetSymbolPointer("rpmReadConfigFiles")
if err != nil {
return nil, err
}

cFun.rpmtsInitIterator, err = librpm.GetSymbolPointer("rpmtsInitIterator")
librpm.rpmtsInitIterator, err = librpm.handle.GetSymbolPointer("rpmtsInitIterator")
if err != nil {
return nil, err
}

cFun.rpmdbNextIterator, err = librpm.GetSymbolPointer("rpmdbNextIterator")
librpm.rpmdbNextIterator, err = librpm.handle.GetSymbolPointer("rpmdbNextIterator")
if err != nil {
return nil, err
}

cFun.headerLink, err = librpm.GetSymbolPointer("headerLink")
librpm.headerLink, err = librpm.handle.GetSymbolPointer("headerLink")
if err != nil {
return nil, err
}

cFun.headerGetString, err = librpm.GetSymbolPointer("headerGetString")
librpm.headerGetString, err = librpm.handle.GetSymbolPointer("headerGetString")
if err != nil {
return nil, err
}

cFun.headerGetNumber, err = librpm.GetSymbolPointer("headerGetNumber")
librpm.headerGetNumber, err = librpm.handle.GetSymbolPointer("headerGetNumber")
if err != nil {
return nil, err
}

cFun.headerFree, err = librpm.GetSymbolPointer("headerFree")
librpm.headerFree, err = librpm.handle.GetSymbolPointer("headerFree")
if err != nil {
return nil, err
}

cFun.rpmdbFreeIterator, err = librpm.GetSymbolPointer("rpmdbFreeIterator")
librpm.rpmdbFreeIterator, err = librpm.handle.GetSymbolPointer("rpmdbFreeIterator")
if err != nil {
return nil, err
}

cFun.rpmtsFree, err = librpm.GetSymbolPointer("rpmtsFree")
librpm.rpmtsFree, err = librpm.handle.GetSymbolPointer("rpmtsFree")
if err != nil {
return nil, err
}

cFun.rpmFreeRpmrc, err = librpm.GetSymbolPointer("rpmFreeRpmrc")
librpm.rpmFreeRpmrc, err = librpm.handle.GetSymbolPointer("rpmFreeRpmrc")
if err != nil {
return nil, err
}

// Only available in librpm>=4.13.0
cFun.rpmsqSetInterruptSafety, err = librpm.GetSymbolPointer("rpmsqSetInterruptSafety")
librpm.rpmsqSetInterruptSafety, err = librpm.handle.GetSymbolPointer("rpmsqSetInterruptSafety")
// no error check

// Only available in librpm>=4.6.0
cFun.rpmFreeMacros, err = librpm.GetSymbolPointer("rpmFreeMacros")
librpm.rpmFreeMacros, err = librpm.handle.GetSymbolPointer("rpmFreeMacros")
// no error check

return &cFun, nil
return &librpm, nil
}

func listRPMPackages() ([]*Package, error) {
Expand All @@ -279,43 +302,43 @@ func listRPMPackages() ([]*Package, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()

if cFun == nil {
if openedLibrpm == nil {
var err error
cFun, err = dlopenCFunctions()
openedLibrpm, err = openLibrpm()
if err != nil {
return nil, err
}
}

if cFun.rpmsqSetInterruptSafety != nil {
C.my_rpmsqSetInterruptSafety(cFun.rpmsqSetInterruptSafety, 0)
if openedLibrpm.rpmsqSetInterruptSafety != nil {
C.my_rpmsqSetInterruptSafety(openedLibrpm.rpmsqSetInterruptSafety, 0)
}

rpmts := C.my_rpmtsCreate(cFun.rpmtsCreate)
rpmts := C.my_rpmtsCreate(openedLibrpm.rpmtsCreate)
if rpmts == nil {
return nil, fmt.Errorf("Failed to get rpmts")
}
defer C.my_rpmtsFree(cFun.rpmtsFree, rpmts)
defer C.my_rpmtsFree(openedLibrpm.rpmtsFree, rpmts)

res := C.my_rpmReadConfigFiles(cFun.rpmReadConfigFiles)
res := C.my_rpmReadConfigFiles(openedLibrpm.rpmReadConfigFiles)
if int(res) != 0 {
return nil, fmt.Errorf("Error: %d", int(res))
}
defer C.my_rpmFreeRpmrc(cFun.rpmFreeRpmrc)
if cFun.rpmFreeMacros != nil {
defer C.my_rpmFreeMacros(cFun.rpmFreeMacros)
defer C.my_rpmFreeRpmrc(openedLibrpm.rpmFreeRpmrc)
if openedLibrpm.rpmFreeMacros != nil {
defer C.my_rpmFreeMacros(openedLibrpm.rpmFreeMacros)
}

mi := C.my_rpmtsInitIterator(cFun.rpmtsInitIterator, rpmts)
mi := C.my_rpmtsInitIterator(openedLibrpm.rpmtsInitIterator, rpmts)
if mi == nil {
return nil, fmt.Errorf("Failed to get match iterator")
}
defer C.my_rpmdbFreeIterator(cFun.rpmdbFreeIterator, mi)
defer C.my_rpmdbFreeIterator(openedLibrpm.rpmdbFreeIterator, mi)

var packages []*Package
for header := C.my_rpmdbNextIterator(cFun.rpmdbNextIterator, mi); header != nil; header = C.my_rpmdbNextIterator(cFun.rpmdbNextIterator, mi) {
for header := C.my_rpmdbNextIterator(openedLibrpm.rpmdbNextIterator, mi); header != nil; header = C.my_rpmdbNextIterator(openedLibrpm.rpmdbNextIterator, mi) {

pkg, err := packageFromHeader(header, cFun)
pkg, err := packageFromHeader(header, openedLibrpm)
if err != nil {
return nil, err
}
Expand All @@ -326,39 +349,39 @@ func listRPMPackages() ([]*Package, error) {
return packages, nil
}

func packageFromHeader(header C.Header, cFun *cFunctions) (*Package, error) {
func packageFromHeader(header C.Header, openedLibrpm *librpm) (*Package, error) {

header = C.my_headerLink(cFun.headerLink, header)
header = C.my_headerLink(openedLibrpm.headerLink, header)
if header == nil {
return nil, fmt.Errorf("Error calling headerLink")
}
defer C.my_headerFree(cFun.headerFree, header)
defer C.my_headerFree(openedLibrpm.headerFree, header)

pkg := Package{}

name := C.my_headerGetString(cFun.headerGetString, header, RPMTAG_NAME)
name := C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_NAME)
if name != nil {
pkg.Name = C.GoString(name)
} else {
return nil, errors.New("Failed to get package name")
}

version := C.my_headerGetString(cFun.headerGetString, header, RPMTAG_VERSION)
version := C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_VERSION)
if version != nil {
pkg.Version = C.GoString(version)
} else {
pkg.Error = errors.New("Failed to get package version")
}

pkg.Release = C.GoString(C.my_headerGetString(cFun.headerGetString, header, RPMTAG_RELEASE))
pkg.License = C.GoString(C.my_headerGetString(cFun.headerGetString, header, RPMTAG_LICENSE))
pkg.Arch = C.GoString(C.my_headerGetString(cFun.headerGetString, header, RPMTAG_ARCH))
pkg.URL = C.GoString(C.my_headerGetString(cFun.headerGetString, header, RPMTAG_URL))
pkg.Summary = C.GoString(C.my_headerGetString(cFun.headerGetString, header, RPMTAG_SUMMARY))
pkg.Release = C.GoString(C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_RELEASE))
pkg.License = C.GoString(C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_LICENSE))
pkg.Arch = C.GoString(C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_ARCH))
pkg.URL = C.GoString(C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_URL))
pkg.Summary = C.GoString(C.my_headerGetString(openedLibrpm.headerGetString, header, RPMTAG_SUMMARY))

pkg.Size = uint64(C.my_headerGetNumber(cFun.headerGetNumber, header, RPMTAG_SIZE))
pkg.Size = uint64(C.my_headerGetNumber(openedLibrpm.headerGetNumber, header, RPMTAG_SIZE))

installTime := C.my_headerGetNumber(cFun.headerGetNumber, header, RPMTAG_INSTALLTIME)
installTime := C.my_headerGetNumber(openedLibrpm.headerGetNumber, header, RPMTAG_INSTALLTIME)
if installTime != 0 {
pkg.InstallTime = time.Unix(int64(installTime), 0)
}
Expand Down
4 changes: 4 additions & 0 deletions x-pack/auditbeat/module/system/package/rpm_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ import "github.com/pkg/errors"
func listRPMPackages() ([]*Package, error) {
return nil, errors.New("listing RPM packages is only supported on Linux")
}

func closeDataset() error {
return nil
}