Skip to content

Commit d5320ed

Browse files
tracee-ebpf: export initialization logic (#2006)
Add new initialization package for bpfobject and kernelconfig. Move the flags package outside internal for external usage. This is done in order to share init logic for integration tests and other apps that need to initialize tracee.
1 parent d7552d6 commit d5320ed

File tree

10 files changed

+244
-216
lines changed

10 files changed

+244
-216
lines changed
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

cmd/tracee-ebpf/internal/flags/flags_test.go renamed to cmd/tracee-ebpf/flags/flags_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"io/ioutil"
77
"testing"
88

9-
"github.com/aquasecurity/tracee/cmd/tracee-ebpf/internal/flags"
9+
"github.com/aquasecurity/tracee/cmd/tracee-ebpf/flags"
1010
tracee "github.com/aquasecurity/tracee/pkg/ebpf"
1111
"github.com/aquasecurity/tracee/pkg/events"
1212
"github.com/aquasecurity/tracee/pkg/events/queue"
File renamed without changes.
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package initialize
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"io/ioutil"
7+
"os"
8+
"path/filepath"
9+
"strings"
10+
11+
"github.com/aquasecurity/libbpfgo/helpers"
12+
embed "github.com/aquasecurity/tracee"
13+
"github.com/aquasecurity/tracee/cmd/tracee-ebpf/internal/debug"
14+
tracee "github.com/aquasecurity/tracee/pkg/ebpf"
15+
)
16+
17+
func BpfObject(config *tracee.Config, kConfig *helpers.KernelConfig, OSInfo *helpers.OSInfo, installPath string, version string) error {
18+
var d = struct {
19+
btfenv bool
20+
bpfenv bool
21+
btfvmlinux bool
22+
}{
23+
btfenv: false,
24+
bpfenv: false,
25+
btfvmlinux: helpers.OSBTFEnabled(),
26+
}
27+
28+
debug := config.Debug
29+
30+
bpfFilePath, err := checkEnvPath("TRACEE_BPF_FILE")
31+
if bpfFilePath != "" {
32+
d.bpfenv = true
33+
} else if bpfFilePath == "" && err != nil {
34+
return err
35+
}
36+
btfFilePath, err := checkEnvPath("TRACEE_BTF_FILE")
37+
if btfFilePath != "" {
38+
d.btfenv = true
39+
} else if btfFilePath == "" && err != nil {
40+
return err
41+
}
42+
if debug {
43+
fmt.Printf("BTF: bpfenv = %v, btfenv = %v, vmlinux = %v\n", d.bpfenv, d.btfenv, d.btfvmlinux)
44+
}
45+
46+
var tVersion, kVersion string
47+
var bpfBytes []byte
48+
var unpackBTFFile string
49+
50+
// Decision ordering:
51+
52+
// (1) BPF file given & BTF (vmlinux or env) exists: always load BPF as CO-RE
53+
// (2) BPF file given & if no BTF exists: it is a non CO-RE BPF
54+
55+
if d.bpfenv {
56+
if debug {
57+
fmt.Printf("BPF: using BPF object from environment: %v\n", bpfFilePath)
58+
}
59+
if d.btfvmlinux || d.btfenv { // (1)
60+
if d.btfenv {
61+
if debug {
62+
fmt.Printf("BTF: using BTF file from environment: %v\n", btfFilePath)
63+
}
64+
config.BTFObjPath = btfFilePath
65+
}
66+
} // else {} (2)
67+
if bpfBytes, err = ioutil.ReadFile(bpfFilePath); err != nil {
68+
return err
69+
}
70+
71+
goto out
72+
}
73+
74+
// (3) no BPF file given & BTF (vmlinux or env) exists: load embedded BPF as CO-RE
75+
76+
if d.btfvmlinux || d.btfenv { // (3)
77+
if debug {
78+
fmt.Println("BPF: using embedded BPF object")
79+
}
80+
if d.btfenv {
81+
if debug {
82+
fmt.Printf("BTF: using BTF file from environment: %v\n", btfFilePath)
83+
}
84+
config.BTFObjPath = btfFilePath
85+
}
86+
bpfFilePath = "embedded-core"
87+
bpfBytes, err = unpackCOREBinary()
88+
if err != nil {
89+
return fmt.Errorf("could not unpack embedded CO-RE eBPF object: %v", err)
90+
}
91+
92+
goto out
93+
}
94+
95+
// (4) no BPF file given & no BTF available: check embedded BTF files
96+
97+
unpackBTFFile = filepath.Join(installPath, "/tracee.btf")
98+
err = unpackBTFHub(unpackBTFFile, OSInfo)
99+
100+
if err == nil {
101+
if debug {
102+
fmt.Printf("BTF: using BTF file from embedded btfhub: %v\n", unpackBTFFile)
103+
}
104+
config.BTFObjPath = unpackBTFFile
105+
bpfFilePath = "embedded-core"
106+
bpfBytes, err = unpackCOREBinary()
107+
if err != nil {
108+
return fmt.Errorf("could not unpack embedded CO-RE eBPF object: %v", err)
109+
}
110+
111+
goto out
112+
}
113+
114+
// (5) no BPF file given & no BTF available & no embedded BTF: non CO-RE BPF
115+
116+
tVersion = strings.ReplaceAll(version, "\"", "")
117+
tVersion = strings.ReplaceAll(tVersion, ".", "_")
118+
kVersion = OSInfo.GetOSReleaseFieldValue(helpers.OS_KERNEL_RELEASE)
119+
kVersion = strings.ReplaceAll(kVersion, ".", "_")
120+
121+
bpfFilePath = fmt.Sprintf("%s/tracee.bpf.%s.%s.o", installPath, kVersion, tVersion)
122+
if debug {
123+
fmt.Printf("BPF: no BTF file was found or provided\n")
124+
fmt.Printf("BPF: trying non CO-RE eBPF at %s\n", bpfFilePath)
125+
}
126+
if bpfBytes, err = ioutil.ReadFile(bpfFilePath); err != nil {
127+
// tell entrypoint that eBPF non CO-RE obj compilation is needed
128+
fmt.Printf("BPF: %v\n", err)
129+
fmt.Printf("BPF: ATTENTION:\n")
130+
fmt.Printf("BPF: It seems tracee-ebpf can't load CO-RE eBPF obj and could not find\n")
131+
fmt.Printf("BPF: the non CO-RE object in %s. You may build a non CO-RE eBPF\n", installPath)
132+
fmt.Printf("BPF: obj by using the source tree and executing \"make install-bpf-nocore\".\n")
133+
os.Exit(2)
134+
}
135+
136+
out:
137+
config.KernelConfig = kConfig
138+
config.BPFObjPath = bpfFilePath
139+
config.BPFObjBytes = bpfBytes
140+
141+
return nil
142+
}
143+
144+
func checkEnvPath(env string) (string, error) {
145+
filePath, _ := os.LookupEnv(env)
146+
if filePath != "" {
147+
_, err := os.Stat(filePath)
148+
if err != nil {
149+
return "", fmt.Errorf("could not open %s %s", env, filePath)
150+
}
151+
return filePath, nil
152+
}
153+
return "", nil
154+
}
155+
156+
func unpackCOREBinary() ([]byte, error) {
157+
b, err := embed.BPFBundleInjected.ReadFile("dist/tracee.bpf.core.o")
158+
if err != nil {
159+
return nil, err
160+
}
161+
162+
if debug.Enabled() {
163+
fmt.Println("unpacked CO:RE bpf object file into memory")
164+
}
165+
166+
return b, nil
167+
}
168+
169+
// unpackBTFHub unpacks tailored, to the compiled eBPF object, BTF files for kernel supported by BTFHub
170+
func unpackBTFHub(outFilePath string, OSInfo *helpers.OSInfo) error {
171+
var btfFilePath string
172+
173+
osId := OSInfo.GetOSReleaseFieldValue(helpers.OS_ID)
174+
versionId := strings.Replace(OSInfo.GetOSReleaseFieldValue(helpers.OS_VERSION_ID), "\"", "", -1)
175+
kernelRelease := OSInfo.GetOSReleaseFieldValue(helpers.OS_KERNEL_RELEASE)
176+
arch := OSInfo.GetOSReleaseFieldValue(helpers.OS_ARCH)
177+
178+
if err := os.MkdirAll(filepath.Dir(outFilePath), 0755); err != nil {
179+
return fmt.Errorf("could not create temp dir: %s", err.Error())
180+
}
181+
182+
btfFilePath = fmt.Sprintf("dist/btfhub/%s/%s/%s/%s.btf", osId, versionId, arch, kernelRelease)
183+
btfFile, err := embed.BPFBundleInjected.Open(btfFilePath)
184+
if err != nil {
185+
return fmt.Errorf("error opening embedded btfhub file: %s", err.Error())
186+
}
187+
defer btfFile.Close()
188+
189+
outFile, err := os.Create(outFilePath)
190+
if err != nil {
191+
return fmt.Errorf("could not create btf file: %s", err.Error())
192+
}
193+
defer outFile.Close()
194+
195+
if _, err := io.Copy(outFile, btfFile); err != nil {
196+
return fmt.Errorf("error copying embedded btfhub file: %s", err.Error())
197+
198+
}
199+
200+
return nil
201+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package initialize
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/aquasecurity/libbpfgo/helpers"
8+
)
9+
10+
func KernelConfig() (*helpers.KernelConfig, error) {
11+
kernelConfig, err := helpers.InitKernelConfig()
12+
if err != nil {
13+
// do not fail if we cannot init kconfig - print out warning messages
14+
fmt.Fprintf(os.Stderr, "KConfig: warning: could not check enabled kconfig features\n(%v)\n", err)
15+
fmt.Fprintf(os.Stderr, "KConfig: warning: assuming kconfig values, might have unexpected behavior\n")
16+
return kernelConfig, nil
17+
}
18+
19+
kernelConfig.AddNeeded(helpers.CONFIG_BPF, helpers.BUILTIN)
20+
kernelConfig.AddNeeded(helpers.CONFIG_BPF_SYSCALL, helpers.BUILTIN)
21+
kernelConfig.AddNeeded(helpers.CONFIG_KPROBE_EVENTS, helpers.BUILTIN)
22+
kernelConfig.AddNeeded(helpers.CONFIG_BPF_EVENTS, helpers.BUILTIN)
23+
missing := kernelConfig.CheckMissing() // do fail if we found os-release file and it is not enough
24+
if len(missing) > 0 {
25+
return nil, fmt.Errorf("missing kernel configuration options: %s", missing)
26+
}
27+
return kernelConfig, nil
28+
}

cmd/tracee-ebpf/internal/printer/printer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"os"
66
"testing"
77

8-
"github.com/aquasecurity/tracee/cmd/tracee-ebpf/internal/flags"
8+
"github.com/aquasecurity/tracee/cmd/tracee-ebpf/flags"
99
"github.com/aquasecurity/tracee/cmd/tracee-ebpf/internal/printer"
1010
"github.com/stretchr/testify/assert"
1111
)

0 commit comments

Comments
 (0)