Skip to content

Commit

Permalink
Merge pull request #2707 from Creatone/malloc-fix
Browse files Browse the repository at this point in the history
[Fix] Avoid random values in unix.PerfEventAttr{}
  • Loading branch information
bobbypage authored Nov 9, 2020
2 parents 19ba5a8 + 82662da commit 51dbd62
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
20 changes: 15 additions & 5 deletions perf/collector_libpfm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package perf
// #cgo LDFLAGS: -lpfm
// #include <perfmon/pfmlib.h>
// #include <stdlib.h>
// #include <string.h>
import "C"

import (
Expand Down Expand Up @@ -231,8 +232,18 @@ func (c *collector) setup() error {
return nil
}

func readPerfEventAttr(name string) (*unix.PerfEventAttr, error) {
func readPerfEventAttr(name string, pfmGetOsEventEncoding func(string, unsafe.Pointer) error) (*unix.PerfEventAttr, error) {
perfEventAttrMemory := C.malloc(C.ulong(unsafe.Sizeof(unix.PerfEventAttr{})))
// Fill memory with 0 values.
C.memset(perfEventAttrMemory, 0, C.ulong(unsafe.Sizeof(unix.PerfEventAttr{})))
err := pfmGetOsEventEncoding(name, unsafe.Pointer(perfEventAttrMemory))
if err != nil {
return nil, err
}
return (*unix.PerfEventAttr)(perfEventAttrMemory), nil
}

func pfmGetOsEventEncoding(name string, perfEventAttrMemory unsafe.Pointer) error {
event := pfmPerfEncodeArgT{}
fstr := C.CString("")
event.fstr = unsafe.Pointer(fstr)
Expand All @@ -241,10 +252,9 @@ func readPerfEventAttr(name string) (*unix.PerfEventAttr, error) {
cSafeName := C.CString(name)
pErr := C.pfm_get_os_event_encoding(cSafeName, C.PFM_PLM0|C.PFM_PLM3, C.PFM_OS_PERF_EVENT, unsafe.Pointer(&event))
if pErr != C.PFM_SUCCESS {
return nil, fmt.Errorf("unable to transform event name %s to perf_event_attr: %d", name, int(pErr))
return fmt.Errorf("unable to transform event name %s to perf_event_attr: %d", name, int(pErr))
}

return (*unix.PerfEventAttr)(perfEventAttrMemory), nil
return nil
}

type eventInfo struct {
Expand Down Expand Up @@ -408,7 +418,7 @@ func (c *collector) createConfigFromRawEvent(event *CustomEvent) *unix.PerfEvent
func (c *collector) createConfigFromEvent(event Event) (*unix.PerfEventAttr, error) {
klog.V(5).Infof("Setting up perf event %s", string(event))

config, err := readPerfEventAttr(string(event))
config, err := readPerfEventAttr(string(event), pfmGetOsEventEncoding)
if err != nil {
C.free((unsafe.Pointer)(config))
return nil, err
Expand Down
42 changes: 42 additions & 0 deletions perf/collector_libpfm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"bytes"
"encoding/binary"
"testing"
"unsafe"

"golang.org/x/sys/unix"

"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -387,3 +390,42 @@ func TestReadPerfStat(t *testing.T) {
})
}
}

func TestReadPerfEventAttr(t *testing.T) {
var testCases = []struct {
expected *unix.PerfEventAttr
pfmMockedFunc func(string, unsafe.Pointer) error
}{
{
&unix.PerfEventAttr{
Type: 0,
Size: 0,
Config: 0,
Sample: 0,
Sample_type: 0,
Read_format: 0,
Bits: 0,
Wakeup: 0,
Bp_type: 0,
Ext1: 0,
Ext2: 0,
Branch_sample_type: 0,
Sample_regs_user: 0,
Sample_stack_user: 0,
Clockid: 0,
Sample_regs_intr: 0,
Aux_watermark: 0,
Sample_max_stack: 0,
},
func(s string, pointer unsafe.Pointer) error {
return nil
},
},
}

for _, test := range testCases {
got, err := readPerfEventAttr("event_name", test.pfmMockedFunc)
assert.NoError(t, err)
assert.Equal(t, test.expected, got)
}
}
2 changes: 1 addition & 1 deletion perf/uncore_libpfm.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ func (c *uncoreCollector) setupEvent(name string, pmus uncorePMUs, groupIndex in

klog.V(5).Infof("Setting up uncore perf event %s", name)

config, err := readPerfEventAttr(name)
config, err := readPerfEventAttr(name, pfmGetOsEventEncoding)
if err != nil {
C.free((unsafe.Pointer)(config))
return err
Expand Down

0 comments on commit 51dbd62

Please sign in to comment.