From 2b56ef422e71d79f5038df4246035e4cc0b84dcb Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 6 Dec 2023 17:43:22 +0100 Subject: [PATCH] fix(pkg,cmd): eBPF probe must be symlinked under /root/.falco/falco-bpf.o. Signed-off-by: Federico Di Pierro --- cmd/driver/install/install.go | 5 ++-- pkg/driver/type/bpf.go | 52 ++++++++++++++++++++++++----------- pkg/driver/type/kmod.go | 10 +++---- pkg/driver/type/modernbpf.go | 2 +- pkg/driver/type/type.go | 2 +- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/cmd/driver/install/install.go b/cmd/driver/install/install.go index 0ea3cf6a..5b99b060 100644 --- a/cmd/driver/install/install.go +++ b/cmd/driver/install/install.go @@ -72,7 +72,7 @@ func NewDriverInstallCmd(ctx context.Context, opt *options.Common, driver *optio // It is only useful for kmod, as it will try to // modprobe a pre-existent version of the driver, // hoping it will be compatible. - _ = driver.Type.Load(o.Printer, dest, err != nil) + _ = driver.Type.Load(o.Printer, dest, o.Driver.Name, err != nil) } return err }, @@ -141,7 +141,7 @@ func (o *driverInstallOptions) RunDriverInstall(ctx context.Context) (string, er return "", fmt.Errorf("detected an unsupported target system, please get in touch with the Falco community") } } - o.Printer.Logger.Info("found distro", o.Printer.Logger.Args("target", d)) + o.Printer.Logger.Info("Found distro", o.Printer.Logger.Args("target", d)) var ( dest string @@ -163,6 +163,7 @@ func (o *driverInstallOptions) RunDriverInstall(ctx context.Context) (string, er // Print much more readable output as-is o.Printer.DefaultText.Print(buf.String()) } + buf.Reset() if err != nil { return "", err } diff --git a/pkg/driver/type/bpf.go b/pkg/driver/type/bpf.go index 6f475cfc..3d4885af 100644 --- a/pkg/driver/type/bpf.go +++ b/pkg/driver/type/bpf.go @@ -17,9 +17,11 @@ package drivertype import ( "fmt" + "os" "os/exec" "path/filepath" + "github.com/docker/docker/pkg/homedir" "github.com/falcosecurity/driverkit/pkg/kernelrelease" "golang.org/x/net/context" "k8s.io/utils/mount" @@ -41,25 +43,23 @@ func (b *bpf) String() string { return TypeBpf } -func (b *bpf) Cleanup(printer *output.Printer, _ string) error { - // Mount /sys/kernel/debug that is needed on old (pre 4.17) kernel releases, - // since these releases still did not support raw tracepoints. - // BPF_PROG_TYPE_RAW_TRACEPOINT was introduced in 4.17 indeed: - // https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9 - exists, _ := utils.FileExists("/sys/kernel/debug/tracing") - if exists { - return nil - } - printer.Logger.Info("Mounting debugfs for bpf driver.") - mounter := mount.New("/bin/mount") - // We don't fail if this fails; let's try to build a probe anyway. - if err := mounter.Mount("debugfs", "/sys/kernel/debug", "debugfs", []string{"nodev"}); err != nil { - printer.Logger.Warn("Failed to mount debugfs.", printer.Logger.Args("err", err)) - } +func (b *bpf) Cleanup(_ *output.Printer, _ string) error { return nil } -func (b *bpf) Load(_ *output.Printer, _ string, _ bool) error { +func (b *bpf) Load(printer *output.Printer, src, driverName string, fallback bool) error { + if !fallback { + symlinkPath := filepath.Join(homedir.Get(), ".falco", fmt.Sprintf("%s-bpf.o", driverName)) + printer.Logger.Info("Symlinking eBPF probe", printer.Logger.Args("src", src, "dest", symlinkPath)) + _ = os.Remove(symlinkPath) + err := os.Symlink(src, symlinkPath) + if err == nil { + printer.Logger.Info("eBPF probe symlinked") + } else { + printer.Logger.Info("Failed to symlink eBPF probe") + } + return err + } return nil } @@ -78,6 +78,8 @@ func (b *bpf) Build(ctx context.Context, driverName, driverVersion string, env map[string]string, ) (string, error) { + // We don't fail if this fails; let's try to build a probe anyway. + _ = mountKernelDebug(printer) srcPath := fmt.Sprintf("/usr/src/%s-%s/bpf", driverName, driverVersion) makeCmdArgs := fmt.Sprintf(`make -C %q`, filepath.Clean(srcPath)) @@ -93,3 +95,21 @@ func (b *bpf) Build(ctx context.Context, outProbe := fmt.Sprintf("%s/probe.o", srcPath) return outProbe, err } + +func mountKernelDebug(printer *output.Printer) error { + // Mount /sys/kernel/debug that is needed on old (pre 4.17) kernel releases, + // since these releases still did not support raw tracepoints. + // BPF_PROG_TYPE_RAW_TRACEPOINT was introduced in 4.17 indeed: + // https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9 + exists, _ := utils.FileExists("/sys/kernel/debug/tracing") + if exists { + return nil + } + printer.Logger.Info("Mounting debugfs for bpf driver.") + mounter := mount.New("/bin/mount") + err := mounter.Mount("debugfs", "/sys/kernel/debug", "debugfs", []string{"nodev"}) + if err != nil { + printer.Logger.Warn("Failed to mount debugfs.", printer.Logger.Args("err", err)) + } + return err +} diff --git a/pkg/driver/type/kmod.go b/pkg/driver/type/kmod.go index bb2ee2dc..06f24e39 100644 --- a/pkg/driver/type/kmod.go +++ b/pkg/driver/type/kmod.go @@ -130,7 +130,7 @@ func (k *kmod) Cleanup(printer *output.Printer, driverName string) error { return nil } -func (k *kmod) Load(printer *output.Printer, driverName string, fallback bool) error { +func (k *kmod) Load(printer *output.Printer, src, driverName string, fallback bool) error { if fallback { // Try to modprobe any existent version of the kmod; this is a fallback // when both download and build of kmod fail. @@ -144,15 +144,15 @@ func (k *kmod) Load(printer *output.Printer, driverName string, fallback bool) e return err } - chconCmdArgs := fmt.Sprintf(`chcon -t modules_object_t %q`, driverName) + chconCmdArgs := fmt.Sprintf(`chcon -t modules_object_t %q`, src) // We don't want to catch any error from this call // chcon(1): change file SELinux security context _, _ = exec.Command("bash", "-c", chconCmdArgs).Output() //nolint:gosec // false positive - _, err := exec.Command("insmod", driverName).Output() + _, err := exec.Command("insmod", src).Output() if err == nil { - printer.Logger.Info("Success: module found and loaded in dkms.", printer.Logger.Args("driver", driverName)) + printer.Logger.Info("Success: module found and loaded in dkms.", printer.Logger.Args("driver", src)) } else { - printer.Logger.Warn("Unable to insmod module.", printer.Logger.Args("driver", driverName, "err", err)) + printer.Logger.Warn("Unable to insmod module.", printer.Logger.Args("driver", src, "err", err)) } return err } diff --git a/pkg/driver/type/modernbpf.go b/pkg/driver/type/modernbpf.go index 9d822064..82a11210 100644 --- a/pkg/driver/type/modernbpf.go +++ b/pkg/driver/type/modernbpf.go @@ -39,7 +39,7 @@ func (m *modernBpf) Cleanup(_ *output.Printer, _ string) error { return nil } -func (m *modernBpf) Load(_ *output.Printer, _ string, _ bool) error { +func (m *modernBpf) Load(_ *output.Printer, _, _ string, _ bool) error { return nil } diff --git a/pkg/driver/type/type.go b/pkg/driver/type/type.go index dcebf6fb..d8ec14b0 100644 --- a/pkg/driver/type/type.go +++ b/pkg/driver/type/type.go @@ -34,7 +34,7 @@ var driverTypes = map[string]DriverType{} type DriverType interface { fmt.Stringer Cleanup(printer *output.Printer, driverName string) error - Load(printer *output.Printer, driverName string, fallback bool) error + Load(printer *output.Printer, src, driverName string, fallback bool) error Extension() string HasArtifacts() bool Build(ctx context.Context, printer *output.Printer, kr kernelrelease.KernelRelease,