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  }