Skip to content

Commit 80a7e31

Browse files
committed
prog,btf: explicitly refuse ambiguous AttachTo targets
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]>
1 parent c7ba7f0 commit 80a7e31

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

btf/btf.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ const btfMagic = 0xeB9F
2222

2323
// Errors returned by BTF functions.
2424
var (
25-
ErrNotSupported = internal.ErrNotSupported
26-
ErrNotFound = errors.New("not found")
27-
ErrNoExtendedInfo = errors.New("no extended info")
25+
ErrNotSupported = internal.ErrNotSupported
26+
ErrNotFound = errors.New("not found")
27+
ErrNoExtendedInfo = errors.New("no extended info")
28+
ErrMultipleMatches = errors.New("multiple matching types")
2829
)
2930

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

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

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

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

616616
candidate = typ

prog.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,12 @@ func findTargetInKernel(name string, progType ProgramType, attachType AttachType
891891
}
892892
return module, id, nil
893893
}
894+
// See cilium/ebpf#894. Until we can disambiguate between equally-named kernel
895+
// symbols, we should explicitly refuse program loads. They will not reliably
896+
// do what the caller intended.
897+
if errors.Is(err, btf.ErrMultipleMatches) {
898+
return nil, 0, fmt.Errorf("attaching to ambiguous kernel symbol is not supported: %w", err)
899+
}
894900
if err != nil {
895901
return nil, 0, fmt.Errorf("find target for %s in vmlinux: %w", featureName, err)
896902
}

0 commit comments

Comments
 (0)