Skip to content

Commit

Permalink
[Auditbeat] Package: Close librpm handle (#12215)
Browse files Browse the repository at this point in the history
Closes the librpm handle we `dlopen()` when the dataset is closed.
  • Loading branch information
Christoph Wurm authored May 28, 2019
1 parent 5502f4e commit bc72158
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 47 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,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
}

0 comments on commit bc72158

Please sign in to comment.