github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/util/caps/caps.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build linux 6 // +build linux 7 8 // this is copied from https://golang.org/src/syscall/exec_linux_test.go 9 10 package caps 11 12 import ( 13 "fmt" 14 "syscall" 15 "unsafe" 16 ) 17 18 type header struct { 19 version uint32 20 pid int32 21 } 22 23 type data struct { 24 effective uint32 25 permitted uint32 26 inheritable uint32 27 } 28 29 //revive:disable:var-naming Those names mimics system constants names 30 const ( 31 CAP_SYS_TIME = 25 32 CAP_SYSLOG = 34 33 CAP_SYS_PTRACE = 19 34 ) 35 36 //revive:enable:var-naming 37 38 type Caps struct { 39 header header 40 data data 41 } 42 43 func (c Caps) has(capSearch uint) bool { 44 return (c.data.inheritable & (1 << capSearch)) != 0 45 } 46 47 func (c Caps) inheritable() uint32 { 48 return c.data.inheritable 49 } 50 func Get() (Caps, error) { 51 var c Caps 52 53 // Get capability version 54 if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&c.header)), uintptr(unsafe.Pointer(nil)), 0); errno != 0 { 55 return c, fmt.Errorf("SYS_CAPGET: %v", errno) 56 } 57 58 // Get current capabilities 59 if _, _, errno := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(&c.header)), uintptr(unsafe.Pointer(&c.data)), 0); errno != 0 { 60 return c, fmt.Errorf("SYS_CAPGET: %v", errno) 61 } 62 63 return c, nil 64 } 65 66 func HasSysPtraceCap() bool { 67 c, err := Get() 68 if err != nil { 69 return true // I don't know of cases when this would happen, but if it does I'd rather give this program a chance 70 } 71 72 if c.inheritable() == 0 { 73 return true // I don't know of cases when this would happen, but if it does I'd rather give this program a chance 74 } 75 76 return c.has(CAP_SYS_PTRACE) 77 }