Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unprivileged objNameAllowsDot, return *btf.Var from Variable{Spec}.Type() #1612

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion elf_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -1239,7 +1239,7 @@ func (ec *elfCode) loadDataSections() error {
return fmt.Errorf("data section %s: variable %s size in datasec (%d) doesn't match ELF symbol size (%d)", sec.Name, name, v.Size, ev.size)
}

ev.t = vt.Type
ev.t = vt
}
}
}
Expand Down
21 changes: 19 additions & 2 deletions syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,18 @@ var haveObjName = internal.NewFeatureTest("object names", func() error {
MapName: sys.NewObjName("feature_test"),
}

// Tolerate EPERM as this runs during ELF loading which is potentially
// unprivileged. Only EINVAL is conclusive, thrown from CHECK_ATTR.
fd, err := sys.MapCreate(&attr)
if err != nil {
if errors.Is(err, unix.EPERM) {
return nil
}
if errors.Is(err, unix.EINVAL) {
return internal.ErrNotSupported
}
if err != nil {
return err
}

_ = fd.Close()
return nil
Expand All @@ -201,10 +209,19 @@ var objNameAllowsDot = internal.NewFeatureTest("dot in object names", func() err
MapName: sys.NewObjName(".test"),
}

// Tolerate EPERM, otherwise MapSpec.Name has its dots removed when run by
// unprivileged tools. (bpf2go, other code gen). Only EINVAL is conclusive,
// thrown from bpf_obj_name_cpy().
fd, err := sys.MapCreate(&attr)
if err != nil {
if errors.Is(err, unix.EPERM) {
return nil
}
if errors.Is(err, unix.EINVAL) {
return internal.ErrNotSupported
}
if err != nil {
return err
}

_ = fd.Close()
return nil
Expand Down
32 changes: 25 additions & 7 deletions variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type VariableSpec struct {
size uint64

m *MapSpec
t btf.Type
t *btf.Var
}

// Set sets the value of the VariableSpec to the provided input using the host's
Expand Down Expand Up @@ -75,14 +75,28 @@ func (s *VariableSpec) Size() uint64 {
return s.size
}

// MapName returns the name of the underlying MapSpec.
func (s *VariableSpec) MapName() string {
return s.m.Name
}

// Offset returns the offset of the variable in the underlying MapSpec.
func (s *VariableSpec) Offset() uint64 {
return s.offset
}

// Constant returns true if the VariableSpec represents a variable that is
// read-only from the perspective of the BPF program.
func (s *VariableSpec) Constant() bool {
return s.m.readOnly()
}

// Type returns the BTF Type of the variable.
func (s *VariableSpec) Type() btf.Type {
// Type returns the [btf.Var] representing the variable in its data section.
// This is useful for inspecting the variable's decl tags and the type
// information of the inner type.
//
// Returns nil if the original ELF object did not contain BTF information.
func (s *VariableSpec) Type() *btf.Var {
return s.t
}

Expand Down Expand Up @@ -122,12 +136,12 @@ type Variable struct {
name string
offset uint64
size uint64
t btf.Type
t *btf.Var

mm *Memory
}

func newVariable(name string, offset, size uint64, t btf.Type, mm *Memory) (*Variable, error) {
func newVariable(name string, offset, size uint64, t *btf.Var, mm *Memory) (*Variable, error) {
if mm != nil {
if int(offset+size) > mm.Size() {
return nil, fmt.Errorf("offset %d(+%d) is out of bounds", offset, size)
Expand Down Expand Up @@ -159,8 +173,12 @@ func (v *Variable) ReadOnly() bool {
return v.mm.ReadOnly()
}

// Type returns the BTF Type of the variable.
func (v *Variable) Type() btf.Type {
// Type returns the [btf.Var] representing the variable in its data section.
// This is useful for inspecting the variable's decl tags and the type
// information of the inner type.
//
// Returns nil if the original ELF object did not contain BTF information.
func (v *Variable) Type() *btf.Var {
return v.t
}

Expand Down
2 changes: 1 addition & 1 deletion variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestVariable(t *testing.T) {

typ := obj.BSS.Type()
qt.Assert(t, qt.IsNotNil(typ))
i, ok := btf.As[*btf.Int](typ)
i, ok := btf.As[*btf.Int](typ.Type)
qt.Assert(t, qt.IsTrue(ok))
qt.Assert(t, qt.Equals(i.Size, 4))

Expand Down
Loading