-
Notifications
You must be signed in to change notification settings - Fork 626
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
linux, exec: adds capabilities detection - prints a message when runn…
…ing pyroscope exec with no proper capabilities
- Loading branch information
1 parent
30ec4c0
commit e37a9a0
Showing
4 changed files
with
110 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// +build darwin | ||
|
||
package exec | ||
|
||
import ( | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func performOSChecks() { | ||
if !isRoot() { | ||
logrus.Fatal("on macOS you're required to run the agent with sudo") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// +build linux | ||
|
||
package exec | ||
|
||
import ( | ||
"github.com/pyroscope-io/pyroscope/pkg/util/caps" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func performOSChecks() { | ||
if !hasSysPtraceCap() { | ||
logrus.Fatal("if you're running pyroscope in a Docker container, add --cap-add=sys_ptrace. See our Docker Guide for more information: https://pyroscope.io/docs/docker-guide") | ||
} | ||
} | ||
|
||
// See linux source code: https://github.com/torvalds/linux/blob/6ad4bf6ea1609fb539a62f10fca87ddbd53a0315/include/uapi/linux/capability.h#L235 | ||
const CAP_SYS_PTRACE = 19 | ||
|
||
func hasSysPtraceCap() bool { | ||
c, err := caps.Get() | ||
if err != nil { | ||
logrus.Warn("Could not read capabilities. Please submit an issue at https://github.com/pyroscope-io/pyroscope/issues") | ||
return true // I don't know of cases when this would happen, but if it does I'd rather give this program a chance | ||
} | ||
|
||
if c.Inheritable() == 0 { | ||
logrus.Warn("Could not read capabilities. Please submit an issue at https://github.com/pyroscope-io/pyroscope/issues") | ||
return true // I don't know of cases when this would happen, but if it does I'd rather give this program a chance | ||
} | ||
|
||
return c.Has(CAP_SYS_PTRACE) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright 2015 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// +build linux | ||
|
||
// this is copied from https://golang.org/src/syscall/exec_linux_test.go | ||
|
||
package caps | ||
|
||
import ( | ||
"fmt" | ||
"syscall" | ||
"unsafe" | ||
) | ||
|
||
type header struct { | ||
version uint32 | ||
pid int32 | ||
} | ||
|
||
type data struct { | ||
effective uint32 | ||
permitted uint32 | ||
inheritable uint32 | ||
} | ||
|
||
const CAP_SYS_TIME = 25 | ||
const CAP_SYSLOG = 34 | ||
|
||
type Caps struct { | ||
header header | ||
data [2]data | ||
} | ||
|
||
func Get() (Caps, error) { | ||
var c Caps | ||
|
||
// Get capability version | ||
if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&c.header)), uintptr(unsafe.Pointer(nil)), 0); errno != 0 { | ||
return c, fmt.Errorf("SYS_CAPGET: %v", errno) | ||
} | ||
|
||
// Get current capabilities | ||
if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&c.header)), uintptr(unsafe.Pointer(&c.data[0])), 0); errno != 0 { | ||
return c, fmt.Errorf("SYS_CAPGET: %v", errno) | ||
} | ||
|
||
return c, nil | ||
} | ||
|
||
func (c Caps) Has(capSearch uint) bool { | ||
return (c.data[0].inheritable & (1 << capSearch)) != 0 | ||
} | ||
|
||
func (c Caps) Inheritable() uint32 { | ||
return c.data[0].inheritable | ||
} |