github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/keys/keyctl.go (about)

     1  // +build linux
     2  
     3  package keys
     4  
     5  import (
     6  	"fmt"
     7  	"strconv"
     8  	"strings"
     9  	"syscall"
    10  	"unsafe"
    11  )
    12  
    13  const KEYCTL_JOIN_SESSION_KEYRING = 1
    14  const KEYCTL_SETPERM = 5
    15  const KEYCTL_DESCRIBE = 6
    16  
    17  type KeySerial uint32
    18  
    19  func JoinSessionKeyring(name string) (KeySerial, error) {
    20  	var _name *byte
    21  	var err error
    22  
    23  	if len(name) > 0 {
    24  		_name, err = syscall.BytePtrFromString(name)
    25  		if err != nil {
    26  			return KeySerial(0), err
    27  		}
    28  	}
    29  
    30  	sessKeyId, _, errn := syscall.Syscall(syscall.SYS_KEYCTL, KEYCTL_JOIN_SESSION_KEYRING, uintptr(unsafe.Pointer(_name)), 0)
    31  	if errn != 0 {
    32  		return 0, fmt.Errorf("could not create session key: %v", errn)
    33  	}
    34  	return KeySerial(sessKeyId), nil
    35  }
    36  
    37  // ModKeyringPerm modifies permissions on a keyring by reading the current permissions,
    38  // anding the bits with the given mask (clearing permissions) and setting
    39  // additional permission bits
    40  func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
    41  	dest := make([]byte, 1024)
    42  	destBytes := unsafe.Pointer(&dest[0])
    43  
    44  	if _, _, err := syscall.Syscall6(syscall.SYS_KEYCTL, uintptr(KEYCTL_DESCRIBE), uintptr(ringId), uintptr(destBytes), uintptr(len(dest)), 0, 0); err != 0 {
    45  		return err
    46  	}
    47  
    48  	res := strings.Split(string(dest), ";")
    49  	if len(res) < 5 {
    50  		return fmt.Errorf("Destination buffer for key description is too small")
    51  	}
    52  
    53  	// parse permissions
    54  	perm64, err := strconv.ParseUint(res[3], 16, 32)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	perm := (uint32(perm64) & mask) | setbits
    60  
    61  	if _, _, err := syscall.Syscall(syscall.SYS_KEYCTL, uintptr(KEYCTL_SETPERM), uintptr(ringId), uintptr(perm)); err != 0 {
    62  		return err
    63  	}
    64  
    65  	return nil
    66  }