From d47f2a0045d5cf0d94426bce5d1d7281c6fd9bbe Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Fri, 2 Aug 2019 15:27:59 -0400 Subject: [PATCH] Update keyctl for other arches Use definitions from golang.org/x/sys/unix to get the keyctl package building on other Linux architectures. Signed-off-by: Nalin Dahyabhai --- pkg/keyctl/key.go | 11 ++-- pkg/keyctl/keyring.go | 25 ++++---- pkg/keyctl/keyring_test.go | 4 +- pkg/keyctl/perm.go | 6 +- pkg/keyctl/sys_linux.go | 104 ++-------------------------------- pkg/keyctl/sys_linux_386.go | 12 ---- pkg/keyctl/sys_linux_amd64.go | 12 ---- 7 files changed, 33 insertions(+), 141 deletions(-) delete mode 100644 pkg/keyctl/sys_linux_386.go delete mode 100644 pkg/keyctl/sys_linux_amd64.go diff --git a/pkg/keyctl/key.go b/pkg/keyctl/key.go index 699d7c2d83..0d42a8f1c1 100644 --- a/pkg/keyctl/key.go +++ b/pkg/keyctl/key.go @@ -3,12 +3,11 @@ // license that can be found in the LICENSE file. // +build linux -// +build 386 amd64 package keyctl import ( - "unsafe" + "golang.org/x/sys/unix" ) // Key represents a single key linked to one or more kernel keyrings. @@ -20,8 +19,8 @@ type Key struct { } // ID returns the 32-bit kernel identifier for a specific key -func (k *Key) ID() int32 { - return int32(k.id) +func (k *Key) ID() int { + return int(k.id) } // Get the key's value as a byte slice @@ -41,7 +40,7 @@ func (k *Key) Get() ([]byte, error) { b = make([]byte, int(size)) sizeRead = size + 1 for sizeRead > size { - r1, _, err := keyctl(keyctlRead, uintptr(k.id), uintptr(unsafe.Pointer(&b[0])), uintptr(size)) + r1, err := unix.KeyctlBuffer(unix.KEYCTL_READ, int(k.id), b, size) if err != nil { return nil, err } @@ -60,6 +59,6 @@ func (k *Key) Get() ([]byte, error) { // Unlink a key from the keyring it was loaded from (or added to). If the key // is not linked to any other keyrings, it is destroyed. func (k *Key) Unlink() error { - _, _, err := keyctl(keyctlUnlink, uintptr(k.id), uintptr(k.ring)) + _, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, int(k.id), int(k.ring), 0, 0) return err } diff --git a/pkg/keyctl/keyring.go b/pkg/keyctl/keyring.go index 7df2fa88d0..dd037840a8 100644 --- a/pkg/keyctl/keyring.go +++ b/pkg/keyctl/keyring.go @@ -3,11 +3,14 @@ // license that can be found in the LICENSE file. // +build linux -// +build 386 amd64 // Package keyctl is a Go interface to linux kernel keyrings (keyctl interface) package keyctl +import ( + "golang.org/x/sys/unix" +) + // Keyring is the basic interface to a linux keyctl keyring. type Keyring interface { ID @@ -21,12 +24,12 @@ type keyring struct { // ID is unique 32-bit serial number identifiers for all Keys and Keyrings have. type ID interface { - ID() int32 + ID() int } // Add a new key to a keyring. The key can be searched for later by name. func (kr *keyring) Add(name string, key []byte) (*Key, error) { - r, err := addkey("user", name, key, int32(kr.id)) + r, err := unix.AddKey("user", name, key, int(kr.id)) if err == nil { key := &Key{Name: name, id: keyID(r), ring: kr.id} return key, nil @@ -38,36 +41,36 @@ func (kr *keyring) Add(name string, key []byte) (*Key, error) { // one. The key, if found, is linked to the top keyring that Search() was called // from. func (kr *keyring) Search(name string) (*Key, error) { - id, err := searchKeyring(kr.id, name, "user") + id, err := unix.KeyctlSearch(int(kr.id), "user", name, 0) if err == nil { - return &Key{Name: name, id: id, ring: kr.id}, nil + return &Key{Name: name, id: keyID(id), ring: kr.id}, nil } return nil, err } // ID returns the 32-bit kernel identifier of a keyring -func (kr *keyring) ID() int32 { - return int32(kr.id) +func (kr *keyring) ID() int { + return int(kr.id) } // SessionKeyring returns the current login session keyring func SessionKeyring() (Keyring, error) { - return newKeyring(keySpecSessionKeyring) + return newKeyring(unix.KEY_SPEC_SESSION_KEYRING) } // UserKeyring returns the keyring specific to the current user. func UserKeyring() (Keyring, error) { - return newKeyring(keySpecUserKeyring) + return newKeyring(unix.KEY_SPEC_USER_KEYRING) } // Unlink an object from a keyring func Unlink(parent Keyring, child ID) error { - _, _, err := keyctl(keyctlUnlink, uintptr(child.ID()), uintptr(parent.ID())) + _, err := unix.KeyctlInt(unix.KEYCTL_UNLINK, child.ID(), parent.ID(), 0, 0) return err } // Link a key into a keyring func Link(parent Keyring, child ID) error { - _, _, err := keyctl(keyctlLink, uintptr(child.ID()), uintptr(parent.ID())) + _, err := unix.KeyctlInt(unix.KEYCTL_LINK, child.ID(), parent.ID(), 0, 0) return err } diff --git a/pkg/keyctl/keyring_test.go b/pkg/keyctl/keyring_test.go index 41bd8b5d31..a610584deb 100644 --- a/pkg/keyctl/keyring_test.go +++ b/pkg/keyctl/keyring_test.go @@ -1,5 +1,4 @@ // +build linux -// +build 386 amd64 package keyctl @@ -82,6 +81,9 @@ func TestLink(t *testing.T) { } _, err = userKeyring.Search(testname) + if err == nil { + t.Fatalf("Expected error, but got key %v", testname) + } ExpectedError := "required key not available" if err.Error() != ExpectedError { t.Fatal(err) diff --git a/pkg/keyctl/perm.go b/pkg/keyctl/perm.go index 95252e0af2..152b740047 100644 --- a/pkg/keyctl/perm.go +++ b/pkg/keyctl/perm.go @@ -6,6 +6,10 @@ package keyctl +import ( + "golang.org/x/sys/unix" +) + // KeyPerm represents in-kernel access control permission to keys and keyrings // as a 32-bit integer broken up into four permission sets, one per byte. // In MSB order, the perms are: Processor, User, Group, Other. @@ -24,6 +28,6 @@ const ( // SetPerm sets the permissions on a key or keyring. func SetPerm(k ID, p KeyPerm) error { - _, _, err := keyctl(keyctlSetPerm, uintptr(k.ID()), uintptr(p)) + err := unix.KeyctlSetperm(k.ID(), uint32(p)) return err } diff --git a/pkg/keyctl/sys_linux.go b/pkg/keyctl/sys_linux.go index 63aa87d259..80e6d6a065 100644 --- a/pkg/keyctl/sys_linux.go +++ b/pkg/keyctl/sys_linux.go @@ -3,119 +3,27 @@ // license that can be found in the LICENSE file. // +build linux -// +build 386 amd64 package keyctl import ( - "syscall" - "unsafe" + "golang.org/x/sys/unix" ) -type keyctlCommand int +type keyID int -type keyID int32 - -const ( - keySpecSessionKeyring keyID = -3 - keySpecUserKeyring keyID = -4 -) - -const ( - keyctlGetKeyringID keyctlCommand = 0 - keyctlSetPerm keyctlCommand = 5 - keyctlLink keyctlCommand = 8 - keyctlUnlink keyctlCommand = 9 - keyctlSearch keyctlCommand = 10 - keyctlRead keyctlCommand = 11 -) - -func (id keyID) ID() int32 { - return int32(id) -} - -func keyctl(cmd keyctlCommand, args ...uintptr) (r1 int32, r2 int32, err error) { - a := make([]uintptr, 6) - l := len(args) - if l > 5 { - l = 5 - } - a[0] = uintptr(cmd) - for idx, v := range args[:l] { - a[idx+1] = v - } - v1, v2, errno := syscall.Syscall6(syscallKeyctl, a[0], a[1], a[2], a[3], a[4], a[5]) - if errno != 0 { - err = errno - return - } - - r1 = int32(v1) - r2 = int32(v2) - return -} - -func addkey(keyType, keyDesc string, payload []byte, id int32) (int32, error) { - var ( - err error - errno syscall.Errno - b1, b2 *byte - r1 uintptr - pptr unsafe.Pointer - ) - - if b1, err = syscall.BytePtrFromString(keyType); err != nil { - return 0, err - } - - if b2, err = syscall.BytePtrFromString(keyDesc); err != nil { - return 0, err - } - - if len(payload) > 0 { - pptr = unsafe.Pointer(&payload[0]) - } - r1, _, errno = syscall.Syscall6(syscallAddKey, - uintptr(unsafe.Pointer(b1)), - uintptr(unsafe.Pointer(b2)), - uintptr(pptr), - uintptr(len(payload)), - uintptr(id), - 0) - - if errno != 0 { - err = errno - return 0, err - } - return int32(r1), nil +func (id keyID) ID() int { + return int(id) } func newKeyring(id keyID) (*keyring, error) { - r1, _, err := keyctl(keyctlGetKeyringID, uintptr(id), uintptr(1)) + r1, err := unix.KeyctlGetKeyringID(int(id), true) if err != nil { return nil, err } if id < 0 { - r1 = int32(id) + r1 = int(id) } return &keyring{id: keyID(r1)}, nil } - -func searchKeyring(id keyID, name, keyType string) (keyID, error) { - var ( - r1 int32 - b1, b2 *byte - err error - ) - - if b1, err = syscall.BytePtrFromString(keyType); err != nil { - return 0, err - } - if b2, err = syscall.BytePtrFromString(name); err != nil { - return 0, err - } - - r1, _, err = keyctl(keyctlSearch, uintptr(id), uintptr(unsafe.Pointer(b1)), uintptr(unsafe.Pointer(b2))) - return keyID(r1), err -} diff --git a/pkg/keyctl/sys_linux_386.go b/pkg/keyctl/sys_linux_386.go deleted file mode 100644 index 0611855180..0000000000 --- a/pkg/keyctl/sys_linux_386.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015 Jesse Sipprell. 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 - -package keyctl - -const ( - syscallKeyctl uintptr = 288 - syscallAddKey uintptr = 286 -) diff --git a/pkg/keyctl/sys_linux_amd64.go b/pkg/keyctl/sys_linux_amd64.go deleted file mode 100644 index 60c7ad8560..0000000000 --- a/pkg/keyctl/sys_linux_amd64.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015 Jesse Sipprell. 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 - -package keyctl - -const ( - syscallKeyctl uintptr = 250 - syscallAddKey uintptr = 248 -)