github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/sentry/kernel/ipc_namespace.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package kernel
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/nicocha30/gvisor-ligolo/pkg/context"
    21  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/fsimpl/mqfs"
    22  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/auth"
    23  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/mq"
    24  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/msgqueue"
    25  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/semaphore"
    26  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/shm"
    27  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/vfs"
    28  )
    29  
    30  // IPCNamespace represents an IPC namespace.
    31  //
    32  // +stateify savable
    33  type IPCNamespace struct {
    34  	IPCNamespaceRefs
    35  
    36  	// User namespace which owns this IPC namespace. Immutable.
    37  	userNS *auth.UserNamespace
    38  
    39  	// System V utilities.
    40  	queues     *msgqueue.Registry
    41  	semaphores *semaphore.Registry
    42  	shms       *shm.Registry
    43  
    44  	// posixQueues is a POSIX message queue registry.
    45  	//
    46  	// posixQueues is somewhat equivelant to Linux's ipc_namespace.mq_mnt.
    47  	// Unlike SysV utilities, mq.Registry is not map-based, but is backed by
    48  	// a virtual filesystem.
    49  	posixQueues *mq.Registry
    50  }
    51  
    52  // NewIPCNamespace creates a new IPC namespace.
    53  func NewIPCNamespace(userNS *auth.UserNamespace) *IPCNamespace {
    54  	ns := &IPCNamespace{
    55  		userNS:     userNS,
    56  		queues:     msgqueue.NewRegistry(userNS),
    57  		semaphores: semaphore.NewRegistry(userNS),
    58  		shms:       shm.NewRegistry(userNS),
    59  	}
    60  	ns.InitRefs()
    61  	return ns
    62  }
    63  
    64  // MsgqueueRegistry returns the message queue registry for this namespace.
    65  func (i *IPCNamespace) MsgqueueRegistry() *msgqueue.Registry {
    66  	return i.queues
    67  }
    68  
    69  // SemaphoreRegistry returns the semaphore set registry for this namespace.
    70  func (i *IPCNamespace) SemaphoreRegistry() *semaphore.Registry {
    71  	return i.semaphores
    72  }
    73  
    74  // ShmRegistry returns the shm segment registry for this namespace.
    75  func (i *IPCNamespace) ShmRegistry() *shm.Registry {
    76  	return i.shms
    77  }
    78  
    79  // InitPosixQueues creates a new POSIX queue registry, and returns an error if
    80  // the registry was previously initialized.
    81  func (i *IPCNamespace) InitPosixQueues(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials) error {
    82  	if i.posixQueues != nil {
    83  		return fmt.Errorf("IPCNamespace.InitPosixQueues: already initialized")
    84  	}
    85  
    86  	impl, err := mqfs.NewRegistryImpl(ctx, vfsObj, creds)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	i.posixQueues = mq.NewRegistry(i.userNS, impl)
    91  	return nil
    92  }
    93  
    94  // PosixQueues returns the posix message queue registry for this namespace.
    95  //
    96  // Precondition: i.InitPosixQueues must have been called.
    97  func (i *IPCNamespace) PosixQueues() *mq.Registry {
    98  	return i.posixQueues
    99  }
   100  
   101  // DecRef implements refs.RefCounter.DecRef.
   102  func (i *IPCNamespace) DecRef(ctx context.Context) {
   103  	i.IPCNamespaceRefs.DecRef(func() {
   104  		i.shms.Release(ctx)
   105  		if i.posixQueues != nil {
   106  			i.posixQueues.Destroy(ctx)
   107  		}
   108  	})
   109  }
   110  
   111  // IPCNamespace returns the task's IPC namespace.
   112  func (t *Task) IPCNamespace() *IPCNamespace {
   113  	t.mu.Lock()
   114  	defer t.mu.Unlock()
   115  	return t.ipcns
   116  }