From 0f4e45b03cf56d4759095f5a5d5fc72894560cc6 Mon Sep 17 00:00:00 2001 From: Nikola Grcevski <6207777+grcevski@users.noreply.github.com> Date: Mon, 17 Jul 2023 10:38:16 +0200 Subject: [PATCH] Check and warn on insufficient permissions during process discovery (#194) --- pkg/ebpf/tracer.go | 1 + pkg/exec/file.go | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pkg/ebpf/tracer.go b/pkg/ebpf/tracer.go index 2031aa714..efd1c1483 100644 --- a/pkg/ebpf/tracer.go +++ b/pkg/ebpf/tracer.go @@ -79,6 +79,7 @@ func TracerProvider(ctx context.Context, cfg ebpfcommon.TracerConfig) ([]node.St allFuncs := allGoFunctionNames(programs) elfInfo, goffsets, err := inspect(ctx, &cfg, allFuncs) if err != nil { + log.Error("Error inspecting", err) return nil, fmt.Errorf("inspecting offsets: %w", err) } diff --git a/pkg/exec/file.go b/pkg/exec/file.go index aff3ab976..5268e864c 100644 --- a/pkg/exec/file.go +++ b/pkg/exec/file.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "io" + "os" "strings" "time" @@ -52,7 +53,11 @@ func ProcessNamed(pathSuffix string) ProcessFinder { for _, p := range processes { exePath, err := p.Exe() if err != nil { - // expected for many processes, so we just ignore and keep going + // expected for some processes, but it could also be due to insufficient permissions. + // we check for insufficient permissions, log a warning, and continue + if err := tryAccessPid(p.Pid); err != nil { + log.Warn("can't get process information, possibly because of insufficient permissions", "process", p.Pid, "error", err) + } continue } @@ -81,6 +86,18 @@ func OwnedPort(port int) ProcessFinder { log.Warn("can't get process connections. Ignoring", "process", p.Pid, "error", err) continue } + + if len(conns) == 0 { + // there will be processes with no open file descriptors, but unfortunately the library we use to + // get the connections for a given 'pid' swallows any permission errors. We ensure we didn't fail to + // find the open file descriptors because of access permissions. If we did, we log a warning to let + // the user know they may have configuration issues. + if err := tryAccessPid(p.Pid); err != nil { + log.Warn("can't get process information, possibly because of insufficient permissions", "process", p.Pid, "error", err) + continue + } + } + for _, c := range conns { if c.Laddr.Port == uint32(port) { comm, _ := p.Cmdline() @@ -89,10 +106,17 @@ func OwnedPort(port int) ProcessFinder { } } } + return found, len(found) != 0 } } +func tryAccessPid(pid int32) error { + dir := fmt.Sprintf("/proc/%d/fd", pid) + _, err := os.Open(dir) + return err +} + // findExecELF operation blocks until the executable is available. // TODO: check that all the existing instances of the excutable are instrumented, even when it is offloaded from memory func FindExecELF(ctx context.Context, finder ProcessFinder) ([]FileInfo, error) {