From 762f45a326532dd0ddc579b7596befc356c0b0b3 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 19 Mar 2024 11:03:18 +0800 Subject: [PATCH 1/3] chore(prog): Add Autoload api Signed-off-by: Tao Chen --- prog.go | 4 ++++ selftest/probe-features/main.go | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/prog.go b/prog.go index 2feddbdb..6c14909e 100644 --- a/prog.go +++ b/prog.go @@ -111,6 +111,10 @@ func (p *BPFProg) SetAutoload(autoload bool) error { return nil } +func (p *BPFProg) Autoload() bool { + return bool(C.bpf_program__autoload(p.prog)) +} + func (p *BPFProg) SetAutoattach(autoload bool) { C.bpf_program__set_autoattach(p.prog, C.bool(autoload)) } diff --git a/selftest/probe-features/main.go b/selftest/probe-features/main.go index 2d8dd13c..caf264b7 100644 --- a/selftest/probe-features/main.go +++ b/selftest/probe-features/main.go @@ -44,6 +44,15 @@ func main() { } } + // Test auto load result + autoLoadOrig := kprobeProg.Autoload() + kprobeProg.SetAutoload((!autoLoadOrig)) + if kprobeProg.Autoload() == autoLoadOrig { + fmt.Println(os.Stderr, "auto load result wrong") + os.Exit(-1) + } + kprobeProg.SetAutoload((autoLoadOrig)) + err = bpfModule.BPFLoadObject() if err != nil { fmt.Fprintln(os.Stderr, err) From 09e1e076ccf04ace586c194c31985a43b6ec4a1d Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 19 Mar 2024 14:06:43 +0800 Subject: [PATCH 2/3] feature: Add {Attach,Detach}Programs api to object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It introduces api for bpf object like api in libbpf: bpf_object__attach_skeleton/bpf_object__detach_skeleton. So we don't need to specify the program name to attach one by one. Signed-off-by: Tao Chen CC: Dylane Chen Co-authored-by: Geyslan Gregório --- module.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/module.go b/module.go index 139503dc..c454cfd8 100644 --- a/module.go +++ b/module.go @@ -391,3 +391,65 @@ func (m *Module) Iterator() *BPFObjectIterator { prevMap: nil, } } + +func (m *Module) linkExist(prog *BPFProg) bool { + for _, link := range m.links { + if link.prog.Name() == prog.Name() { + return true + } + } + + return false +} + +// AttachPrograms attach all loaded and no attached progs once like bpf_object__attach_skeleton +func (m *Module) AttachPrograms() error { + iters := m.Iterator() + for { + prog := iters.NextProgram() + if prog == nil { + break + } + + if !prog.Autoload() || !prog.Autoattach() { + continue + } + // if link already exist (is attached), skip it + if m.linkExist(prog) { + continue + } + + link, err := prog.AttachGeneric() + if err != nil { + return err + } + + m.links = append(m.links, link) + } + + return nil +} + +// DetachPrograms detach all attached progs once like bpf_object__detach_skeleton +func (m *Module) DetachPrograms() error { + errInfo := make(map[string]error) + + for _, link := range m.links { + err := link.Destroy() + if err != nil { + errInfo[link.prog.Name()] = err + } + } + m.links = nil + + if len(errInfo) > 0 { + var str string + for name, err := range errInfo { + str += fmt.Sprintf(" [prog:%s,err:%s]", name, err) + } + + return fmt.Errorf("link destroy failed:%s", str) + } + + return nil +} From 5b4913686832047c44528e76643532b83a8a190c Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Tue, 19 Mar 2024 14:07:10 +0800 Subject: [PATCH 3/3] selftest: Add selftest for {Attach,Detach}Programs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tao Chen CC: Dylane Chen Co-authored-by: Geyslan Gregório --- selftest/module-attach-detach/Makefile | 1 + selftest/module-attach-detach/go.mod | 14 +++++++++ selftest/module-attach-detach/go.sum | 6 ++++ selftest/module-attach-detach/main.bpf.c | 24 ++++++++++++++ selftest/module-attach-detach/main.go | 40 ++++++++++++++++++++++++ selftest/module-attach-detach/run.sh | 1 + 6 files changed, 86 insertions(+) create mode 120000 selftest/module-attach-detach/Makefile create mode 100644 selftest/module-attach-detach/go.mod create mode 100644 selftest/module-attach-detach/go.sum create mode 100644 selftest/module-attach-detach/main.bpf.c create mode 100644 selftest/module-attach-detach/main.go create mode 120000 selftest/module-attach-detach/run.sh diff --git a/selftest/module-attach-detach/Makefile b/selftest/module-attach-detach/Makefile new file mode 120000 index 00000000..d981720c --- /dev/null +++ b/selftest/module-attach-detach/Makefile @@ -0,0 +1 @@ +../common/Makefile \ No newline at end of file diff --git a/selftest/module-attach-detach/go.mod b/selftest/module-attach-detach/go.mod new file mode 100644 index 00000000..538bc32d --- /dev/null +++ b/selftest/module-attach-detach/go.mod @@ -0,0 +1,14 @@ +module github.com/aquasecurity/libbpfgo/selftest/module-attach-detach + +go 1.18 + +require ( + github.com/aquasecurity/libbpfgo v0.4.7-libbpf-1.2.0-b2e29a1 + github.com/aquasecurity/libbpfgo/helpers v0.4.5 +) + +require golang.org/x/sys v0.7.0 // indirect + +replace github.com/aquasecurity/libbpfgo => ../../ + +replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers diff --git a/selftest/module-attach-detach/go.sum b/selftest/module-attach-detach/go.sum new file mode 100644 index 00000000..70691e6f --- /dev/null +++ b/selftest/module-attach-detach/go.sum @@ -0,0 +1,6 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/selftest/module-attach-detach/main.bpf.c b/selftest/module-attach-detach/main.bpf.c new file mode 100644 index 00000000..ded9dcdc --- /dev/null +++ b/selftest/module-attach-detach/main.bpf.c @@ -0,0 +1,24 @@ +//+build ignore + +#include + +#include +#include + +#ifdef __TARGET_ARCH_amd64 +SEC("fentry/__x64_sys_mmap") +#elif defined(__TARGET_ARCH_arm64) +SEC("fentry/__arm64_sys_mmap") +#endif +int sys_mmap(struct pt_regs *ctx) +{ + return 0; +} + +SEC("kprobe/do_sys_open") +int kprobe__sys_open(struct pt_regs *ctx) +{ + return 0; +} + +char LICENSE[] SEC("license") = "GPL"; diff --git a/selftest/module-attach-detach/main.go b/selftest/module-attach-detach/main.go new file mode 100644 index 00000000..c318a552 --- /dev/null +++ b/selftest/module-attach-detach/main.go @@ -0,0 +1,40 @@ +package main + +import "C" + +import ( + "os" + + "fmt" + + bpf "github.com/aquasecurity/libbpfgo" +) + +func main() { + bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(-1) + } + defer bpfModule.Close() + + err = bpfModule.BPFLoadObject() + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(-1) + } + + // attach all programs + err = bpfModule.AttachPrograms() + if err != nil { + fmt.Fprintln(os.Stderr, fmt.Sprintf("attach programs failed: %s", err)) + os.Exit(-1) + } + + // detach all programs + err = bpfModule.DetachPrograms() + if err != nil { + fmt.Fprintln(os.Stderr, fmt.Sprintf("detach programs failed: %s", err)) + os.Exit(-1) + } +} diff --git a/selftest/module-attach-detach/run.sh b/selftest/module-attach-detach/run.sh new file mode 120000 index 00000000..aee911b2 --- /dev/null +++ b/selftest/module-attach-detach/run.sh @@ -0,0 +1 @@ +../common/run.sh \ No newline at end of file