Skip to content

Commit

Permalink
prog,btf: explicitly refuse ambiguous AttachTo targets
Browse files Browse the repository at this point in the history
See #894 for more context. Explicitly refuse loading programs with
multiple AttachTo candidates. BTF needs to carry more information to allow
disambiguating between them. The kernel API likely needs to be extended to
allow specifying which candidate to pick.

Signed-off-by: Timo Beckers <[email protected]>
  • Loading branch information
ti-mo committed Jan 13, 2023
1 parent c7ba7f0 commit 80a7e31
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
24 changes: 12 additions & 12 deletions btf/btf.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ const btfMagic = 0xeB9F

// Errors returned by BTF functions.
var (
ErrNotSupported = internal.ErrNotSupported
ErrNotFound = errors.New("not found")
ErrNoExtendedInfo = errors.New("no extended info")
ErrNotSupported = internal.ErrNotSupported
ErrNotFound = errors.New("not found")
ErrNoExtendedInfo = errors.New("no extended info")
ErrMultipleMatches = errors.New("multiple matching types")
)

// ID represents the unique ID of a BTF object.
Expand Down Expand Up @@ -564,16 +565,15 @@ func (s *Spec) AnyTypeByName(name string) (Type, error) {
return types[0], nil
}

// TypeByName searches for a Type with a specific name. Since multiple
// Types with the same name can exist, the parameter typ is taken to
// narrow down the search in case of a clash.
// TypeByName searches for a Type with a specific name. Since multiple Types
// with the same name can exist, the parameter typ is taken to narrow down the
// search in case of a clash.
//
// typ must be a non-nil pointer to an implementation of a Type.
// On success, the address of the found Type will be copied to typ.
// typ must be a non-nil pointer to an implementation of a Type. On success, the
// address of the found Type will be copied to typ.
//
// Returns an error wrapping ErrNotFound if no matching
// Type exists in the Spec. If multiple candidates are found,
// an error is returned.
// Returns an error wrapping ErrNotFound if no matching Type exists in the Spec.
// Returns an error wrapping ErrMultipleTypes if multiple candidates are found.
func (s *Spec) TypeByName(name string, typ interface{}) error {
typeInterface := reflect.TypeOf((*Type)(nil)).Elem()

Expand Down Expand Up @@ -610,7 +610,7 @@ func (s *Spec) TypeByName(name string, typ interface{}) error {
}

if candidate != nil {
return fmt.Errorf("type %s: multiple candidates for %T", name, typ)
return fmt.Errorf("type %s(%T): %w", name, typ, ErrMultipleMatches)
}

candidate = typ
Expand Down
6 changes: 6 additions & 0 deletions prog.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,12 @@ func findTargetInKernel(name string, progType ProgramType, attachType AttachType
}
return module, id, nil
}
// See cilium/ebpf#894. Until we can disambiguate between equally-named kernel
// symbols, we should explicitly refuse program loads. They will not reliably
// do what the caller intended.
if errors.Is(err, btf.ErrMultipleMatches) {
return nil, 0, fmt.Errorf("attaching to ambiguous kernel symbol is not supported: %w", err)
}
if err != nil {
return nil, 0, fmt.Errorf("find target for %s in vmlinux: %w", featureName, err)
}
Expand Down

0 comments on commit 80a7e31

Please sign in to comment.