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

     1  // Copyright 2021 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 linux
    16  
    17  import (
    18  	"github.com/nicocha30/gvisor-ligolo/pkg/abi/linux"
    19  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/arch"
    20  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel"
    21  	"github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel/mq"
    22  )
    23  
    24  // MqOpen implements mq_open(2).
    25  func MqOpen(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
    26  	nameAddr := args[0].Pointer()
    27  	flag := args[1].Int()
    28  	mode := args[2].ModeT()
    29  	attrAddr := args[3].Pointer()
    30  
    31  	name, err := t.CopyInString(nameAddr, mq.MaxName)
    32  	if err != nil {
    33  		return 0, nil, err
    34  	}
    35  
    36  	rOnly := flag&linux.O_RDONLY == linux.O_RDONLY
    37  	wOnly := flag&linux.O_WRONLY == linux.O_WRONLY
    38  	readWrite := flag&linux.O_RDWR == linux.O_RDWR
    39  
    40  	create := flag&linux.O_CREAT == linux.O_CREAT
    41  	exclusive := flag&linux.O_EXCL == linux.O_EXCL
    42  	block := flag&linux.O_NONBLOCK != linux.O_NONBLOCK
    43  
    44  	var attr linux.MqAttr
    45  	var attrPtr *linux.MqAttr
    46  	if attrAddr != 0 {
    47  		if _, err := attr.CopyIn(t, attrAddr); err != nil {
    48  			return 0, nil, err
    49  		}
    50  		attrPtr = &attr
    51  	}
    52  
    53  	opts := openOpts(name, rOnly, wOnly, readWrite, create, exclusive, block)
    54  
    55  	r := t.IPCNamespace().PosixQueues()
    56  	queue, err := r.FindOrCreate(t, opts, linux.FileMode(mode), attrPtr)
    57  	if err != nil {
    58  		return 0, nil, err
    59  	}
    60  
    61  	fd, err := t.NewFDFrom(0, queue, kernel.FDFlags{
    62  		CloseOnExec: flag&linux.O_CLOEXEC != 0,
    63  	})
    64  	if err != nil {
    65  		return 0, nil, err
    66  	}
    67  	return uintptr(fd), nil, nil
    68  }
    69  
    70  // MqUnlink implements mq_unlink(2).
    71  func MqUnlink(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
    72  	nameAddr := args[0].Pointer()
    73  	name, err := t.CopyInString(nameAddr, mq.MaxName)
    74  	if err != nil {
    75  		return 0, nil, err
    76  	}
    77  	return 0, nil, t.IPCNamespace().PosixQueues().Remove(t, name)
    78  }
    79  
    80  func openOpts(name string, rOnly, wOnly, readWrite, create, exclusive, block bool) mq.OpenOpts {
    81  	var access mq.AccessType
    82  	switch {
    83  	case readWrite:
    84  		access = mq.ReadWrite
    85  	case wOnly:
    86  		access = mq.WriteOnly
    87  	case rOnly:
    88  		access = mq.ReadOnly
    89  	}
    90  
    91  	return mq.OpenOpts{
    92  		Name:      name,
    93  		Access:    access,
    94  		Create:    create,
    95  		Exclusive: exclusive,
    96  		Block:     block,
    97  	}
    98  }