Skip to content

Commit

Permalink
Handle librpm's thread-local storage.
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoph Wurm committed Feb 16, 2019
1 parent ae5006e commit 5862064
Showing 1 changed file with 25 additions and 13 deletions.
38 changes: 25 additions & 13 deletions x-pack/auditbeat/module/system/package/rpm_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package pkg

import (
"fmt"
"runtime"
"time"
"unsafe"

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -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")
Expand Down

0 comments on commit 5862064

Please sign in to comment.