summaryrefslogtreecommitdiff
path: root/vendor/github.com/cilium/ebpf/link
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/cilium/ebpf/link')
-rw-r--r--vendor/github.com/cilium/ebpf/link/cgroup.go165
-rw-r--r--vendor/github.com/cilium/ebpf/link/doc.go2
-rw-r--r--vendor/github.com/cilium/ebpf/link/iter.go85
-rw-r--r--vendor/github.com/cilium/ebpf/link/kprobe.go568
-rw-r--r--vendor/github.com/cilium/ebpf/link/link.go313
-rw-r--r--vendor/github.com/cilium/ebpf/link/netns.go36
-rw-r--r--vendor/github.com/cilium/ebpf/link/perf_event.go394
-rw-r--r--vendor/github.com/cilium/ebpf/link/platform.go25
-rw-r--r--vendor/github.com/cilium/ebpf/link/program.go76
-rw-r--r--vendor/github.com/cilium/ebpf/link/raw_tracepoint.go87
-rw-r--r--vendor/github.com/cilium/ebpf/link/socket_filter.go40
-rw-r--r--vendor/github.com/cilium/ebpf/link/syscalls.go103
-rw-r--r--vendor/github.com/cilium/ebpf/link/tracepoint.go77
-rw-r--r--vendor/github.com/cilium/ebpf/link/tracing.go141
-rw-r--r--vendor/github.com/cilium/ebpf/link/uprobe.go373
-rw-r--r--vendor/github.com/cilium/ebpf/link/xdp.go54
16 files changed, 0 insertions, 2539 deletions
diff --git a/vendor/github.com/cilium/ebpf/link/cgroup.go b/vendor/github.com/cilium/ebpf/link/cgroup.go
deleted file mode 100644
index 003b0638e..000000000
--- a/vendor/github.com/cilium/ebpf/link/cgroup.go
+++ /dev/null
@@ -1,165 +0,0 @@
-package link
-
-import (
- "errors"
- "fmt"
- "os"
-
- "github.com/cilium/ebpf"
-)
-
-type cgroupAttachFlags uint32
-
-// cgroup attach flags
-const (
- flagAllowOverride cgroupAttachFlags = 1 << iota
- flagAllowMulti
- flagReplace
-)
-
-type CgroupOptions struct {
- // Path to a cgroupv2 folder.
- Path string
- // One of the AttachCgroup* constants
- Attach ebpf.AttachType
- // Program must be of type CGroup*, and the attach type must match Attach.
- Program *ebpf.Program
-}
-
-// AttachCgroup links a BPF program to a cgroup.
-func AttachCgroup(opts CgroupOptions) (Link, error) {
- cgroup, err := os.Open(opts.Path)
- if err != nil {
- return nil, fmt.Errorf("can't open cgroup: %s", err)
- }
-
- clone, err := opts.Program.Clone()
- if err != nil {
- cgroup.Close()
- return nil, err
- }
-
- var cg Link
- cg, err = newLinkCgroup(cgroup, opts.Attach, clone)
- if errors.Is(err, ErrNotSupported) {
- cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowMulti)
- }
- if errors.Is(err, ErrNotSupported) {
- cg, err = newProgAttachCgroup(cgroup, opts.Attach, clone, flagAllowOverride)
- }
- if err != nil {
- cgroup.Close()
- clone.Close()
- return nil, err
- }
-
- return cg, nil
-}
-
-type progAttachCgroup struct {
- cgroup *os.File
- current *ebpf.Program
- attachType ebpf.AttachType
- flags cgroupAttachFlags
-}
-
-var _ Link = (*progAttachCgroup)(nil)
-
-func (cg *progAttachCgroup) isLink() {}
-
-func newProgAttachCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program, flags cgroupAttachFlags) (*progAttachCgroup, error) {
- if flags&flagAllowMulti > 0 {
- if err := haveProgAttachReplace(); err != nil {
- return nil, fmt.Errorf("can't support multiple programs: %w", err)
- }
- }
-
- err := RawAttachProgram(RawAttachProgramOptions{
- Target: int(cgroup.Fd()),
- Program: prog,
- Flags: uint32(flags),
- Attach: attach,
- })
- if err != nil {
- return nil, fmt.Errorf("cgroup: %w", err)
- }
-
- return &progAttachCgroup{cgroup, prog, attach, flags}, nil
-}
-
-func (cg *progAttachCgroup) Close() error {
- defer cg.cgroup.Close()
- defer cg.current.Close()
-
- err := RawDetachProgram(RawDetachProgramOptions{
- Target: int(cg.cgroup.Fd()),
- Program: cg.current,
- Attach: cg.attachType,
- })
- if err != nil {
- return fmt.Errorf("close cgroup: %s", err)
- }
- return nil
-}
-
-func (cg *progAttachCgroup) Update(prog *ebpf.Program) error {
- new, err := prog.Clone()
- if err != nil {
- return err
- }
-
- args := RawAttachProgramOptions{
- Target: int(cg.cgroup.Fd()),
- Program: prog,
- Attach: cg.attachType,
- Flags: uint32(cg.flags),
- }
-
- if cg.flags&flagAllowMulti > 0 {
- // Atomically replacing multiple programs requires at least
- // 5.5 (commit 7dd68b3279f17921 "bpf: Support replacing cgroup-bpf
- // program in MULTI mode")
- args.Flags |= uint32(flagReplace)
- args.Replace = cg.current
- }
-
- if err := RawAttachProgram(args); err != nil {
- new.Close()
- return fmt.Errorf("can't update cgroup: %s", err)
- }
-
- cg.current.Close()
- cg.current = new
- return nil
-}
-
-func (cg *progAttachCgroup) Pin(string) error {
- return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported)
-}
-
-func (cg *progAttachCgroup) Unpin() error {
- return fmt.Errorf("can't pin cgroup: %w", ErrNotSupported)
-}
-
-func (cg *progAttachCgroup) Info() (*Info, error) {
- return nil, fmt.Errorf("can't get cgroup info: %w", ErrNotSupported)
-}
-
-type linkCgroup struct {
- RawLink
-}
-
-var _ Link = (*linkCgroup)(nil)
-
-func newLinkCgroup(cgroup *os.File, attach ebpf.AttachType, prog *ebpf.Program) (*linkCgroup, error) {
- link, err := AttachRawLink(RawLinkOptions{
- Target: int(cgroup.Fd()),
- Program: prog,
- Attach: attach,
- })
- if err != nil {
- return nil, err
- }
-
- return &linkCgroup{*link}, err
-}
diff --git a/vendor/github.com/cilium/ebpf/link/doc.go b/vendor/github.com/cilium/ebpf/link/doc.go
deleted file mode 100644
index 2bde35ed7..000000000
--- a/vendor/github.com/cilium/ebpf/link/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package link allows attaching eBPF programs to various kernel hooks.
-package link
diff --git a/vendor/github.com/cilium/ebpf/link/iter.go b/vendor/github.com/cilium/ebpf/link/iter.go
deleted file mode 100644
index d2b32ef33..000000000
--- a/vendor/github.com/cilium/ebpf/link/iter.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package link
-
-import (
- "fmt"
- "io"
- "unsafe"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/internal/sys"
-)
-
-type IterOptions struct {
- // Program must be of type Tracing with attach type
- // AttachTraceIter. The kind of iterator to attach to is
- // determined at load time via the AttachTo field.
- //
- // AttachTo requires the kernel to include BTF of itself,
- // and it to be compiled with a recent pahole (>= 1.16).
- Program *ebpf.Program
-
- // Map specifies the target map for bpf_map_elem and sockmap iterators.
- // It may be nil.
- Map *ebpf.Map
-}
-
-// AttachIter attaches a BPF seq_file iterator.
-func AttachIter(opts IterOptions) (*Iter, error) {
- if err := haveBPFLink(); err != nil {
- return nil, err
- }
-
- progFd := opts.Program.FD()
- if progFd < 0 {
- return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd)
- }
-
- var info bpfIterLinkInfoMap
- if opts.Map != nil {
- mapFd := opts.Map.FD()
- if mapFd < 0 {
- return nil, fmt.Errorf("invalid map: %w", sys.ErrClosedFd)
- }
- info.map_fd = uint32(mapFd)
- }
-
- attr := sys.LinkCreateIterAttr{
- ProgFd: uint32(progFd),
- AttachType: sys.AttachType(ebpf.AttachTraceIter),
- IterInfo: sys.NewPointer(unsafe.Pointer(&info)),
- IterInfoLen: uint32(unsafe.Sizeof(info)),
- }
-
- fd, err := sys.LinkCreateIter(&attr)
- if err != nil {
- return nil, fmt.Errorf("can't link iterator: %w", err)
- }
-
- return &Iter{RawLink{fd, ""}}, err
-}
-
-// Iter represents an attached bpf_iter.
-type Iter struct {
- RawLink
-}
-
-// Open creates a new instance of the iterator.
-//
-// Reading from the returned reader triggers the BPF program.
-func (it *Iter) Open() (io.ReadCloser, error) {
- attr := &sys.IterCreateAttr{
- LinkFd: it.fd.Uint(),
- }
-
- fd, err := sys.IterCreate(attr)
- if err != nil {
- return nil, fmt.Errorf("can't create iterator: %w", err)
- }
-
- return fd.File("bpf_iter"), nil
-}
-
-// union bpf_iter_link_info.map
-type bpfIterLinkInfoMap struct {
- map_fd uint32
-}
diff --git a/vendor/github.com/cilium/ebpf/link/kprobe.go b/vendor/github.com/cilium/ebpf/link/kprobe.go
deleted file mode 100644
index fdf622a0c..000000000
--- a/vendor/github.com/cilium/ebpf/link/kprobe.go
+++ /dev/null
@@ -1,568 +0,0 @@
-package link
-
-import (
- "bytes"
- "crypto/rand"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "runtime"
- "strings"
- "sync"
- "syscall"
- "unsafe"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/internal/sys"
- "github.com/cilium/ebpf/internal/unix"
-)
-
-var (
- kprobeEventsPath = filepath.Join(tracefsPath, "kprobe_events")
-
- kprobeRetprobeBit = struct {
- once sync.Once
- value uint64
- err error
- }{}
-)
-
-type probeType uint8
-
-type probeArgs struct {
- symbol, group, path string
- offset, refCtrOffset, cookie uint64
- pid int
- ret bool
-}
-
-// KprobeOptions defines additional parameters that will be used
-// when loading Kprobes.
-type KprobeOptions struct {
- // Arbitrary value that can be fetched from an eBPF program
- // via `bpf_get_attach_cookie()`.
- //
- // Needs kernel 5.15+.
- Cookie uint64
- // Offset of the kprobe relative to the traced symbol.
- // Can be used to insert kprobes at arbitrary offsets in kernel functions,
- // e.g. in places where functions have been inlined.
- Offset uint64
-}
-
-const (
- kprobeType probeType = iota
- uprobeType
-)
-
-func (pt probeType) String() string {
- if pt == kprobeType {
- return "kprobe"
- }
- return "uprobe"
-}
-
-func (pt probeType) EventsPath() string {
- if pt == kprobeType {
- return kprobeEventsPath
- }
- return uprobeEventsPath
-}
-
-func (pt probeType) PerfEventType(ret bool) perfEventType {
- if pt == kprobeType {
- if ret {
- return kretprobeEvent
- }
- return kprobeEvent
- }
- if ret {
- return uretprobeEvent
- }
- return uprobeEvent
-}
-
-func (pt probeType) RetprobeBit() (uint64, error) {
- if pt == kprobeType {
- return kretprobeBit()
- }
- return uretprobeBit()
-}
-
-// 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():
-//
-// kp, err := Kprobe("printk", prog, nil)
-//
-// Losing the reference to the resulting Link (kp) will close the Kprobe
-// and prevent further execution of prog. The Link must be Closed during
-// program shutdown to avoid leaking system resources.
-func Kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) {
- k, err := kprobe(symbol, prog, opts, false)
- if err != nil {
- return nil, err
- }
-
- lnk, err := attachPerfEvent(k, prog)
- if err != nil {
- k.Close()
- return nil, err
- }
-
- return lnk, nil
-}
-
-// Kretprobe attaches the given eBPF program to a perf event that fires right
-// before the given kernel symbol exits, with the function stack left intact.
-// See /proc/kallsyms for available symbols. For example, printk():
-//
-// kp, err := Kretprobe("printk", prog, nil)
-//
-// Losing the reference to the resulting Link (kp) will close the Kretprobe
-// and prevent further execution of prog. The Link must be Closed during
-// program shutdown to avoid leaking system resources.
-func Kretprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions) (Link, error) {
- k, err := kprobe(symbol, prog, opts, true)
- if err != nil {
- return nil, err
- }
-
- lnk, err := attachPerfEvent(k, prog)
- if err != nil {
- k.Close()
- return nil, err
- }
-
- return lnk, nil
-}
-
-// isValidKprobeSymbol implements the equivalent of a regex match
-// against "^[a-zA-Z_][0-9a-zA-Z_.]*$".
-func isValidKprobeSymbol(s string) bool {
- if len(s) < 1 {
- return false
- }
-
- for i, c := range []byte(s) {
- switch {
- case c >= 'a' && c <= 'z':
- case c >= 'A' && c <= 'Z':
- case c == '_':
- case i > 0 && c >= '0' && c <= '9':
-
- // Allow `.` in symbol name. GCC-compiled kernel may change symbol name
- // to have a `.isra.$n` suffix, like `udp_send_skb.isra.52`.
- // See: https://gcc.gnu.org/gcc-10/changes.html
- case i > 0 && c == '.':
-
- default:
- return false
- }
- }
-
- return true
-}
-
-// kprobe opens a perf event on the given symbol and attaches prog to it.
-// If ret is true, create a kretprobe.
-func kprobe(symbol string, prog *ebpf.Program, opts *KprobeOptions, ret bool) (*perfEvent, error) {
- if symbol == "" {
- return nil, fmt.Errorf("symbol name cannot be empty: %w", errInvalidInput)
- }
- if prog == nil {
- return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
- }
- if !isValidKprobeSymbol(symbol) {
- return nil, fmt.Errorf("symbol '%s' must be a valid symbol in /proc/kallsyms: %w", symbol, errInvalidInput)
- }
- if prog.Type() != ebpf.Kprobe {
- return nil, fmt.Errorf("eBPF program type %s is not a Kprobe: %w", prog.Type(), errInvalidInput)
- }
-
- args := probeArgs{
- pid: perfAllThreads,
- symbol: symbol,
- ret: ret,
- }
-
- if opts != nil {
- args.cookie = opts.Cookie
- args.offset = opts.Offset
- }
-
- // Use kprobe PMU if the kernel has it available.
- tp, err := pmuKprobe(args)
- if errors.Is(err, os.ErrNotExist) {
- args.symbol = platformPrefix(symbol)
- tp, err = pmuKprobe(args)
- }
- if err == nil {
- return tp, nil
- }
- if err != nil && !errors.Is(err, ErrNotSupported) {
- return nil, fmt.Errorf("creating perf_kprobe PMU: %w", err)
- }
-
- // Use tracefs if kprobe PMU is missing.
- args.symbol = symbol
- tp, err = tracefsKprobe(args)
- if errors.Is(err, os.ErrNotExist) {
- args.symbol = platformPrefix(symbol)
- tp, err = tracefsKprobe(args)
- }
- if err != nil {
- return nil, fmt.Errorf("creating trace event '%s' in tracefs: %w", symbol, err)
- }
-
- return tp, nil
-}
-
-// pmuKprobe opens a perf event based on the kprobe PMU.
-// Returns os.ErrNotExist if the given symbol does not exist in the kernel.
-func pmuKprobe(args probeArgs) (*perfEvent, error) {
- return pmuProbe(kprobeType, args)
-}
-
-// pmuProbe opens a perf event based on a Performance Monitoring Unit.
-//
-// Requires at least a 4.17 kernel.
-// e12f03d7031a "perf/core: Implement the 'perf_kprobe' PMU"
-// 33ea4b24277b "perf/core: Implement the 'perf_uprobe' PMU"
-//
-// Returns ErrNotSupported if the kernel doesn't support perf_[k,u]probe PMU
-func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) {
- // Getting the PMU type will fail if the kernel doesn't support
- // the perf_[k,u]probe PMU.
- et, err := getPMUEventType(typ)
- if err != nil {
- return nil, err
- }
-
- var config uint64
- if args.ret {
- bit, err := typ.RetprobeBit()
- if err != nil {
- return nil, err
- }
- config |= 1 << bit
- }
-
- 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(args.symbol)
- if err != nil {
- return nil, err
- }
-
- attr = unix.PerfEventAttr{
- // The minimum size required for PMU kprobes is PERF_ATTR_SIZE_VER1,
- // since it added the config2 (Ext2) field. Use Ext2 as probe_offset.
- Size: unix.PERF_ATTR_SIZE_VER1,
- Type: uint32(et), // PMU event type read from sysfs
- Ext1: uint64(uintptr(sp)), // Kernel symbol to trace
- Ext2: args.offset, // Kernel symbol offset
- Config: config, // Retprobe flag
- }
- case uprobeType:
- sp, err = unsafeStringPtr(args.path)
- if err != nil {
- return nil, err
- }
-
- if args.refCtrOffset != 0 {
- config |= args.refCtrOffset << uprobeRefCtrOffsetShift
- }
-
- attr = unix.PerfEventAttr{
- // The minimum size required for PMU uprobes is PERF_ATTR_SIZE_VER1,
- // since it added the config2 (Ext2) field. The Size field controls the
- // size of the internal buffer the kernel allocates for reading the
- // perf_event_attr argument from userspace.
- Size: unix.PERF_ATTR_SIZE_VER1,
- Type: uint32(et), // PMU event type read from sysfs
- Ext1: uint64(uintptr(sp)), // Uprobe path
- Ext2: args.offset, // Uprobe offset
- Config: config, // RefCtrOffset, Retprobe flag
- }
- }
-
- rawFd, err := unix.PerfEventOpen(&attr, args.pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
-
- // On some old kernels, kprobe PMU doesn't allow `.` in symbol names and
- // return -EINVAL. Return ErrNotSupported to allow falling back to tracefs.
- // https://github.com/torvalds/linux/blob/94710cac0ef4/kernel/trace/trace_kprobe.c#L340-L343
- if errors.Is(err, unix.EINVAL) && strings.Contains(args.symbol, ".") {
- return nil, fmt.Errorf("symbol '%s+%#x': older kernels don't accept dots: %w", args.symbol, args.offset, ErrNotSupported)
- }
- // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL
- // when trying to create a kretprobe for a missing symbol. Make sure ENOENT
- // is returned to the caller.
- if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
- return nil, fmt.Errorf("symbol '%s+%#x' not found: %w", args.symbol, args.offset, os.ErrNotExist)
- }
- // Since commit ab105a4fb894, -EILSEQ is returned when a kprobe sym+offset is resolved
- // to an invalid insn boundary.
- if errors.Is(err, syscall.EILSEQ) {
- return nil, fmt.Errorf("symbol '%s+%#x' not found (bad insn boundary): %w", args.symbol, args.offset, os.ErrNotExist)
- }
- // Since at least commit cb9a19fe4aa51, ENOTSUPP is returned
- // when attempting to set a uprobe on a trap instruction.
- if errors.Is(err, unix.ENOTSUPP) {
- return nil, fmt.Errorf("failed setting uprobe on offset %#x (possible trap insn): %w", args.offset, err)
- }
- if err != nil {
- return nil, fmt.Errorf("opening perf event: %w", err)
- }
-
- // Ensure the string pointer is not collected before PerfEventOpen returns.
- runtime.KeepAlive(sp)
-
- fd, err := sys.NewFD(rawFd)
- if err != nil {
- return nil, err
- }
-
- // Kernel has perf_[k,u]probe PMU available, initialize perf event.
- return &perfEvent{
- typ: typ.PerfEventType(args.ret),
- name: args.symbol,
- pmuID: et,
- cookie: args.cookie,
- fd: fd,
- }, nil
-}
-
-// tracefsKprobe creates a Kprobe tracefs entry.
-func tracefsKprobe(args probeArgs) (*perfEvent, error) {
- return tracefsProbe(kprobeType, args)
-}
-
-// tracefsProbe creates a trace event by writing an entry to <tracefs>/[k,u]probe_events.
-// A new trace event group name is generated on every call to support creating
-// multiple trace events for the same kernel or userspace symbol.
-// Path and offset are only set in the case of uprobe(s) and are used to set
-// the executable/library path on the filesystem and the offset where the probe is inserted.
-// A perf event is then opened on the newly-created trace event and returned to the caller.
-func tracefsProbe(typ probeType, args probeArgs) (_ *perfEvent, err error) {
- // Generate a random string for each trace event we attempt to create.
- // This value is used as the 'group' token in tracefs to allow creating
- // multiple kprobe trace events with the same name.
- group, err := randomGroup("ebpf")
- if err != nil {
- return nil, fmt.Errorf("randomizing group name: %w", err)
- }
- args.group = group
-
- // Before attempting to create a trace event through tracefs,
- // check if an event with the same group and name already exists.
- // Kernels 4.x and earlier don't return os.ErrExist on writing a duplicate
- // entry, so we need to rely on reads for detecting uniqueness.
- _, err = getTraceEventID(group, args.symbol)
- if err == nil {
- return nil, fmt.Errorf("trace event already exists: %s/%s", group, args.symbol)
- }
- if err != nil && !errors.Is(err, os.ErrNotExist) {
- return nil, fmt.Errorf("checking trace event %s/%s: %w", group, args.symbol, err)
- }
-
- // Create the [k,u]probe trace event using tracefs.
- if err := createTraceFSProbeEvent(typ, args); err != nil {
- return nil, fmt.Errorf("creating probe entry on tracefs: %w", err)
- }
- defer func() {
- if err != nil {
- // Make sure we clean up the created tracefs event when we return error.
- // If a livepatch handler is already active on the symbol, the write to
- // tracefs will succeed, a trace event will show up, but creating the
- // perf event will fail with EBUSY.
- _ = closeTraceFSProbeEvent(typ, args.group, args.symbol)
- }
- }()
-
- // Get the newly-created trace event's id.
- tid, err := getTraceEventID(group, args.symbol)
- if err != nil {
- return nil, fmt.Errorf("getting trace event id: %w", err)
- }
-
- // Kprobes are ephemeral tracepoints and share the same perf event type.
- fd, err := openTracepointPerfEvent(tid, args.pid)
- if err != nil {
- return nil, err
- }
-
- return &perfEvent{
- typ: typ.PerfEventType(args.ret),
- group: group,
- name: args.symbol,
- tracefsID: tid,
- cookie: args.cookie,
- fd: fd,
- }, nil
-}
-
-// createTraceFSProbeEvent creates a new ephemeral trace event by writing to
-// <tracefs>/[k,u]probe_events. Returns os.ErrNotExist if symbol is not a valid
-// kernel symbol, or if it is not traceable with kprobes. Returns os.ErrExist
-// if a probe with the same group and symbol already exists.
-func createTraceFSProbeEvent(typ probeType, args probeArgs) error {
- // Open the kprobe_events file in tracefs.
- f, err := os.OpenFile(typ.EventsPath(), os.O_APPEND|os.O_WRONLY, 0666)
- if err != nil {
- return fmt.Errorf("error opening '%s': %w", typ.EventsPath(), err)
- }
- defer f.Close()
-
- var pe, token string
- switch typ {
- case kprobeType:
- // The kprobe_events syntax is as follows (see Documentation/trace/kprobetrace.txt):
- // p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe
- // r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe
- // -:[GRP/]EVENT : Clear a probe
- //
- // Some examples:
- // r:ebpf_1234/r_my_kretprobe nf_conntrack_destroy
- // p:ebpf_5678/p_my_kprobe __x64_sys_execve
- //
- // Leaving the kretprobe's MAXACTIVE set to 0 (or absent) will make the
- // kernel default to NR_CPUS. This is desired in most eBPF cases since
- // subsampling or rate limiting logic can be more accurately implemented in
- // the eBPF program itself.
- // See Documentation/kprobes.txt for more details.
- token = kprobeToken(args)
- pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, sanitizeSymbol(args.symbol), token)
- case uprobeType:
- // The uprobe_events syntax is as follows:
- // p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a probe
- // r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return probe
- // -:[GRP/]EVENT : Clear a probe
- //
- // Some examples:
- // r:ebpf_1234/readline /bin/bash:0x12345
- // p:ebpf_5678/main_mySymbol /bin/mybin:0x12345(0x123)
- //
- // See Documentation/trace/uprobetracer.txt for more details.
- token = uprobeToken(args)
- pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, args.symbol, token)
- }
- _, err = f.WriteString(pe)
- // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL
- // when trying to create a kretprobe for a missing symbol. Make sure ENOENT
- // is returned to the caller.
- // EINVAL is also returned on pre-5.2 kernels when the `SYM[+offs]` token
- // is resolved to an invalid insn boundary.
- if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.EINVAL) {
- return fmt.Errorf("token %s: %w", token, os.ErrNotExist)
- }
- // Since commit ab105a4fb894, -EILSEQ is returned when a kprobe sym+offset is resolved
- // to an invalid insn boundary.
- if errors.Is(err, syscall.EILSEQ) {
- return fmt.Errorf("token %s: bad insn boundary: %w", token, os.ErrNotExist)
- }
- // ERANGE is returned when the `SYM[+offs]` token is too big and cannot
- // be resolved.
- if errors.Is(err, syscall.ERANGE) {
- return fmt.Errorf("token %s: offset too big: %w", token, os.ErrNotExist)
- }
- if err != nil {
- return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err)
- }
-
- return nil
-}
-
-// closeTraceFSProbeEvent removes the [k,u]probe with the given type, group and symbol
-// from <tracefs>/[k,u]probe_events.
-func closeTraceFSProbeEvent(typ probeType, group, symbol string) error {
- f, err := os.OpenFile(typ.EventsPath(), os.O_APPEND|os.O_WRONLY, 0666)
- if err != nil {
- return fmt.Errorf("error opening %s: %w", typ.EventsPath(), err)
- }
- defer f.Close()
-
- // See [k,u]probe_events syntax above. The probe type does not need to be specified
- // for removals.
- pe := fmt.Sprintf("-:%s/%s", group, sanitizeSymbol(symbol))
- if _, err = f.WriteString(pe); err != nil {
- return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err)
- }
-
- return nil
-}
-
-// randomGroup generates a pseudorandom string for use as a tracefs group name.
-// Returns an error when the output string would exceed 63 characters (kernel
-// limitation), when rand.Read() fails or when prefix contains characters not
-// allowed by isValidTraceID.
-func randomGroup(prefix string) (string, error) {
- if !isValidTraceID(prefix) {
- return "", fmt.Errorf("prefix '%s' must be alphanumeric or underscore: %w", prefix, errInvalidInput)
- }
-
- b := make([]byte, 8)
- if _, err := rand.Read(b); err != nil {
- return "", fmt.Errorf("reading random bytes: %w", err)
- }
-
- group := fmt.Sprintf("%s_%x", prefix, b)
- if len(group) > 63 {
- return "", fmt.Errorf("group name '%s' cannot be longer than 63 characters: %w", group, errInvalidInput)
- }
-
- return group, nil
-}
-
-func probePrefix(ret bool) string {
- if ret {
- return "r"
- }
- return "p"
-}
-
-// determineRetprobeBit reads a Performance Monitoring Unit's retprobe bit
-// from /sys/bus/event_source/devices/<pmu>/format/retprobe.
-func determineRetprobeBit(typ probeType) (uint64, error) {
- p := filepath.Join("/sys/bus/event_source/devices/", typ.String(), "/format/retprobe")
-
- data, err := os.ReadFile(p)
- if err != nil {
- return 0, err
- }
-
- var rp uint64
- n, err := fmt.Sscanf(string(bytes.TrimSpace(data)), "config:%d", &rp)
- if err != nil {
- return 0, fmt.Errorf("parse retprobe bit: %w", err)
- }
- if n != 1 {
- return 0, fmt.Errorf("parse retprobe bit: expected 1 item, got %d", n)
- }
-
- return rp, nil
-}
-
-func kretprobeBit() (uint64, error) {
- kprobeRetprobeBit.once.Do(func() {
- kprobeRetprobeBit.value, kprobeRetprobeBit.err = determineRetprobeBit(kprobeType)
- })
- return kprobeRetprobeBit.value, kprobeRetprobeBit.err
-}
-
-// kprobeToken creates the SYM[+offs] token for the tracefs api.
-func kprobeToken(args probeArgs) string {
- po := args.symbol
-
- if args.offset != 0 {
- po += fmt.Sprintf("+%#x", args.offset)
- }
-
- return po
-}
diff --git a/vendor/github.com/cilium/ebpf/link/link.go b/vendor/github.com/cilium/ebpf/link/link.go
deleted file mode 100644
index 067d0101a..000000000
--- a/vendor/github.com/cilium/ebpf/link/link.go
+++ /dev/null
@@ -1,313 +0,0 @@
-package link
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/btf"
- "github.com/cilium/ebpf/internal"
- "github.com/cilium/ebpf/internal/sys"
-)
-
-var ErrNotSupported = internal.ErrNotSupported
-
-// Link represents a Program attached to a BPF hook.
-type Link interface {
- // Replace the current program with a new program.
- //
- // Passing a nil program is an error. May return an error wrapping ErrNotSupported.
- Update(*ebpf.Program) error
-
- // Persist a link by pinning it into a bpffs.
- //
- // May return an error wrapping ErrNotSupported.
- Pin(string) error
-
- // Undo a previous call to Pin.
- //
- // May return an error wrapping ErrNotSupported.
- Unpin() error
-
- // Close frees resources.
- //
- // The link will be broken unless it has been successfully pinned.
- // A link may continue past the lifetime of the process if Close is
- // not called.
- Close() error
-
- // Info returns metadata on a link.
- //
- // May return an error wrapping ErrNotSupported.
- Info() (*Info, error)
-
- // Prevent external users from implementing this interface.
- isLink()
-}
-
-// LoadPinnedLink loads a link that was persisted into a bpffs.
-func LoadPinnedLink(fileName string, opts *ebpf.LoadPinOptions) (Link, error) {
- raw, err := loadPinnedRawLink(fileName, opts)
- if err != nil {
- return nil, err
- }
-
- return wrapRawLink(raw)
-}
-
-// wrap a RawLink in a more specific type if possible.
-//
-// The function takes ownership of raw and closes it on error.
-func wrapRawLink(raw *RawLink) (Link, error) {
- info, err := raw.Info()
- if err != nil {
- raw.Close()
- return nil, err
- }
-
- switch info.Type {
- case RawTracepointType:
- return &rawTracepoint{*raw}, nil
- case TracingType:
- return &tracing{*raw}, nil
- case CgroupType:
- return &linkCgroup{*raw}, nil
- case IterType:
- return &Iter{*raw}, nil
- case NetNsType:
- return &NetNsLink{*raw}, nil
- default:
- return raw, nil
- }
-}
-
-// ID uniquely identifies a BPF link.
-type ID = sys.LinkID
-
-// RawLinkOptions control the creation of a raw link.
-type RawLinkOptions struct {
- // File descriptor to attach to. This differs for each attach type.
- Target int
- // Program to attach.
- Program *ebpf.Program
- // Attach must match the attach type of Program.
- Attach ebpf.AttachType
- // BTF is the BTF of the attachment target.
- BTF btf.TypeID
- // Flags control the attach behaviour.
- Flags uint32
-}
-
-// Info contains metadata on a link.
-type Info struct {
- Type Type
- ID ID
- Program ebpf.ProgramID
- extra interface{}
-}
-
-type TracingInfo sys.TracingLinkInfo
-type CgroupInfo sys.CgroupLinkInfo
-type NetNsInfo sys.NetNsLinkInfo
-type XDPInfo sys.XDPLinkInfo
-
-// Tracing returns tracing type-specific link info.
-//
-// Returns nil if the type-specific link info isn't available.
-func (r Info) Tracing() *TracingInfo {
- e, _ := r.extra.(*TracingInfo)
- return e
-}
-
-// Cgroup returns cgroup type-specific link info.
-//
-// Returns nil if the type-specific link info isn't available.
-func (r Info) Cgroup() *CgroupInfo {
- e, _ := r.extra.(*CgroupInfo)
- return e
-}
-
-// NetNs returns netns type-specific link info.
-//
-// Returns nil if the type-specific link info isn't available.
-func (r Info) NetNs() *NetNsInfo {
- e, _ := r.extra.(*NetNsInfo)
- return e
-}
-
-// ExtraNetNs returns XDP type-specific link info.
-//
-// Returns nil if the type-specific link info isn't available.
-func (r Info) XDP() *XDPInfo {
- e, _ := r.extra.(*XDPInfo)
- return e
-}
-
-// RawLink is the low-level API to bpf_link.
-//
-// You should consider using the higher level interfaces in this
-// package instead.
-type RawLink struct {
- fd *sys.FD
- pinnedPath string
-}
-
-// AttachRawLink creates a raw link.
-func AttachRawLink(opts RawLinkOptions) (*RawLink, error) {
- if err := haveBPFLink(); err != nil {
- return nil, err
- }
-
- if opts.Target < 0 {
- return nil, fmt.Errorf("invalid target: %s", sys.ErrClosedFd)
- }
-
- progFd := opts.Program.FD()
- if progFd < 0 {
- return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd)
- }
-
- attr := sys.LinkCreateAttr{
- TargetFd: uint32(opts.Target),
- ProgFd: uint32(progFd),
- AttachType: sys.AttachType(opts.Attach),
- TargetBtfId: uint32(opts.BTF),
- Flags: opts.Flags,
- }
- fd, err := sys.LinkCreate(&attr)
- if err != nil {
- return nil, fmt.Errorf("can't create link: %s", err)
- }
-
- return &RawLink{fd, ""}, nil
-}
-
-func loadPinnedRawLink(fileName string, opts *ebpf.LoadPinOptions) (*RawLink, error) {
- fd, err := sys.ObjGet(&sys.ObjGetAttr{
- Pathname: sys.NewStringPointer(fileName),
- FileFlags: opts.Marshal(),
- })
- if err != nil {
- return nil, fmt.Errorf("load pinned link: %w", err)
- }
-
- return &RawLink{fd, fileName}, nil
-}
-
-func (l *RawLink) isLink() {}
-
-// FD returns the raw file descriptor.
-func (l *RawLink) FD() int {
- return l.fd.Int()
-}
-
-// Close breaks the link.
-//
-// Use Pin if you want to make the link persistent.
-func (l *RawLink) Close() error {
- return l.fd.Close()
-}
-
-// Pin persists a link past the lifetime of the process.
-//
-// Calling Close on a pinned Link will not break the link
-// until the pin is removed.
-func (l *RawLink) Pin(fileName string) error {
- if err := internal.Pin(l.pinnedPath, fileName, l.fd); err != nil {
- return err
- }
- l.pinnedPath = fileName
- return nil
-}
-
-// Unpin implements the Link interface.
-func (l *RawLink) Unpin() error {
- if err := internal.Unpin(l.pinnedPath); err != nil {
- return err
- }
- l.pinnedPath = ""
- return nil
-}
-
-// Update implements the Link interface.
-func (l *RawLink) Update(new *ebpf.Program) error {
- return l.UpdateArgs(RawLinkUpdateOptions{
- New: new,
- })
-}
-
-// RawLinkUpdateOptions control the behaviour of RawLink.UpdateArgs.
-type RawLinkUpdateOptions struct {
- New *ebpf.Program
- Old *ebpf.Program
- Flags uint32
-}
-
-// UpdateArgs updates a link based on args.
-func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error {
- newFd := opts.New.FD()
- if newFd < 0 {
- return fmt.Errorf("invalid program: %s", sys.ErrClosedFd)
- }
-
- var oldFd int
- if opts.Old != nil {
- oldFd = opts.Old.FD()
- if oldFd < 0 {
- return fmt.Errorf("invalid replacement program: %s", sys.ErrClosedFd)
- }
- }
-
- attr := sys.LinkUpdateAttr{
- LinkFd: l.fd.Uint(),
- NewProgFd: uint32(newFd),
- OldProgFd: uint32(oldFd),
- Flags: opts.Flags,
- }
- return sys.LinkUpdate(&attr)
-}
-
-// Info returns metadata about the link.
-func (l *RawLink) Info() (*Info, error) {
- var info sys.LinkInfo
-
- if err := sys.ObjInfo(l.fd, &info); err != nil {
- return nil, fmt.Errorf("link info: %s", err)
- }
-
- var extra interface{}
- switch info.Type {
- case CgroupType:
- extra = &CgroupInfo{}
- case IterType:
- // not supported
- case NetNsType:
- extra = &NetNsInfo{}
- case RawTracepointType:
- // not supported
- case TracingType:
- extra = &TracingInfo{}
- case XDPType:
- extra = &XDPInfo{}
- case PerfEventType:
- // no extra
- default:
- return nil, fmt.Errorf("unknown link info type: %d", info.Type)
- }
-
- if info.Type != RawTracepointType && info.Type != IterType && info.Type != PerfEventType {
- buf := bytes.NewReader(info.Extra[:])
- err := binary.Read(buf, internal.NativeEndian, extra)
- if err != nil {
- return nil, fmt.Errorf("can not read extra link info: %w", err)
- }
- }
-
- return &Info{
- info.Type,
- info.Id,
- ebpf.ProgramID(info.ProgId),
- extra,
- }, nil
-}
diff --git a/vendor/github.com/cilium/ebpf/link/netns.go b/vendor/github.com/cilium/ebpf/link/netns.go
deleted file mode 100644
index 344ecced6..000000000
--- a/vendor/github.com/cilium/ebpf/link/netns.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package link
-
-import (
- "fmt"
-
- "github.com/cilium/ebpf"
-)
-
-// NetNsLink is a program attached to a network namespace.
-type NetNsLink struct {
- RawLink
-}
-
-// AttachNetNs attaches a program to a network namespace.
-func AttachNetNs(ns int, prog *ebpf.Program) (*NetNsLink, error) {
- var attach ebpf.AttachType
- switch t := prog.Type(); t {
- case ebpf.FlowDissector:
- attach = ebpf.AttachFlowDissector
- case ebpf.SkLookup:
- attach = ebpf.AttachSkLookup
- default:
- return nil, fmt.Errorf("can't attach %v to network namespace", t)
- }
-
- link, err := AttachRawLink(RawLinkOptions{
- Target: ns,
- Program: prog,
- Attach: attach,
- })
- if err != nil {
- return nil, err
- }
-
- return &NetNsLink{*link}, nil
-}
diff --git a/vendor/github.com/cilium/ebpf/link/perf_event.go b/vendor/github.com/cilium/ebpf/link/perf_event.go
deleted file mode 100644
index 0e5bd4791..000000000
--- a/vendor/github.com/cilium/ebpf/link/perf_event.go
+++ /dev/null
@@ -1,394 +0,0 @@
-package link
-
-import (
- "bytes"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "unsafe"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/asm"
- "github.com/cilium/ebpf/internal"
- "github.com/cilium/ebpf/internal/sys"
- "github.com/cilium/ebpf/internal/unix"
-)
-
-// Getting the terminology right is usually the hardest part. For posterity and
-// for staying sane during implementation:
-//
-// - trace event: Representation of a kernel runtime hook. Filesystem entries
-// under <tracefs>/events. Can be tracepoints (static), kprobes or uprobes.
-// Can be instantiated into perf events (see below).
-// - tracepoint: A predetermined hook point in the kernel. Exposed as trace
-// events in (sub)directories under <tracefs>/events. Cannot be closed or
-// removed, they are static.
-// - k(ret)probe: Ephemeral trace events based on entry or exit points of
-// exported kernel symbols. kprobe-based (tracefs) trace events can be
-// created system-wide by writing to the <tracefs>/kprobe_events file, or
-// they can be scoped to the current process by creating PMU perf events.
-// - u(ret)probe: Ephemeral trace events based on user provides ELF binaries
-// and offsets. uprobe-based (tracefs) trace events can be
-// created system-wide by writing to the <tracefs>/uprobe_events file, or
-// they can be scoped to the current process by creating PMU perf events.
-// - perf event: An object instantiated based on an existing trace event or
-// kernel symbol. Referred to by fd in userspace.
-// Exactly one eBPF program can be attached to a perf event. Multiple perf
-// events can be created from a single trace event. Closing a perf event
-// stops any further invocations of the attached eBPF program.
-
-var (
- tracefsPath = "/sys/kernel/debug/tracing"
-
- errInvalidInput = errors.New("invalid input")
-)
-
-const (
- perfAllThreads = -1
-)
-
-type perfEventType uint8
-
-const (
- tracepointEvent perfEventType = iota
- kprobeEvent
- kretprobeEvent
- uprobeEvent
- uretprobeEvent
-)
-
-// A perfEvent represents a perf event kernel object. Exactly one eBPF program
-// can be attached to it. It is created based on a tracefs trace event or a
-// Performance Monitoring Unit (PMU).
-type perfEvent struct {
- // The event type determines the types of programs that can be attached.
- typ perfEventType
-
- // Group and name of the tracepoint/kprobe/uprobe.
- group string
- name string
-
- // PMU event ID read from sysfs. Valid IDs are non-zero.
- pmuID uint64
- // ID of the trace event read from tracefs. Valid IDs are non-zero.
- tracefsID uint64
-
- // User provided arbitrary value.
- cookie uint64
-
- // This is the perf event FD.
- fd *sys.FD
-}
-
-func (pe *perfEvent) Close() error {
- if err := pe.fd.Close(); err != nil {
- return fmt.Errorf("closing perf event fd: %w", err)
- }
-
- switch pe.typ {
- case kprobeEvent, kretprobeEvent:
- // Clean up kprobe tracefs entry.
- if pe.tracefsID != 0 {
- return closeTraceFSProbeEvent(kprobeType, pe.group, pe.name)
- }
- case uprobeEvent, uretprobeEvent:
- // Clean up uprobe tracefs entry.
- if pe.tracefsID != 0 {
- return closeTraceFSProbeEvent(uprobeType, pe.group, pe.name)
- }
- case tracepointEvent:
- // Tracepoint trace events don't hold any extra resources.
- return nil
- }
-
- return nil
-}
-
-// perfEventLink represents a bpf perf link.
-type perfEventLink struct {
- RawLink
- pe *perfEvent
-}
-
-func (pl *perfEventLink) isLink() {}
-
-// Pinning requires the underlying perf event FD to stay open.
-//
-// | PerfEvent FD | BpfLink FD | Works |
-// |--------------|------------|-------|
-// | Open | Open | Yes |
-// | Closed | Open | No |
-// | Open | Closed | No (Pin() -> EINVAL) |
-// | Closed | Closed | No (Pin() -> EINVAL) |
-//
-// There is currently no pretty way to recover the perf event FD
-// when loading a pinned link, so leave as not supported for now.
-func (pl *perfEventLink) Pin(string) error {
- return fmt.Errorf("perf event link pin: %w", ErrNotSupported)
-}
-
-func (pl *perfEventLink) Unpin() error {
- return fmt.Errorf("perf event link unpin: %w", ErrNotSupported)
-}
-
-func (pl *perfEventLink) Close() error {
- if err := pl.pe.Close(); err != nil {
- return fmt.Errorf("perf event link close: %w", err)
- }
- return pl.fd.Close()
-}
-
-func (pl *perfEventLink) Update(prog *ebpf.Program) error {
- return fmt.Errorf("perf event link update: %w", ErrNotSupported)
-}
-
-// perfEventIoctl implements Link and handles the perf event lifecycle
-// via ioctl().
-type perfEventIoctl struct {
- *perfEvent
-}
-
-func (pi *perfEventIoctl) isLink() {}
-
-// Since 4.15 (e87c6bc3852b "bpf: permit multiple bpf attachments for a single perf event"),
-// calling PERF_EVENT_IOC_SET_BPF appends the given program to a prog_array
-// owned by the perf event, which means multiple programs can be attached
-// simultaneously.
-//
-// Before 4.15, calling PERF_EVENT_IOC_SET_BPF more than once on a perf event
-// returns EEXIST.
-//
-// Detaching a program from a perf event is currently not possible, so a
-// program replacement mechanism cannot be implemented for perf events.
-func (pi *perfEventIoctl) Update(prog *ebpf.Program) error {
- return fmt.Errorf("perf event ioctl update: %w", ErrNotSupported)
-}
-
-func (pi *perfEventIoctl) Pin(string) error {
- return fmt.Errorf("perf event ioctl pin: %w", ErrNotSupported)
-}
-
-func (pi *perfEventIoctl) Unpin() error {
- return fmt.Errorf("perf event ioctl unpin: %w", ErrNotSupported)
-}
-
-func (pi *perfEventIoctl) Info() (*Info, error) {
- return nil, fmt.Errorf("perf event ioctl info: %w", ErrNotSupported)
-}
-
-// attach the given eBPF prog to the perf event stored in pe.
-// pe must contain a valid perf event fd.
-// prog's type must match the program type stored in pe.
-func attachPerfEvent(pe *perfEvent, prog *ebpf.Program) (Link, error) {
- if prog == nil {
- return nil, errors.New("cannot attach a nil program")
- }
- if prog.FD() < 0 {
- return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd)
- }
-
- switch pe.typ {
- case kprobeEvent, kretprobeEvent, uprobeEvent, uretprobeEvent:
- if t := prog.Type(); t != ebpf.Kprobe {
- return nil, fmt.Errorf("invalid program type (expected %s): %s", ebpf.Kprobe, t)
- }
- case tracepointEvent:
- if t := prog.Type(); t != ebpf.TracePoint {
- return nil, fmt.Errorf("invalid program type (expected %s): %s", ebpf.TracePoint, t)
- }
- default:
- return nil, fmt.Errorf("unknown perf event type: %d", pe.typ)
- }
-
- if err := haveBPFLinkPerfEvent(); err == nil {
- return attachPerfEventLink(pe, prog)
- }
- return attachPerfEventIoctl(pe, prog)
-}
-
-func attachPerfEventIoctl(pe *perfEvent, prog *ebpf.Program) (*perfEventIoctl, error) {
- if pe.cookie != 0 {
- return nil, fmt.Errorf("cookies are not supported: %w", ErrNotSupported)
- }
-
- // Assign the eBPF program to the perf event.
- err := unix.IoctlSetInt(pe.fd.Int(), unix.PERF_EVENT_IOC_SET_BPF, prog.FD())
- if err != nil {
- return nil, fmt.Errorf("setting perf event bpf program: %w", err)
- }
-
- // PERF_EVENT_IOC_ENABLE and _DISABLE ignore their given values.
- if err := unix.IoctlSetInt(pe.fd.Int(), unix.PERF_EVENT_IOC_ENABLE, 0); err != nil {
- return nil, fmt.Errorf("enable perf event: %s", err)
- }
-
- pi := &perfEventIoctl{pe}
-
- // Close the perf event when its reference is lost to avoid leaking system resources.
- runtime.SetFinalizer(pi, (*perfEventIoctl).Close)
- return pi, nil
-}
-
-// Use the bpf api to attach the perf event (BPF_LINK_TYPE_PERF_EVENT, 5.15+).
-//
-// https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e
-func attachPerfEventLink(pe *perfEvent, prog *ebpf.Program) (*perfEventLink, error) {
- fd, err := sys.LinkCreatePerfEvent(&sys.LinkCreatePerfEventAttr{
- ProgFd: uint32(prog.FD()),
- TargetFd: pe.fd.Uint(),
- AttachType: sys.BPF_PERF_EVENT,
- BpfCookie: pe.cookie,
- })
- if err != nil {
- return nil, fmt.Errorf("cannot create bpf perf link: %v", err)
- }
-
- pl := &perfEventLink{RawLink{fd: fd}, pe}
-
- // Close the perf event when its reference is lost to avoid leaking system resources.
- runtime.SetFinalizer(pl, (*perfEventLink).Close)
- return pl, nil
-}
-
-// unsafeStringPtr returns an unsafe.Pointer to a NUL-terminated copy of str.
-func unsafeStringPtr(str string) (unsafe.Pointer, error) {
- p, err := unix.BytePtrFromString(str)
- if err != nil {
- return nil, err
- }
- return unsafe.Pointer(p), nil
-}
-
-// getTraceEventID reads a trace event's ID from tracefs given its group and name.
-// The kernel requires group and name to be alphanumeric or underscore.
-//
-// name automatically has its invalid symbols converted to underscores so the caller
-// can pass a raw symbol name, e.g. a kernel symbol containing dots.
-func getTraceEventID(group, name string) (uint64, error) {
- name = sanitizeSymbol(name)
- tid, err := uint64FromFile(tracefsPath, "events", group, name, "id")
- if errors.Is(err, os.ErrNotExist) {
- return 0, fmt.Errorf("trace event %s/%s: %w", group, name, os.ErrNotExist)
- }
- if err != nil {
- return 0, fmt.Errorf("reading trace event ID of %s/%s: %w", group, name, err)
- }
-
- return tid, nil
-}
-
-// getPMUEventType reads a Performance Monitoring Unit's type (numeric identifier)
-// from /sys/bus/event_source/devices/<pmu>/type.
-//
-// Returns ErrNotSupported if the pmu type is not supported.
-func getPMUEventType(typ probeType) (uint64, error) {
- et, err := uint64FromFile("/sys/bus/event_source/devices", typ.String(), "type")
- if errors.Is(err, os.ErrNotExist) {
- return 0, fmt.Errorf("pmu type %s: %w", typ, ErrNotSupported)
- }
- if err != nil {
- return 0, fmt.Errorf("reading pmu type %s: %w", typ, err)
- }
-
- return et, nil
-}
-
-// openTracepointPerfEvent opens a tracepoint-type perf event. System-wide
-// [k,u]probes created by writing to <tracefs>/[k,u]probe_events are tracepoints
-// behind the scenes, and can be attached to using these perf events.
-func openTracepointPerfEvent(tid uint64, pid int) (*sys.FD, error) {
- attr := unix.PerfEventAttr{
- Type: unix.PERF_TYPE_TRACEPOINT,
- Config: tid,
- Sample_type: unix.PERF_SAMPLE_RAW,
- Sample: 1,
- Wakeup: 1,
- }
-
- fd, err := unix.PerfEventOpen(&attr, pid, 0, -1, unix.PERF_FLAG_FD_CLOEXEC)
- if err != nil {
- return nil, fmt.Errorf("opening tracepoint perf event: %w", err)
- }
-
- return sys.NewFD(fd)
-}
-
-// uint64FromFile reads a uint64 from a file. All elements of path are sanitized
-// and joined onto base. Returns error if base no longer prefixes the path after
-// joining all components.
-func uint64FromFile(base string, path ...string) (uint64, error) {
- l := filepath.Join(path...)
- p := filepath.Join(base, l)
- if !strings.HasPrefix(p, base) {
- return 0, fmt.Errorf("path '%s' attempts to escape base path '%s': %w", l, base, errInvalidInput)
- }
-
- data, err := os.ReadFile(p)
- if err != nil {
- return 0, fmt.Errorf("reading file %s: %w", p, err)
- }
-
- et := bytes.TrimSpace(data)
- return strconv.ParseUint(string(et), 10, 64)
-}
-
-// Probe BPF perf link.
-//
-// https://elixir.bootlin.com/linux/v5.16.8/source/kernel/bpf/syscall.c#L4307
-// https://github.com/torvalds/linux/commit/b89fbfbb854c9afc3047e8273cc3a694650b802e
-var haveBPFLinkPerfEvent = internal.FeatureTest("bpf_link_perf_event", "5.15", func() error {
- prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
- Name: "probe_bpf_perf_link",
- Type: ebpf.Kprobe,
- Instructions: asm.Instructions{
- asm.Mov.Imm(asm.R0, 0),
- asm.Return(),
- },
- License: "MIT",
- })
- if err != nil {
- return err
- }
- defer prog.Close()
-
- _, err = sys.LinkCreatePerfEvent(&sys.LinkCreatePerfEventAttr{
- ProgFd: uint32(prog.FD()),
- AttachType: sys.BPF_PERF_EVENT,
- })
- if errors.Is(err, unix.EINVAL) {
- return internal.ErrNotSupported
- }
- if errors.Is(err, unix.EBADF) {
- return nil
- }
- return err
-})
-
-// isValidTraceID implements the equivalent of a regex match
-// against "^[a-zA-Z_][0-9a-zA-Z_]*$".
-//
-// Trace event groups, names and kernel symbols must adhere to this set
-// of characters. Non-empty, first character must not be a number, all
-// characters must be alphanumeric or underscore.
-func isValidTraceID(s string) bool {
- if len(s) < 1 {
- return false
- }
- for i, c := range []byte(s) {
- switch {
- case c >= 'a' && c <= 'z':
- case c >= 'A' && c <= 'Z':
- case c == '_':
- case i > 0 && c >= '0' && c <= '9':
-
- default:
- return false
- }
- }
-
- return true
-}
diff --git a/vendor/github.com/cilium/ebpf/link/platform.go b/vendor/github.com/cilium/ebpf/link/platform.go
deleted file mode 100644
index eb6f7b7a3..000000000
--- a/vendor/github.com/cilium/ebpf/link/platform.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package link
-
-import (
- "fmt"
- "runtime"
-)
-
-func platformPrefix(symbol string) string {
-
- prefix := runtime.GOARCH
-
- // per https://github.com/golang/go/blob/master/src/go/build/syslist.go
- switch prefix {
- case "386":
- prefix = "ia32"
- case "amd64", "amd64p32":
- prefix = "x64"
- case "arm64", "arm64be":
- prefix = "arm64"
- default:
- return symbol
- }
-
- return fmt.Sprintf("__%s_%s", prefix, symbol)
-}
diff --git a/vendor/github.com/cilium/ebpf/link/program.go b/vendor/github.com/cilium/ebpf/link/program.go
deleted file mode 100644
index ea3181737..000000000
--- a/vendor/github.com/cilium/ebpf/link/program.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package link
-
-import (
- "fmt"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/internal/sys"
-)
-
-type RawAttachProgramOptions struct {
- // File descriptor to attach to. This differs for each attach type.
- Target int
- // Program to attach.
- Program *ebpf.Program
- // Program to replace (cgroups).
- Replace *ebpf.Program
- // Attach must match the attach type of Program (and Replace).
- Attach ebpf.AttachType
- // Flags control the attach behaviour. This differs for each attach type.
- Flags uint32
-}
-
-// RawAttachProgram is a low level wrapper around BPF_PROG_ATTACH.
-//
-// You should use one of the higher level abstractions available in this
-// package if possible.
-func RawAttachProgram(opts RawAttachProgramOptions) error {
- if err := haveProgAttach(); err != nil {
- return err
- }
-
- var replaceFd uint32
- if opts.Replace != nil {
- replaceFd = uint32(opts.Replace.FD())
- }
-
- attr := sys.ProgAttachAttr{
- TargetFd: uint32(opts.Target),
- AttachBpfFd: uint32(opts.Program.FD()),
- ReplaceBpfFd: replaceFd,
- AttachType: uint32(opts.Attach),
- AttachFlags: uint32(opts.Flags),
- }
-
- if err := sys.ProgAttach(&attr); err != nil {
- return fmt.Errorf("can't attach program: %w", err)
- }
- return nil
-}
-
-type RawDetachProgramOptions struct {
- Target int
- Program *ebpf.Program
- Attach ebpf.AttachType
-}
-
-// RawDetachProgram is a low level wrapper around BPF_PROG_DETACH.
-//
-// You should use one of the higher level abstractions available in this
-// package if possible.
-func RawDetachProgram(opts RawDetachProgramOptions) error {
- if err := haveProgAttach(); err != nil {
- return err
- }
-
- attr := sys.ProgDetachAttr{
- TargetFd: uint32(opts.Target),
- AttachBpfFd: uint32(opts.Program.FD()),
- AttachType: uint32(opts.Attach),
- }
- if err := sys.ProgDetach(&attr); err != nil {
- return fmt.Errorf("can't detach program: %w", err)
- }
-
- return nil
-}
diff --git a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go b/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
deleted file mode 100644
index 925e621cb..000000000
--- a/vendor/github.com/cilium/ebpf/link/raw_tracepoint.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package link
-
-import (
- "errors"
- "fmt"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/internal/sys"
-)
-
-type RawTracepointOptions struct {
- // Tracepoint name.
- Name string
- // Program must be of type RawTracepoint*
- Program *ebpf.Program
-}
-
-// AttachRawTracepoint links a BPF program to a raw_tracepoint.
-//
-// Requires at least Linux 4.17.
-func AttachRawTracepoint(opts RawTracepointOptions) (Link, error) {
- if t := opts.Program.Type(); t != ebpf.RawTracepoint && t != ebpf.RawTracepointWritable {
- return nil, fmt.Errorf("invalid program type %s, expected RawTracepoint(Writable)", t)
- }
- if opts.Program.FD() < 0 {
- return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd)
- }
-
- fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{
- Name: sys.NewStringPointer(opts.Name),
- ProgFd: uint32(opts.Program.FD()),
- })
- if err != nil {
- return nil, err
- }
-
- err = haveBPFLink()
- if errors.Is(err, ErrNotSupported) {
- // Prior to commit 70ed506c3bbc ("bpf: Introduce pinnable bpf_link abstraction")
- // raw_tracepoints are just a plain fd.
- return &simpleRawTracepoint{fd}, nil
- }
-
- if err != nil {
- return nil, err
- }
-
- return &rawTracepoint{RawLink{fd: fd}}, nil
-}
-
-type simpleRawTracepoint struct {
- fd *sys.FD
-}
-
-var _ Link = (*simpleRawTracepoint)(nil)
-
-func (frt *simpleRawTracepoint) isLink() {}
-
-func (frt *simpleRawTracepoint) Close() error {
- return frt.fd.Close()
-}
-
-func (frt *simpleRawTracepoint) Update(_ *ebpf.Program) error {
- return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported)
-}
-
-func (frt *simpleRawTracepoint) Pin(string) error {
- return fmt.Errorf("pin raw_tracepoint: %w", ErrNotSupported)
-}
-
-func (frt *simpleRawTracepoint) Unpin() error {
- return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported)
-}
-
-func (frt *simpleRawTracepoint) Info() (*Info, error) {
- return nil, fmt.Errorf("can't get raw_tracepoint info: %w", ErrNotSupported)
-}
-
-type rawTracepoint struct {
- RawLink
-}
-
-var _ Link = (*rawTracepoint)(nil)
-
-func (rt *rawTracepoint) Update(_ *ebpf.Program) error {
- return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported)
-}
diff --git a/vendor/github.com/cilium/ebpf/link/socket_filter.go b/vendor/github.com/cilium/ebpf/link/socket_filter.go
deleted file mode 100644
index 94f3958cc..000000000
--- a/vendor/github.com/cilium/ebpf/link/socket_filter.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package link
-
-import (
- "syscall"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/internal/unix"
-)
-
-// AttachSocketFilter attaches a SocketFilter BPF program to a socket.
-func AttachSocketFilter(conn syscall.Conn, program *ebpf.Program) error {
- rawConn, err := conn.SyscallConn()
- if err != nil {
- return err
- }
- var ssoErr error
- err = rawConn.Control(func(fd uintptr) {
- ssoErr = syscall.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_ATTACH_BPF, program.FD())
- })
- if ssoErr != nil {
- return ssoErr
- }
- return err
-}
-
-// DetachSocketFilter detaches a SocketFilter BPF program from a socket.
-func DetachSocketFilter(conn syscall.Conn) error {
- rawConn, err := conn.SyscallConn()
- if err != nil {
- return err
- }
- var ssoErr error
- err = rawConn.Control(func(fd uintptr) {
- ssoErr = syscall.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_DETACH_BPF, 0)
- })
- if ssoErr != nil {
- return ssoErr
- }
- return err
-}
diff --git a/vendor/github.com/cilium/ebpf/link/syscalls.go b/vendor/github.com/cilium/ebpf/link/syscalls.go
deleted file mode 100644
index a661395b3..000000000
--- a/vendor/github.com/cilium/ebpf/link/syscalls.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package link
-
-import (
- "errors"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/asm"
- "github.com/cilium/ebpf/internal"
- "github.com/cilium/ebpf/internal/sys"
- "github.com/cilium/ebpf/internal/unix"
-)
-
-// Type is the kind of link.
-type Type = sys.LinkType
-
-// Valid link types.
-const (
- UnspecifiedType = sys.BPF_LINK_TYPE_UNSPEC
- RawTracepointType = sys.BPF_LINK_TYPE_RAW_TRACEPOINT
- TracingType = sys.BPF_LINK_TYPE_TRACING
- CgroupType = sys.BPF_LINK_TYPE_CGROUP
- IterType = sys.BPF_LINK_TYPE_ITER
- NetNsType = sys.BPF_LINK_TYPE_NETNS
- XDPType = sys.BPF_LINK_TYPE_XDP
- PerfEventType = sys.BPF_LINK_TYPE_PERF_EVENT
-)
-
-var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() error {
- prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
- Type: ebpf.CGroupSKB,
- License: "MIT",
- Instructions: asm.Instructions{
- asm.Mov.Imm(asm.R0, 0),
- asm.Return(),
- },
- })
- if err != nil {
- return internal.ErrNotSupported
- }
-
- // BPF_PROG_ATTACH was introduced at the same time as CGgroupSKB,
- // so being able to load the program is enough to infer that we
- // have the syscall.
- prog.Close()
- return nil
-})
-
-var haveProgAttachReplace = internal.FeatureTest("BPF_PROG_ATTACH atomic replacement", "5.5", func() error {
- if err := haveProgAttach(); err != nil {
- return err
- }
-
- prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
- Type: ebpf.CGroupSKB,
- AttachType: ebpf.AttachCGroupInetIngress,
- License: "MIT",
- Instructions: asm.Instructions{
- asm.Mov.Imm(asm.R0, 0),
- asm.Return(),
- },
- })
- if err != nil {
- return internal.ErrNotSupported
- }
- defer prog.Close()
-
- // We know that we have BPF_PROG_ATTACH since we can load CGroupSKB programs.
- // If passing BPF_F_REPLACE gives us EINVAL we know that the feature isn't
- // present.
- attr := sys.ProgAttachAttr{
- // We rely on this being checked after attachFlags.
- TargetFd: ^uint32(0),
- AttachBpfFd: uint32(prog.FD()),
- AttachType: uint32(ebpf.AttachCGroupInetIngress),
- AttachFlags: uint32(flagReplace),
- }
-
- err = sys.ProgAttach(&attr)
- if errors.Is(err, unix.EINVAL) {
- return internal.ErrNotSupported
- }
- if errors.Is(err, unix.EBADF) {
- return nil
- }
- return err
-})
-
-var haveBPFLink = internal.FeatureTest("bpf_link", "5.7", func() error {
- attr := sys.LinkCreateAttr{
- // This is a hopefully invalid file descriptor, which triggers EBADF.
- TargetFd: ^uint32(0),
- ProgFd: ^uint32(0),
- AttachType: sys.AttachType(ebpf.AttachCGroupInetIngress),
- }
- _, err := sys.LinkCreate(&attr)
- if errors.Is(err, unix.EINVAL) {
- return internal.ErrNotSupported
- }
- if errors.Is(err, unix.EBADF) {
- return nil
- }
- return err
-})
diff --git a/vendor/github.com/cilium/ebpf/link/tracepoint.go b/vendor/github.com/cilium/ebpf/link/tracepoint.go
deleted file mode 100644
index a59ef9d1c..000000000
--- a/vendor/github.com/cilium/ebpf/link/tracepoint.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package link
-
-import (
- "fmt"
-
- "github.com/cilium/ebpf"
-)
-
-// TracepointOptions defines additional parameters that will be used
-// when loading Tracepoints.
-type TracepointOptions struct {
- // Arbitrary value that can be fetched from an eBPF program
- // via `bpf_get_attach_cookie()`.
- //
- // Needs kernel 5.15+.
- Cookie uint64
-}
-
-// Tracepoint attaches the given eBPF program to the tracepoint with the given
-// group and name. See /sys/kernel/debug/tracing/events to find available
-// tracepoints. The top-level directory is the group, the event's subdirectory
-// is the name. Example:
-//
-// tp, err := Tracepoint("syscalls", "sys_enter_fork", prog, nil)
-//
-// Losing the reference to the resulting Link (tp) will close the Tracepoint
-// and prevent further execution of prog. The Link must be Closed during
-// program shutdown to avoid leaking system resources.
-//
-// Note that attaching eBPF programs to syscalls (sys_enter_*/sys_exit_*) is
-// only possible as of kernel 4.14 (commit cf5f5ce).
-func Tracepoint(group, name string, prog *ebpf.Program, opts *TracepointOptions) (Link, error) {
- if group == "" || name == "" {
- return nil, fmt.Errorf("group and name cannot be empty: %w", errInvalidInput)
- }
- if prog == nil {
- return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
- }
- if !isValidTraceID(group) || !isValidTraceID(name) {
- return nil, fmt.Errorf("group and name '%s/%s' must be alphanumeric or underscore: %w", group, name, errInvalidInput)
- }
- if prog.Type() != ebpf.TracePoint {
- return nil, fmt.Errorf("eBPF program type %s is not a Tracepoint: %w", prog.Type(), errInvalidInput)
- }
-
- tid, err := getTraceEventID(group, name)
- if err != nil {
- return nil, err
- }
-
- fd, err := openTracepointPerfEvent(tid, perfAllThreads)
- if err != nil {
- return nil, err
- }
-
- var cookie uint64
- if opts != nil {
- cookie = opts.Cookie
- }
-
- pe := &perfEvent{
- typ: tracepointEvent,
- group: group,
- name: name,
- tracefsID: tid,
- cookie: cookie,
- fd: fd,
- }
-
- lnk, err := attachPerfEvent(pe, prog)
- if err != nil {
- pe.Close()
- return nil, err
- }
-
- return lnk, nil
-}
diff --git a/vendor/github.com/cilium/ebpf/link/tracing.go b/vendor/github.com/cilium/ebpf/link/tracing.go
deleted file mode 100644
index e47e61a3b..000000000
--- a/vendor/github.com/cilium/ebpf/link/tracing.go
+++ /dev/null
@@ -1,141 +0,0 @@
-package link
-
-import (
- "fmt"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/btf"
- "github.com/cilium/ebpf/internal/sys"
-)
-
-type tracing struct {
- RawLink
-}
-
-func (f *tracing) Update(new *ebpf.Program) error {
- return fmt.Errorf("tracing update: %w", ErrNotSupported)
-}
-
-// AttachFreplace attaches the given eBPF program to the function it replaces.
-//
-// The program and name can either be provided at link time, or can be provided
-// at program load time. If they were provided at load time, they should be nil
-// and empty respectively here, as they will be ignored by the kernel.
-// Examples:
-//
-// AttachFreplace(dispatcher, "function", replacement)
-// AttachFreplace(nil, "", replacement)
-func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (Link, error) {
- if (name == "") != (targetProg == nil) {
- return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput)
- }
- if prog == nil {
- return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
- }
- if prog.Type() != ebpf.Extension {
- return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput)
- }
-
- var (
- target int
- typeID btf.TypeID
- )
- if targetProg != nil {
- btfHandle, err := targetProg.Handle()
- if err != nil {
- return nil, err
- }
- defer btfHandle.Close()
-
- spec, err := btfHandle.Spec(nil)
- if err != nil {
- return nil, err
- }
-
- var function *btf.Func
- if err := spec.TypeByName(name, &function); err != nil {
- return nil, err
- }
-
- target = targetProg.FD()
- typeID, err = spec.TypeID(function)
- if err != nil {
- return nil, err
- }
- }
-
- link, err := AttachRawLink(RawLinkOptions{
- Target: target,
- Program: prog,
- Attach: ebpf.AttachNone,
- BTF: typeID,
- })
- if err != nil {
- return nil, err
- }
-
- return &tracing{*link}, nil
-}
-
-type TracingOptions struct {
- // Program must be of type Tracing with attach type
- // AttachTraceFEntry/AttachTraceFExit/AttachModifyReturn or
- // AttachTraceRawTp.
- Program *ebpf.Program
-}
-
-type LSMOptions struct {
- // Program must be of type LSM with attach type
- // AttachLSMMac.
- Program *ebpf.Program
-}
-
-// attachBTFID links all BPF program types (Tracing/LSM) that they attach to a btf_id.
-func attachBTFID(program *ebpf.Program) (Link, error) {
- if program.FD() < 0 {
- return nil, fmt.Errorf("invalid program %w", sys.ErrClosedFd)
- }
-
- fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{
- ProgFd: uint32(program.FD()),
- })
- if err != nil {
- return nil, err
- }
-
- raw := RawLink{fd: fd}
- info, err := raw.Info()
- if err != nil {
- raw.Close()
- return nil, err
- }
-
- if info.Type == RawTracepointType {
- // Sadness upon sadness: a Tracing program with AttachRawTp returns
- // a raw_tracepoint link. Other types return a tracing link.
- return &rawTracepoint{raw}, nil
- }
-
- return &tracing{RawLink: RawLink{fd: fd}}, nil
-}
-
-// AttachTracing links a tracing (fentry/fexit/fmod_ret) BPF program or
-// a BTF-powered raw tracepoint (tp_btf) BPF Program to a BPF hook defined
-// in kernel modules.
-func AttachTracing(opts TracingOptions) (Link, error) {
- if t := opts.Program.Type(); t != ebpf.Tracing {
- return nil, fmt.Errorf("invalid program type %s, expected Tracing", t)
- }
-
- return attachBTFID(opts.Program)
-}
-
-// AttachLSM links a Linux security module (LSM) BPF Program to a BPF
-// hook defined in kernel modules.
-func AttachLSM(opts LSMOptions) (Link, error) {
- if t := opts.Program.Type(); t != ebpf.LSM {
- return nil, fmt.Errorf("invalid program type %s, expected LSM", t)
- }
-
- return attachBTFID(opts.Program)
-}
diff --git a/vendor/github.com/cilium/ebpf/link/uprobe.go b/vendor/github.com/cilium/ebpf/link/uprobe.go
deleted file mode 100644
index edf925b57..000000000
--- a/vendor/github.com/cilium/ebpf/link/uprobe.go
+++ /dev/null
@@ -1,373 +0,0 @@
-package link
-
-import (
- "debug/elf"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "strings"
- "sync"
-
- "github.com/cilium/ebpf"
- "github.com/cilium/ebpf/internal"
-)
-
-var (
- uprobeEventsPath = filepath.Join(tracefsPath, "uprobe_events")
-
- uprobeRetprobeBit = struct {
- once sync.Once
- value uint64
- err error
- }{}
-
- uprobeRefCtrOffsetPMUPath = "/sys/bus/event_source/devices/uprobe/format/ref_ctr_offset"
- // elixir.bootlin.com/linux/v5.15-rc7/source/kernel/events/core.c#L9799
- uprobeRefCtrOffsetShift = 32
- haveRefCtrOffsetPMU = internal.FeatureTest("RefCtrOffsetPMU", "4.20", func() error {
- _, err := os.Stat(uprobeRefCtrOffsetPMUPath)
- if err != nil {
- return internal.ErrNotSupported
- }
- return nil
- })
-
- // ErrNoSymbol indicates that the given symbol was not found
- // in the ELF symbols table.
- ErrNoSymbol = errors.New("not found")
-)
-
-// Executable defines an executable program on the filesystem.
-type Executable struct {
- // Path of the executable on the filesystem.
- path string
- // Parsed ELF and dynamic symbols' addresses.
- addresses map[string]uint64
-}
-
-// UprobeOptions defines additional parameters that will be used
-// when loading Uprobes.
-type UprobeOptions struct {
- // Symbol address. Must be provided in case of external symbols (shared libs).
- // If set, overrides the address eventually parsed from the executable.
- Address uint64
- // The offset relative to given symbol. Useful when tracing an arbitrary point
- // inside the frame of given symbol.
- //
- // Note: this field changed from being an absolute offset to being relative
- // to Address.
- Offset uint64
- // Only set the uprobe on the given process ID. Useful when tracing
- // shared library calls or programs that have many running instances.
- PID int
- // Automatically manage SDT reference counts (semaphores).
- //
- // If this field is set, the Kernel will increment/decrement the
- // semaphore located in the process memory at the provided address on
- // probe attach/detach.
- //
- // See also:
- // sourceware.org/systemtap/wiki/UserSpaceProbeImplementation (Semaphore Handling)
- // github.com/torvalds/linux/commit/1cc33161a83d
- // github.com/torvalds/linux/commit/a6ca88b241d5
- RefCtrOffset uint64
- // Arbitrary value that can be fetched from an eBPF program
- // via `bpf_get_attach_cookie()`.
- //
- // Needs kernel 5.15+.
- Cookie uint64
-}
-
-// To open a new Executable, use:
-//
-// OpenExecutable("/bin/bash")
-//
-// The returned value can then be used to open Uprobe(s).
-func OpenExecutable(path string) (*Executable, error) {
- if path == "" {
- return nil, fmt.Errorf("path cannot be empty")
- }
-
- f, err := os.Open(path)
- if err != nil {
- return nil, fmt.Errorf("open file '%s': %w", path, err)
- }
- defer f.Close()
-
- se, err := internal.NewSafeELFFile(f)
- if err != nil {
- return nil, fmt.Errorf("parse ELF file: %w", err)
- }
-
- if se.Type != elf.ET_EXEC && se.Type != elf.ET_DYN {
- // ELF is not an executable or a shared object.
- return nil, errors.New("the given file is not an executable or a shared object")
- }
-
- ex := Executable{
- path: path,
- addresses: make(map[string]uint64),
- }
-
- if err := ex.load(se); err != nil {
- return nil, err
- }
-
- return &ex, nil
-}
-
-func (ex *Executable) load(f *internal.SafeELFFile) error {
- syms, err := f.Symbols()
- if err != nil && !errors.Is(err, elf.ErrNoSymbols) {
- return err
- }
-
- dynsyms, err := f.DynamicSymbols()
- if err != nil && !errors.Is(err, elf.ErrNoSymbols) {
- return err
- }
-
- syms = append(syms, dynsyms...)
-
- for _, s := range syms {
- if elf.ST_TYPE(s.Info) != elf.STT_FUNC {
- // Symbol not associated with a function or other executable code.
- continue
- }
-
- address := s.Value
-
- // Loop over ELF segments.
- for _, prog := range f.Progs {
- // Skip uninteresting segments.
- if prog.Type != elf.PT_LOAD || (prog.Flags&elf.PF_X) == 0 {
- continue
- }
-
- if prog.Vaddr <= s.Value && s.Value < (prog.Vaddr+prog.Memsz) {
- // If the symbol value is contained in the segment, calculate
- // the symbol offset.
- //
- // fn symbol offset = fn symbol VA - .text VA + .text offset
- //
- // stackoverflow.com/a/40249502
- address = s.Value - prog.Vaddr + prog.Off
- break
- }
- }
-
- ex.addresses[s.Name] = address
- }
-
- return nil
-}
-
-// address calculates the address of a symbol in the executable.
-//
-// opts must not be nil.
-func (ex *Executable) address(symbol string, opts *UprobeOptions) (uint64, error) {
- if opts.Address > 0 {
- return opts.Address + opts.Offset, nil
- }
-
- address, ok := ex.addresses[symbol]
- if !ok {
- return 0, fmt.Errorf("symbol %s: %w", symbol, ErrNoSymbol)
- }
-
- // Symbols with location 0 from section undef are shared library calls and
- // are relocated before the binary is executed. Dynamic linking is not
- // implemented by the library, so mark this as unsupported for now.
- //
- // Since only offset values are stored and not elf.Symbol, if the value is 0,
- // assume it's an external symbol.
- if address == 0 {
- return 0, fmt.Errorf("cannot resolve %s library call '%s': %w "+
- "(consider providing UprobeOptions.Address)", ex.path, symbol, ErrNotSupported)
- }
-
- return address + opts.Offset, nil
-}
-
-// Uprobe attaches the given eBPF program to a perf event that fires when the
-// given symbol starts executing in the given Executable.
-// For example, /bin/bash::main():
-//
-// ex, _ = OpenExecutable("/bin/bash")
-// ex.Uprobe("main", prog, nil)
-//
-// When using symbols which belongs to shared libraries,
-// an offset must be provided via options:
-//
-// up, err := ex.Uprobe("main", prog, &UprobeOptions{Offset: 0x123})
-//
-// Note: Setting the Offset field in the options supersedes the symbol's offset.
-//
-// Losing the reference to the resulting Link (up) will close the Uprobe
-// and prevent further execution of prog. The Link must be Closed during
-// program shutdown to avoid leaking system resources.
-//
-// Functions provided by shared libraries can currently not be traced and
-// will result in an ErrNotSupported.
-func (ex *Executable) Uprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions) (Link, error) {
- u, err := ex.uprobe(symbol, prog, opts, false)
- if err != nil {
- return nil, err
- }
-
- lnk, err := attachPerfEvent(u, prog)
- if err != nil {
- u.Close()
- return nil, err
- }
-
- return lnk, nil
-}
-
-// Uretprobe attaches the given eBPF program to a perf event that fires right
-// before the given symbol exits. For example, /bin/bash::main():
-//
-// ex, _ = OpenExecutable("/bin/bash")
-// ex.Uretprobe("main", prog, nil)
-//
-// When using symbols which belongs to shared libraries,
-// an offset must be provided via options:
-//
-// up, err := ex.Uretprobe("main", prog, &UprobeOptions{Offset: 0x123})
-//
-// Note: Setting the Offset field in the options supersedes the symbol's offset.
-//
-// Losing the reference to the resulting Link (up) will close the Uprobe
-// and prevent further execution of prog. The Link must be Closed during
-// program shutdown to avoid leaking system resources.
-//
-// Functions provided by shared libraries can currently not be traced and
-// will result in an ErrNotSupported.
-func (ex *Executable) Uretprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions) (Link, error) {
- u, err := ex.uprobe(symbol, prog, opts, true)
- if err != nil {
- return nil, err
- }
-
- lnk, err := attachPerfEvent(u, prog)
- if err != nil {
- u.Close()
- return nil, err
- }
-
- return lnk, nil
-}
-
-// uprobe opens a perf event for the given binary/symbol and attaches prog to it.
-// If ret is true, create a uretprobe.
-func (ex *Executable) uprobe(symbol string, prog *ebpf.Program, opts *UprobeOptions, ret bool) (*perfEvent, error) {
- if prog == nil {
- return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
- }
- if prog.Type() != ebpf.Kprobe {
- return nil, fmt.Errorf("eBPF program type %s is not Kprobe: %w", prog.Type(), errInvalidInput)
- }
- if opts == nil {
- opts = &UprobeOptions{}
- }
-
- offset, err := ex.address(symbol, opts)
- if err != nil {
- return nil, err
- }
-
- pid := opts.PID
- if pid == 0 {
- pid = perfAllThreads
- }
-
- if opts.RefCtrOffset != 0 {
- if err := haveRefCtrOffsetPMU(); err != nil {
- return nil, fmt.Errorf("uprobe ref_ctr_offset: %w", err)
- }
- }
-
- args := probeArgs{
- symbol: symbol,
- path: ex.path,
- offset: offset,
- pid: pid,
- refCtrOffset: opts.RefCtrOffset,
- ret: ret,
- cookie: opts.Cookie,
- }
-
- // Use uprobe PMU if the kernel has it available.
- tp, err := pmuUprobe(args)
- if err == nil {
- return tp, nil
- }
- if err != nil && !errors.Is(err, ErrNotSupported) {
- return nil, fmt.Errorf("creating perf_uprobe PMU: %w", err)
- }
-
- // Use tracefs if uprobe PMU is missing.
- args.symbol = sanitizeSymbol(symbol)
- tp, err = tracefsUprobe(args)
- if err != nil {
- return nil, fmt.Errorf("creating trace event '%s:%s' in tracefs: %w", ex.path, symbol, err)
- }
-
- return tp, nil
-}
-
-// pmuUprobe opens a perf event based on the uprobe PMU.
-func pmuUprobe(args probeArgs) (*perfEvent, error) {
- return pmuProbe(uprobeType, args)
-}
-
-// tracefsUprobe creates a Uprobe tracefs entry.
-func tracefsUprobe(args probeArgs) (*perfEvent, error) {
- return tracefsProbe(uprobeType, args)
-}
-
-// sanitizeSymbol replaces every invalid character for the tracefs api with an underscore.
-// It is equivalent to calling regexp.MustCompile("[^a-zA-Z0-9]+").ReplaceAllString("_").
-func sanitizeSymbol(s string) string {
- var b strings.Builder
- b.Grow(len(s))
- var skip bool
- for _, c := range []byte(s) {
- switch {
- case c >= 'a' && c <= 'z',
- c >= 'A' && c <= 'Z',
- c >= '0' && c <= '9':
- skip = false
- b.WriteByte(c)
-
- default:
- if !skip {
- b.WriteByte('_')
- skip = true
- }
- }
- }
-
- return b.String()
-}
-
-// uprobeToken creates the PATH:OFFSET(REF_CTR_OFFSET) token for the tracefs api.
-func uprobeToken(args probeArgs) string {
- po := fmt.Sprintf("%s:%#x", args.path, args.offset)
-
- if args.refCtrOffset != 0 {
- // This is not documented in Documentation/trace/uprobetracer.txt.
- // elixir.bootlin.com/linux/v5.15-rc7/source/kernel/trace/trace.c#L5564
- po += fmt.Sprintf("(%#x)", args.refCtrOffset)
- }
-
- return po
-}
-
-func uretprobeBit() (uint64, error) {
- uprobeRetprobeBit.once.Do(func() {
- uprobeRetprobeBit.value, uprobeRetprobeBit.err = determineRetprobeBit(uprobeType)
- })
- return uprobeRetprobeBit.value, uprobeRetprobeBit.err
-}
diff --git a/vendor/github.com/cilium/ebpf/link/xdp.go b/vendor/github.com/cilium/ebpf/link/xdp.go
deleted file mode 100644
index aa8dd3a4c..000000000
--- a/vendor/github.com/cilium/ebpf/link/xdp.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package link
-
-import (
- "fmt"
-
- "github.com/cilium/ebpf"
-)
-
-// XDPAttachFlags represents how XDP program will be attached to interface.
-type XDPAttachFlags uint32
-
-const (
- // XDPGenericMode (SKB) links XDP BPF program for drivers which do
- // not yet support native XDP.
- XDPGenericMode XDPAttachFlags = 1 << (iota + 1)
- // XDPDriverMode links XDP BPF program into the driver’s receive path.
- XDPDriverMode
- // XDPOffloadMode offloads the entire XDP BPF program into hardware.
- XDPOffloadMode
-)
-
-type XDPOptions struct {
- // Program must be an XDP BPF program.
- Program *ebpf.Program
-
- // Interface is the interface index to attach program to.
- Interface int
-
- // Flags is one of XDPAttachFlags (optional).
- //
- // Only one XDP mode should be set, without flag defaults
- // to driver/generic mode (best effort).
- Flags XDPAttachFlags
-}
-
-// AttachXDP links an XDP BPF program to an XDP hook.
-func AttachXDP(opts XDPOptions) (Link, error) {
- if t := opts.Program.Type(); t != ebpf.XDP {
- return nil, fmt.Errorf("invalid program type %s, expected XDP", t)
- }
-
- if opts.Interface < 1 {
- return nil, fmt.Errorf("invalid interface index: %d", opts.Interface)
- }
-
- rawLink, err := AttachRawLink(RawLinkOptions{
- Program: opts.Program,
- Attach: ebpf.AttachXDP,
- Target: opts.Interface,
- Flags: uint32(opts.Flags),
- })
-
- return rawLink, err
-}