Skip to content

Commit ee9c16d

Browse files
committed
keyring: for test
Signed-off-by: Bin Tang <[email protected]>
1 parent ce775ee commit ee9c16d

File tree

3 files changed

+96
-18
lines changed

3 files changed

+96
-18
lines changed

pkg/auth/cache.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ func (c *Cache) GetAuth(imageHost string) (string, error) {
6363
return data, err
6464
}
6565

66-
func (c *Cache) GetKeyChain(ImageID string) (*PassKeyChain, error) {
67-
image, err := registry.ParseImage(ImageID)
66+
func (c *Cache) GetKeyChain(imageID string) (*PassKeyChain, error) {
67+
image, err := registry.ParseImage(imageID)
6868
if err != nil {
69-
return nil, errors.Wrapf(err, "parse image %s", ImageID)
69+
return nil, errors.Wrapf(err, "parse image %s", imageID)
7070
}
7171

7272
cachedAuth, err := c.GetAuth(image.Host)

pkg/auth/keyring.go

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package auth
88

99
import (
10+
"os"
1011
"strconv"
1112
"strings"
1213
"sync"
@@ -28,7 +29,7 @@ var (
2829
type KeyRing struct {
2930
sessKeyID int
3031
keyLock sync.RWMutex
31-
avaliable bool
32+
available bool
3233
}
3334

3435
func GetSessionID() (int, error) {
@@ -51,33 +52,75 @@ func GetSessionID() (int, error) {
5152
log.L.Infof("added search permission for session keyring %s", defaultSessionName)
5253

5354
globalKeyRing.sessKeyID = sessKeyID
54-
globalKeyRing.avaliable = true
55+
globalKeyRing.available = true
5556
},
5657
)
57-
if joinSessionErr != nil {
58-
return 0, errors.Wrapf(joinSessionErr, "join session keyring %s.", defaultSessionName)
59-
}
60-
if !globalKeyRing.avaliable {
58+
if !globalKeyRing.available || joinSessionErr != nil {
6159
return 0, unix.EINVAL
6260
}
6361

6462
return globalKeyRing.sessKeyID, nil
6563
}
6664

65+
func ClearKeyring() error {
66+
sessKeyID, err := GetSessionID()
67+
if err != nil {
68+
return err
69+
}
70+
log.L.Infof("[abin] clear keyring session ID: %d", sessKeyID)
71+
72+
_, err = unix.KeyctlInt(unix.KEYCTL_CLEAR, sessKeyID, 0, 0, 0)
73+
74+
return err
75+
}
76+
6777
func AddKeyring(id, value string) (int, error) {
6878
sessKeyID, err := GetSessionID()
6979
if err != nil {
7080
return 0, err
7181
}
82+
log.L.Infof("[abin]session ID: %d", sessKeyID)
7283

7384
globalKeyRing.keyLock.Lock()
7485
defer globalKeyRing.keyLock.Unlock()
7586

87+
permFull, _, err := checkPermission(sessKeyID, 0)
88+
if err != nil {
89+
return 0, errors.Wrap(err, "check permission before adding key")
90+
}
91+
log.L.Infof("[abin] keyring permission: %b, uid: %d, gid: %d", permFull, os.Getuid(), os.Getgid())
92+
7693
keyID, err := unix.AddKey("user", id, []byte(value), sessKeyID)
94+
if err != nil {
95+
if errors.Is(err, unix.EACCES) {
96+
log.L.Infof("[abin] error unix.EACCES: %d", err)
97+
return 0, unix.EINVAL
98+
}
99+
return 0, errors.Wrapf(err, "add key %s", id)
100+
}
101+
102+
_, err = unix.KeyctlInt(unix.KEYCTL_LINK, keyID, sessKeyID, 0, 0)
77103
if err != nil {
78104
return 0, err
79105
}
80106

107+
permFull, _, err = checkPermission(keyID, 0)
108+
if err != nil {
109+
return 0, errors.Wrap(err, "check permission before adding key")
110+
}
111+
log.L.Infof("[abin] key %d permission: %b", keyID, permFull)
112+
113+
if err := addSearchPermission(keyID); err != nil {
114+
log.L.Infof("[abin] add permission to key: %d, err: %v", keyID, err)
115+
return keyID, unix.EINVAL
116+
}
117+
118+
permFull, _, err = checkPermission(keyID, 0)
119+
if err != nil {
120+
return 0, errors.Wrap(err, "check permission before adding key")
121+
}
122+
log.L.Infof("[abin] key %d after add permission: %b", keyID, permFull)
123+
81124
return keyID, nil
82125
}
83126

@@ -105,7 +148,7 @@ func checkPermission(ringID int, targetMask uint32) (uint32, bool, error) {
105148

106149
permFull := uint32(perm64) & mask
107150

108-
return permFull, (permFull & targetMask) != 0, nil
151+
return permFull, (permFull&targetMask)^targetMask == 0, nil
109152
}
110153

111154
func addSearchPermission(ringID int) error {
@@ -130,10 +173,10 @@ func addSearchPermission(ringID int) error {
130173
*
131174
* Refer to https://man7.org/linux/man-pages/man7/keyrings.7.html
132175
*/
133-
var searchPermissionBits uint32 = 0x80000
176+
var allUserPermissionBits uint32 = 0x3f0000
134177

135178
// Check if the search right for user already exists.
136-
permFull, hasPermission, err := checkPermission(ringID, searchPermissionBits)
179+
permFull, hasPermission, err := checkPermission(ringID, allUserPermissionBits)
137180
if err != nil {
138181
return errors.Wrap(err, "check permission")
139182
}
@@ -142,17 +185,21 @@ func addSearchPermission(ringID int) error {
142185
}
143186

144187
// Add search right for user.
145-
if err := unix.KeyctlSetperm(ringID, permFull|searchPermissionBits); err != nil {
188+
if err := unix.KeyctlSetperm(ringID, permFull|allUserPermissionBits); err != nil {
189+
log.L.Infof("[abin] set perm error: %v, ringID: %d, bits: %b", err, ringID, permFull|allUserPermissionBits)
146190
return errors.Wrap(err, "set permission")
147191
}
148192

149-
permFull, hasPermission, err = checkPermission(ringID, searchPermissionBits)
193+
permFull, hasPermission, err = checkPermission(ringID, allUserPermissionBits)
150194
if err != nil {
151195
return errors.Wrap(err, "check permission after add search permission")
152196
}
153197
if !hasPermission {
154-
return errors.Errorf("add search permission failed, current permission: %b", permFull)
198+
return unix.EINVAL
155199
}
200+
201+
log.L.Infof("[abin] keyring permission: %b", permFull)
202+
156203
return nil
157204
}
158205

@@ -177,6 +224,10 @@ func getData(key int) (string, error) {
177224
for {
178225
sizeRead, err := unix.KeyctlBuffer(unix.KEYCTL_READ, key, buffer, size)
179226
if err != nil {
227+
log.L.Infof("[abin] KEYCTL_READ error:%v : %d", err, err)
228+
if errors.Is(err, unix.EACCES) {
229+
return "", unix.EINVAL
230+
}
180231
return "", err
181232
}
182233

pkg/auth/keyring_test.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,50 @@ package auth
99
import (
1010
"testing"
1111

12+
"github.com/containerd/containerd/log"
1213
"github.com/stretchr/testify/assert"
14+
"golang.org/x/sys/unix"
1315
)
1416

1517
func TestKeyRing_Add(t *testing.T) {
1618
A := assert.New(t)
1719

20+
err := ClearKeyring()
21+
A.NoError(err)
22+
1823
testKey := "test"
1924
testValue := "value"
2025
keyID, err := AddKeyring(testKey, testValue)
26+
if err != nil && err == unix.EINVAL {
27+
return
28+
}
2129
A.NoError(err)
2230

31+
log.L.Infof("[abin] keyID: %d", keyID)
2332
value, err := getData(keyID)
33+
if err != nil && err == unix.EINVAL {
34+
return
35+
}
2436
A.NoError(err)
2537
A.Equal(testValue, value)
2638

27-
value, err = getData(-1)
39+
value, err = getData(0)
2840
A.ErrorContains(err, "required key not available")
2941
A.Equal("", value)
3042
}
3143

3244
func TestKeyRing_Search(t *testing.T) {
3345
A := assert.New(t)
3446

47+
err := ClearKeyring()
48+
A.NoError(err)
49+
3550
testKey := "test"
3651
testValue := "value"
37-
_, err := AddKeyring(testKey, testValue)
52+
_, err = AddKeyring(testKey, testValue)
53+
if err != nil && err == unix.EINVAL {
54+
return
55+
}
3856
A.NoError(err)
3957

4058
value, err := SearchKeyring(testKey)
@@ -49,6 +67,9 @@ func TestKeyRing_Search(t *testing.T) {
4967
func TestKeyRing_getData(t *testing.T) {
5068
A := assert.New(t)
5169

70+
err := ClearKeyring()
71+
A.NoError(err)
72+
5273
testKey := "test"
5374
tests := []struct {
5475
name string
@@ -78,10 +99,16 @@ func TestKeyRing_getData(t *testing.T) {
7899
testValue = append(testValue, 'A')
79100
}
80101

81-
keyID, err := AddKeyring(testKey, string(testValue[:]))
102+
keyID, err := AddKeyring(testKey, string(testValue))
103+
if err != nil && err == unix.EINVAL {
104+
return
105+
}
82106
A.NoError(err)
83107

84108
value, err := getData(keyID)
109+
if err != nil && err == unix.EINVAL {
110+
return
111+
}
85112
A.NoError(err)
86113
A.Equal(tt.length, len([]byte(value)))
87114
})

0 commit comments

Comments
 (0)