Skip to content

Commit

Permalink
tetragon: Pin kprobe/multi links
Browse files Browse the repository at this point in the history
Signed-off-by: Jiri Olsa <[email protected]>
  • Loading branch information
olsajiri committed Jun 22, 2024
1 parent ebe0991 commit 7075882
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
41 changes: 32 additions & 9 deletions pkg/sensors/program/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,16 @@ func KprobeOpen(load *Program) OpenFunc {
}
}

func kprobeAttach(load *Program, prog *ebpf.Program, spec *ebpf.ProgramSpec, symbol string) (unloader.Unloader, error) {
func linkPin(lnk link.Link, bpfDir, path string) error {
pinPath := filepath.Join(bpfDir, path)
err := lnk.Pin(pinPath)
if err != nil {
return fmt.Errorf("pinning link '%s' failed: %w", pinPath, err)
}
return nil
}

func kprobeAttach(load *Program, prog *ebpf.Program, spec *ebpf.ProgramSpec, symbol, bpfDir, name string) (unloader.Unloader, error) {
var linkFn func() (link.Link, error)

if load.RetProbe {
Expand All @@ -170,6 +179,13 @@ func kprobeAttach(load *Program, prog *ebpf.Program, spec *ebpf.ProgramSpec, sym
if err != nil {
return nil, fmt.Errorf("attaching '%s' failed: %w", spec.Name, err)
}

err = linkPin(lnk, bpfDir, fmt.Sprintf("%s-%s", load.PinPath, name))
if err != nil {
lnk.Close()
return nil, err
}

return &unloader.RelinkUnloader{
UnloadProg: unloader.PinUnloader{Prog: prog}.Unload,
IsLinked: true,
Expand Down Expand Up @@ -202,7 +218,7 @@ func kprobeAttachOverride(load *Program, bpfDir string,
return fmt.Errorf("pinning '%s' to '%s' failed: %w", load.Label, pinPath, err)
}

load.unloaderOverride, err = kprobeAttach(load, prog, spec, load.Attach)
load.unloaderOverride, err = kprobeAttach(load, prog, spec, load.Attach, bpfDir, "link-override")
if err != nil {
logger.GetLogger().Warnf("Failed to attach override program: %w", err)
}
Expand Down Expand Up @@ -271,7 +287,7 @@ func KprobeAttach(load *Program, bpfDir string) AttachFunc {
}
}

return kprobeAttach(load, prog, spec, load.Attach)
return kprobeAttach(load, prog, spec, load.Attach, bpfDir, "link")
}
}

Expand Down Expand Up @@ -404,7 +420,7 @@ func LSMAttach() AttachFunc {
}

func multiKprobeAttach(load *Program, prog *ebpf.Program,
spec *ebpf.ProgramSpec, opts link.KprobeMultiOptions) (unloader.Unloader, error) {
spec *ebpf.ProgramSpec, bpfDir, name string, opts link.KprobeMultiOptions) (unloader.Unloader, error) {

var lnk link.Link
var err error
Expand All @@ -417,6 +433,13 @@ func multiKprobeAttach(load *Program, prog *ebpf.Program,
if err != nil {
return nil, fmt.Errorf("attaching '%s' failed: %w", spec.Name, err)
}

err = linkPin(lnk, bpfDir, fmt.Sprintf("%s-%s", load.PinPath, name))
if err != nil {
lnk.Close()
return nil, err
}

return unloader.ChainUnloader{
unloader.PinUnloader{
Prog: prog,
Expand Down Expand Up @@ -462,7 +485,7 @@ func MultiKprobeAttach(load *Program, bpfDir string) AttachFunc {
Symbols: data.Overrides,
}

load.unloaderOverride, err = multiKprobeAttach(load, progOverride, progOverrideSpec, opts)
load.unloaderOverride, err = multiKprobeAttach(load, progOverride, progOverrideSpec, bpfDir, "link-override", opts)
if err != nil {
logger.GetLogger().Warnf("Failed to attach override program: %w", err)
}
Expand All @@ -473,7 +496,7 @@ func MultiKprobeAttach(load *Program, bpfDir string) AttachFunc {
Cookies: data.Cookies,
}

return multiKprobeAttach(load, prog, spec, opts)
return multiKprobeAttach(load, prog, spec, bpfDir, "link", opts)
}
}

Expand Down Expand Up @@ -517,7 +540,7 @@ func LoadKprobeProgram(bpfDir string, load *Program, verbose int) error {
return loadProgram(bpfDir, load, opts, verbose)
}

func KprobeAttachMany(load *Program, syms []string) AttachFunc {
func KprobeAttachMany(load *Program, syms []string, bpfDir string) AttachFunc {
return func(_ *ebpf.Collection, _ *ebpf.CollectionSpec,
prog *ebpf.Program, spec *ebpf.ProgramSpec) (unloader.Unloader, error) {

Expand All @@ -528,7 +551,7 @@ func KprobeAttachMany(load *Program, syms []string) AttachFunc {
}

for idx := range syms {
un, err := kprobeAttach(load, prog, spec, syms[idx])
un, err := kprobeAttach(load, prog, spec, syms[idx], bpfDir, "link")
if err != nil {
return nil, err
}
Expand All @@ -541,7 +564,7 @@ func KprobeAttachMany(load *Program, syms []string) AttachFunc {

func LoadKprobeProgramAttachMany(bpfDir string, load *Program, syms []string, verbose int) error {
opts := &LoadOpts{
Attach: KprobeAttachMany(load, syms),
Attach: KprobeAttachMany(load, syms, bpfDir),
}
return loadProgram(bpfDir, load, opts, verbose)
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/sensors/unloader/unloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ type LinkUnloader struct {
}

func (lu LinkUnloader) Unload() error {
return lu.Link.Close()
defer lu.Link.Close()
return lu.Link.Unpin()
}

// rawDetachUnloader can be used to unload cgroup and sockmap programs.
Expand Down Expand Up @@ -163,6 +164,9 @@ type RelinkUnloader struct {
func (u *RelinkUnloader) Unload() error {
var ret error
if u.IsLinked {
if err := u.Link.Unpin(); err != nil {
ret = multierr.Append(ret, err)
}
if err := u.Link.Close(); err != nil {
ret = multierr.Append(ret, err)
} else {
Expand All @@ -178,6 +182,10 @@ func (u *RelinkUnloader) Unlink() error {
return errors.New("Unlink failed: program not linked")
}

if err := u.Link.Unpin(); err != nil {
return fmt.Errorf("Unlink failed: %w", err)
}

if err := u.Link.Close(); err != nil {
return fmt.Errorf("Unlink failed: %w", err)
}
Expand Down

0 comments on commit 7075882

Please sign in to comment.