From 58620647d63dfee854423ed4ec2b3f1ecbee82c3 Mon Sep 17 00:00:00 2001 From: Christoph Wurm Date: Sat, 16 Feb 2019 16:53:09 +0000 Subject: [PATCH] Handle librpm's thread-local storage. --- .../module/system/package/rpm_linux.go | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/x-pack/auditbeat/module/system/package/rpm_linux.go b/x-pack/auditbeat/module/system/package/rpm_linux.go index 704a0edac01..292db1d5ed6 100644 --- a/x-pack/auditbeat/module/system/package/rpm_linux.go +++ b/x-pack/auditbeat/module/system/package/rpm_linux.go @@ -8,6 +8,7 @@ package pkg import ( "fmt" + "runtime" "time" "unsafe" @@ -154,16 +155,17 @@ const ( ) type cFunctions struct { - rpmtsCreate unsafe.Pointer - rpmReadConfigFiles unsafe.Pointer - rpmtsInitIterator unsafe.Pointer - rpmdbNextIterator unsafe.Pointer - headerLink unsafe.Pointer - headerGetEntry unsafe.Pointer - headerFree unsafe.Pointer - rpmdbFreeIterator unsafe.Pointer - rpmtsFree unsafe.Pointer - rpmsqEnable unsafe.Pointer + rpmtsCreate unsafe.Pointer + rpmReadConfigFiles unsafe.Pointer + rpmtsInitIterator unsafe.Pointer + rpmdbNextIterator unsafe.Pointer + headerLink unsafe.Pointer + headerGetEntry unsafe.Pointer + headerFree unsafe.Pointer + rpmdbFreeIterator unsafe.Pointer + rpmtsFree unsafe.Pointer + rpmsqEnable unsafe.Pointer + rpmsqSetInterruptSafety unsafe.Pointer } var cFun *cFunctions @@ -225,7 +227,7 @@ func dlopenCFunctions() (*cFunctions, error) { } // Only available in librpm>=4.13.0 - rpmsqSetInterruptSafety, err := librpm.GetSymbolPointer("rpmsqSetInterruptSafety") + cFun.rpmsqSetInterruptSafety, err = librpm.GetSymbolPointer("rpmsqSetInterruptSafety") if err != nil { var err2 error // Only available in librpm<4.14.0 @@ -235,14 +237,20 @@ func dlopenCFunctions() (*cFunctions, error) { errs = append(errs, err, err2) return nil, errs.Err() } - } else { - C.my_rpmsqSetInterruptSafety(rpmsqSetInterruptSafety, 0) } return &cFun, nil } func listRPMPackages() ([]*Package, error) { + // In newer versions, librpm is using the thread-local variable + // `disableInterruptSafety` in rpmio/rpmsq.c to disable signal + // traps. To make sure our settings remain in effect throughout + // our function calls we have to lock the OS thread here, since + // Golang can otherwise use any thread it likes for each C.* call. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if cFun == nil { var err error cFun, err = dlopenCFunctions() @@ -251,6 +259,10 @@ func listRPMPackages() ([]*Package, error) { } } + if cFun.rpmsqSetInterruptSafety != nil { + C.my_rpmsqSetInterruptSafety(cFun.rpmsqSetInterruptSafety, 0) + } + rpmts := C.my_rpmtsCreate(cFun.rpmtsCreate) if rpmts == nil { return nil, fmt.Errorf("Failed to get rpmts")