From 2403b03e27402af2744eeee8896ca56f107f19f2 Mon Sep 17 00:00:00 2001 From: Timo Beckers Date: Mon, 2 May 2022 15:55:56 +0200 Subject: [PATCH] prog,syscalls: probe expected_attach_type field in BPF_PROG_LOAD Discovered while running the test suite on kernel 4.14. With the addition BPF_PROG_ATTACH tests in package link, the haveProgAttach feature test was added, gated on 4.10. This helper uses the AttachType field, which sets the bpf_attr expected_attach_type field, available as of 4.17. There are more issues to address, but this patch fixes the tests on kernels between 4.10 and 4.17. Signed-off-by: Timo Beckers --- prog.go | 20 ++++++++++++++------ syscalls.go | 29 +++++++++++++++++++++++++++++ syscalls_test.go | 4 ++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/prog.go b/prog.go index 5e990af7f..5cc572235 100644 --- a/prog.go +++ b/prog.go @@ -58,7 +58,12 @@ type ProgramSpec struct { Name string // Type determines at which hook in the kernel a program will run. - Type ProgramType + Type ProgramType + + // AttachType of the program, needed to differentiate allowed context + // accesses in some newer program types like CGroupSockAddr. + // + // Ignored on kernels before 4.17. AttachType AttachType // Name of a kernel data structure or function to attach to. Its @@ -265,17 +270,20 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, handles *hand } attr := &sys.ProgLoadAttr{ - ProgType: sys.ProgType(spec.Type), - ProgFlags: spec.Flags, - ExpectedAttachType: sys.AttachType(spec.AttachType), - License: sys.NewStringPointer(spec.License), - KernVersion: kv, + ProgType: sys.ProgType(spec.Type), + ProgFlags: spec.Flags, + License: sys.NewStringPointer(spec.License), + KernVersion: kv, } if haveObjName() == nil { attr.ProgName = sys.NewObjName(spec.Name) } + if haveProgAttachType() == nil { + attr.ExpectedAttachType = sys.AttachType(spec.AttachType) + } + var err error var targetBTF *btf.Spec if opts.TargetBTF != nil { diff --git a/syscalls.go b/syscalls.go index ccbbe096e..1c7b3ee82 100644 --- a/syscalls.go +++ b/syscalls.go @@ -244,3 +244,32 @@ var haveProbeReadKernel = internal.FeatureTest("bpf_probe_read_kernel", "5.5", f _ = fd.Close() return nil }) + +var haveProgAttachType = internal.FeatureTest("expected_attach_type", "4.17", func() error { + insns := asm.Instructions{ + asm.Mov.Imm(asm.R0, 0), + asm.Return(), + } + buf := bytes.NewBuffer(make([]byte, 0, insns.Size())) + if err := insns.Marshal(buf, internal.NativeEndian); err != nil { + return err + } + bytecode := buf.Bytes() + + fd, err := sys.ProgLoad(&sys.ProgLoadAttr{ + ProgType: sys.ProgType(SocketFilter), + License: sys.NewStringPointer("MIT"), + Insns: sys.NewSlicePointer(bytecode), + InsnCnt: uint32(len(bytecode) / asm.InstructionSize), + // Provide a non-zero value to trip check_uarg_tail_zero in the syscall handler. + ExpectedAttachType: sys.AttachType(1), + }) + if errors.Is(err, unix.E2BIG) { + return internal.ErrNotSupported + } + if err != nil { + return err + } + _ = fd.Close() + return nil +}) diff --git a/syscalls_test.go b/syscalls_test.go index 7ad03c079..8d223bd82 100644 --- a/syscalls_test.go +++ b/syscalls_test.go @@ -54,3 +54,7 @@ func TestHaveInnerMaps(t *testing.T) { func TestHaveProbeReadKernel(t *testing.T) { testutils.CheckFeatureTest(t, haveProbeReadKernel) } + +func TestHaveProgAttachType(t *testing.T) { + testutils.CheckFeatureTest(t, haveProgAttachType) +}