diff options
author | Rahat Mahmood <rahat@google.com> | 2018-05-17 15:37:19 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-05-17 15:38:11 -0700 |
commit | b904250b862c5c14da84e08b6a5400c7bf2458b0 (patch) | |
tree | c6365aa58237dda6602b358acdc11f39c4eecb67 /pkg/sentry/kernel | |
parent | 8878a66a565733493e702199b284cd7855f80bf0 (diff) |
Fix capability check for sysv semaphores.
Capabilities for sysv sem operations were being checked against the
current task's user namespace. They should be checked against the user
namespace owning the ipc namespace for the sems instead, per
ipc/util.c:ipcperms().
PiperOrigin-RevId: 197063111
Change-Id: Iba29486b316f2e01ee331dda4e48a6ab7960d589
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r-- | pkg/sentry/kernel/ipc_namespace.go | 2 | ||||
-rw-r--r-- | pkg/sentry/kernel/semaphore/semaphore.go | 15 | ||||
-rw-r--r-- | pkg/sentry/kernel/semaphore/semaphore_test.go | 2 |
3 files changed, 14 insertions, 5 deletions
diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index 3049fead4..a86bda77b 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -33,7 +33,7 @@ type IPCNamespace struct { func NewIPCNamespace(userNS *auth.UserNamespace) *IPCNamespace { return &IPCNamespace{ userNS: userNS, - semaphores: semaphore.NewRegistry(), + semaphores: semaphore.NewRegistry(userNS), shms: shm.NewRegistry(userNS), } } diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index fb8c2f98c..e9027dc14 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -43,6 +43,8 @@ const ( // Registry maintains a set of semaphores that can be found by key or ID. type Registry struct { + // userNS owning the ipc name this registry belongs to. Immutable. + userNS *auth.UserNamespace // mu protects all fields below. mu sync.Mutex `state:"nosave"` semaphores map[int32]*Set @@ -51,6 +53,9 @@ type Registry struct { // Set represents a set of semaphores that can be operated atomically. type Set struct { + // registry owning this sem set. Immutable. + registry *Registry + // Id is a handle that identifies the set. ID int32 @@ -90,8 +95,11 @@ type waiter struct { } // NewRegistry creates a new semaphore set registry. -func NewRegistry() *Registry { - return &Registry{semaphores: make(map[int32]*Set)} +func NewRegistry(userNS *auth.UserNamespace) *Registry { + return &Registry{ + userNS: userNS, + semaphores: make(map[int32]*Set), + } } // FindOrCreate searches for a semaphore set that matches 'key'. If not found, @@ -175,6 +183,7 @@ func (r *Registry) RemoveID(id int32, creds *auth.Credentials) error { func (r *Registry) newSet(ctx context.Context, key int32, owner, creator fs.FileOwner, perms fs.FilePermissions, nsems int32) (*Set, error) { set := &Set{ + registry: r, key: key, owner: owner, creator: owner, @@ -415,7 +424,7 @@ func (s *Set) checkCredentials(creds *auth.Credentials) bool { } func (s *Set) checkCapability(creds *auth.Credentials) bool { - return creds.HasCapability(linux.CAP_IPC_OWNER) && creds.UserNamespace.MapFromKUID(s.owner.UID).Ok() + return creds.HasCapabilityIn(linux.CAP_IPC_OWNER, s.registry.userNS) && creds.UserNamespace.MapFromKUID(s.owner.UID).Ok() } func (s *Set) checkPerms(creds *auth.Credentials, reqPerms fs.PermMask) bool { diff --git a/pkg/sentry/kernel/semaphore/semaphore_test.go b/pkg/sentry/kernel/semaphore/semaphore_test.go index 1c6a2e1e9..f9eb382e9 100644 --- a/pkg/sentry/kernel/semaphore/semaphore_test.go +++ b/pkg/sentry/kernel/semaphore/semaphore_test.go @@ -136,7 +136,7 @@ func TestNoWait(t *testing.T) { func TestUnregister(t *testing.T) { ctx := contexttest.Context(t) - r := NewRegistry() + r := NewRegistry(auth.NewRootUserNamespace()) set, err := r.FindOrCreate(ctx, 123, 2, linux.FileMode(0x600), true, true, true) if err != nil { t.Fatalf("FindOrCreate() failed, err: %v", err) |