Skip to content

Commit

Permalink
Fix capability check for sysv semaphores.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mrahatm authored and shentubot committed May 17, 2018
1 parent 7dea9f9 commit 18b3ba4
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pkg/sentry/kernel/ipc_namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
15 changes: 12 additions & 3 deletions pkg/sentry/kernel/semaphore/semaphore.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion pkg/sentry/kernel/semaphore/semaphore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 18b3ba4

Please sign in to comment.