├── .clang-format ├── .clang-tidy ├── .github ├── actions │ └── build-dependencies │ │ └── action.yaml ├── dependabot.yml └── workflows │ ├── codeql.yaml │ └── pr.yaml ├── .gitignore ├── .gitmodules ├── .revive.toml ├── LICENSE ├── Makefile ├── Readme.md ├── btf.go ├── buf-common.go ├── buf-perf.go ├── buf-ring.go ├── builder ├── Vagrantfile-ubuntu └── prepare-ubuntu.sh ├── docs ├── Vagrantfile.md ├── helpers.md └── images │ └── aqua-tux.png ├── elf.go ├── go.mod ├── go.sum ├── helpers ├── argumentParsers.go ├── argumentParsers_amd64.go ├── argumentParsers_test.go ├── btfhub.go ├── common.go ├── common_test.go ├── elf.go ├── example_tracelisten_test.go ├── go.mod ├── go.sum ├── kernel_config.go ├── kernel_config_test.go ├── kernel_symbols.go ├── kernel_symbols_test.go ├── osinfo.go ├── osinfo_test.go ├── testdata │ ├── config_comments │ ├── config_comments.gz │ ├── config_standard.gz │ ├── os-release-almalinux │ ├── os-release-centos │ ├── os-release-debian │ ├── os-release-rhel │ └── os-release-ubuntu └── tracelisten.go ├── helpers_test.go ├── libbpf_cb.go ├── libbpfgo.c ├── libbpfgo.go ├── libbpfgo.h ├── link-reader.go ├── link.go ├── logger_cb.go ├── logger_cb_test.go ├── map-common.go ├── map-iterator.go ├── map-low.go ├── map.go ├── misc.go ├── module-iterator.go ├── module.go ├── prog-common.go ├── prog.go ├── rwArray.go ├── rwArray_test.go ├── selftest ├── attachgenericfd │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── build │ ├── Makefile │ └── libbpfgo_test.bpf.c ├── cgroup-legacy │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── cgroup │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── common │ ├── .gitignore │ ├── Makefile │ ├── common.sh │ ├── run-4.12.sh │ ├── run-5.8.sh │ ├── run-6.1.sh │ ├── run-vm-stage2.sh │ ├── run-warn-bt-5.4.sh │ ├── run.sh │ ├── vmlinux.h │ └── vmlinux_missing.h ├── create-map │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── error-handling │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── getbtffdbyid │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── global-variable │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── iter │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── iterators │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── log-callbacks │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-autocreate │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-batch │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-getbyid │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-getfdbyid │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-getmapsbyname │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-innerinfo │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-keysize │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-of-maps-outer-high-inner-high │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-of-maps-outer-high-inner-low │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-of-maps-outer-low-inner-low │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-pin-info │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-setinner │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── map-update │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── module-attach-detach │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── multiple-objects │ ├── Makefile │ ├── README.md │ ├── first.bpf.c │ ├── go.mod │ ├── go.sum │ ├── main.go │ ├── map.bpf.c │ ├── map.bpf.h │ ├── run.sh │ └── second.bpf.c ├── netns │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── object-iterator │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── percpu │ ├── Makefile │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── perfbuffers │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── probe-features │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── probe-ringbuf-non-supported │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ ├── run-vm.sh │ └── run.sh ├── probe-ringbuf │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ ├── run-vm.sh │ └── run.sh ├── prog-run │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── reuse-fd │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.bpf.h │ ├── main.go │ └── run.sh ├── ringbuffers │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── set-attach │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── spinlocks │ ├── Makefile │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── struct-ops │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ ├── run-vm.sh │ └── run.sh ├── tc │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── tracing-by-offset │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── tracing │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── uprobe-multi │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ ├── run.sh │ ├── test.c │ └── test.go ├── uprobe │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ ├── run.sh │ ├── test.c │ └── test.go ├── usdt │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ ├── run.sh │ └── test.c ├── userringbuf │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── version │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh └── xdp │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── main.bpf.c │ ├── main.go │ └── run.sh ├── tchook-common.go ├── tchook.go └── user-buf-ring.go /.github/actions/build-dependencies/action.yaml: -------------------------------------------------------------------------------- 1 | name: Build Dependencies 2 | description: | 3 | Install build dependencies to test and compile tracee artifacts 4 | inputs: 5 | go-version: 6 | description: go version 7 | default: "1.21" 8 | runs: 9 | using: composite 10 | steps: 11 | - name: Setup Go 12 | uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 13 | with: 14 | go-version: "${{ inputs.go-version }}" 15 | - name: Install Compilers & Formatters 16 | run: | 17 | sudo apt-get update 18 | sudo apt-get install --yes bsdutils 19 | sudo apt-get install --yes build-essential 20 | sudo apt-get install --yes pkgconf 21 | sudo apt-get install --yes llvm-14 clang-14 clang-format-14 22 | sudo apt-get install --yes libelf-dev libzstd-dev zlib1g-dev 23 | sudo apt-get install --yes virtme-ng 24 | sudo apt-get install --yes gcc-multilib 25 | sudo apt-get install --yes systemtap-sdt-dev 26 | for tool in "clang" "clang-format" "llc" "llvm-strip" 27 | do 28 | sudo rm -f /usr/bin/$tool 29 | sudo ln -s /usr/bin/$tool-14 /usr/bin/$tool 30 | done 31 | shell: bash 32 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | # - package-ecosystem: "github-actions" 8 | # directory: "/helpers" 9 | # schedule: 10 | # interval: daily 11 | - package-ecosystem: "gomod" 12 | directory: "/" 13 | schedule: 14 | interval: daily 15 | # - package-ecosystem: "gomod" 16 | # directory: "/helpers" 17 | # schedule: 18 | # interval: daily 19 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yaml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "main" 7 | - "v*.*.*" 8 | pull_request: 9 | branches: 10 | - "main" 11 | - "v*.*.*" 12 | 13 | jobs: 14 | analyze: 15 | name: Analyze (${{ matrix.language }}) 16 | runs-on: 'ubuntu-latest' 17 | permissions: 18 | security-events: write 19 | packages: read 20 | actions: read 21 | contents: read 22 | 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | include: 27 | - language: c-cpp 28 | build-mode: autobuild 29 | - language: go 30 | build-mode: autobuild 31 | 32 | steps: 33 | - name: Checkout repository 34 | uses: actions/checkout@v4 35 | 36 | - name: Install dependencies 37 | run: | 38 | sudo apt-get update 39 | sudo apt-get install -y libelf-dev clang make gcc pkg-config 40 | 41 | - name: Update submodules 42 | run: git submodule update --init --recursive 43 | 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v3 46 | with: 47 | languages: ${{ matrix.language }} 48 | build-mode: ${{ matrix.build-mode }} 49 | 50 | - name: Perform CodeQL Analysis 51 | uses: github/codeql-action/analyze@v3 52 | with: 53 | category: "/language:${{matrix.language}}" 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output* 2 | selftest/*/*.o 3 | selftest/*/*.skel.h 4 | selftest/*/*-static 5 | selftest/*/*-dynamic 6 | selftest/*/ctest 7 | selftest/*/gotest 8 | testing/tracee 9 | .vagrant* 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libbpf"] 2 | path = libbpf 3 | url = https://github.com/libbpf/libbpf.git 4 | -------------------------------------------------------------------------------- /btf.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | import ( 10 | "fmt" 11 | "syscall" 12 | ) 13 | 14 | // 15 | // BTF (low-level API) 16 | // 17 | 18 | // GetBTFFDByID returns a file descriptor for the BTF with the given ID. 19 | func GetBTFFDByID(id uint32) (int, error) { 20 | fdC := C.bpf_btf_get_fd_by_id(C.uint(id)) 21 | if fdC < 0 { 22 | return int(fdC), fmt.Errorf("could not find BTF id %d: %w", id, syscall.Errno(-fdC)) 23 | } 24 | 25 | return int(fdC), nil 26 | } 27 | -------------------------------------------------------------------------------- /buf-common.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | const ( 10 | // Maximum number of channels (RingBuffers + PerfBuffers) supported 11 | maxEventChannels = 512 12 | ) 13 | 14 | var ( 15 | eventChannels = newRWArray(maxEventChannels) 16 | ) 17 | -------------------------------------------------------------------------------- /builder/Vagrantfile-ubuntu: -------------------------------------------------------------------------------- 1 | ARCH = ENV["ARCH"] || "amd64" 2 | HOSTOS = ENV["HOSTOS"] || "undefined" 3 | 4 | if ! %w(amd64 arm64).include?(ARCH) then 5 | puts "ERROR: ARCH #{ARCH} not supported" 6 | abort 7 | end 8 | 9 | if ! %w(Linux Darwin).include?(HOSTOS) then 10 | puts "ERROR: HOSTOS #{HOSTOS} not supported" 11 | abort 12 | end 13 | 14 | VM_NAME = "libbpfgo-#{ARCH}-vm" 15 | VM_SOURCE = "/vagrant" 16 | 17 | Vagrant.configure("2") do |config| 18 | case ARCH 19 | when "amd64" 20 | config.vm.box = "bento/ubuntu-24.04" 21 | when "arm64" 22 | config.vm.box = "bento/ubuntu-24.04" 23 | end 24 | 25 | case HOSTOS 26 | when "Linux" 27 | config.vm.provider "virtualbox" do |vb| 28 | vb.name = VM_NAME 29 | vb.cpus = "4" 30 | vb.memory = "2048" 31 | end 32 | when "Darwin" 33 | config.vm.provider "parallels" do |prl| 34 | prl.name = VM_NAME 35 | end 36 | end 37 | 38 | config.vm.hostname = VM_NAME 39 | config.vm.synced_folder "./", "#{VM_SOURCE}" 40 | 41 | config.ssh.extra_args = ["-t", "cd #{VM_SOURCE}; bash --login"] 42 | 43 | config.vm.provision :shell, inline: "echo INFO: Starting Provision" 44 | config.vm.provision :shell, inline: "ARCH=#{ARCH} #{VM_SOURCE}/builder/prepare-ubuntu.sh" 45 | config.vm.provision :shell, inline: "echo INFO: Provision finished, now connect via ssh" 46 | end 47 | -------------------------------------------------------------------------------- /docs/Vagrantfile.md: -------------------------------------------------------------------------------- 1 | # Vagrantfile 2 | 3 | ## Boxes 4 | 5 | Currently there is one box available in [Vagrantfile-ubuntu](./../builder/Vagrantfile-ubuntu): 6 | 7 | | Box | Providers | 8 | |--------------------------------------------------------------------------|--------------------------| 9 | | [bento/ubuntu-24.04](https://app.vagrantup.com/bento/boxes/ubuntu-24.04) | virtualbox (amd64), parallels (arm64,amd64), ...| 10 | 11 | It is recommended to use them through the respective [Makefile rules](../Readme.md#contributing) as they are or overriding the `ARCH` environment variable if your architecture and provider allow such virtualization. E.g.: `make vagrant-up ARCH=amd64`. 12 | 13 | ## Requirements 14 | 15 | ### Linux 16 | 17 | Install them as per your flavour. 18 | 19 | - Vagrant 20 | - VirtualBox 21 | 22 | ### Darwin 23 | 24 | - Vagrant 25 | 26 | ```shell 27 | brew install vagrant 28 | ``` 29 | 30 | - Parallels 31 | 32 | ```shell 33 | brew install --cask parallels 34 | vagrant plugin install vagrant-parallels 35 | ``` 36 | 37 | ## More information 38 | 39 | For further information check: 40 | 41 | - [Vagrant Documentation](https://www.vagrantup.com/docs) 42 | - [Vagrant Boxes](https://app.vagrantup.com/boxes/search) 43 | - [VirtualBox Documentation](https://www.virtualbox.org/wiki/Documentation) 44 | - [Parallels](https://www.parallels.com) 45 | -------------------------------------------------------------------------------- /docs/images/aqua-tux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/libbpfgo/0884266043bb2edb3843205dbe45c2d9ab3be022/docs/images/aqua-tux.png -------------------------------------------------------------------------------- /elf.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | import ( 4 | "debug/elf" 5 | "encoding/binary" 6 | "errors" 7 | "strings" 8 | ) 9 | 10 | type Symbol struct { 11 | name string 12 | size int 13 | offset int 14 | 15 | sectionName string 16 | byteOrder binary.ByteOrder 17 | } 18 | 19 | func getGlobalVariableSymbol(e *elf.File, varName string) (*Symbol, error) { 20 | regularSymbols, err := e.Symbols() 21 | if err != nil { 22 | return nil, err 23 | } 24 | 25 | var symbols []Symbol 26 | for _, s := range regularSymbols { 27 | i := int(s.Section) 28 | if i >= len(e.Sections) { 29 | continue 30 | } 31 | sectionName := e.Sections[i].Name 32 | if isGlobalVariableSection(sectionName) { 33 | symbols = append(symbols, Symbol{ 34 | name: s.Name, 35 | size: int(s.Size), 36 | offset: int(s.Value), 37 | sectionName: sectionName, 38 | byteOrder: e.ByteOrder, 39 | }) 40 | } 41 | } 42 | 43 | for _, s := range symbols { 44 | if s.name == varName { 45 | return &s, nil 46 | } 47 | } 48 | 49 | return nil, errors.New("symbol not found") 50 | } 51 | 52 | func isGlobalVariableSection(sectionName string) bool { 53 | if sectionName == ".data" || sectionName == ".rodata" { 54 | return true 55 | } 56 | if strings.HasPrefix(sectionName, ".data.") || 57 | strings.HasPrefix(sectionName, ".rodata.") { 58 | return true 59 | } 60 | 61 | return false 62 | } 63 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/stretchr/testify v1.10.0 7 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/pmezard/go-difflib v1.0.0 // indirect 13 | gopkg.in/yaml.v3 v3.0.1 // indirect 14 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 12 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 13 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 14 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 15 | -------------------------------------------------------------------------------- /helpers/argumentParsers_amd64.go: -------------------------------------------------------------------------------- 1 | // Deprecated: helpers package is deprecated and will be removed. 2 | // See https://github.com/aquasecurity/tracee/pull/4090 3 | package helpers 4 | 5 | import ( 6 | "golang.org/x/sys/unix" 7 | ) 8 | 9 | var ( 10 | Map32bit = MmapFlagArgument{rawValue: unix.MAP_32BIT, stringValue: "MAP_32BIT"} 11 | ) 12 | 13 | func init() { 14 | mmapFlagMap[Map32bit.Value()] = Map32bit 15 | } 16 | -------------------------------------------------------------------------------- /helpers/btfhub.go: -------------------------------------------------------------------------------- 1 | // Deprecated: helpers package is deprecated and will be removed. 2 | // See https://github.com/aquasecurity/tracee/pull/4090 3 | package helpers 4 | -------------------------------------------------------------------------------- /helpers/example_tracelisten_test.go: -------------------------------------------------------------------------------- 1 | // Deprecated: helpers package is deprecated and will be removed. 2 | // See https://github.com/aquasecurity/tracee/pull/4090 3 | package helpers_test 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/aquasecurity/libbpfgo/helpers" 10 | ) 11 | 12 | func ExampleTracePipeListen_usage() { 13 | go func() { 14 | err := helpers.TracePipeListen() 15 | if err != nil { 16 | fmt.Fprintf(os.Stderr, "%s\n", err.Error()) 17 | } 18 | }() 19 | } 20 | -------------------------------------------------------------------------------- /helpers/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/helpers 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/stretchr/testify v1.10.0 7 | golang.org/x/sys v0.25.0 8 | ) 9 | 10 | require ( 11 | github.com/davecgh/go-spew v1.1.1 // indirect 12 | github.com/pmezard/go-difflib v1.0.0 // indirect 13 | gopkg.in/yaml.v3 v3.0.1 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /helpers/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 8 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 10 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 11 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 12 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 13 | -------------------------------------------------------------------------------- /helpers/kernel_symbols_test.go: -------------------------------------------------------------------------------- 1 | // Deprecated: helpers package is deprecated and will be removed. 2 | // See https://github.com/aquasecurity/tracee/pull/4090 3 | package helpers 4 | 5 | import ( 6 | "reflect" 7 | "testing" 8 | ) 9 | 10 | // TestParseLine tests the parseLine function. 11 | func TestParseLine(t *testing.T) { 12 | testCases := []struct { 13 | line []string 14 | expected *KernelSymbol 15 | }{ 16 | {[]string{"00000000", "t", "my_symbol", "[my_owner]"}, &KernelSymbol{Name: "my_symbol", Type: "t", Address: 0, Owner: "my_owner"}}, 17 | // Add more test cases as needed. 18 | } 19 | 20 | for _, tc := range testCases { 21 | result := parseLine(tc.line) 22 | if !reflect.DeepEqual(result, tc.expected) { 23 | t.Errorf("parseLine(%v) = %v; want %v", tc.line, result, tc.expected) 24 | } 25 | } 26 | } 27 | 28 | func TestRefresh(t *testing.T) { 29 | kst, err := NewKernelSymbolTable() 30 | if err != nil { 31 | t.Fatalf("NewKernelSymbolTable() failed: %v", err) 32 | } 33 | 34 | // Test well-known symbols like _stext and _etext. 35 | symbolsToTest := []string{"_stext", "_etext"} 36 | 37 | for _, symbol := range symbolsToTest { 38 | if syms, err := kst.GetSymbolByName(symbol); err != nil || len(syms) == 0 { 39 | t.Errorf("Expected to find symbol %s, but it was not found", symbol) 40 | } 41 | } 42 | 43 | // Text the text swegment contains function. 44 | if _, err := kst.TextSegmentContains(0); err != nil { 45 | t.Errorf("TextSegmentContains failed: %v", err) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /helpers/testdata/config_comments: -------------------------------------------------------------------------------- 1 | # this is a comment in the beginning 2 | CONFIG_BPF=y 3 | CONFIG_BPF_LSM=y 4 | CONFIG_BPF_SYSCALL=y 5 | # this is comment in the middle 6 | CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y 7 | CONFIG_BPF_JIT_ALWAYS_ON=y 8 | CONFIG_BPF_JIT_DEFAULT_ON=y 9 | CONFIG_BPF_PRELOAD=y 10 | CONFIG_BPF_PRELOAD_UMD=m 11 | # CONFIG_BLAH is not set 12 | CONFIG_IPV6_SEG6_BPF=y 13 | CONFIG_NETFILTER_XT_MATCH_BPF=m 14 | CONFIG_HZ_250=y 15 | CONFIG_HZ=250 16 | CONFIG_TEST_BPF=m 17 | # a comment at the end 18 | -------------------------------------------------------------------------------- /helpers/testdata/config_comments.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/libbpfgo/0884266043bb2edb3843205dbe45c2d9ab3be022/helpers/testdata/config_comments.gz -------------------------------------------------------------------------------- /helpers/testdata/config_standard.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aquasecurity/libbpfgo/0884266043bb2edb3843205dbe45c2d9ab3be022/helpers/testdata/config_standard.gz -------------------------------------------------------------------------------- /helpers/testdata/os-release-almalinux: -------------------------------------------------------------------------------- 1 | NAME="AlmaLinux" 2 | VERSION="8.7 (Stone Smilodon)" 3 | ID="almalinux" 4 | ID_LIKE="rhel centos fedora" 5 | VERSION_ID="8.7" 6 | PLATFORM_ID="platform:el8" 7 | PRETTY_NAME="AlmaLinux 8.7 (Stone Smilodon)" 8 | ANSI_COLOR="0;34" 9 | LOGO="fedora-logo-icon" 10 | CPE_NAME="cpe:/o:almalinux:almalinux:8::baseos" 11 | HOME_URL="https://almalinux.org/" 12 | DOCUMENTATION_URL="https://wiki.almalinux.org/" 13 | BUG_REPORT_URL="https://bugs.almalinux.org/" 14 | 15 | ALMALINUX_MANTISBT_PROJECT="AlmaLinux-8" 16 | ALMALINUX_MANTISBT_PROJECT_VERSION="8.7" 17 | REDHAT_SUPPORT_PRODUCT="AlmaLinux" 18 | REDHAT_SUPPORT_PRODUCT_VERSION="8.7" -------------------------------------------------------------------------------- /helpers/testdata/os-release-centos: -------------------------------------------------------------------------------- 1 | NAME="CentOS Stream" 2 | VERSION="8" 3 | ID="centos" 4 | ID_LIKE="rhel fedora" 5 | VERSION_ID="8" 6 | PLATFORM_ID="platform:el8" 7 | PRETTY_NAME="CentOS Stream 8" 8 | ANSI_COLOR="0;31" 9 | CPE_NAME="cpe:/o:centos:centos:8" 10 | HOME_URL="https://centos.org/" 11 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 12 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 8" 13 | REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream" 14 | -------------------------------------------------------------------------------- /helpers/testdata/os-release-debian: -------------------------------------------------------------------------------- 1 | PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" 2 | NAME="Debian GNU/Linux" 3 | VERSION_ID="11" 4 | VERSION="11 (bullseye)" 5 | VERSION_CODENAME=bullseye 6 | ID=debian 7 | HOME_URL="https://www.debian.org/" 8 | SUPPORT_URL="https://www.debian.org/support" 9 | BUG_REPORT_URL="https://bugs.debian.org/" 10 | -------------------------------------------------------------------------------- /helpers/testdata/os-release-rhel: -------------------------------------------------------------------------------- 1 | NAME="Red Hat Enterprise Linux" 2 | VERSION="8.5 (Ootpa)" 3 | ID="rhel" 4 | ID_LIKE="fedora" 5 | VERSION_ID="8.5" 6 | PLATFORM_ID="platform:el8" 7 | PRETTY_NAME="Red Hat Enterprise Linux 8.5 (Ootpa)" 8 | ANSI_COLOR="0;31" 9 | CPE_NAME="cpe:/o:redhat:enterprise_linux:8::baseos" 10 | HOME_URL="https://www.redhat.com/" 11 | DOCUMENTATION_URL="https://access.redhat.com/documentation/red_hat_enterprise_linux/8/" 12 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 13 | 14 | REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8" 15 | REDHAT_BUGZILLA_PRODUCT_VERSION=8.5 16 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" 17 | REDHAT_SUPPORT_PRODUCT_VERSION="8.5" 18 | -------------------------------------------------------------------------------- /helpers/testdata/os-release-ubuntu: -------------------------------------------------------------------------------- 1 | PRETTY_NAME="Ubuntu 22.10" 2 | NAME="Ubuntu" 3 | VERSION_ID="22.10" 4 | VERSION="22.10 (Kinetic Kudu)" 5 | VERSION_CODENAME=kinetic 6 | ID=ubuntu 7 | ID_LIKE=debian 8 | HOME_URL="https://www.ubuntu.com/" 9 | SUPPORT_URL="https://help.ubuntu.com/" 10 | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" 11 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 12 | UBUNTU_CODENAME=kinetic 13 | LOGO=ubuntu-logo 14 | -------------------------------------------------------------------------------- /helpers/tracelisten.go: -------------------------------------------------------------------------------- 1 | // Deprecated: helpers package is deprecated and will be removed. 2 | // See https://github.com/aquasecurity/tracee/pull/4090 3 | package helpers 4 | 5 | import ( 6 | "bufio" 7 | "fmt" 8 | "os" 9 | ) 10 | 11 | // TracePipeListen reads data from the trace pipe that bpf_trace_printk() writes to, 12 | // (/sys/kernel/debug/tracing/trace_pipe). 13 | // It writes the data to stdout. The pipe is global, so this function is not 14 | // associated with any BPF program. It is recommended to use bpf_trace_printk() 15 | // and this function for debug purposes only. 16 | // This is a blocking function intended to be called from a goroutine. 17 | func TracePipeListen() error { 18 | f, err := os.Open("/sys/kernel/debug/tracing/trace_pipe") 19 | if err != nil { 20 | return fmt.Errorf("failed to open trace pipe: %w", err) 21 | } 22 | defer f.Close() 23 | 24 | r := bufio.NewReader(f) 25 | b := make([]byte, 1024) 26 | 27 | for { 28 | l, err := r.Read(b) 29 | if err != nil { 30 | return fmt.Errorf("failed to read from trace pipe: %w", err) 31 | } 32 | 33 | s := string(b[:l]) 34 | fmt.Println(s) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /libbpf_cb.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | import ( 4 | "C" 5 | "unsafe" 6 | ) 7 | 8 | // revive:disable 9 | 10 | // This callback definition needs to be in a different file from where it is declared in C 11 | // Otherwise, multiple definition compilation error will occur 12 | 13 | //export perfCallback 14 | func perfCallback(ctx unsafe.Pointer, cpu C.int, data unsafe.Pointer, size C.int) { 15 | pb := eventChannels.get(uint(uintptr(ctx))).(*PerfBuffer) 16 | pb.eventsChan <- C.GoBytes(data, size) 17 | } 18 | 19 | //export perfLostCallback 20 | func perfLostCallback(ctx unsafe.Pointer, cpu C.int, cnt C.ulonglong) { 21 | pb := eventChannels.get(uint(uintptr(ctx))).(*PerfBuffer) 22 | if pb.lostChan != nil { 23 | pb.lostChan <- uint64(cnt) 24 | } 25 | } 26 | 27 | //export ringbufferCallback 28 | func ringbufferCallback(ctx unsafe.Pointer, data unsafe.Pointer, size C.int) C.int { 29 | ch := eventChannels.get(uint(uintptr(ctx))).(chan []byte) 30 | ch <- C.GoBytes(data, size) 31 | 32 | return C.int(0) 33 | } 34 | 35 | // revive:enable 36 | -------------------------------------------------------------------------------- /link-reader.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | import "syscall" 10 | 11 | // 12 | // BPFLinkReader 13 | // 14 | 15 | // BPFLinkReader read data from a BPF link 16 | type BPFLinkReader struct { 17 | l *BPFLink 18 | fd int 19 | } 20 | 21 | func (i *BPFLinkReader) Read(p []byte) (n int, err error) { 22 | return syscall.Read(i.fd, p) 23 | } 24 | 25 | func (i *BPFLinkReader) Close() error { 26 | return syscall.Close(i.fd) 27 | } 28 | -------------------------------------------------------------------------------- /logger_cb.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "fmt" 10 | "os" 11 | ) 12 | 13 | // This callback definition needs to be in a different file from where it is 14 | // declared in C Otherwise, multiple definition compilation error will occur 15 | 16 | // loggerCallback is called by libbpf_print_fn() which in turn is called by 17 | // libbpf 18 | // 19 | // revive:disable 20 | // 21 | //export loggerCallback 22 | func loggerCallback(libbpfPrintLevel int, libbpfOutput *C.char) { 23 | goOutput := C.GoString(libbpfOutput) 24 | 25 | for _, fnFilterOut := range callbacks.LogFilters { 26 | if fnFilterOut != nil { 27 | if fnFilterOut(libbpfPrintLevel, goOutput) { 28 | return 29 | } 30 | } 31 | } 32 | 33 | // pass received output to callback, leaving formatting to consumer 34 | callbacks.Log(libbpfPrintLevel, goOutput) 35 | } 36 | 37 | const ( 38 | // libbpf print levels 39 | LibbpfWarnLevel = int(C.LIBBPF_WARN) 40 | LibbpfInfoLevel = int(C.LIBBPF_INFO) 41 | LibbpfDebugLevel = int(C.LIBBPF_DEBUG) 42 | ) 43 | 44 | // Callbacks stores the callbacks to be used by libbpfgo 45 | type Callbacks struct { 46 | Log func(level int, msg string) 47 | LogFilters []func(libLevel int, msg string) bool 48 | } 49 | 50 | // callbacks is initialized with default callbacks, but can be changed by SetLoggerCbs 51 | var callbacks = Callbacks{ 52 | Log: logFallback, 53 | LogFilters: []func(libLevel int, msg string) bool{}, 54 | } 55 | 56 | // SetLoggerCbs receives Callbacks type to be used to log libbpf outputs and to filter out those outputs 57 | func SetLoggerCbs(cbs Callbacks) { 58 | if cbs.Log == nil { // guarantee that there is always an outputter 59 | cbs.Log = logFallback 60 | } 61 | 62 | callbacks = cbs 63 | } 64 | 65 | // logFallback is the default logger callback 66 | // - level is ignored 67 | func logFallback(level int, msg string) { 68 | fmt.Fprint(os.Stderr, msg) 69 | } 70 | 71 | // revive:enable 72 | -------------------------------------------------------------------------------- /logger_cb_test.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "os" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestLogFallback(t *testing.T) { 14 | tt := []struct { 15 | message string 16 | }{ 17 | { 18 | message: "This is a warning message", 19 | }, 20 | { 21 | message: "This is a information message", 22 | }, 23 | { 24 | message: "This is a debug message", 25 | }, 26 | } 27 | 28 | for _, tc := range tt { 29 | var buf bytes.Buffer 30 | 31 | r, w, err := os.Pipe() 32 | require.NoError(t, err, "failed to create pipe") 33 | 34 | writeEnd := os.NewFile(uintptr(w.Fd()), "pipe") 35 | 36 | oldStderr := os.Stderr 37 | os.Stderr = writeEnd 38 | 39 | // level is ignored 40 | logFallback(LibbpfInfoLevel, tc.message) 41 | 42 | os.Stderr = oldStderr 43 | 44 | err = writeEnd.Close() 45 | require.NoError(t, err, "failed to close writeEnd") 46 | _, err = io.Copy(&buf, r) 47 | require.NoError(t, err, "failed to copy from read end to buffer") 48 | 49 | assert.Equal(t, tc.message, buf.String()) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /map-iterator.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | // 15 | // BPFMapIterator (low-level API) 16 | // 17 | 18 | // BPFMapIterator iterates over keys in a BPF map. 19 | type BPFMapIterator struct { 20 | mapFD int 21 | keySize int 22 | err error 23 | prev []byte 24 | next []byte 25 | } 26 | 27 | // Next advances the iterator to the next key in the map. 28 | func (it *BPFMapIterator) Next() bool { 29 | if it.err != nil { 30 | return false 31 | } 32 | 33 | prevPtr := unsafe.Pointer(nil) 34 | if it.next != nil { 35 | prevPtr = unsafe.Pointer(&it.next[0]) 36 | } 37 | 38 | next := make([]byte, it.keySize) 39 | nextPtr := unsafe.Pointer(&next[0]) 40 | 41 | retC := C.bpf_map_get_next_key(C.int(it.mapFD), prevPtr, nextPtr) 42 | if retC < 0 { 43 | if err := syscall.Errno(-retC); err != syscall.ENOENT { 44 | it.err = err 45 | } 46 | 47 | return false 48 | } 49 | 50 | it.prev = it.next 51 | it.next = next 52 | 53 | return true 54 | } 55 | 56 | // Key returns the current key value of the iterator, if the most recent call 57 | // to Next returned true. 58 | // The slice is valid only until the next call to Next. 59 | func (it *BPFMapIterator) Key() []byte { 60 | return it.next 61 | } 62 | 63 | // Err returns the last error that ocurred while table.Iter or iter.Next. 64 | func (it *BPFMapIterator) Err() error { 65 | return it.err 66 | } 67 | -------------------------------------------------------------------------------- /misc.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | // 10 | // Misc generic helpers 11 | // 12 | 13 | // roundUp rounds x up to the nearest multiple of y. 14 | func roundUp(x, y uint64) uint64 { 15 | return ((x + (y - 1)) / y) * y 16 | } 17 | -------------------------------------------------------------------------------- /module-iterator.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | // 10 | // BPFObjectIterator (Module Iterator) 11 | // 12 | 13 | // BPFObjectProgramIterator iterates over programs and maps in a BPF object 14 | type BPFObjectIterator struct { 15 | m *Module 16 | prevProg *BPFProg 17 | prevMap *BPFMap 18 | } 19 | 20 | func (it *BPFObjectIterator) NextMap() *BPFMap { 21 | var startMapC *C.struct_bpf_map 22 | if it.prevMap != nil && it.prevMap.bpfMap != nil { 23 | startMapC = it.prevMap.bpfMap 24 | } 25 | 26 | bpfMapC, errno := C.bpf_object__next_map(it.m.obj, startMapC) 27 | if bpfMapC == nil { 28 | _ = errno // intentionally ignored 29 | return nil 30 | } 31 | 32 | bpfMap := &BPFMap{ 33 | bpfMap: bpfMapC, 34 | module: it.m, 35 | } 36 | it.prevMap = bpfMap 37 | 38 | if !bpfMap.module.loaded { 39 | bpfMap.bpfMapLow = &BPFMapLow{ 40 | fd: -1, 41 | info: &BPFMapInfo{}, 42 | } 43 | 44 | return bpfMap 45 | } 46 | 47 | fd := bpfMap.FileDescriptor() 48 | info, err := GetMapInfoByFD(fd) 49 | if err != nil { 50 | return nil 51 | } 52 | 53 | bpfMap.bpfMapLow = &BPFMapLow{ 54 | fd: fd, 55 | info: info, 56 | } 57 | 58 | return bpfMap 59 | } 60 | 61 | func (it *BPFObjectIterator) NextProgram() *BPFProg { 62 | var startProg *C.struct_bpf_program 63 | if it.prevProg != nil && it.prevProg.prog != nil { 64 | startProg = it.prevProg.prog 65 | } 66 | 67 | progC, errno := C.bpf_object__next_program(it.m.obj, startProg) 68 | if progC == nil { 69 | _ = errno // intentionally ignored 70 | return nil 71 | } 72 | 73 | prog := &BPFProg{ 74 | prog: progC, 75 | module: it.m, 76 | } 77 | 78 | it.prevProg = prog 79 | 80 | return prog 81 | } 82 | -------------------------------------------------------------------------------- /rwArray.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type slot struct { 8 | value interface{} 9 | used bool 10 | } 11 | 12 | // rwArray allows for multiple concurrent readers but 13 | // only a single writer. The writers lock a mutex while the readers 14 | // are lock free. 15 | // It is implemented as an array of slots where each slot holds a 16 | // value (of type interface{}) and a boolean marker to indicate if it's 17 | // in use or not. The insertion (Put) performs a linear probe 18 | // looking for an available slot as indicated by the in-use marker. 19 | // While probing, it is not touching the value itself, as it's 20 | // being read without a lock by the readers. 21 | type rwArray struct { 22 | slots []slot 23 | mux sync.Mutex 24 | } 25 | 26 | func newRWArray(capacity uint) rwArray { 27 | return rwArray{ 28 | slots: make([]slot, capacity), 29 | } 30 | } 31 | 32 | func (a *rwArray) put(v interface{}) int { 33 | a.mux.Lock() 34 | defer a.mux.Unlock() 35 | 36 | limit := len(a.slots) 37 | 38 | for i := 0; i < limit; i++ { 39 | if !a.slots[i].used { 40 | a.slots[i].value = v 41 | a.slots[i].used = true 42 | 43 | return i 44 | } 45 | } 46 | 47 | return -1 48 | } 49 | 50 | func (a *rwArray) remove(index uint) { 51 | a.mux.Lock() 52 | defer a.mux.Unlock() 53 | 54 | if int(index) >= len(a.slots) { 55 | return 56 | } 57 | 58 | a.slots[index].value = nil 59 | a.slots[index].used = false 60 | } 61 | 62 | func (a *rwArray) get(index uint) interface{} { 63 | if int(index) >= len(a.slots) { 64 | return nil 65 | } 66 | 67 | // N.B. If slot[index].used == false, this is technically 68 | // a race since put() might be putting the value in there 69 | // at the same time. 70 | return a.slots[index].value 71 | } 72 | 73 | func (a *rwArray) capacity() uint { 74 | return uint(len(a.slots)) 75 | } 76 | -------------------------------------------------------------------------------- /selftest/attachgenericfd/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/attachgenericfd/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/attachgenericfd 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | require golang.org/x/sys v0.25.0 8 | 9 | replace github.com/aquasecurity/libbpfgo => ../../ 10 | -------------------------------------------------------------------------------- /selftest/attachgenericfd/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 8 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 12 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 13 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 14 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 15 | -------------------------------------------------------------------------------- /selftest/attachgenericfd/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_SOCKMAP); 10 | __uint(max_entries, 1); 11 | __type(key, int); 12 | __type(value, int); 13 | } sock_map_rx SEC(".maps"); 14 | 15 | SEC("sk_skb/stream_parser") 16 | int bpf_prog_parser(struct __sk_buff *skb) 17 | { 18 | return skb->len; 19 | } 20 | 21 | SEC("sk_skb/stream_verdict") 22 | int bpf_prog_verdict(struct __sk_buff *skb) 23 | { 24 | int idx = 0; 25 | return bpf_sk_redirect_map(skb, &sock_map_rx, idx, 0); 26 | } 27 | 28 | char LICENSE[] SEC("license") = "GPL"; 29 | -------------------------------------------------------------------------------- /selftest/attachgenericfd/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=15 # seconds 7 | 8 | # COMMON 9 | 10 | COMMON="$(dirname $0)/../common/common.sh" 11 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 12 | 13 | # MAIN 14 | 15 | kern_version ge 5.8 16 | 17 | check_build 18 | check_ppid 19 | test_exec 20 | test_finish 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /selftest/build/Makefile: -------------------------------------------------------------------------------- 1 | BASEDIR = $(abspath ../../) 2 | 3 | OUTPUT = ../../output 4 | 5 | CC = gcc 6 | CLANG = clang 7 | 8 | CFLAGS = -g -O2 -Wall -fpie 9 | LDFLAGS = 10 | ARCH := $(shell uname -m | sed 's/x86_64/amd64/g; s/aarch64/arm64/g') 11 | 12 | TEST = libbpfgo_test 13 | 14 | all: $(TEST).bpf.o 15 | 16 | ## main tree dependency 17 | 18 | outputdir: 19 | $(MAKE) -C $(BASEDIR) outputdir 20 | 21 | ## test bpf dependency 22 | 23 | $(TEST).bpf.o: $(TEST).bpf.c 24 | $(CLANG) $(CFLAGS) -target bpf -D__TARGET_ARCH_$(ARCH) -I$(OUTPUT) -I$(abspath ../common) -c $< -o $@ 25 | 26 | ## clean 27 | 28 | clean: 29 | rm -f *.o 30 | -------------------------------------------------------------------------------- /selftest/build/libbpfgo_test.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 9 | 10 | struct { 11 | __uint(type, BPF_MAP_TYPE_HASH); 12 | __type(key, u32); 13 | __type(value, u32); 14 | __uint(max_entries, 1 << 24); 15 | } tester SEC(".maps"); 16 | 17 | SEC("tp/syscalls/sys_enter_dup") 18 | int tracepoint__sys_enter_dup(struct trace_event_raw_sys_enter *args) 19 | { 20 | return 0; 21 | } 22 | 23 | SEC("raw_tp/sched_switch") 24 | int raw_tracepoint__sched_switch(struct bpf_raw_tracepoint_args *args) 25 | { 26 | return 0; 27 | } 28 | 29 | SEC("kprobe/get_task_pid") 30 | int kprobe__get_task_pid(struct pt_regs *ctx) 31 | { 32 | return 0; 33 | } 34 | 35 | SEC("kretprobe/get_task_pid") 36 | int kretprobe__get_task_pid(struct pt_regs *ctx) 37 | { 38 | return 0; 39 | } 40 | 41 | SEC("lsm/socket_connect") 42 | int BPF_PROG(socket_connect, struct socket *sock, struct sockaddr *address, int addrlen) 43 | { 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /selftest/cgroup-legacy/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/cgroup-legacy/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/cgroup-legacy 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/cgroup-legacy/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/cgroup-legacy/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | struct { 10 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 11 | __uint(max_entries, 1024); 12 | __uint(key_size, sizeof(u32)); 13 | __uint(value_size, sizeof(u32)); 14 | } perfbuffer SEC(".maps"); 15 | 16 | SEC("cgroup_skb/ingress") 17 | int cgroup__skb_ingress(struct __sk_buff *ctx) 18 | { 19 | if (ctx->protocol != bpf_htons(ETH_P_IP)) // ethernet (IP) only 20 | return 1; 21 | 22 | struct bpf_sock *sk = ctx->sk; 23 | if (!sk) { 24 | bpf_printk("ERROR: cgroup_skb/ingress: could not get bpf_sock"); 25 | return 1; 26 | } 27 | 28 | sk = bpf_sk_fullsock(sk); 29 | if (!sk) { 30 | bpf_printk("ERROR: cgroup_skb/ingress: could not get full bpf_sock"); 31 | return 1; 32 | } 33 | 34 | struct iphdr ip = {0}; 35 | struct icmphdr icmp = {0}; 36 | 37 | u32 s_iphdr = bpf_core_type_size(struct iphdr); 38 | u32 s_icmphdr = bpf_core_type_size(struct icmphdr); 39 | 40 | if (bpf_skb_load_bytes_relative(ctx, 0, &ip, s_iphdr, BPF_HDR_START_NET)) 41 | return 1; 42 | 43 | // clang-format off 44 | 45 | switch (ip.protocol) { 46 | case IPPROTO_ICMP: 47 | if (bpf_skb_load_bytes_relative(ctx, 48 | s_iphdr, 49 | &icmp, 50 | s_icmphdr, 51 | BPF_HDR_START_NET)) 52 | return 1; 53 | 54 | u32 bleh = 20220823; 55 | bpf_perf_event_output(ctx, 56 | &perfbuffer, 57 | BPF_F_CURRENT_CPU, 58 | &bleh, 59 | sizeof(bleh)); 60 | break; 61 | } 62 | 63 | // clang-format on 64 | 65 | return 1; 66 | } 67 | 68 | char LICENSE[] SEC("license") = "GPL"; 69 | -------------------------------------------------------------------------------- /selftest/cgroup-legacy/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-warn-bt-5.4.sh -------------------------------------------------------------------------------- /selftest/cgroup/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/cgroup/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/cgroup 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/cgroup/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/cgroup/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_RINGBUF); 9 | __uint(max_entries, 1 << 24); 10 | } events SEC(".maps"); 11 | long ringbuffer_flags = 0; 12 | 13 | SEC("cgroup/sock") 14 | int cgroup__sock(struct bpf_sock *sk) 15 | { 16 | int *process; 17 | 18 | // Reserve space on the ringbuffer for the sample 19 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 20 | if (!process) { 21 | return 1; 22 | } 23 | 24 | *process = 2021; 25 | 26 | bpf_ringbuf_submit(process, ringbuffer_flags); 27 | return 1; 28 | } 29 | 30 | char LICENSE[] SEC("license") = "GPL"; 31 | -------------------------------------------------------------------------------- /selftest/cgroup/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/common/.gitignore: -------------------------------------------------------------------------------- 1 | scx -------------------------------------------------------------------------------- /selftest/common/run-4.12.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | # COMMON 9 | 10 | COMMON="$(dirname $0)/../common/common.sh" 11 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 12 | 13 | # MAIN 14 | 15 | kern_version gt 4.12 16 | 17 | check_build 18 | check_ppid 19 | test_exec 20 | test_finish 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /selftest/common/run-5.8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | # COMMON 9 | 10 | COMMON="$(dirname $0)/../common/common.sh" 11 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 12 | 13 | # MAIN 14 | 15 | kern_version ge 5.8 16 | 17 | check_build 18 | check_ppid 19 | test_exec 20 | test_finish 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /selftest/common/run-6.1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | # COMMON 9 | 10 | COMMON="$(dirname $0)/../common/common.sh" 11 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 12 | 13 | # MAIN 14 | 15 | kern_version ge 6.1 16 | 17 | check_build 18 | check_ppid 19 | test_exec 20 | test_finish 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /selftest/common/run-vm-stage2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # COMMON 4 | 5 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 6 | 7 | # MAIN 8 | 9 | check_build 10 | # check_ppid # not needed for VM 11 | test_exec 12 | test_finish 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /selftest/common/run-warn-bt-5.4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | # COMMON 9 | 10 | COMMON="$(dirname $0)/../common/common.sh" 11 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 12 | 13 | # MAIN 14 | 15 | kern_version le 5.4 1 # 1 == not fatal (skip if greater or equal to 5.4) 16 | 17 | check_build 18 | check_ppid 19 | test_exec 20 | test_finish 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /selftest/common/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | # COMMON 9 | 10 | COMMON="$(dirname $0)/../common/common.sh" 11 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 12 | 13 | # MAIN 14 | 15 | kern_version gt 4.18 16 | 17 | check_build 18 | check_ppid 19 | test_exec 20 | test_finish 21 | 22 | exit 0 23 | -------------------------------------------------------------------------------- /selftest/common/vmlinux_missing.h: -------------------------------------------------------------------------------- 1 | #ifndef __VMLINUX_MISSING_H__ 2 | #define __VMLINUX_MISSING_H__ 3 | ; 4 | ; // don't remove: clangd parsing bug https://github.com/clangd/clangd/issues/1167 5 | #pragma clang attribute push(__attribute__((preserve_access_index)), apply_to = record) 6 | 7 | #ifdef asm_inline 8 | #undef asm_inline 9 | #define asm_inline asm 10 | #endif 11 | 12 | #pragma clang attribute pop 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /selftest/create-map/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/create-map/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/create-map 2 | 3 | go 1.21 4 | 5 | replace github.com/aquasecurity/libbpfgo => ../../ 6 | 7 | require github.com/aquasecurity/libbpfgo v0.0.0 8 | -------------------------------------------------------------------------------- /selftest/create-map/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/create-map/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | SEC("kprobe/sys_execve") 8 | int kprobe__sys_execve(struct pt_regs *ctx) 9 | { 10 | return 0; 11 | } 12 | 13 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 14 | -------------------------------------------------------------------------------- /selftest/create-map/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "fmt" 7 | "log" 8 | "os" 9 | "unsafe" 10 | 11 | bpf "github.com/aquasecurity/libbpfgo" 12 | ) 13 | 14 | // CreateMap uses `bpf_map_create()`, a 'low-level' API in libbpf 15 | // As such, it does not have access to the higher level APIs in 16 | // libbpf, which are denoted by starting with `bpf_map__*`. 17 | 18 | // As such, you can use bpf_map_create() to populate arrays of maps 19 | // in userspace, then iterate over those arrays on the bpf side, and 20 | // use them as a normal map there as those operations only require 21 | // a file descriptor. 22 | 23 | // You can update values in the map from userspace, but currently 24 | // can't retrieve values outright. 25 | 26 | // For example: 27 | // https://elixir.bootlin.com/linux/latest/source/samples/bpf/fds_example.c 28 | // https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/bpf/test_maps.c 29 | // https://lore.kernel.org/bpf/CAO658oWagXsQDeFtRA2vZBzov7cwwVNTs5nHE9fMGrMOs6bbpQ@mail.gmail.com/ 30 | 31 | func main() { 32 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 33 | if err != nil { 34 | fmt.Fprintln(os.Stderr, err) 35 | os.Exit(-1) 36 | } 37 | defer bpfModule.Close() 38 | 39 | bpfModule.BPFLoadObject() 40 | 41 | m, err := bpf.CreateMap(bpf.MapTypeHash, "foobar", 4, 4, 420, nil) 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | key1 := uint32(1) 47 | value1 := uint32(55) 48 | key1Unsafe := unsafe.Pointer(&key1) 49 | value1Unsafe := unsafe.Pointer(&value1) 50 | err = m.Update(key1Unsafe, value1Unsafe) 51 | if err != nil { 52 | log.Fatal(err) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /selftest/create-map/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/error-handling/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/error-handling/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/error-handling 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/error-handling/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/error-handling/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | SEC("kprobe/sys_mmap") 8 | int kprobe__sys_mmap(struct pt_regs *ctx) 9 | { 10 | return 0; 11 | } 12 | 13 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 14 | -------------------------------------------------------------------------------- /selftest/error-handling/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "errors" 7 | "os" 8 | "syscall" 9 | 10 | "fmt" 11 | 12 | bpf "github.com/aquasecurity/libbpfgo" 13 | ) 14 | 15 | func main() { 16 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 17 | if err != nil { 18 | fmt.Fprintln(os.Stderr, err) 19 | os.Exit(-1) 20 | } 21 | defer bpfModule.Close() 22 | 23 | bpfModule.BPFLoadObject() 24 | 25 | // non-existant program 26 | _, err = bpfModule.GetProgram("NewYorkYankeesRule") 27 | if err == nil { 28 | fmt.Fprintln(os.Stderr, "undetected error, non-existant program") 29 | os.Exit(-1) 30 | } 31 | if !errors.Is(err, syscall.ENOENT) { 32 | fmt.Fprintf(os.Stderr, "unexpected wrapped error received, expected ENOENT\n") 33 | os.Exit(-1) 34 | } 35 | 36 | // non-existant map 37 | _, err = bpfModule.GetMap("Ih8BostonRedSox") 38 | if err == nil { 39 | fmt.Fprintln(os.Stderr, "undetected error, non-existant map") 40 | os.Exit(-1) 41 | } 42 | if !errors.Is(err, syscall.ENOENT) { 43 | fmt.Fprintf(os.Stderr, "unexpected wrapped error received, expected ENOENT\n") 44 | os.Exit(-1) 45 | } 46 | 47 | // invalid tc hook 48 | tchook := bpfModule.TcHookInit() 49 | err = tchook.Create() 50 | if err == nil { 51 | fmt.Fprintln(os.Stderr, "undetected error, invalid tchook create arguments") 52 | os.Exit(-1) 53 | } 54 | if !errors.Is(err, syscall.EINVAL) { 55 | fmt.Fprintf(os.Stderr, "unexpected wrapped error received, expected EINVAL\n") 56 | os.Exit(-1) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /selftest/error-handling/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/getbtffdbyid/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/getbtffdbyid/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/getbtffdbyid 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/getbtffdbyid/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/getbtffdbyid/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_ARRAY); 9 | __uint(max_entries, 1); 10 | __type(key, __u32); 11 | __type(value, __u32); 12 | } inner_array_proto SEC(".maps"); 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/getbtffdbyid/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "log" 7 | "unsafe" 8 | 9 | bpf "github.com/aquasecurity/libbpfgo" 10 | ) 11 | 12 | func main() { 13 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 14 | if err != nil { 15 | log.Fatal(err) 16 | } 17 | defer bpfModule.Close() 18 | 19 | err = bpfModule.BPFLoadObject() 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | // Use the "inner_array_proto" map BTF ID to create a new map with the same 25 | // BTF type. 26 | innerArrayProto, err := bpfModule.GetMap("inner_array_proto") 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | optsProto, err := bpf.GetMapInfoByFD(innerArrayProto.FileDescriptor()) 32 | if err != nil { 33 | log.Fatal(err) 34 | } 35 | 36 | // The "inner_array_proto" map is a BTF map, so its ID can be used to create 37 | // a new map with the same BTF type. 38 | btfFD, err := bpf.GetBTFFDByID(optsProto.BTFID) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | createOpts := &bpf.BPFMapCreateOpts{ 44 | BTFFD: uint32(btfFD), 45 | } 46 | innerArray, err := bpf.CreateMap(bpf.MapTypeArray, "inner_array", 4, 4, 1, createOpts) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | 51 | // Save an element in the "inner_array" map. 52 | key := uint32(0) // index 0 53 | keyUnsafe := unsafe.Pointer(&key) 54 | value := uint32(191711) 55 | valueUnsafe := unsafe.Pointer(&value) 56 | err = innerArray.Update(keyUnsafe, valueUnsafe) 57 | if err != nil { 58 | log.Fatal(err) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /selftest/getbtffdbyid/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/global-variable/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/global-variable/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/global-variable 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/global-variable/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/global-variable/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_RINGBUF); 9 | __uint(max_entries, 1 << 24); 10 | } events SEC(".maps"); 11 | 12 | struct config_t { 13 | u64 a; 14 | char c[6]; 15 | }; 16 | 17 | struct event_t { 18 | u64 sum; 19 | char c[6]; 20 | }; 21 | 22 | const volatile u32 abc = 1; 23 | const volatile u32 efg = 2; 24 | const volatile struct config_t foobar = {}; 25 | const volatile long foo = 3; 26 | volatile int bar = 4; 27 | const volatile int baz SEC(".rodata.baz") = 5; 28 | const volatile int qux SEC(".data.qux") = 6; 29 | 30 | long ringbuffer_flags = 0; 31 | 32 | SEC("kprobe/sys_mmap") 33 | int kprobe__sys_mmap(struct pt_regs *ctx) 34 | { 35 | struct event_t *event; 36 | int i; 37 | 38 | // Reserve space on the ringbuffer for the sample 39 | event = bpf_ringbuf_reserve(&events, sizeof(*event), ringbuffer_flags); 40 | if (!event) { 41 | return 1; 42 | } 43 | 44 | event->sum = abc + efg + foobar.a + foo + bar + baz + qux; 45 | for (i = 0; i < sizeof(foobar.c); i++) { 46 | event->c[i] = foobar.c[i]; 47 | } 48 | 49 | bpf_ringbuf_submit(event, ringbuffer_flags); 50 | return 1; 51 | } 52 | 53 | char LICENSE[] SEC("license") = "GPL"; 54 | -------------------------------------------------------------------------------- /selftest/global-variable/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/iter/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/iter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/iter 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/iter/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/iter/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | SEC("iter/task") 8 | int iter__task(struct bpf_iter__task *ctx) 9 | { 10 | struct seq_file *seq = ctx->meta->seq; 11 | struct task_struct *task = ctx->task; 12 | if (task == NULL) 13 | return 0; 14 | 15 | BPF_SEQ_PRINTF(seq, "%d\t%d\t%s\n", task->parent->pid, task->pid, task->comm); 16 | return 0; 17 | } 18 | 19 | char LICENSE[] SEC("license") = "GPL"; 20 | -------------------------------------------------------------------------------- /selftest/iter/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "bufio" 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "strconv" 11 | "strings" 12 | "syscall" 13 | "time" 14 | 15 | bpf "github.com/aquasecurity/libbpfgo" 16 | ) 17 | 18 | func exitWithErr(err error) { 19 | fmt.Fprintln(os.Stderr, err) 20 | os.Exit(-1) 21 | } 22 | 23 | func main() { 24 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 25 | if err != nil { 26 | exitWithErr(err) 27 | } 28 | defer bpfModule.Close() 29 | 30 | err = bpfModule.BPFLoadObject() 31 | if err != nil { 32 | exitWithErr(err) 33 | } 34 | 35 | prog, err := bpfModule.GetProgram("iter__task") 36 | if err != nil { 37 | exitWithErr(err) 38 | } 39 | 40 | link, err := prog.AttachIter(bpf.IterOpts{}) 41 | if err != nil { 42 | exitWithErr(err) 43 | } 44 | 45 | reader, err := link.Reader() 46 | if err != nil { 47 | exitWithErr(err) 48 | } 49 | defer reader.Close() 50 | 51 | totalExecs := 10 52 | thisPid := syscall.Getpid() 53 | pids := make(map[int]*os.Process, 0) 54 | for i := 0; i < totalExecs; i++ { 55 | cmd := exec.Command("ping", "-c1", "-w1", "0.0.0.0") 56 | err := cmd.Start() 57 | if err != nil { 58 | exitWithErr(err) 59 | } 60 | pids[cmd.Process.Pid] = cmd.Process 61 | } 62 | 63 | time.Sleep(5 * time.Second) 64 | 65 | numberOfMatches := 0 66 | scanner := bufio.NewScanner(reader) 67 | for scanner.Scan() { 68 | fields := strings.Split(scanner.Text(), "\t") 69 | if len(fields) != 3 { 70 | fmt.Fprintf(os.Stderr, "invalid data retrieved\n") 71 | } 72 | if fields[2] == "ping" { 73 | ppid, err := strconv.Atoi(fields[0]) 74 | if err != nil { 75 | exitWithErr(err) 76 | } 77 | pid, err := strconv.Atoi(fields[1]) 78 | if err != nil { 79 | exitWithErr(err) 80 | } 81 | if proc, found := pids[pid]; found { 82 | if ppid == thisPid { 83 | numberOfMatches++ 84 | proc.Kill() 85 | } 86 | } 87 | } 88 | if numberOfMatches == totalExecs { 89 | break 90 | } 91 | } 92 | if numberOfMatches != totalExecs { 93 | err := fmt.Errorf("expect numberOfMatches == %d but got %d", totalExecs, numberOfMatches) 94 | exitWithErr(err) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /selftest/iter/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/iterators/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/iterators/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/iterators 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/iterators/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/iterators/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 8 | 9 | struct { 10 | __uint(max_entries, 5); 11 | __uint(type, BPF_MAP_TYPE_HASH); 12 | __type(key, u32); 13 | __type(value, u32); 14 | } numbers SEC(".maps"); 15 | -------------------------------------------------------------------------------- /selftest/iterators/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "fmt" 8 | "os" 9 | "unsafe" 10 | 11 | bpf "github.com/aquasecurity/libbpfgo" 12 | ) 13 | 14 | const ( 15 | iteratorMax uint32 = 5 16 | added uint32 = 1 17 | checked uint32 = 2 18 | ) 19 | 20 | var one = 1 21 | 22 | func main() { 23 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 24 | if err != nil { 25 | fmt.Fprintln(os.Stderr, err) 26 | os.Exit(-1) 27 | } 28 | defer bpfModule.Close() 29 | bpfModule.BPFLoadObject() 30 | 31 | numbers, err := bpfModule.GetMap("numbers") 32 | if err != nil { 33 | fmt.Fprintln(os.Stderr, err) 34 | os.Exit(-1) 35 | } 36 | 37 | testMap := map[uint32]uint32{} 38 | var i uint32 39 | for i = 0; i < iteratorMax; i++ { 40 | testMap[i] = added 41 | index := unsafe.Pointer(&i) 42 | value := unsafe.Pointer(&one) 43 | err = numbers.Update(index, value) 44 | if err != nil { 45 | fmt.Fprintln(os.Stderr, err) 46 | os.Exit(-1) 47 | } 48 | } 49 | 50 | iterator := numbers.Iterator() 51 | for iterator.Next() { 52 | keyBytes := iterator.Key() 53 | key := determineHostByteOrder().Uint32(keyBytes) 54 | 55 | val, ok := testMap[key] 56 | if !ok { 57 | fmt.Fprintln(os.Stderr, "Unknown key was found: %d", val) 58 | os.Exit(-1) 59 | } 60 | if val != 1 { 61 | fmt.Fprintln(os.Stderr, "Corrupted value: %d", val) 62 | os.Exit(-1) 63 | } 64 | testMap[key] = checked 65 | } 66 | if iterator.Err() != nil { 67 | fmt.Fprintf(os.Stderr, "iterator error: %v\n", iterator.Err()) 68 | os.Exit(-1) 69 | } 70 | 71 | // make sure it got everything 72 | for k, v := range testMap { 73 | if v != 2 { 74 | fmt.Fprintln(os.Stderr, "Key was not found: ", k) 75 | os.Exit(-1) 76 | } 77 | } 78 | } 79 | 80 | func determineHostByteOrder() binary.ByteOrder { 81 | var i int32 = 0x01020304 82 | u := unsafe.Pointer(&i) 83 | pb := (*byte)(u) 84 | b := *pb 85 | if b == 0x04 { 86 | return binary.LittleEndian 87 | } 88 | 89 | return binary.BigEndian 90 | } 91 | -------------------------------------------------------------------------------- /selftest/iterators/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/log-callbacks/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/log-callbacks/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/log-callbacks 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/log-callbacks/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/log-callbacks/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | SEC("kprobe/sys_mmap") 8 | int kprobe__sys_mmap(struct pt_regs *ctx) 9 | { 10 | return 0; 11 | } 12 | 13 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 14 | -------------------------------------------------------------------------------- /selftest/log-callbacks/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "os" 7 | "strings" 8 | 9 | "fmt" 10 | 11 | bpf "github.com/aquasecurity/libbpfgo" 12 | ) 13 | 14 | var logOutput []string 15 | 16 | // log is a handler to save the log output 17 | func log(level int, msg string) { 18 | logOutput = append(logOutput, msg) 19 | } 20 | 21 | func main() { 22 | // 23 | // Filter example 1: filter out all outputs but containing "found program 'kprobe__sys_mmap'" 24 | // 25 | filterMatch := "found program 'kprobe__sys_mmap'" 26 | bpf.SetLoggerCbs(bpf.Callbacks{ 27 | Log: log, 28 | LogFilters: []func(libLevel int, msg string) bool{ 29 | func(libLevel int, msg string) bool { 30 | return !strings.Contains(msg, filterMatch) 31 | }, 32 | }, 33 | }) 34 | 35 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 36 | if err != nil { 37 | fmt.Fprintln(os.Stderr, err) 38 | os.Exit(-1) 39 | } 40 | bpfModule.Close() 41 | 42 | if len(logOutput) != 1 { 43 | fmt.Fprintln(os.Stderr, fmt.Sprintf("Log output should contain only one output matching the string: %s", filterMatch)) 44 | fmt.Fprintln(os.Stderr, fmt.Sprintf("Log output: %v", logOutput)) 45 | os.Exit(-1) 46 | } 47 | 48 | // clean logOutput 49 | logOutput = []string{} 50 | 51 | // 52 | // Filter example 2: filter out all outputs which level is LibbpfDebugLevel 53 | // 54 | bpf.SetLoggerCbs(bpf.Callbacks{ 55 | Log: log, 56 | LogFilters: []func(libLevel int, msg string) bool{ 57 | func(libLevel int, msg string) bool { 58 | return libLevel == bpf.LibbpfDebugLevel 59 | }, 60 | }, 61 | }) 62 | 63 | bpfModule, err = bpf.NewModuleFromFile("main.bpf.o") 64 | if err != nil { 65 | fmt.Fprintln(os.Stderr, err) 66 | os.Exit(-1) 67 | } 68 | bpfModule.Close() 69 | 70 | if len(logOutput) != 0 { 71 | fmt.Fprintln(os.Stderr, "Log output should be empty") 72 | fmt.Fprintln(os.Stderr, fmt.Sprintf("Log output: %v", logOutput)) 73 | os.Exit(-1) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /selftest/log-callbacks/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-autocreate/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-autocreate/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-autocreate 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-autocreate/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-autocreate/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, ~0U); 9 | } tester SEC(".maps"); 10 | 11 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 12 | -------------------------------------------------------------------------------- /selftest/map-autocreate/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "log" 7 | 8 | bpf "github.com/aquasecurity/libbpfgo" 9 | ) 10 | 11 | func main() { 12 | bpfModuleWithAutocreate, err := bpf.NewModuleFromFile("main.bpf.o") 13 | if err != nil { 14 | log.Fatal(err) 15 | } 16 | defer bpfModuleWithAutocreate.Close() 17 | 18 | testerMapWithAutocreate, err := bpfModuleWithAutocreate.GetMap("tester") 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | 23 | isAutocreate := testerMapWithAutocreate.Autocreate() 24 | if !isAutocreate { 25 | log.Fatal("Autocreate is false") 26 | } 27 | 28 | err = bpfModuleWithAutocreate.BPFLoadObject() 29 | if err == nil { 30 | log.Fatal("Was able to load with a bad type of map") 31 | } 32 | 33 | bpfModuleWithoutAutocreate, err := bpf.NewModuleFromFile("main.bpf.o") 34 | if err != nil { 35 | log.Fatal(err) 36 | } 37 | defer bpfModuleWithoutAutocreate.Close() 38 | 39 | testerMapWithoutAutocreate, err := bpfModuleWithoutAutocreate.GetMap("tester") 40 | if err != nil { 41 | log.Fatal(err) 42 | } 43 | 44 | err = testerMapWithoutAutocreate.SetAutocreate(false) 45 | if err != nil { 46 | log.Fatal(err) 47 | } 48 | 49 | isAutocreate = testerMapWithoutAutocreate.Autocreate() 50 | if isAutocreate { 51 | log.Fatal("Autocreate is true") 52 | } 53 | 54 | err = bpfModuleWithoutAutocreate.BPFLoadObject() 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /selftest/map-autocreate/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-batch/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-batch/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-batch 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-batch/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-batch/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_HASH); 9 | __type(key, u32); 10 | __type(value, u32); 11 | __uint(max_entries, 4); 12 | } tester SEC(".maps"); 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/map-batch/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-getbyid/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-getbyid/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-getbyid 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-getbyid/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-getbyid/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_HASH); 9 | __type(key, u32); 10 | __type(value, u32); 11 | __uint(max_entries, 1); 12 | } tester SEC(".maps"); 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/map-getbyid/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-getfdbyid/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-getfdbyid/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-getfdbyid 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-getfdbyid/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-getfdbyid/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_HASH); 9 | __type(key, u32); 10 | __type(value, u32); 11 | __uint(max_entries, 1); 12 | } tester SEC(".maps"); 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/map-getfdbyid/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-getmapsbyname/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-getmapsbyname/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-getmapsbyname 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-getmapsbyname/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-getmapsbyname/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_ARRAY); 9 | __uint(max_entries, 1); 10 | __uint(key_size, sizeof(u32)); 11 | __uint(value_size, sizeof(u32)); 12 | } test_name SEC(".maps"); 13 | 14 | struct test_struct { 15 | char value[10]; 16 | }; 17 | 18 | struct { 19 | __uint(type, BPF_MAP_TYPE_HASH); 20 | __uint(max_entries, 1); 21 | __type(key, int); 22 | __type(value, struct test_struct); 23 | } test_hash_name SEC(".maps"); 24 | 25 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 26 | -------------------------------------------------------------------------------- /selftest/map-getmapsbyname/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-innerinfo/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-innerinfo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-innerinfo 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-innerinfo/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-innerinfo/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | // https://lore.kernel.org/bpf/20200429002739.48006-4-andriin@fb.com/ 8 | 9 | struct inner_map { 10 | __uint(type, BPF_MAP_TYPE_ARRAY); 11 | __uint(max_entries, 1); 12 | __type(key, __u32); 13 | __type(value, __u32); 14 | } inner_map1 SEC(".maps"), inner_map2 SEC(".maps"); 15 | 16 | struct outer_hash { 17 | __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); 18 | __uint(max_entries, 5); 19 | __uint(key_size, sizeof(__u32)); 20 | __array(values, struct inner_map); 21 | } outer_hash SEC(".maps") = { 22 | .values = 23 | { 24 | [0] = &inner_map2, 25 | [4] = &inner_map1, 26 | }, 27 | }; 28 | 29 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 30 | -------------------------------------------------------------------------------- /selftest/map-innerinfo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "log" 7 | 8 | bpf "github.com/aquasecurity/libbpfgo" 9 | ) 10 | 11 | func main() { 12 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 13 | if err != nil { 14 | log.Fatal(err) 15 | } 16 | defer bpfModule.Close() 17 | 18 | outerHash, err := bpfModule.GetMap("outer_hash") 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | 23 | // Retrieve an inner map prototype information from the outer map. 24 | innerInfo, err := outerHash.InnerMapInfo() 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | if innerInfo.Name != "outer_hash.inner" { 30 | log.Fatal("inner prototype name should be 'outer_hash.inner'") 31 | } 32 | if innerInfo.Type != bpf.MapTypeArray { 33 | log.Fatal("inner prototype type should be MapTypeArray") 34 | } 35 | if innerInfo.MaxEntries != 1 { 36 | log.Fatal("inner prototype max entries should be 1") 37 | } 38 | if innerInfo.KeySize != 4 { 39 | log.Fatal("inner prototype key size should be 4") 40 | } 41 | if innerInfo.ValueSize != 4 { 42 | log.Fatal("inner prototype value size should be 4") 43 | } 44 | if innerInfo.MapFlags != 0 { 45 | log.Fatal("inner prototype map flags should be 0") 46 | } 47 | if innerInfo.IfIndex != 0 { 48 | log.Fatal("inner prototype ifindex should be 0") 49 | } 50 | if innerInfo.MapExtra != 0 { 51 | log.Fatal("inner prototype map extra should be 0") 52 | } 53 | 54 | err = bpfModule.BPFLoadObject() 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | 59 | // Attempting to get inner map prototype information after the 60 | // object is loaded will fail. 61 | _, err = outerHash.InnerMapInfo() 62 | if err == nil { 63 | log.Fatal("should fail after object is loaded") 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /selftest/map-innerinfo/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-keysize/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-keysize/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-keysize 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-keysize/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-keysize/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_HASH); 9 | __type(key, u32); 10 | __type(value, u32); 11 | __uint(max_entries, 1); 12 | } tester SEC(".maps"); 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/map-keysize/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "log" 7 | 8 | bpf "github.com/aquasecurity/libbpfgo" 9 | ) 10 | 11 | func main() { 12 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 13 | if err != nil { 14 | log.Fatal(err) 15 | } 16 | defer bpfModule.Close() 17 | 18 | testerMap, err := bpfModule.GetMap("tester") 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | 23 | keySize := testerMap.KeySize() 24 | if keySize != 4 { 25 | log.Fatal("keySize do not match") 26 | } 27 | 28 | err = testerMap.SetKeySize(8) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | 33 | keySize = testerMap.KeySize() 34 | if keySize != 8 { 35 | log.Fatal("keySize do not match") 36 | } 37 | 38 | bpfModule.BPFLoadObject() 39 | } 40 | -------------------------------------------------------------------------------- /selftest/map-keysize/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-high/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-high/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-of-maps-outer-high-inner-high 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-high/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-high/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_ARRAY); 9 | __uint(max_entries, 1); 10 | __type(key, __u32); 11 | __type(value, __u32); 12 | } inner_array SEC(".maps"); 13 | 14 | struct { 15 | __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); 16 | __uint(max_entries, 1); 17 | __type(key, __u32); 18 | __array(values, typeof(inner_array)); 19 | } outer_hash SEC(".maps") = { 20 | .values = 21 | { 22 | [1917] = &inner_array, 23 | }, 24 | }; 25 | 26 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 27 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-high/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "log" 8 | "unsafe" 9 | 10 | bpf "github.com/aquasecurity/libbpfgo" 11 | ) 12 | 13 | func main() { 14 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | defer bpfModule.Close() 19 | 20 | // Since the outer and inner map definitions are pre-allocated in the 21 | // BPF object, we do not need to do anything before loading the object. 22 | err = bpfModule.BPFLoadObject() 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | 27 | outerHash, err := bpfModule.GetMap("outer_hash") 28 | if err != nil { 29 | log.Fatal(err) 30 | } 31 | 32 | innerArray, err := bpfModule.GetMap("inner_array") 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | 37 | // Retrieve the "inner_array" map ID from the "outer_hash" map, 38 | // using the hash key 1917. 39 | key1 := uint32(1917) 40 | key1Unsafe := unsafe.Pointer(&key1) 41 | innerMapIDBytes, err := outerHash.GetValue(key1Unsafe) 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | // Inner map ID retrieved from the outer map element. 47 | innerMapID := endian().Uint32(innerMapIDBytes) 48 | 49 | // Retrieve the "inner_array" map Info. 50 | innerMapInfo, error := bpf.GetMapInfoByFD(innerArray.FileDescriptor()) 51 | if error != nil { 52 | log.Fatal(error) 53 | } 54 | 55 | // Check if the inner map ID retrieved from the outer map matches the 56 | // inner map ID retrieved directly from the inner map. 57 | if innerMapInfo.ID != innerMapID { 58 | log.Fatal("inner map ID does not match") 59 | } 60 | 61 | // Save an element in the "inner_array" map. 62 | key1 = uint32(0) // index 0 63 | value1 := uint32(191711) 64 | value1Unsafe := unsafe.Pointer(&value1) 65 | err = innerArray.Update(key1Unsafe, value1Unsafe) 66 | if err != nil { 67 | log.Fatal(err) 68 | } 69 | } 70 | 71 | func endian() binary.ByteOrder { 72 | var i int32 = 0x01020304 73 | u := unsafe.Pointer(&i) 74 | pb := (*byte)(u) 75 | b := *pb 76 | if b == 0x04 { 77 | return binary.LittleEndian 78 | } 79 | 80 | return binary.BigEndian 81 | } 82 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-high/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-low/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-low/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-of-maps-outer-high-inner-low 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-low/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-low/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct { 8 | __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); 9 | __uint(max_entries, 1); 10 | __type(key, __u32); 11 | __type(value, __u32); 12 | } outer_hash SEC(".maps"); 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-high-inner-low/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-low-inner-low/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-low-inner-low/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-of-maps-outer-low-inner-low 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-low-inner-low/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-low-inner-low/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 8 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-low-inner-low/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "log" 8 | "unsafe" 9 | 10 | bpf "github.com/aquasecurity/libbpfgo" 11 | ) 12 | 13 | func main() { 14 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | defer bpfModule.Close() 19 | 20 | err = bpfModule.BPFLoadObject() 21 | if err != nil { 22 | log.Fatal(err) 23 | } 24 | 25 | innerArray, err := bpf.CreateMap(bpf.MapTypeArray, "inner_array", 4, 4, 1, nil) 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | 30 | // Create the "outer_hash" map, using the "inner_array" map as a prototype. 31 | opts := bpf.BPFMapCreateOpts{ 32 | InnerMapFD: uint32(innerArray.FileDescriptor()), 33 | } 34 | outerHash, err := bpf.CreateMap(bpf.MapTypeHash, "outer_hash", 4, 4, 1, &opts) 35 | if err != nil { 36 | log.Fatal(err) 37 | } 38 | 39 | // Save the inner map in the "outer_hash" map, using the hash key 1917. 40 | // The value used to save the element is the the inner map file descriptor, 41 | // however the actual saved value is the inner map ID. 42 | key1 := uint32(1917) 43 | key1Unsafe := unsafe.Pointer(&key1) 44 | value1 := uint32(innerArray.FileDescriptor()) // "inner_array" FD. 45 | value1Unsafe := unsafe.Pointer(&value1) 46 | err = outerHash.Update(key1Unsafe, value1Unsafe) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | 51 | // Save an element in the "inner_array" map. 52 | key1 = uint32(0) // index 0 53 | value1 = uint32(191711) 54 | value1Unsafe = unsafe.Pointer(&value1) 55 | err = innerArray.Update(key1Unsafe, value1Unsafe) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | } 60 | 61 | func endian() binary.ByteOrder { 62 | var i int32 = 0x01020304 63 | u := unsafe.Pointer(&i) 64 | pb := (*byte)(u) 65 | b := *pb 66 | if b == 0x04 { 67 | return binary.LittleEndian 68 | } 69 | 70 | return binary.BigEndian 71 | } 72 | -------------------------------------------------------------------------------- /selftest/map-of-maps-outer-low-inner-low/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-pin-info/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-pin-info/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-pin-info 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-pin-info/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-pin-info/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct value { 8 | int x; 9 | char y; 10 | }; 11 | 12 | struct { 13 | __uint(type, BPF_MAP_TYPE_HASH); 14 | __type(key, u32); 15 | __type(value, struct value); 16 | __uint(max_entries, 1 << 10); 17 | } not_pinned_map SEC(".maps"); 18 | 19 | struct { 20 | __uint(type, BPF_MAP_TYPE_HASH); 21 | __type(key, u32); 22 | __type(value, struct value); 23 | __uint(max_entries, 1 << 10); 24 | __uint(pinning, LIBBPF_PIN_BY_NAME); 25 | } pinned_map SEC(".maps"); 26 | 27 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 28 | -------------------------------------------------------------------------------- /selftest/map-pin-info/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | bpf "github.com/aquasecurity/libbpfgo" 10 | ) 11 | 12 | func getSupposedPinPath(m *bpf.BPFMap) string { 13 | return "/sys/fs/bpf/" + m.GetName() 14 | } 15 | 16 | func main() { 17 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 18 | if err != nil { 19 | fmt.Fprintln(os.Stderr, err) 20 | os.Exit(-1) 21 | } 22 | defer bpfModule.Close() 23 | 24 | bpfModule.BPFLoadObject() 25 | 26 | pinnedMap, err := bpfModule.GetMap("pinned_map") 27 | if err != nil { 28 | fmt.Fprintln(os.Stderr, err) 29 | os.Exit(-1) 30 | } 31 | var supposedPinPath = getSupposedPinPath(pinnedMap) 32 | var actualPinPath string 33 | 34 | defer pinnedMap.Unpin(supposedPinPath) 35 | 36 | if !pinnedMap.IsPinned() { 37 | fmt.Fprintf(os.Stderr, 38 | "IsPinned() returned 'false' when map %s should be pinned\n", 39 | pinnedMap.GetName()) 40 | os.Exit(-1) 41 | } 42 | 43 | actualPinPath = pinnedMap.GetPinPath() 44 | if actualPinPath != supposedPinPath { 45 | fmt.Fprintf(os.Stderr, 46 | "GetPinPath() returned %s when should be %s\n", 47 | actualPinPath, supposedPinPath) 48 | os.Exit(-1) 49 | } 50 | 51 | notPinnedMap, err := bpfModule.GetMap("not_pinned_map") 52 | if err != nil { 53 | fmt.Fprintln(os.Stderr, err) 54 | os.Exit(-1) 55 | } 56 | 57 | if notPinnedMap.IsPinned() { 58 | fmt.Fprintf(os.Stderr, 59 | "IsPinned() returned 'true' when map %s should not be pinned\n", 60 | pinnedMap.GetName()) 61 | os.Exit(-1) 62 | } 63 | 64 | supposedPinPath = getSupposedPinPath(notPinnedMap) 65 | 66 | notPinnedMap.Pin(supposedPinPath) 67 | defer notPinnedMap.Unpin(supposedPinPath) 68 | 69 | actualPinPath = notPinnedMap.GetPinPath() 70 | if actualPinPath != supposedPinPath { 71 | fmt.Fprintf(os.Stderr, 72 | "GetPinPath() returned %s when should be %s\n", 73 | actualPinPath, supposedPinPath) 74 | os.Exit(-1) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /selftest/map-pin-info/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-setinner/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-setinner/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-setinner 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-setinner/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-setinner/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | // Hash map of maps with no inner maps preallocated. 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); 10 | __uint(max_entries, 1); 11 | __type(key, __u32); 12 | __type(value, __u32); 13 | } outer_hash SEC(".maps"); 14 | 15 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 16 | -------------------------------------------------------------------------------- /selftest/map-setinner/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "log" 7 | "syscall" 8 | 9 | bpf "github.com/aquasecurity/libbpfgo" 10 | ) 11 | 12 | func main() { 13 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 14 | if err != nil { 15 | log.Fatal(err) 16 | } 17 | defer bpfModule.Close() 18 | 19 | outerHash, err := bpfModule.GetMap("outer_hash") 20 | if err != nil { 21 | log.Fatal(err) 22 | } 23 | 24 | templateInnerMap, err := bpf.CreateMap(bpf.MapTypeHash, "template_inner_map", 4, 4, 420, nil) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | // As the "outer_hash" map does not have an inner map prototype pre-allocated, 30 | // an active map (from any origin) must be used as a template, by calling 31 | // SetInnerMap() before the object is loaded, otherwise the BPF program will 32 | // fail to load. The template map can be removed after the object is loaded. 33 | err = outerHash.SetInnerMap(templateInnerMap.FileDescriptor()) 34 | if err != nil { 35 | log.Fatal(err) 36 | } 37 | 38 | err = bpfModule.BPFLoadObject() 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | // 44 | // "outer_hash" map of maps is now fully loaded and can be used. 45 | // 46 | 47 | // Attempting to set inner map after the object is loaded will fail. 48 | err = outerHash.SetInnerMap(templateInnerMap.FileDescriptor()) 49 | if err == nil { 50 | log.Fatal("should fail after object is loaded") 51 | } 52 | 53 | // If not needed anymore, remove the "template_inner_map", 54 | // freeing up resources. 55 | err = syscall.Close(templateInnerMap.FileDescriptor()) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /selftest/map-setinner/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/map-update/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/map-update/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/map-update 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/map-update/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/map-update/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | struct value { 8 | int x; 9 | char y; 10 | }; 11 | 12 | struct { 13 | __uint(type, BPF_MAP_TYPE_HASH); 14 | __type(key, u32); 15 | __type(value, struct value); 16 | __uint(max_entries, 1 << 24); 17 | } tester SEC(".maps"); 18 | 19 | struct { 20 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 21 | __uint(key_size, sizeof(u32)); 22 | __uint(value_size, sizeof(u32)); 23 | } events SEC(".maps"); 24 | 25 | SEC("kprobe/sys_mmap") 26 | int kprobe__sys_mmap(struct pt_regs *ctx) 27 | { 28 | u32 firstKey = 1; 29 | struct value *v1 = bpf_map_lookup_elem(&tester, &firstKey); 30 | if (!v1) { 31 | return 1; 32 | } 33 | bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, v1, sizeof(struct value)); 34 | 35 | s64 secondKey = 42069420; 36 | struct value *v2 = bpf_map_lookup_elem(&tester, &secondKey); 37 | if (!v2) { 38 | return 1; 39 | } 40 | bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, v2, sizeof(char) * 3); 41 | 42 | return 0; 43 | } 44 | 45 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 46 | -------------------------------------------------------------------------------- /selftest/map-update/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/module-attach-detach/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/module-attach-detach/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/module-attach-detach 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | 9 | replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers 10 | -------------------------------------------------------------------------------- /selftest/module-attach-detach/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/module-attach-detach/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #ifdef __TARGET_ARCH_amd64 9 | SEC("fentry/__x64_sys_mmap") 10 | #elif defined(__TARGET_ARCH_arm64) 11 | SEC("fentry/__arm64_sys_mmap") 12 | #endif 13 | int sys_mmap(struct pt_regs *ctx) 14 | { 15 | return 0; 16 | } 17 | 18 | SEC("kprobe/do_sys_open") 19 | int kprobe__sys_open(struct pt_regs *ctx) 20 | { 21 | return 0; 22 | } 23 | 24 | char LICENSE[] SEC("license") = "GPL"; 25 | -------------------------------------------------------------------------------- /selftest/module-attach-detach/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "os" 7 | 8 | "fmt" 9 | 10 | bpf "github.com/aquasecurity/libbpfgo" 11 | ) 12 | 13 | func main() { 14 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | os.Exit(-1) 18 | } 19 | defer bpfModule.Close() 20 | 21 | err = bpfModule.BPFLoadObject() 22 | if err != nil { 23 | fmt.Fprintln(os.Stderr, err) 24 | os.Exit(-1) 25 | } 26 | 27 | // attach all programs 28 | err = bpfModule.AttachPrograms() 29 | if err != nil { 30 | fmt.Fprintln(os.Stderr, fmt.Sprintf("attach programs failed: %s", err)) 31 | os.Exit(-1) 32 | } 33 | 34 | // detach all programs 35 | err = bpfModule.DetachPrograms() 36 | if err != nil { 37 | fmt.Fprintln(os.Stderr, fmt.Sprintf("detach programs failed: %s", err)) 38 | os.Exit(-1) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /selftest/module-attach-detach/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/multiple-objects/README.md: -------------------------------------------------------------------------------- 1 | # multiple-objects 2 | 3 | This selftest demonstrates having multiple bpf objects which each have 4 | programs which rely on a single ringbuffer. 5 | 6 | This is accomplished via map pinning. See the ringbuffer definition: 7 | 8 | ```C 9 | struct { 10 | __uint(pinning, LIBBPF_PIN_BY_NAME); 11 | __uint(type, BPF_MAP_TYPE_RINGBUF); 12 | __uint(max_entries, 1 << 24); 13 | } events SEC(".maps"); 14 | ``` 15 | 16 | The `LIBBPF_PIN_BY_NAME` attribute instructs libbpf to pin the map to 17 | a file in the bpf file system. When subsequent bpf maps are loaded by 18 | libbpf with the same name/attribute, libbpf will automatically reuse 19 | the file descriptor and wire it up as the same underly map. 20 | -------------------------------------------------------------------------------- /selftest/multiple-objects/first.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "map.bpf.h" 9 | 10 | // Large instruction count 11 | #ifdef __TARGET_ARCH_amd64 12 | SEC("fentry/__x64_sys_openat") 13 | #elif defined(__TARGET_ARCH_arm64) 14 | SEC("fentry/__arm64_sys_openat") 15 | #endif 16 | int openat_fentry(struct pt_regs* ctx) 17 | { 18 | bpf_printk("openat (multiple objects-1)"); 19 | int* value; 20 | 21 | value = bpf_ringbuf_reserve(&events, sizeof(int), 0); 22 | if (!value) { 23 | return 0; 24 | } 25 | *value = 1; 26 | bpf_ringbuf_submit(value, 0); 27 | 28 | return 0; 29 | } 30 | 31 | char LICENSE[] SEC("license") = "GPL"; 32 | -------------------------------------------------------------------------------- /selftest/multiple-objects/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/multiple-objects 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | 9 | replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers 10 | -------------------------------------------------------------------------------- /selftest/multiple-objects/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/multiple-objects/map.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "map.bpf.h" 9 | -------------------------------------------------------------------------------- /selftest/multiple-objects/map.bpf.h: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(pinning, LIBBPF_PIN_BY_NAME); 10 | __uint(type, BPF_MAP_TYPE_RINGBUF); 11 | __uint(max_entries, 1 << 24); 12 | } events SEC(".maps"); 13 | -------------------------------------------------------------------------------- /selftest/multiple-objects/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/multiple-objects/second.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "map.bpf.h" 9 | 10 | // Large instruction count 11 | #ifdef __TARGET_ARCH_amd64 12 | SEC("fentry/__x64_sys_mmap") 13 | #elif defined(__TARGET_ARCH_arm64) 14 | SEC("fentry/__arm64_sys_mmap") 15 | #endif 16 | int mmap_fentry(struct pt_regs* ctx) 17 | { 18 | bpf_printk("Mmap (multiple objects-2)"); 19 | int* value; 20 | value = bpf_ringbuf_reserve(&events, sizeof(int), 0); 21 | if (!value) { 22 | return 0; 23 | } 24 | *value = 2; 25 | bpf_ringbuf_submit(value, 0); 26 | 27 | return 0; 28 | } 29 | 30 | char LICENSE[] SEC("license") = "GPL"; 31 | -------------------------------------------------------------------------------- /selftest/netns/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/netns/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/netns 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/netns/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/netns/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events SEC(".maps"); 12 | long ringbuffer_flags = 0; 13 | 14 | SEC("sk_lookup") 15 | int sk_lookup__lookup(struct bpf_sk_lookup *ctx) 16 | { 17 | int *process; 18 | 19 | // Reserve space on the ringbuffer for the sample 20 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 21 | if (!process) { 22 | return 1; 23 | } 24 | 25 | *process = 2021; 26 | 27 | bpf_ringbuf_submit(process, ringbuffer_flags); 28 | return 1; 29 | } 30 | 31 | char LICENSE[] SEC("license") = "GPL"; 32 | -------------------------------------------------------------------------------- /selftest/netns/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "fmt" 8 | "net" 9 | "os" 10 | 11 | bpf "github.com/aquasecurity/libbpfgo" 12 | ) 13 | 14 | func main() { 15 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 16 | if err != nil { 17 | fmt.Fprintln(os.Stderr, err) 18 | os.Exit(-1) 19 | } 20 | defer bpfModule.Close() 21 | 22 | err = bpfModule.BPFLoadObject() 23 | if err != nil { 24 | fmt.Fprintln(os.Stderr, err) 25 | os.Exit(-1) 26 | } 27 | 28 | prog, err := bpfModule.GetProgram("sk_lookup__lookup") 29 | if err != nil { 30 | fmt.Fprintln(os.Stderr, err) 31 | os.Exit(-1) 32 | } 33 | 34 | link, err := prog.AttachNetns("/proc/self/ns/net") 35 | if err != nil { 36 | fmt.Fprintln(os.Stderr, err) 37 | os.Exit(-1) 38 | } 39 | if link.GetFd() == 0 { 40 | os.Exit(-1) 41 | } 42 | 43 | eventsChannel := make(chan []byte) 44 | rb, err := bpfModule.InitRingBuf("events", eventsChannel) 45 | if err != nil { 46 | fmt.Fprintln(os.Stderr, err) 47 | os.Exit(-1) 48 | } 49 | 50 | rb.Poll(300) 51 | numberOfEventsReceived := 0 52 | go func() { 53 | l, err := net.Listen("tcp", "127.0.0.1:") 54 | if err != nil { 55 | fmt.Fprintln(os.Stderr, err) 56 | os.Exit(-1) 57 | } 58 | go func() { 59 | for { 60 | l.Accept() 61 | } 62 | }() 63 | for i := 0; i < 10; i++ { 64 | c, err := net.Dial("tcp", l.Addr().String()) 65 | if err != nil { 66 | fmt.Fprintln(os.Stderr, err) 67 | os.Exit(-1) 68 | } 69 | c.Write([]byte{0}) 70 | c.Close() 71 | } 72 | }() 73 | 74 | recvLoop: 75 | for { 76 | b := <-eventsChannel 77 | if binary.LittleEndian.Uint32(b) != 2021 { 78 | fmt.Fprintf(os.Stderr, "invalid data retrieved\n") 79 | os.Exit(-1) 80 | } 81 | numberOfEventsReceived++ 82 | if numberOfEventsReceived > 5 { 83 | break recvLoop 84 | } 85 | } 86 | 87 | rb.Stop() 88 | rb.Close() 89 | } 90 | -------------------------------------------------------------------------------- /selftest/netns/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/object-iterator/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/object-iterator/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/object-iterator 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/object-iterator/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/object-iterator/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_HASH); 10 | __type(key, u32); 11 | __type(value, u32); 12 | __uint(max_entries, 1); 13 | } one SEC(".maps"); 14 | 15 | struct { 16 | __uint(type, BPF_MAP_TYPE_ARRAY); 17 | __uint(key_size, sizeof(u32)); 18 | __uint(value_size, sizeof(u32)); 19 | __uint(max_entries, 1); 20 | } two SEC(".maps"); 21 | 22 | #ifdef __TARGET_ARCH_amd64 23 | SEC("fentry/__x64_sys_mmap") 24 | #elif defined(__TARGET_ARCH_arm64) 25 | SEC("fentry/__arm64_sys_mmap") 26 | #endif 27 | int mmap_fentry(struct pt_regs *ctx) 28 | { 29 | return 0; 30 | } 31 | 32 | #ifdef __TARGET_ARCH_amd64 33 | SEC("fentry/__x64_sys_execve") 34 | #elif defined(__TARGET_ARCH_arm64) 35 | SEC("fentry/__arm64_sys_execve") 36 | #endif 37 | int execve_fentry(struct pt_regs *ctx) 38 | { 39 | return 0; 40 | } 41 | 42 | #ifdef __TARGET_ARCH_amd64 43 | SEC("fentry/__x64_sys_execveat") 44 | #elif defined(__TARGET_ARCH_arm64) 45 | SEC("fentry/__arm64_sys_execveat") 46 | #endif 47 | int execveat_fentry(struct pt_regs *ctx) 48 | { 49 | return 0; 50 | } 51 | 52 | char LICENSE[] SEC("license") = "GPL"; 53 | -------------------------------------------------------------------------------- /selftest/object-iterator/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "os" 7 | 8 | "fmt" 9 | 10 | bpf "github.com/aquasecurity/libbpfgo" 11 | ) 12 | 13 | func main() { 14 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | os.Exit(-1) 18 | } 19 | defer bpfModule.Close() 20 | 21 | err = bpfModule.BPFLoadObject() 22 | if err != nil { 23 | fmt.Fprintln(os.Stderr, err) 24 | os.Exit(-1) 25 | } 26 | 27 | iterator := bpfModule.Iterator() 28 | 29 | // Iterate over programs 30 | expectedProgramNames := map[string]bool{ 31 | "mmap_fentry": false, 32 | "execve_fentry": false, 33 | "execveat_fentry": false, 34 | } 35 | 36 | currentProg := iterator.NextProgram() 37 | for currentProg != nil { 38 | expectedProgramNames[currentProg.GetName()] = true 39 | currentProg = iterator.NextProgram() 40 | } 41 | 42 | if len(expectedProgramNames) != 3 { 43 | fmt.Fprintln(os.Stderr, "did not iterate over expected programs") 44 | os.Exit(-1) 45 | } 46 | for k, v := range expectedProgramNames { 47 | if !v { 48 | fmt.Fprintf(os.Stderr, "did not iterate over expected program: %s", k) 49 | os.Exit(-1) 50 | } 51 | } 52 | 53 | // Iterate over maps 54 | expectedMapNames := map[string]bool{ 55 | "one": false, 56 | "two": false, 57 | } 58 | 59 | currentMap := iterator.NextMap() 60 | for currentMap != nil { 61 | expectedMapNames[currentMap.GetName()] = true 62 | currentMap = iterator.NextMap() 63 | } 64 | 65 | if len(expectedMapNames) != 2 { 66 | fmt.Fprintln(os.Stderr, "did not iterate over expected maps") 67 | os.Exit(-1) 68 | } 69 | for k, v := range expectedMapNames { 70 | if !v { 71 | fmt.Fprintf(os.Stderr, "did not iterate over expected map: %s", k) 72 | os.Exit(-1) 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /selftest/object-iterator/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/percpu/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/percpu/README.md: -------------------------------------------------------------------------------- 1 | # PER CPU -------------------------------------------------------------------------------- /selftest/percpu/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/percu 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/percpu/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/percpu/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); 10 | __uint(max_entries, 1); 11 | __type(key, __u32); 12 | __type(value, __u64); 13 | } percpu_hash SEC(".maps"); 14 | 15 | #ifdef __TARGET_ARCH_amd64 16 | SEC("fentry/__x64_sys_mmap") 17 | #elif defined(__TARGET_ARCH_arm64) 18 | SEC("fentry/__arm64_sys_mmap") 19 | #endif 20 | int mmap_fentry(struct pt_regs *ctx) 21 | { 22 | __u32 key = 0; 23 | __u8 *value = bpf_map_lookup_elem(&percpu_hash, &key); 24 | if (value) { 25 | *value += 1; 26 | bpf_printk("%d", *value); 27 | return 0; 28 | } 29 | 30 | bpf_printk("nothing"); 31 | 32 | return 0; 33 | } 34 | char LICENSE[] SEC("license") = "GPL"; 35 | -------------------------------------------------------------------------------- /selftest/percpu/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "fmt" 8 | "os" 9 | "runtime" 10 | "syscall" 11 | "time" 12 | "unsafe" 13 | 14 | bpf "github.com/aquasecurity/libbpfgo" 15 | ) 16 | 17 | func main() { 18 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 19 | if err != nil { 20 | fmt.Fprintln(os.Stderr, err) 21 | os.Exit(-1) 22 | } 23 | defer bpfModule.Close() 24 | 25 | err = bpfModule.BPFLoadObject() 26 | if err != nil { 27 | fmt.Fprintln(os.Stderr, err) 28 | os.Exit(-1) 29 | } 30 | 31 | prog, err := bpfModule.GetProgram("mmap_fentry") 32 | if err != nil { 33 | fmt.Fprintln(os.Stderr, err) 34 | os.Exit(-1) 35 | } 36 | 37 | link, err := prog.AttachGeneric() 38 | if err != nil { 39 | fmt.Fprintln(os.Stderr, err) 40 | os.Exit(-1) 41 | } 42 | if link.GetFd() == 0 { 43 | os.Exit(-1) 44 | } 45 | 46 | go func() { 47 | for { 48 | syscall.Mmap(999, 999, 999, 1, 1) 49 | time.Sleep(time.Millisecond * 30) 50 | } 51 | }() 52 | 53 | lostEventCounterMap, err := bpfModule.GetMap("percpu_hash") 54 | if err != nil { 55 | fmt.Fprintln(os.Stderr, err) 56 | os.Exit(-1) 57 | } 58 | 59 | time.Sleep(time.Second * 2) 60 | key := 0 61 | values := make([]byte, 8*runtime.NumCPU()) 62 | err = lostEventCounterMap.GetValueReadInto(unsafe.Pointer(&key), &values) 63 | if err != nil { 64 | fmt.Fprintln(os.Stderr, err) 65 | os.Exit(-1) 66 | } 67 | 68 | last := 0 69 | for i := 0; i < runtime.NumCPU(); i++ { 70 | fmt.Printf("CPU %d: %d\n", i, binary.LittleEndian.Uint32(values[last:last+8])) 71 | last += 8 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /selftest/percpu/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/perfbuffers/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/perfbuffers/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/perfbuffers 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/perfbuffers/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/perfbuffers/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 9 | 10 | struct { 11 | __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 12 | __uint(key_size, sizeof(u32)); 13 | __uint(value_size, sizeof(u32)); 14 | } events SEC(".maps"); 15 | 16 | SEC("kprobe/sys_mmap") 17 | int kprobe__sys_mmap(struct pt_regs *ctx) 18 | { 19 | int process = 2021; 20 | bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &process, sizeof(int)); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /selftest/perfbuffers/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/probe-features/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/probe-features/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/probe-features 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/probe-features/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/probe-features/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | SEC("kprobe/sys_mmap") 9 | int kprobe__sys_mmap(struct pt_regs *ctx) 10 | { 11 | bpf_printk("Yankees will win the 2022 world series"); 12 | return 0; 13 | } 14 | 15 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 16 | -------------------------------------------------------------------------------- /selftest/probe-features/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "fmt" 7 | "log" 8 | "os" 9 | 10 | bpf "github.com/aquasecurity/libbpfgo" 11 | ) 12 | 13 | func main() { 14 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 15 | if err != nil { 16 | fmt.Fprintln(os.Stderr, err) 17 | os.Exit(-1) 18 | } 19 | defer bpfModule.Close() 20 | 21 | kprobeProg, err := bpfModule.GetProgram("kprobe__sys_mmap") 22 | if err != nil { 23 | fmt.Fprintln(os.Stderr, err) 24 | os.Exit(-1) 25 | } 26 | 27 | err = kprobeProg.SetAutoload(false) 28 | if err != nil { 29 | fmt.Fprintln(os.Stderr, err) 30 | os.Exit(-1) 31 | } 32 | 33 | isSupported, err := bpf.BPFProgramTypeIsSupported(bpf.BPFProgTypeKprobe) 34 | if err != nil { 35 | fmt.Fprintln(os.Stderr, err) 36 | os.Exit(-1) 37 | } 38 | 39 | if isSupported { 40 | err = kprobeProg.SetAutoload(true) 41 | if err != nil { 42 | fmt.Fprintln(os.Stderr, err) 43 | os.Exit(-1) 44 | } 45 | } 46 | 47 | // Test auto load result 48 | autoLoadOrig := kprobeProg.Autoload() 49 | kprobeProg.SetAutoload((!autoLoadOrig)) 50 | if kprobeProg.Autoload() == autoLoadOrig { 51 | fmt.Println(os.Stderr, "auto load result wrong") 52 | os.Exit(-1) 53 | } 54 | kprobeProg.SetAutoload((autoLoadOrig)) 55 | 56 | err = bpfModule.BPFLoadObject() 57 | if err != nil { 58 | fmt.Fprintln(os.Stderr, err) 59 | os.Exit(-1) 60 | } 61 | 62 | isSupported, err = bpf.BPFMapTypeIsSupported(bpf.MapTypeHash) 63 | if err != nil { 64 | fmt.Fprintln(os.Stderr, err) 65 | os.Exit(-1) 66 | } 67 | 68 | if isSupported { 69 | _, err = bpf.CreateMap(bpf.MapTypeHash, "foobar", 4, 4, 420, nil) 70 | if err != nil { 71 | log.Fatal(err) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /selftest/probe-features/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/probe-ringbuf-non-supported 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 9 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | bpf "github.com/aquasecurity/libbpfgo" 8 | ) 9 | 10 | func main() { 11 | // Should not be supported before 5.8 12 | isSupported, err := bpf.BPFMapTypeIsSupported(bpf.MapTypeRingbuf) 13 | if err == nil || isSupported { 14 | fmt.Fprintln(os.Stderr, "Ringbuf is supported unexpectedly or no error") 15 | os.Exit(-1) 16 | } 17 | 18 | fmt.Fprintln(os.Stdout, "Ringbuf is not supported as expected") 19 | } 20 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/run-vm.sh: -------------------------------------------------------------------------------- 1 | ../common/run-vm-stage2.sh -------------------------------------------------------------------------------- /selftest/probe-ringbuf-non-supported/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TEST=$(dirname $0)/$1 # execute 4 | TIMEOUT=10 # seconds 5 | KERNEL_VERSION=v5.7 # kernel version 6 | 7 | # SETTINGS 8 | COMMON="$(dirname $0)/../common/common.sh" 9 | 10 | vng -v -r $KERNEL_VERSION --rodir="$(realpath ..)" -- "export TEST=$TEST COMMON=$COMMON TIMEOUT=$TIMEOUT; ./run-vm.sh" 11 | 12 | exit 0 13 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/probe-ringbuf/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/probe-ringbuf 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 8); 11 | } events1 SEC(".maps"); 12 | 13 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 14 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | bpf "github.com/aquasecurity/libbpfgo" 10 | ) 11 | 12 | func main() { 13 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 14 | if err != nil { 15 | fmt.Fprintln(os.Stderr, err) 16 | os.Exit(-1) 17 | } 18 | defer bpfModule.Close() 19 | 20 | err = bpfModule.BPFLoadObject() 21 | if err != nil { 22 | fmt.Fprintln(os.Stderr, err) 23 | os.Exit(-1) 24 | } 25 | 26 | // Should be supported from 5.8 onwards 27 | isSupported, err := bpf.BPFMapTypeIsSupported(bpf.MapTypeRingbuf) 28 | if err != nil || !isSupported { 29 | fmt.Fprintln(os.Stderr, err) 30 | os.Exit(-1) 31 | } 32 | 33 | eventsChannel1 := make(chan []byte) 34 | _, err = bpfModule.InitRingBuf("events1", eventsChannel1) 35 | if err != nil { 36 | fmt.Fprintln(os.Stderr, err) 37 | os.Exit(-1) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /selftest/probe-ringbuf/run-vm.sh: -------------------------------------------------------------------------------- 1 | ../common/run-vm-stage2.sh -------------------------------------------------------------------------------- /selftest/probe-ringbuf/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TEST=$(dirname $0)/$1 # execute 4 | TIMEOUT=10 # seconds 5 | KERNEL_VERSION=v5.8 # kernel version 6 | 7 | # SETTINGS 8 | COMMON="$(dirname $0)/../common/common.sh" 9 | 10 | vng -v -r $KERNEL_VERSION --rodir="$(realpath ..)" -- "export TEST=$TEST COMMON=$COMMON TIMEOUT=$TIMEOUT; ./run-vm.sh" 11 | 12 | exit 0 13 | -------------------------------------------------------------------------------- /selftest/prog-run/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/prog-run/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/prog-run 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/prog-run/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/prog-run/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | SEC("tc") 9 | int test_tc(struct __sk_buff *skb) 10 | { 11 | void *data = (void *) (long) skb->data; 12 | void *data_end = (void *) (long) skb->data_end; 13 | if (data + 4 > data_end) { 14 | return -1; 15 | } 16 | 17 | if (*(__u32 *) data == 0xdeadbeef) { 18 | char new_data[] = {0x01, 0x02, 0x03, 0x04}; 19 | bpf_skb_store_bytes(skb, 0, new_data, 4, 0); 20 | bpf_skb_change_tail(skb, 14, 0); 21 | return 1; 22 | } 23 | 24 | return 2; 25 | } 26 | 27 | char LICENSE[] SEC("license") = "GPL"; 28 | -------------------------------------------------------------------------------- /selftest/prog-run/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "log" 8 | 9 | bpf "github.com/aquasecurity/libbpfgo" 10 | ) 11 | 12 | func main() { 13 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 14 | if err != nil { 15 | log.Fatalf("Failed to load BPF module: %v", err) 16 | } 17 | defer bpfModule.Close() 18 | 19 | err = bpfModule.BPFLoadObject() 20 | if err != nil { 21 | log.Fatalf("Failed to load object: %v", err) 22 | } 23 | 24 | tcProg, err := bpfModule.GetProgram("test_tc") 25 | if err != nil || tcProg == nil { 26 | log.Fatalf("Failed to get prog test_tc: %v", err) 27 | } 28 | 29 | dataIn := make([]byte, 16) 30 | binary.LittleEndian.PutUint32(dataIn, 0xdeadbeef) 31 | opts := bpf.RunOpts{ 32 | DataIn: dataIn, 33 | DataSizeIn: 16, 34 | DataOut: make([]byte, 32), 35 | DataSizeOut: 32, 36 | Repeat: 1, 37 | } 38 | 39 | err = tcProg.Run(&opts) 40 | if err != nil { 41 | log.Fatalf("Failed to run prog: %v", err) 42 | } 43 | if opts.RetVal != 1 { 44 | log.Fatalf("retVal %d should be 1", opts.RetVal) 45 | } 46 | if len(opts.DataOut) != 14 { 47 | log.Fatalf("dataOut len %v should be 14", opts.DataOut) 48 | } 49 | if binary.LittleEndian.Uint32(opts.DataOut) != 0x04030201 { 50 | log.Fatalf("dataOut 0x%x should be 0x04030201", binary.LittleEndian.Uint32(opts.DataOut)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /selftest/prog-run/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-4.12.sh -------------------------------------------------------------------------------- /selftest/reuse-fd/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/reuse-fd/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/reuse-fd 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/reuse-fd/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/reuse-fd/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "main.bpf.h" 8 | 9 | struct { 10 | __uint(type, BPF_MAP_TYPE_HASH); 11 | __type(key, u32); 12 | __type(value, struct value); 13 | __uint(max_entries, 1 << 4); 14 | } tester SEC(".maps"); 15 | 16 | struct { 17 | __uint(type, BPF_MAP_TYPE_HASH); 18 | __type(key, u32); 19 | __type(value, struct value); 20 | __uint(max_entries, 1 << 4); 21 | } tester_reused SEC(".maps"); 22 | 23 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 24 | -------------------------------------------------------------------------------- /selftest/reuse-fd/main.bpf.h: -------------------------------------------------------------------------------- 1 | struct value { 2 | char a; 3 | char b; 4 | char c; 5 | char d; 6 | }; 7 | -------------------------------------------------------------------------------- /selftest/reuse-fd/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/ringbuffers/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/ringbuffers/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/ringbuffers 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/ringbuffers/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/ringbuffers/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events1 SEC(".maps"), events2 SEC(".maps"); 12 | 13 | long ringbuffer_flags = 0; 14 | 15 | SEC("kprobe/sys_mmap") 16 | int kprobe__sys_mmap(struct pt_regs *ctx) 17 | { 18 | int *process; 19 | 20 | // Reserve space on the ringbuffer for the sample 21 | process = bpf_ringbuf_reserve(&events1, sizeof(int), ringbuffer_flags); 22 | if (!process) { 23 | return 0; 24 | } 25 | 26 | *process = 2021; 27 | 28 | bpf_ringbuf_submit(process, ringbuffer_flags); 29 | 30 | process = bpf_ringbuf_reserve(&events2, sizeof(int), ringbuffer_flags); 31 | if (!process) { 32 | return 0; 33 | } 34 | 35 | *process = 2024; 36 | 37 | bpf_ringbuf_submit(process, ringbuffer_flags); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /selftest/ringbuffers/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/set-attach/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/set-attach/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/set-attach 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/set-attach/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/set-attach/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events SEC(".maps"); 12 | long ringbuffer_flags = 0; 13 | 14 | SEC("fentry") 15 | int BPF_PROG(foobar) 16 | { 17 | int *process; 18 | // Reserve space on the ringbuffer for the sample 19 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 20 | if (!process) { 21 | return 0; 22 | } 23 | *process = 2021; 24 | bpf_ringbuf_submit(process, ringbuffer_flags); 25 | return 0; 26 | } 27 | 28 | char LICENSE[] SEC("license") = "GPL"; 29 | -------------------------------------------------------------------------------- /selftest/set-attach/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/spinlocks/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/spinlocks/README.md: -------------------------------------------------------------------------------- 1 | # Spinlocks 2 | 3 | https://lwn.net/Articles/776909/ 4 | 5 | In BTF annotated BPF maps, we can use a bpf_spin_lock to allow for atomic reads/updates of values in BPF maps. 6 | 7 | It is NOT supported in programs of type: 8 | 9 | - BPF_PROG_TYPE_KPROBE 10 | - BPF_PROG_TYPE_TRACEPOINT 11 | - BPF_PROG_TYPE_PERF_EVENT 12 | - BPF_PROG_TYPE_RAW_TRACEPOINT 13 | -------------------------------------------------------------------------------- /selftest/spinlocks/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/spinlocks 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/spinlocks/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/spinlocks/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #define VAR_NUM 16 9 | 10 | struct hmap_elem { 11 | struct bpf_spin_lock lock; 12 | int val; 13 | }; 14 | 15 | struct { 16 | __uint(type, BPF_MAP_TYPE_HASH); 17 | __uint(max_entries, 1); 18 | __type(key, u32); 19 | __type(value, struct hmap_elem); 20 | } counter_hash_map SEC(".maps"); 21 | 22 | long ringbuffer_flags = 0; 23 | 24 | struct { 25 | __uint(type, BPF_MAP_TYPE_RINGBUF); 26 | __uint(max_entries, 1 << 24); 27 | } events SEC(".maps"); 28 | 29 | #ifdef __TARGET_ARCH_amd64 30 | SEC("fentry/__x64_sys_mmap") 31 | #elif defined(__TARGET_ARCH_arm64) 32 | SEC("fentry/__arm64_sys_mmap") 33 | #endif 34 | int mmap_fentry(struct pt_regs *ctx) 35 | { 36 | int *process; 37 | struct hmap_elem *lost_event_counter; 38 | int key = 1; 39 | 40 | lost_event_counter = bpf_map_lookup_elem(&counter_hash_map, &key); 41 | if (!lost_event_counter) { 42 | return 0; 43 | } 44 | 45 | // Reserve space on the ringbuffer for the sample 46 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 47 | if (!process) { 48 | bpf_spin_lock(&lost_event_counter->lock); 49 | lost_event_counter->val++; 50 | bpf_spin_unlock(&lost_event_counter->lock); 51 | return 0; 52 | } 53 | 54 | *process = 2021; 55 | 56 | bpf_ringbuf_submit(process, ringbuffer_flags); 57 | return 0; 58 | } 59 | char LICENSE[] SEC("license") = "GPL"; 60 | -------------------------------------------------------------------------------- /selftest/spinlocks/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/struct-ops/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/struct-ops 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/struct-ops/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/struct-ops/run-vm.sh: -------------------------------------------------------------------------------- 1 | ../common/run-vm-stage2.sh -------------------------------------------------------------------------------- /selftest/struct-ops/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | TEST=$(dirname $0)/$1 # execute 4 | TIMEOUT=10 # seconds 5 | KERNEL_VERSION=v6.12.2 # kernel version 6 | 7 | # SETTINGS 8 | COMMON="$(dirname $0)/../common/common.sh" 9 | 10 | vng -v -r $KERNEL_VERSION --rodir="$(realpath ..)" -- "export TEST=$TEST COMMON=$COMMON TIMEOUT=$TIMEOUT; ./run-vm.sh" 11 | 12 | exit 0 13 | -------------------------------------------------------------------------------- /selftest/tc/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/tc/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/tc 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/tc/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/tc/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events SEC(".maps"); 12 | long ringbuffer_flags = 0; 13 | 14 | SEC("tc") 15 | int target(struct __sk_buff *skb) 16 | { 17 | int *process; 18 | 19 | // Reserve space on the ringbuffer for the sample 20 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 21 | if (!process) { 22 | return 0; 23 | } 24 | 25 | *process = 2021; 26 | 27 | bpf_ringbuf_submit(process, ringbuffer_flags); 28 | return 0; 29 | } 30 | 31 | // SEC("fentry/FUNC") 32 | // int BPF_PROG(follower) 33 | // { 34 | // int *process; 35 | // // Reserve space on the ringbuffer for the sample 36 | // process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 37 | // if (!process) { 38 | // return 0; 39 | // } 40 | // *process = 2021; 41 | // bpf_ringbuf_submit(process, ringbuffer_flags); 42 | // return 0; 43 | // } 44 | 45 | char LICENSE[] SEC("license") = "GPL"; 46 | -------------------------------------------------------------------------------- /selftest/tc/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/tracing-by-offset/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/tracing-by-offset/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/tracing-by-offset 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/aquasecurity/libbpfgo v0.0.0 7 | github.com/aquasecurity/libbpfgo/helpers v0.4.5 8 | ) 9 | 10 | require golang.org/x/sys v0.25.0 // indirect 11 | 12 | replace github.com/aquasecurity/libbpfgo => ../../ 13 | 14 | replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers 15 | -------------------------------------------------------------------------------- /selftest/tracing-by-offset/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 8 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 12 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 13 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 14 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 15 | -------------------------------------------------------------------------------- /selftest/tracing-by-offset/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | 7 | SEC("kprobe/sys_mmap") 8 | int kprobe__sys_mmap(struct pt_regs *ctx) 9 | { 10 | bpf_printk("Hello, World!\n"); 11 | return 0; 12 | } 13 | 14 | char LICENSE[] SEC("license") = "Dual BSD/GPL"; 15 | -------------------------------------------------------------------------------- /selftest/tracing-by-offset/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "os" 7 | "runtime" 8 | "time" 9 | 10 | "fmt" 11 | "syscall" 12 | 13 | bpf "github.com/aquasecurity/libbpfgo" 14 | "github.com/aquasecurity/libbpfgo/helpers" 15 | ) 16 | 17 | func main() { 18 | funcName := fmt.Sprintf("__%s_sys_mmap", ksymArch()) 19 | 20 | kst, err := helpers.NewKernelSymbolTable() 21 | if err != nil { 22 | fmt.Fprintln(os.Stderr, "NewKernelSymbolTable() failed: %v", err) 23 | os.Exit(-1) 24 | } 25 | 26 | funcSymbol, err := kst.GetSymbolByName(funcName) 27 | if err != nil { 28 | fmt.Fprintln(os.Stderr, "Expected to find symbol %s, but it was not found", funcSymbol) 29 | os.Exit(-1) 30 | } 31 | 32 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 33 | if err != nil { 34 | fmt.Fprintln(os.Stderr, err) 35 | os.Exit(-1) 36 | } 37 | defer bpfModule.Close() 38 | 39 | bpfModule.BPFLoadObject() 40 | prog, err := bpfModule.GetProgram("kprobe__sys_mmap") 41 | if err != nil { 42 | fmt.Fprintln(os.Stderr, err) 43 | os.Exit(-1) 44 | } 45 | 46 | _, err = prog.AttachKprobeOffset(funcSymbol[0].Address) 47 | if err != nil { 48 | fmt.Fprintln(os.Stderr, err) 49 | os.Exit(-1) 50 | } 51 | 52 | go func() { 53 | time.Sleep(time.Second) 54 | syscall.Mmap(999, 999, 999, 1, 1) 55 | syscall.Mmap(999, 999, 999, 1, 1) 56 | }() 57 | 58 | time.Sleep(time.Second * 2) 59 | } 60 | 61 | func ksymArch() string { 62 | switch runtime.GOARCH { 63 | case "amd64": 64 | return "x64" 65 | case "arm64": 66 | return "arm64" 67 | default: 68 | panic("unsupported architecture") 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /selftest/tracing-by-offset/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run.sh -------------------------------------------------------------------------------- /selftest/tracing/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/tracing/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/tracing 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/aquasecurity/libbpfgo v0.0.0 7 | github.com/aquasecurity/libbpfgo/helpers v0.4.5 8 | ) 9 | 10 | require golang.org/x/sys v0.25.0 // indirect 11 | 12 | replace github.com/aquasecurity/libbpfgo => ../../ 13 | 14 | replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers 15 | -------------------------------------------------------------------------------- /selftest/tracing/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 8 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 12 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 13 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 14 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 15 | -------------------------------------------------------------------------------- /selftest/tracing/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events SEC(".maps"); 12 | long ringbuffer_flags = 0; 13 | 14 | #ifdef __TARGET_ARCH_amd64 15 | SEC("fentry/__x64_sys_mmap") 16 | #elif defined(__TARGET_ARCH_arm64) 17 | SEC("fentry/__arm64_sys_mmap") 18 | #endif 19 | int mmap_fentry(struct pt_regs *ctx) 20 | { 21 | int *process; 22 | 23 | // Reserve space on the ringbuffer for the sample 24 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 25 | if (!process) { 26 | return 0; 27 | } 28 | 29 | *process = 2021; 30 | 31 | bpf_ringbuf_submit(process, ringbuffer_flags); 32 | return 0; 33 | } 34 | 35 | char LICENSE[] SEC("license") = "GPL"; 36 | -------------------------------------------------------------------------------- /selftest/tracing/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/uprobe-multi/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/uprobe 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/aquasecurity/libbpfgo v0.0.0 7 | github.com/aquasecurity/libbpfgo/helpers v0.0.0-00010101000000-000000000000 8 | ) 9 | 10 | require golang.org/x/sys v0.25.0 // indirect 11 | 12 | replace github.com/aquasecurity/libbpfgo => ../../ 13 | 14 | replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers 15 | -------------------------------------------------------------------------------- /selftest/uprobe-multi/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 8 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 12 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 13 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 14 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 15 | -------------------------------------------------------------------------------- /selftest/uprobe-multi/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct event_t { 9 | __u64 cookie; 10 | }; 11 | 12 | struct { 13 | __uint(type, BPF_MAP_TYPE_RINGBUF); 14 | __uint(max_entries, 1 << 24); 15 | } events SEC(".maps"); 16 | 17 | long ringbuffer_flags = 0; 18 | 19 | SEC("uprobe/test_functions") 20 | int uprobe__test_functions(struct pt_regs *ctx) 21 | { 22 | __u64 cookie = bpf_get_attach_cookie(ctx); 23 | 24 | bpf_printk("handle user function with cookie %llu\n", cookie); 25 | 26 | // Reserve space on the ringbuffer for the sample 27 | struct event_t *event = bpf_ringbuf_reserve(&events, sizeof(struct event_t), ringbuffer_flags); 28 | if (!event) { 29 | bpf_printk("error submitting event to ring buffer for user function with cookie %llu\n", 30 | cookie); 31 | return 0; 32 | } 33 | 34 | // Send back to userspace the function name 35 | event->cookie = cookie; 36 | bpf_ringbuf_submit(event, ringbuffer_flags); 37 | return 0; 38 | } 39 | char __license[] SEC("license") = "GPL"; 40 | -------------------------------------------------------------------------------- /selftest/uprobe-multi/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | CTEST=$(dirname $0)/ctest 9 | GOTEST=$(dirname $0)/gotest 10 | CFUNCS="fooFunction,barFunction,bazFunction" 11 | GOFUNCS="main.fooFunction,main.barFunction,main.bazFunction" 12 | 13 | # COMMON 14 | 15 | COMMON="$(dirname $0)/../common/common.sh" 16 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 17 | 18 | # MAIN 19 | 20 | kern_version gt 4.3 21 | check_build 22 | check_ppid 23 | 24 | execbg 10 $CTEST 25 | execbg 10 $GOTEST 26 | 27 | execfg 5 $TEST $CTEST $CFUNCS 28 | test_step 29 | 30 | execfg 5 $TEST $GOTEST $GOFUNCS 31 | test_finish 32 | 33 | waitbg 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /selftest/uprobe-multi/test.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | #include 3 | 4 | __attribute__((optnone)) void fooFunction() {} 5 | __attribute__((optnone)) void barFunction() {} 6 | __attribute__((optnone)) void bazFunction() {} 7 | 8 | int main() 9 | { 10 | int i; 11 | 12 | while (1) { 13 | usleep(100 * 1000); 14 | fooFunction(); 15 | usleep(100 * 1000); 16 | barFunction(); 17 | usleep(100 * 1000); 18 | bazFunction(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /selftest/uprobe-multi/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "time" 6 | ) 7 | 8 | //go:noinline 9 | func fooFunction() int { 10 | if os.Getenv("SELFTEST_UPROBE_DO_BRANCH") == "y" { 11 | return 1 12 | } 13 | return 0 14 | } 15 | 16 | //go:noinline 17 | func barFunction() int { 18 | if os.Getenv("SELFTEST_UPROBE_DO_BRANCH") == "y" { 19 | return 1 20 | } 21 | return 0 22 | } 23 | 24 | //go:noinline 25 | func bazFunction() int { 26 | if os.Getenv("SELFTEST_UPROBE_DO_BRANCH") == "y" { 27 | return 1 28 | } 29 | return 0 30 | } 31 | 32 | func main() { 33 | for { 34 | time.Sleep(100 * time.Millisecond) 35 | fooFunction() 36 | time.Sleep(100 * time.Millisecond) 37 | barFunction() 38 | time.Sleep(100 * time.Millisecond) 39 | bazFunction() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /selftest/uprobe/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/uprobe 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | 9 | replace github.com/aquasecurity/libbpfgo/helpers => ../../helpers 10 | -------------------------------------------------------------------------------- /selftest/uprobe/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/uprobe/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events SEC(".maps"); 12 | 13 | long ringbuffer_flags = 0; 14 | 15 | SEC("uprobe/test_function") 16 | int uprobe__test_function(struct pt_regs *ctx) 17 | { 18 | int *process; 19 | 20 | // Reserve space on the ringbuffer for the sample 21 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 22 | if (!process) { 23 | return 0; 24 | } 25 | 26 | *process = 2021; 27 | 28 | bpf_ringbuf_submit(process, ringbuffer_flags); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /selftest/uprobe/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | CTEST=$(dirname $0)/ctest 9 | GOTEST=$(dirname $0)/gotest 10 | CFUNC="testFunction" 11 | GOFUNC="main.testFunction" 12 | 13 | # COMMON 14 | 15 | COMMON="$(dirname $0)/../common/common.sh" 16 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 17 | 18 | # MAIN 19 | 20 | kern_version gt 4.3 21 | check_build 22 | check_ppid 23 | 24 | execbg 10 $CTEST 25 | execbg 10 $GOTEST 26 | 27 | execfg 5 $TEST $CTEST $CFUNC 28 | test_step 29 | 30 | execfg 5 $TEST $GOTEST $GOFUNC 31 | test_finish 32 | 33 | waitbg 34 | 35 | exit 0 36 | -------------------------------------------------------------------------------- /selftest/uprobe/test.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | #include 3 | 4 | __attribute__((optnone)) void testFunction() {} 5 | 6 | int main() 7 | { 8 | int i; 9 | 10 | while (1) { 11 | usleep(100 * 1000); 12 | testFunction(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /selftest/uprobe/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "time" 6 | ) 7 | 8 | //go:noinline 9 | func testFunction() int { 10 | if os.Getenv("SELFTEST_UPROBE_DO_BRANCH") == "y" { 11 | return 1 12 | } 13 | return 0 14 | } 15 | 16 | func main() { 17 | for { 18 | time.Sleep(100 * time.Millisecond) 19 | testFunction() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /selftest/usdt/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/usdt 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/usdt/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/usdt/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | struct { 10 | __uint(type, BPF_MAP_TYPE_RINGBUF); 11 | __uint(max_entries, 1 << 24); 12 | } events SEC(".maps"); 13 | 14 | long ringbuffer_flags = 0; 15 | 16 | SEC("usdt/test_marker") 17 | int usdt__test_marker(struct pt_regs *ctx) 18 | { 19 | long *value; 20 | 21 | // Reserve space on the ringbuffer for the sample 22 | value = bpf_ringbuf_reserve(&events, sizeof(*value), ringbuffer_flags); 23 | if (!value) { 24 | return 0; 25 | } 26 | 27 | if (bpf_usdt_arg(ctx, 0, value) < 0) { 28 | bpf_ringbuf_discard(value, ringbuffer_flags); 29 | return 0; 30 | } 31 | 32 | bpf_ringbuf_submit(value, ringbuffer_flags); 33 | return 0; 34 | } 35 | 36 | char LICENSE[] SEC("license") = "GPL"; 37 | -------------------------------------------------------------------------------- /selftest/usdt/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "os" 7 | 8 | bpf "github.com/aquasecurity/libbpfgo" 9 | ) 10 | 11 | func main() { 12 | binaryPath := "./ctest" 13 | providerName := "test" 14 | markerName := "test_marker" 15 | 16 | _, err := os.Stat(binaryPath) 17 | if err != nil { 18 | fmt.Fprintln(os.Stderr, err) 19 | os.Exit(-1) 20 | } 21 | 22 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 23 | if err != nil { 24 | fmt.Fprintln(os.Stderr, err) 25 | os.Exit(-1) 26 | } 27 | defer bpfModule.Close() 28 | 29 | if err = resizeMap(bpfModule, "events", 8192); err != nil { 30 | fmt.Fprintln(os.Stderr, err) 31 | os.Exit(-1) 32 | } 33 | 34 | bpfModule.BPFLoadObject() 35 | prog, err := bpfModule.GetProgram("usdt__test_marker") 36 | if err != nil { 37 | fmt.Fprintln(os.Stderr, err) 38 | os.Exit(-1) 39 | } 40 | 41 | _, err = prog.AttachUSDT(-1, binaryPath, providerName, markerName) 42 | if err != nil { 43 | fmt.Fprintln(os.Stderr, err) 44 | os.Exit(-1) 45 | } 46 | 47 | eventsChannel := make(chan []byte) 48 | rb, err := bpfModule.InitRingBuf("events", eventsChannel) 49 | if err != nil { 50 | fmt.Fprintln(os.Stderr, err) 51 | os.Exit(-1) 52 | } 53 | 54 | rb.Poll(300) 55 | 56 | numberOfEventsReceived := 0 57 | 58 | recvLoop: 59 | for { 60 | b := <-eventsChannel 61 | if binary.LittleEndian.Uint32(b) != 1234 { 62 | fmt.Fprintf(os.Stderr, "invalid data retrieved\n") 63 | os.Exit(-1) 64 | } 65 | numberOfEventsReceived++ 66 | if numberOfEventsReceived > 5 { 67 | break recvLoop 68 | } 69 | } 70 | 71 | rb.Stop() 72 | rb.Close() 73 | } 74 | 75 | func resizeMap(module *bpf.Module, name string, size uint32) error { 76 | m, err := module.GetMap("events") 77 | if err != nil { 78 | return err 79 | } 80 | 81 | if err = m.SetMaxEntries(size); err != nil { 82 | return err 83 | } 84 | 85 | if actual := m.MaxEntries(); actual != size { 86 | return fmt.Errorf("map resize failed, expected %v, actual %v", size, actual) 87 | } 88 | 89 | return nil 90 | } 91 | -------------------------------------------------------------------------------- /selftest/usdt/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SETTINGS 4 | 5 | TEST=$(dirname $0)/$1 # execute 6 | TIMEOUT=10 # seconds 7 | 8 | CTEST=$(dirname $0)/ctest 9 | 10 | # COMMON 11 | 12 | COMMON="$(dirname $0)/../common/common.sh" 13 | [[ -f $COMMON ]] && { . $COMMON; } || { error "no common"; exit 1; } 14 | 15 | # MAIN 16 | 17 | check_build 18 | check_ppid 19 | 20 | execbg 10 $CTEST 21 | 22 | execfg 5 $TEST 23 | test_finish 24 | 25 | waitbg 26 | 27 | exit 0 28 | -------------------------------------------------------------------------------- /selftest/usdt/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | while (1) { 7 | usleep(100 * 1000); 8 | DTRACE_PROBE1(test, test_marker, 1234); 9 | } 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /selftest/userringbuf/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/userringbuf/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/userringbuf 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/userringbuf/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/userringbuf/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct dispatched_ctx { 9 | u64 id; 10 | }; 11 | 12 | struct { 13 | __uint(type, BPF_MAP_TYPE_USER_RINGBUF); 14 | __uint(max_entries, 3 * sizeof(struct dispatched_ctx)); 15 | } dispatched SEC(".maps"); 16 | 17 | struct { 18 | __uint(type, BPF_MAP_TYPE_RINGBUF); 19 | __uint(max_entries, 256); 20 | } errEvt SEC(".maps"); 21 | 22 | long ringbuffer_flags = 0; 23 | 24 | static long handle_dispatched_evt(struct bpf_dynptr *dynptr, void *context) 25 | { 26 | const struct dispatched_ctx *ctx; 27 | 28 | ctx = bpf_dynptr_data(dynptr, 0, sizeof(*ctx)); 29 | 30 | if (!ctx || ctx->id != 0x1122334455667788) { 31 | u64 *id = bpf_ringbuf_reserve(&errEvt, sizeof(u64), ringbuffer_flags); 32 | if (!id) { 33 | return 1; 34 | } 35 | bpf_ringbuf_submit(id, ringbuffer_flags); 36 | return 1; 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | SEC("syscall") 43 | int test_user_ring_buff(struct dispatched_ctx *input) 44 | { 45 | int retVal; 46 | retVal = bpf_user_ringbuf_drain(&dispatched, handle_dispatched_evt, NULL, 0); 47 | return retVal; 48 | } 49 | -------------------------------------------------------------------------------- /selftest/userringbuf/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "bytes" 7 | "encoding/binary" 8 | "os" 9 | "time" 10 | 11 | "fmt" 12 | 13 | bpf "github.com/aquasecurity/libbpfgo" 14 | ) 15 | 16 | type test_arg struct { 17 | id uint64 18 | } 19 | 20 | func main() { 21 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 22 | if err != nil { 23 | fmt.Fprintln(os.Stderr, err) 24 | os.Exit(-1) 25 | } 26 | defer bpfModule.Close() 27 | 28 | bpfModule.BPFLoadObject() 29 | 30 | ch := make(chan []byte, 3) // We will send 3 messages 31 | urb, err := bpfModule.InitUserRingBuf("dispatched", ch) 32 | if err != nil { 33 | os.Exit(-1) 34 | } 35 | urb.Start() 36 | 37 | evtChan := make(chan []byte) 38 | rb, err := bpfModule.InitRingBuf("errEvt", evtChan) 39 | if err != nil { 40 | fmt.Fprintln(os.Stderr, err) 41 | os.Exit(-1) 42 | } 43 | rb.Poll(300) 44 | 45 | // Send 3 messages to the ring buffer 46 | var b bytes.Buffer // Stand-in for a network connection 47 | binary.Write(&b, binary.LittleEndian, test_arg{id: 0x1122334455667788}) 48 | ch <- b.Bytes() 49 | ch <- b.Bytes() 50 | ch <- b.Bytes() 51 | 52 | time.Sleep(1 * time.Second) 53 | 54 | prog, err := bpfModule.GetProgram("test_user_ring_buff") 55 | if err != nil { 56 | fmt.Fprintln(os.Stderr, err) 57 | os.Exit(-1) 58 | } 59 | arg := &test_arg{ 60 | id: 0, 61 | } 62 | 63 | var data bytes.Buffer 64 | binary.Write(&data, binary.LittleEndian, arg) 65 | opt := bpf.RunOpts{ 66 | CtxIn: data.Bytes(), 67 | CtxSizeIn: uint32(data.Len()), 68 | } 69 | 70 | // Run the program and check if 3 messages were drained by the program 71 | prog.Run(&opt) 72 | if opt.RetVal != 3 { 73 | fmt.Fprintln(os.Stderr, "error: expected 3, got", opt.RetVal) 74 | os.Exit(-1) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /selftest/userringbuf/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-6.1.sh -------------------------------------------------------------------------------- /selftest/version/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/version/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/version 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/version/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/version/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | -------------------------------------------------------------------------------- /selftest/version/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os/exec" 6 | "strings" 7 | 8 | "github.com/aquasecurity/libbpfgo" 9 | ) 10 | 11 | func main() { 12 | cmd := exec.Command("git", "describe", "--tags") 13 | cmd.Dir = "../../libbpf" 14 | 15 | b, err := cmd.CombinedOutput() 16 | if err != nil { 17 | log.Fatal(string(b), err) 18 | } 19 | 20 | // libbpf doesn't put the patch version in exported version 21 | // symbols, so use just prefix to exclude it 22 | if strings.HasPrefix(libbpfgo.LibbpfVersionString(), string(b)) { 23 | log.Fatalf("Error reading exported symbols for libbpf major and minor version: %s is not %s", libbpfgo.LibbpfVersionString(), b) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /selftest/version/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /selftest/xdp/Makefile: -------------------------------------------------------------------------------- 1 | ../common/Makefile -------------------------------------------------------------------------------- /selftest/xdp/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/aquasecurity/libbpfgo/selftest/xdp 2 | 3 | go 1.21 4 | 5 | require github.com/aquasecurity/libbpfgo v0.0.0 6 | 7 | replace github.com/aquasecurity/libbpfgo => ../../ 8 | -------------------------------------------------------------------------------- /selftest/xdp/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 6 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 7 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 8 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 9 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76 h1:mrdLPj8ujM6eIKGtd1PkkuCIodpFFDM42Cfm0YODkIM= 10 | kernel.org/pub/linux/libs/security/libcap/cap v1.2.76/go.mod h1:7V2BQeHnVAQwhCnCPJ977giCeGDiywVewWF+8vkpPlc= 11 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76 h1:3DyzQ30OHt3wiOZVL1se2g1PAPJIU7+tMUyvfMUj1dY= 12 | kernel.org/pub/linux/libs/security/libcap/psx v1.2.76/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24= 13 | -------------------------------------------------------------------------------- /selftest/xdp/main.bpf.c: -------------------------------------------------------------------------------- 1 | //+build ignore 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | struct { 9 | __uint(type, BPF_MAP_TYPE_RINGBUF); 10 | __uint(max_entries, 1 << 24); 11 | } events SEC(".maps"); 12 | long ringbuffer_flags = 0; 13 | 14 | SEC("xdp") 15 | int target(struct xdp_md *ctx) 16 | { 17 | int *process; 18 | 19 | // Reserve space on the ringbuffer for the sample 20 | process = bpf_ringbuf_reserve(&events, sizeof(int), ringbuffer_flags); 21 | if (!process) { 22 | return 0; 23 | } 24 | 25 | *process = 2021; 26 | 27 | bpf_ringbuf_submit(process, ringbuffer_flags); 28 | return XDP_PASS; 29 | } 30 | 31 | char LICENSE[] SEC("license") = "GPL"; 32 | -------------------------------------------------------------------------------- /selftest/xdp/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "C" 4 | 5 | import ( 6 | "encoding/binary" 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | 11 | bpf "github.com/aquasecurity/libbpfgo" 12 | ) 13 | 14 | const ( 15 | deviceName = "lo" 16 | ) 17 | 18 | func main() { 19 | bpfModule, err := bpf.NewModuleFromFile("main.bpf.o") 20 | if err != nil { 21 | fmt.Fprintln(os.Stderr, err) 22 | os.Exit(-1) 23 | } 24 | defer bpfModule.Close() 25 | 26 | err = bpfModule.BPFLoadObject() 27 | if err != nil { 28 | fmt.Fprintln(os.Stderr, err) 29 | os.Exit(-1) 30 | } 31 | 32 | xdpProg, err := bpfModule.GetProgram("target") 33 | if xdpProg == nil { 34 | fmt.Fprintln(os.Stderr, err) 35 | os.Exit(-1) 36 | } 37 | 38 | err = xdpProg.AttachXDPLegacy(deviceName, bpf.XDPFlagsReplace) 39 | if err != nil { 40 | fmt.Fprintln(os.Stderr, err) 41 | os.Exit(-1) 42 | } 43 | err = xdpProg.DetachXDPLegacy(deviceName, bpf.XDPFlagsReplace) 44 | if err != nil { 45 | fmt.Fprintln(os.Stderr, err) 46 | os.Exit(-1) 47 | } 48 | 49 | _, err = xdpProg.AttachXDP(deviceName) 50 | if err != nil { 51 | fmt.Fprintln(os.Stderr, err) 52 | os.Exit(-1) 53 | } 54 | 55 | eventsChannel := make(chan []byte) 56 | rb, err := bpfModule.InitRingBuf("events", eventsChannel) 57 | if err != nil { 58 | fmt.Fprintln(os.Stderr, err) 59 | os.Exit(-1) 60 | } 61 | 62 | rb.Poll(300) 63 | numberOfEventsReceived := 0 64 | go func() { 65 | _, err := exec.Command("ping", "localhost", "-c 10").Output() 66 | if err != nil { 67 | fmt.Fprintln(os.Stderr, err) 68 | os.Exit(-1) 69 | } 70 | }() 71 | 72 | recvLoop: 73 | 74 | for { 75 | b := <-eventsChannel 76 | if binary.LittleEndian.Uint32(b) != 2021 { 77 | fmt.Fprintf(os.Stderr, "invalid data retrieved\n") 78 | os.Exit(-1) 79 | } 80 | numberOfEventsReceived++ 81 | if numberOfEventsReceived > 5 { 82 | break recvLoop 83 | } 84 | } 85 | 86 | rb.Stop() 87 | rb.Close() 88 | } 89 | -------------------------------------------------------------------------------- /selftest/xdp/run.sh: -------------------------------------------------------------------------------- 1 | ../common/run-5.8.sh -------------------------------------------------------------------------------- /tchook-common.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | 9 | // 10 | // TcAttachPoint 11 | // 12 | 13 | type TcAttachPoint uint32 14 | 15 | const ( 16 | BPFTcIngress TcAttachPoint = C.BPF_TC_INGRESS 17 | BPFTcEgress TcAttachPoint = C.BPF_TC_EGRESS 18 | BPFTcIngressEgress TcAttachPoint = C.BPF_TC_INGRESS | C.BPF_TC_EGRESS 19 | BPFTcCustom TcAttachPoint = C.BPF_TC_CUSTOM 20 | ) 21 | 22 | // 23 | // TcFlags 24 | // 25 | 26 | type TcFlags uint32 27 | 28 | const ( 29 | BpfTcFReplace TcFlags = C.BPF_TC_F_REPLACE 30 | ) 31 | -------------------------------------------------------------------------------- /user-buf-ring.go: -------------------------------------------------------------------------------- 1 | package libbpfgo 2 | 3 | /* 4 | #cgo LDFLAGS: -lelf -lz 5 | #include "libbpfgo.h" 6 | */ 7 | import "C" 8 | import ( 9 | "fmt" 10 | "sync" 11 | "unsafe" 12 | ) 13 | 14 | // 15 | // UserRingBuffer 16 | // 17 | 18 | type UserRingBuffer struct { 19 | rb *C.struct_user_ring_buffer 20 | bpfMap *BPFMap 21 | closed bool 22 | stop chan struct{} 23 | w chan []byte 24 | errChan chan error 25 | wg sync.WaitGroup 26 | } 27 | 28 | func (rb *UserRingBuffer) Start() { 29 | rb.stop = make(chan struct{}) 30 | rb.errChan = make(chan error, 1) 31 | rb.wg.Add(1) 32 | go func() { 33 | defer rb.wg.Done() 34 | for { 35 | select { 36 | case b := <-rb.w: 37 | if err := rb.submit(b); err != nil { 38 | rb.errChan <- err 39 | } 40 | case <-rb.stop: 41 | return 42 | } 43 | } 44 | }() 45 | } 46 | 47 | func (rb *UserRingBuffer) Error() error { 48 | select { 49 | case err := <-rb.errChan: 50 | return err 51 | default: 52 | return nil 53 | } 54 | } 55 | 56 | func (rb *UserRingBuffer) submit(b []byte) error { 57 | bSizeC := C.size_t(len(b)) 58 | entry, errno := C.user_ring_buffer__reserve(rb.rb, C.uint(bSizeC)) 59 | if entry == nil { 60 | return fmt.Errorf("user_ring_buffer__reserve failed: %v", errno) 61 | } 62 | 63 | C.memcpy(entry, unsafe.Pointer(&b[0]), bSizeC) 64 | C.user_ring_buffer__submit(rb.rb, entry) 65 | return nil 66 | } 67 | 68 | func (rb *UserRingBuffer) Stop() { 69 | if rb.stop == nil { 70 | return 71 | } 72 | close(rb.stop) 73 | rb.wg.Wait() 74 | } 75 | 76 | func (rb *UserRingBuffer) Close() { 77 | if rb.closed { 78 | return 79 | } 80 | 81 | rb.Stop() 82 | C.user_ring_buffer__free(rb.rb) 83 | rb.closed = true 84 | } 85 | --------------------------------------------------------------------------------