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 }