Skip to content

Commit cbd86dc

Browse files
author
65a
committed
Support attaching the kernel persistent keyring to an existing keyring (for example, session keyring).
Currently, this will always use the persistent keyring associated with the UID executing the process. Specifying UID is supportable but use case unclear. The AttachPersistent() function will return a Keyring pointing to the kernel persistent keyring, or an error.
1 parent 36ca026 commit cbd86dc

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

keyring.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
//go:build linux
56
// +build linux
67

78
// A Go interface to linux kernel keyrings (keyctl interface)
@@ -21,6 +22,7 @@ type Keyring interface {
2122
Add(string, []byte) (*Key, error)
2223
Search(string) (*Key, error)
2324
SetDefaultTimeout(uint)
25+
AttachPersistent() (Keyring, error)
2426
}
2527

2628
// Named keyrings are user-created keyrings linked to a parent keyring. The
@@ -93,6 +95,13 @@ func (kr *keyring) Search(name string) (*Key, error) {
9395
return nil, err
9496
}
9597

98+
// AttachPersistentKeyring attaches the current executing context's persistent
99+
// keyring to this keyring. See persistent-keyring(7) for more info.
100+
// It returns either an error, or the persistent Keyring.
101+
func (kr *keyring) AttachPersistent() (Keyring, error) {
102+
return attachPersistent(kr.id)
103+
}
104+
96105
// Return the current login session keyring
97106
func SessionKeyring() (Keyring, error) {
98107
return newKeyring(keySpecSessionKeyring)

keyring_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ func TestCreateKeyring(t *testing.T) {
112112
}
113113
}
114114

115+
func TestAttachPersistentKeyring(t *testing.T) {
116+
kr, err := SessionKeyring()
117+
if err != nil {
118+
t.Fatalf("unexpected test failure: could not create session keyring: %v", err)
119+
}
120+
pkr, err := kr.AttachPersistent()
121+
if err != nil {
122+
t.Fatalf("unexpected test failure: could not attach persistent keyring: %v", err)
123+
}
124+
t.Logf("found persistent keyring %d", pkr.Id())
125+
}
126+
115127
func TestCreateNestedKeyring(t *testing.T) {
116128
ring := helperTestCreateKeyring(nil, "", t)
117129

sys_linux.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ const (
3737
keyctlSetReqKeyKeyring
3838
keyctlSetTimeout
3939
keyctlAssumeAuthority
40+
keyctlGetSecurity
41+
keyctlSessionToParent
42+
keyctlReject
43+
keyctlInstantiateIOV
44+
keyctlInvalidate
45+
keyctlGetPersistent
4046
)
4147

4248
var debugSyscalls bool
@@ -81,6 +87,8 @@ func (cmd keyctlCommand) String() string {
8187
return "keyctlSetTimeout"
8288
case keyctlAssumeAuthority:
8389
return "keyctlAssumeAuthority"
90+
case keyctlGetPersistent:
91+
return "keyctlGetPersistent"
8492
}
8593
panic("bad arg")
8694
}
@@ -294,3 +302,12 @@ func updateKey(id keyId, payload []byte) error {
294302
}
295303
return nil
296304
}
305+
306+
func attachPersistent(id keyId) (*keyring, error) {
307+
uid := int32(-1)
308+
r1, _, errno := syscall.Syscall(syscall_keyctl, uintptr(keyctlGetPersistent), uintptr(uid), uintptr(id))
309+
if errno != 0 {
310+
return nil, errno
311+
}
312+
return &keyring{id: keyId(r1)}, nil
313+
}

0 commit comments

Comments
 (0)