diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 1460ef5a..f657a5d3 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -46,7 +46,7 @@ func New(config *Config) (*Debugger, error) { log.Printf("attaching to pid %d", d.config.AttachPid) p, err := proc.Attach(d.config.AttachPid) if err != nil { - return nil, fmt.Errorf("could not attach to pid %d: %s", d.config.AttachPid, err) + return nil, attachErrorMessage(d.config.AttachPid, err) } d.process = p } else { diff --git a/service/debugger/debugger_darwin.go b/service/debugger/debugger_darwin.go new file mode 100644 index 00000000..9edeca65 --- /dev/null +++ b/service/debugger/debugger_darwin.go @@ -0,0 +1,10 @@ +package debugger + +import ( + "fmt" +) + +func attachErrorMessage(pid int, err error) error { + //TODO: mention certificates? + return fmt.Errorf("could not attach to pid %d: %s", pid, err) +} diff --git a/service/debugger/debugger_linux.go b/service/debugger/debugger_linux.go new file mode 100644 index 00000000..5338c622 --- /dev/null +++ b/service/debugger/debugger_linux.go @@ -0,0 +1,30 @@ +package debugger + +import ( + "fmt" + "io/ioutil" + "os" + "syscall" +) + +func attachErrorMessage(pid int, err error) error { + fallbackerr := fmt.Errorf("could not attach to pid %d: %s", pid, err) + if serr, ok := err.(syscall.Errno); ok { + switch serr { + case syscall.EPERM: + bs, err := ioutil.ReadFile("/proc/sys/kernel/yama/ptrace_scope") + if err == nil && len(bs) >= 1 && bs[0] != '0' { + // Yama documentation: https://www.kernel.org/doc/Documentation/security/Yama.txt + return fmt.Errorf("Could not attach to pid %d: set /proc/sys/kernel/yama/ptrace_scope to 0", pid) + } + fi, err := os.Stat(fmt.Sprintf("/proc/%d", pid)) + if err != nil { + return fallbackerr + } + if fi.Sys().(*syscall.Stat_t).Uid != uint32(os.Getuid()) { + return fmt.Errorf("Could not attach to pid %d: current user does not own the process", pid) + } + } + } + return fallbackerr +}