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: Nullify Librpm's rpmsqEnable #11628

Merged
merged 2 commits into from
Apr 5, 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 @@ -49,6 +49,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
*Auditbeat*

- Package dataset: dlopen versioned librpm shared objects. {pull}11565[11565]
- Package dataset: Nullify Librpm's rpmsqEnable. {pull}11628[11628]

*Filebeat*

Expand Down
37 changes: 8 additions & 29 deletions x-pack/auditbeat/module/system/package/rpm_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"unsafe"

"github.com/coreos/pkg/dlopen"
"github.com/joeshaw/multierror"
)

/*
Expand All @@ -25,7 +24,6 @@ import (
#include <rpm/header.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmsq.h>

rpmts
my_rpmtsCreate(void *f) {
Expand Down Expand Up @@ -113,27 +111,21 @@ my_rpmtsFree(void *f, rpmts ts) {
// By default, librpm is going to trap various UNIX signals including SIGINT and SIGTERM
// which will prevent Beats from shutting down correctly.
//
// This disables that behavior. We should be very dilligent in
// This disables that behavior by nullifying rpmsqEnable. We should be very dilligent in
// cleaning up in our use of librpm.
//
// More recent versions of librpm have a new function rpmsqSetInterruptSafety()
// to do this, see below.
//
// See also:
// - librpm traps signals and calls exit(1) to terminate the whole process incl. our Go code: https://github.com/rpm-software-management/rpm/blob/rpm-4.11.3-release/lib/rpmdb.c#L640
// - has caused problems for gdb before, calling rpmsqEnable(_, NULL) is the workaround they also use: https://bugzilla.redhat.com/show_bug.cgi?id=643031
// - has caused problems for gdb before, they also nullify rpmsqEnable: https://bugzilla.redhat.com/show_bug.cgi?id=643031
// - the new rpmsqSetInterruptSafety(), unfortunately only available in librpm>=4.14.0 (CentOS 7 has 4.11.3): https://github.com/rpm-software-management/rpm/commit/56f49d7f5af7c1c8a3eb478431356195adbfdd25
void
my_disableLibrpmSignalTraps(void *f) {
int (*rpmsqEnable)(int, rpmsqAction_t);
rpmsqEnable = (int (*)(int, rpmsqAction_t))f;

// Disable all traps
rpmsqEnable(-SIGHUP, NULL);
rpmsqEnable(-SIGINT, NULL);
rpmsqEnable(-SIGTERM, NULL);
rpmsqEnable(-SIGQUIT, NULL);
rpmsqEnable(-SIGPIPE, NULL);
extern int rpmsqEnable (int signum, void *handler);
int
rpmsqEnable (int signum, void *handler)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder who is calling this function. Is it called internally by librpm?

If that's the case I'm surprised that you can override it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's internal to librpm. This works because we dynamically load librpm using dlopen() after the program is started. Any symbols that are already defined at that point will not be redefined.

{
return 0;
}

void
Expand Down Expand Up @@ -170,7 +162,6 @@ type cFunctions struct {
headerFree unsafe.Pointer
rpmdbFreeIterator unsafe.Pointer
rpmtsFree unsafe.Pointer
rpmsqEnable unsafe.Pointer
rpmsqSetInterruptSafety unsafe.Pointer
}

Expand Down Expand Up @@ -249,16 +240,7 @@ func dlopenCFunctions() (*cFunctions, error) {

// Only available in librpm>=4.13.0
cFun.rpmsqSetInterruptSafety, err = librpm.GetSymbolPointer("rpmsqSetInterruptSafety")
if err != nil {
var err2 error
// Only available in librpm<4.14.0
cFun.rpmsqEnable, err2 = librpm.GetSymbolPointer("rpmsqEnable")
if err2 != nil {
var errs multierror.Errors
errs = append(errs, err, err2)
return nil, errs.Err()
}
}
// no error check

return &cFun, nil
}
Expand Down Expand Up @@ -298,9 +280,6 @@ func listRPMPackages() ([]*Package, error) {
if mi == nil {
return nil, fmt.Errorf("Failed to get match iterator")
}
if cFun.rpmsqEnable != nil {
C.my_disableLibrpmSignalTraps(cFun.rpmsqEnable)
}
defer C.my_rpmdbFreeIterator(cFun.rpmdbFreeIterator, mi)

var packages []*Package
Expand Down