Skip to content

Commit ec7a725

Browse files
adriansrandrewkroh
authored andcommitted
Make ID lookups thread-safe (#42)
Concurrent calls to aucoalesce.ResolveIDs() caused panics due to concurrent map writes.
1 parent 0c842c6 commit ec7a725

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1010

1111
### Changed
1212

13+
- aucoalesce - Made the user/group ID cache thread-safe. #42
14+
1315
### Deprecated
1416

1517
### Removed

aucoalesce/id_lookup.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"math"
2222
"os/user"
2323
"strings"
24+
"sync"
2425
"time"
2526
)
2627

@@ -44,6 +45,7 @@ func (i *stringItem) isExpired() bool {
4445
type UserCache struct {
4546
expiration time.Duration
4647
data map[string]stringItem
48+
mutex sync.Mutex
4749
}
4850

4951
// NewUserCache returns a new UserCache. UserCache is not thread-safe.
@@ -59,11 +61,14 @@ func NewUserCache(expiration time.Duration) UserCache {
5961
// LookupUID looks up a UID and returns the username associated with it. If
6062
// no username could be found an empty string is returned. The value will be
6163
// cached for a minute. This requires cgo on Linux.
62-
func (c UserCache) LookupUID(uid string) string {
64+
func (c *UserCache) LookupUID(uid string) string {
6365
if uid == "" || uid == "unset" {
6466
return ""
6567
}
6668

69+
c.mutex.Lock()
70+
defer c.mutex.Unlock()
71+
6772
if item, found := c.data[uid]; found && !item.isExpired() {
6873
return item.value
6974
}
@@ -83,6 +88,7 @@ func (c UserCache) LookupUID(uid string) string {
8388
type GroupCache struct {
8489
expiration time.Duration
8590
data map[string]stringItem
91+
mutex sync.Mutex
8692
}
8793

8894
// NewGroupCache returns a new GroupCache. GroupCache is not thread-safe.
@@ -98,11 +104,14 @@ func NewGroupCache(expiration time.Duration) GroupCache {
98104
// LookupGID looks up a GID and returns the group associated with it. If
99105
// no group could be found an empty string is returned. The value will be
100106
// cached for a minute. This requires cgo on Linux.
101-
func (c GroupCache) LookupGID(gid string) string {
107+
func (c *GroupCache) LookupGID(gid string) string {
102108
if gid == "" || gid == "unset" {
103109
return ""
104110
}
105111

112+
c.mutex.Lock()
113+
defer c.mutex.Unlock()
114+
106115
if item, found := c.data[gid]; found && !item.isExpired() {
107116
return item.value
108117
}

0 commit comments

Comments
 (0)