Skip to content

Commit

Permalink
link/kprobe: set the correct size to perf_event_attr
Browse files Browse the repository at this point in the history
Signed-off-by: Mattia Meleleo <melmat@tuta.io>
  • Loading branch information
mmat11 committed Apr 22, 2021
1 parent a4ee356 commit 37cc360
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 31 deletions.
1 change: 1 addition & 0 deletions internal/unix/types_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const (
PERF_RECORD_SAMPLE = linux.PERF_RECORD_SAMPLE
AT_FDCWD = linux.AT_FDCWD
RENAME_NOREPLACE = linux.RENAME_NOREPLACE
PERF_ATTR_SIZE_VER5 = linux.PERF_ATTR_SIZE_VER5
)

// Statfs_t is a wrapper
Expand Down
1 change: 1 addition & 0 deletions internal/unix/types_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const (
PERF_RECORD_SAMPLE = 9
AT_FDCWD = -0x2
RENAME_NOREPLACE = 0x1
PERF_ATTR_SIZE_VER5 = 0
)

// Statfs_t is a wrapper
Expand Down
70 changes: 39 additions & 31 deletions link/kprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,36 @@ func (pt probeType) RetprobeBit() (uint64, error) {
return uretprobeBit()
}

func (pt probeType) PerfEventAttr(eventType uint64, symbol, path string, offset, config uint64) (*unix.PerfEventAttr, unsafe.Pointer, error) {
var sp unsafe.Pointer

switch pt {
case kprobeType:
// Create a pointer to a NUL-terminated string for the kernel.
ptr, err := unsafeStringPtr(symbol)
if err != nil {
return nil, sp, err
}
sp = ptr
case uprobeType:
ptr, err := unsafeStringPtr(path)
if err != nil {
return nil, sp, err
}
sp = ptr
}

attr := unix.PerfEventAttr{
Size: unix.PERF_ATTR_SIZE_VER5, // Size is used to create the correct version of PerfEventAttr
Type: uint32(eventType), // PMU event type read from sysfs
Ext1: uint64(uintptr(sp)), // Kernel symbol / Uprobe path
Ext2: offset, // Uprobe offset
Config: config, // Retprobe flag
}

return &attr, sp, nil
}

// Kprobe attaches the given eBPF program to a perf event that fires when the
// given kernel symbol starts executing. See /proc/kallsyms for available
// symbols. For example, printk():
Expand Down Expand Up @@ -169,43 +199,21 @@ func pmuProbe(typ probeType, symbol, path string, offset uint64, ret bool) (*per
return nil, err
}

config, err := typ.RetprobeBit()
if err != nil {
return nil, err
}

var (
attr unix.PerfEventAttr
sp unsafe.Pointer
)
switch typ {
case kprobeType:
// Create a pointer to a NUL-terminated string for the kernel.
sp, err := unsafeStringPtr(symbol)
if err != nil {
return nil, err
}

attr = unix.PerfEventAttr{
Type: uint32(et), // PMU event type read from sysfs
Ext1: uint64(uintptr(sp)), // Kernel symbol to trace
Config: config, // Retprobe flag
}
case uprobeType:
sp, err := unsafeStringPtr(path)
var config uint64
if ret {
bit, err := typ.RetprobeBit()
if err != nil {
return nil, err
}
config |= 1 << bit
}

attr = unix.PerfEventAttr{
Type: uint32(et), // PMU event type read from sysfs
Ext1: uint64(uintptr(sp)), // Uprobe path
Ext2: uint64(uintptr(offset)), // Uprobe offset
Config: config, // Retprobe flag
}
attr, sp, err := typ.PerfEventAttr(et, symbol, path, offset, config)
if err != nil {
return nil, err
}

fd, err := unix.PerfEventOpen(&attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
fd, err := unix.PerfEventOpen(attr, perfAllThreads, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)

// Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL
// when trying to create a kretprobe for a missing symbol. Make sure ENOENT
Expand Down

0 comments on commit 37cc360

Please sign in to comment.