github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/syscalls/linux/sigset.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 linux
    16  
    17  import (
    18  	"github.com/metacubex/gvisor/pkg/abi/linux"
    19  	"github.com/metacubex/gvisor/pkg/errors/linuxerr"
    20  	"github.com/metacubex/gvisor/pkg/hostarch"
    21  	"github.com/metacubex/gvisor/pkg/sentry/kernel"
    22  )
    23  
    24  // copyInSigSet copies in a sigset_t, checks its size, and ensures that KILL and
    25  // STOP are clear.
    26  func copyInSigSet(t *kernel.Task, sigSetAddr hostarch.Addr, size uint) (linux.SignalSet, error) {
    27  	if size != linux.SignalSetSize {
    28  		return 0, linuxerr.EINVAL
    29  	}
    30  	b := t.CopyScratchBuffer(8)
    31  	if _, err := t.CopyInBytes(sigSetAddr, b); err != nil {
    32  		return 0, err
    33  	}
    34  	mask := hostarch.ByteOrder.Uint64(b[:])
    35  	return linux.SignalSet(mask) &^ kernel.UnblockableSignals, nil
    36  }
    37  
    38  // copyOutSigSet copies out a sigset_t.
    39  func copyOutSigSet(t *kernel.Task, sigSetAddr hostarch.Addr, mask linux.SignalSet) error {
    40  	b := t.CopyScratchBuffer(8)
    41  	hostarch.ByteOrder.PutUint64(b, uint64(mask))
    42  	_, err := t.CopyOutBytes(sigSetAddr, b)
    43  	return err
    44  }
    45  
    46  // copyInSigSetWithSize copies in a structure as below
    47  //
    48  //	struct {
    49  //	    sigset_t* sigset_addr;
    50  //	    size_t sizeof_sigset;
    51  //	};
    52  //
    53  // and returns sigset_addr and size.
    54  func copyInSigSetWithSize(t *kernel.Task, addr hostarch.Addr) (hostarch.Addr, uint, error) {
    55  	switch t.Arch().Width() {
    56  	case 8:
    57  		in := t.CopyScratchBuffer(16)
    58  		if _, err := t.CopyInBytes(addr, in); err != nil {
    59  			return 0, 0, err
    60  		}
    61  		maskAddr := hostarch.Addr(hostarch.ByteOrder.Uint64(in[0:]))
    62  		maskSize := uint(hostarch.ByteOrder.Uint64(in[8:]))
    63  		return maskAddr, maskSize, nil
    64  	default:
    65  		return 0, 0, linuxerr.ENOSYS
    66  	}
    67  }