gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

tracing.go (3583B)


      1 package link
      2 
      3 import (
      4 	"fmt"
      5 
      6 	"github.com/cilium/ebpf"
      7 	"github.com/cilium/ebpf/btf"
      8 	"github.com/cilium/ebpf/internal/sys"
      9 )
     10 
     11 type tracing struct {
     12 	RawLink
     13 }
     14 
     15 func (f *tracing) Update(new *ebpf.Program) error {
     16 	return fmt.Errorf("tracing update: %w", ErrNotSupported)
     17 }
     18 
     19 // AttachFreplace attaches the given eBPF program to the function it replaces.
     20 //
     21 // The program and name can either be provided at link time, or can be provided
     22 // at program load time. If they were provided at load time, they should be nil
     23 // and empty respectively here, as they will be ignored by the kernel.
     24 // Examples:
     25 //
     26 //	AttachFreplace(dispatcher, "function", replacement)
     27 //	AttachFreplace(nil, "", replacement)
     28 func AttachFreplace(targetProg *ebpf.Program, name string, prog *ebpf.Program) (Link, error) {
     29 	if (name == "") != (targetProg == nil) {
     30 		return nil, fmt.Errorf("must provide both or neither of name and targetProg: %w", errInvalidInput)
     31 	}
     32 	if prog == nil {
     33 		return nil, fmt.Errorf("prog cannot be nil: %w", errInvalidInput)
     34 	}
     35 	if prog.Type() != ebpf.Extension {
     36 		return nil, fmt.Errorf("eBPF program type %s is not an Extension: %w", prog.Type(), errInvalidInput)
     37 	}
     38 
     39 	var (
     40 		target int
     41 		typeID btf.TypeID
     42 	)
     43 	if targetProg != nil {
     44 		btfHandle, err := targetProg.Handle()
     45 		if err != nil {
     46 			return nil, err
     47 		}
     48 		defer btfHandle.Close()
     49 
     50 		spec, err := btfHandle.Spec(nil)
     51 		if err != nil {
     52 			return nil, err
     53 		}
     54 
     55 		var function *btf.Func
     56 		if err := spec.TypeByName(name, &function); err != nil {
     57 			return nil, err
     58 		}
     59 
     60 		target = targetProg.FD()
     61 		typeID, err = spec.TypeID(function)
     62 		if err != nil {
     63 			return nil, err
     64 		}
     65 	}
     66 
     67 	link, err := AttachRawLink(RawLinkOptions{
     68 		Target:  target,
     69 		Program: prog,
     70 		Attach:  ebpf.AttachNone,
     71 		BTF:     typeID,
     72 	})
     73 	if err != nil {
     74 		return nil, err
     75 	}
     76 
     77 	return &tracing{*link}, nil
     78 }
     79 
     80 type TracingOptions struct {
     81 	// Program must be of type Tracing with attach type
     82 	// AttachTraceFEntry/AttachTraceFExit/AttachModifyReturn or
     83 	// AttachTraceRawTp.
     84 	Program *ebpf.Program
     85 }
     86 
     87 type LSMOptions struct {
     88 	// Program must be of type LSM with attach type
     89 	// AttachLSMMac.
     90 	Program *ebpf.Program
     91 }
     92 
     93 // attachBTFID links all BPF program types (Tracing/LSM) that they attach to a btf_id.
     94 func attachBTFID(program *ebpf.Program) (Link, error) {
     95 	if program.FD() < 0 {
     96 		return nil, fmt.Errorf("invalid program %w", sys.ErrClosedFd)
     97 	}
     98 
     99 	fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{
    100 		ProgFd: uint32(program.FD()),
    101 	})
    102 	if err != nil {
    103 		return nil, err
    104 	}
    105 
    106 	raw := RawLink{fd: fd}
    107 	info, err := raw.Info()
    108 	if err != nil {
    109 		raw.Close()
    110 		return nil, err
    111 	}
    112 
    113 	if info.Type == RawTracepointType {
    114 		// Sadness upon sadness: a Tracing program with AttachRawTp returns
    115 		// a raw_tracepoint link. Other types return a tracing link.
    116 		return &rawTracepoint{raw}, nil
    117 	}
    118 
    119 	return &tracing{RawLink: RawLink{fd: fd}}, nil
    120 }
    121 
    122 // AttachTracing links a tracing (fentry/fexit/fmod_ret) BPF program or
    123 // a BTF-powered raw tracepoint (tp_btf) BPF Program to a BPF hook defined
    124 // in kernel modules.
    125 func AttachTracing(opts TracingOptions) (Link, error) {
    126 	if t := opts.Program.Type(); t != ebpf.Tracing {
    127 		return nil, fmt.Errorf("invalid program type %s, expected Tracing", t)
    128 	}
    129 
    130 	return attachBTFID(opts.Program)
    131 }
    132 
    133 // AttachLSM links a Linux security module (LSM) BPF Program to a BPF
    134 // hook defined in kernel modules.
    135 func AttachLSM(opts LSMOptions) (Link, error) {
    136 	if t := opts.Program.Type(); t != ebpf.LSM {
    137 		return nil, fmt.Errorf("invalid program type %s, expected LSM", t)
    138 	}
    139 
    140 	return attachBTFID(opts.Program)
    141 }