summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel
diff options
context:
space:
mode:
authorRahat Mahmood <rahat@google.com>2018-05-17 15:37:19 -0700
committerShentubot <shentubot@google.com>2018-05-17 15:38:11 -0700
commitb904250b862c5c14da84e08b6a5400c7bf2458b0 (patch)
treec6365aa58237dda6602b358acdc11f39c4eecb67 /pkg/sentry/kernel
parent8878a66a565733493e702199b284cd7855f80bf0 (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.go2
-rw-r--r--pkg/sentry/kernel/semaphore/semaphore.go15
-rw-r--r--pkg/sentry/kernel/semaphore/semaphore_test.go2
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)