diff --git a/btf/btf.go b/btf/btf.go index 89e644f5c..7327c8010 100644 --- a/btf/btf.go +++ b/btf/btf.go @@ -25,6 +25,7 @@ var ( ErrNotSupported = internal.ErrNotSupported ErrNotFound = errors.New("not found") ErrNoExtendedInfo = errors.New("no extended info") + ErrMultipleTypes = errors.New("multiple type candidates") ) // ID represents the unique ID of a BTF object. @@ -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() @@ -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, ErrMultipleTypes) } candidate = typ diff --git a/prog.go b/prog.go index a113a5ff2..2f7333d28 100644 --- a/prog.go +++ b/prog.go @@ -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.ErrMultipleTypes) { + 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) }