github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/syscalls/linux/sys_signal.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  	"math"
    19  	"time"
    20  
    21  	"github.com/SagerNet/gvisor/pkg/abi/linux"
    22  	"github.com/SagerNet/gvisor/pkg/errors/linuxerr"
    23  	"github.com/SagerNet/gvisor/pkg/hostarch"
    24  	"github.com/SagerNet/gvisor/pkg/sentry/arch"
    25  	"github.com/SagerNet/gvisor/pkg/sentry/fs"
    26  	"github.com/SagerNet/gvisor/pkg/sentry/kernel"
    27  	"github.com/SagerNet/gvisor/pkg/sentry/kernel/signalfd"
    28  	"github.com/SagerNet/gvisor/pkg/syserror"
    29  )
    30  
    31  // "For a process to have permission to send a signal it must
    32  // - either be privileged (CAP_KILL), or
    33  // - the real or effective user ID of the sending process must be equal to the
    34  // real or saved set-user-ID of the target process.
    35  //
    36  // In the case of SIGCONT it suffices when the sending and receiving processes
    37  // belong to the same session." - kill(2)
    38  //
    39  // Equivalent to kernel/signal.c:check_kill_permission.
    40  func mayKill(t *kernel.Task, target *kernel.Task, sig linux.Signal) bool {
    41  	// kernel/signal.c:check_kill_permission also allows a signal if the
    42  	// sending and receiving tasks share a thread group, which is not
    43  	// mentioned in kill(2) since kill does not allow task-level
    44  	// granularity in signal sending.
    45  	if t.ThreadGroup() == target.ThreadGroup() {
    46  		return true
    47  	}
    48  
    49  	if t.HasCapabilityIn(linux.CAP_KILL, target.UserNamespace()) {
    50  		return true
    51  	}
    52  
    53  	creds := t.Credentials()
    54  	tcreds := target.Credentials()
    55  	if creds.EffectiveKUID == tcreds.SavedKUID ||
    56  		creds.EffectiveKUID == tcreds.RealKUID ||
    57  		creds.RealKUID == tcreds.SavedKUID ||
    58  		creds.RealKUID == tcreds.RealKUID {
    59  		return true
    60  	}
    61  
    62  	if sig == linux.SIGCONT && target.ThreadGroup().Session() == t.ThreadGroup().Session() {
    63  		return true
    64  	}
    65  	return false
    66  }
    67  
    68  // Kill implements linux syscall kill(2).
    69  func Kill(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
    70  	pid := kernel.ThreadID(args[0].Int())
    71  	sig := linux.Signal(args[1].Int())
    72  
    73  	switch {
    74  	case pid > 0:
    75  		// "If pid is positive, then signal sig is sent to the process with the
    76  		// ID specified by pid." - kill(2)
    77  		// This loops to handle races with execve where target dies between
    78  		// TaskWithID and SendGroupSignal. Compare Linux's
    79  		// kernel/signal.c:kill_pid_info().
    80  		for {
    81  			target := t.PIDNamespace().TaskWithID(pid)
    82  			if target == nil {
    83  				return 0, nil, syserror.ESRCH
    84  			}
    85  			if !mayKill(t, target, sig) {
    86  				return 0, nil, linuxerr.EPERM
    87  			}
    88  			info := &linux.SignalInfo{
    89  				Signo: int32(sig),
    90  				Code:  linux.SI_USER,
    91  			}
    92  			info.SetPID(int32(target.PIDNamespace().IDOfTask(t)))
    93  			info.SetUID(int32(t.Credentials().RealKUID.In(target.UserNamespace()).OrOverflow()))
    94  			if err := target.SendGroupSignal(info); !linuxerr.Equals(linuxerr.ESRCH, err) {
    95  				return 0, nil, err
    96  			}
    97  		}
    98  	case pid == -1:
    99  		// "If pid equals -1, then sig is sent to every process for which the
   100  		// calling process has permission to send signals, except for process 1
   101  		// (init), but see below. ... POSIX.1-2001 requires that kill(-1,sig)
   102  		// send sig to all processes that the calling process may send signals
   103  		// to, except possibly for some implementation-defined system
   104  		// processes. Linux allows a process to signal itself, but on Linux the
   105  		// call kill(-1,sig) does not signal the calling process."
   106  		var (
   107  			lastErr   error
   108  			delivered int
   109  		)
   110  		for _, tg := range t.PIDNamespace().ThreadGroups() {
   111  			if tg == t.ThreadGroup() {
   112  				continue
   113  			}
   114  			if t.PIDNamespace().IDOfThreadGroup(tg) == kernel.InitTID {
   115  				continue
   116  			}
   117  
   118  			// If pid == -1, the returned error is the last non-EPERM error
   119  			// from any call to group_send_sig_info.
   120  			if !mayKill(t, tg.Leader(), sig) {
   121  				continue
   122  			}
   123  			// Here and below, whether or not kill returns an error may
   124  			// depend on the iteration order. We at least implement the
   125  			// semantics documented by the man page: "On success (at least
   126  			// one signal was sent), zero is returned."
   127  			info := &linux.SignalInfo{
   128  				Signo: int32(sig),
   129  				Code:  linux.SI_USER,
   130  			}
   131  			info.SetPID(int32(tg.PIDNamespace().IDOfTask(t)))
   132  			info.SetUID(int32(t.Credentials().RealKUID.In(tg.Leader().UserNamespace()).OrOverflow()))
   133  			err := tg.SendSignal(info)
   134  			if linuxerr.Equals(linuxerr.ESRCH, err) {
   135  				// ESRCH is ignored because it means the task
   136  				// exited while we were iterating.  This is a
   137  				// race which would not normally exist on
   138  				// Linux, so we suppress it.
   139  				continue
   140  			}
   141  			delivered++
   142  			if err != nil {
   143  				lastErr = err
   144  			}
   145  		}
   146  		if delivered > 0 {
   147  			return 0, nil, lastErr
   148  		}
   149  		return 0, nil, syserror.ESRCH
   150  	default:
   151  		// "If pid equals 0, then sig is sent to every process in the process
   152  		// group of the calling process."
   153  		//
   154  		// "If pid is less than -1, then sig is sent to every process
   155  		// in the process group whose ID is -pid."
   156  		pgid := kernel.ProcessGroupID(-pid)
   157  		if pgid == 0 {
   158  			pgid = t.PIDNamespace().IDOfProcessGroup(t.ThreadGroup().ProcessGroup())
   159  		}
   160  
   161  		// If pid != -1 (i.e. signalling a process group), the returned error
   162  		// is the last error from any call to group_send_sig_info.
   163  		lastErr := syserror.ESRCH
   164  		for _, tg := range t.PIDNamespace().ThreadGroups() {
   165  			if t.PIDNamespace().IDOfProcessGroup(tg.ProcessGroup()) == pgid {
   166  				if !mayKill(t, tg.Leader(), sig) {
   167  					lastErr = linuxerr.EPERM
   168  					continue
   169  				}
   170  
   171  				info := &linux.SignalInfo{
   172  					Signo: int32(sig),
   173  					Code:  linux.SI_USER,
   174  				}
   175  				info.SetPID(int32(tg.PIDNamespace().IDOfTask(t)))
   176  				info.SetUID(int32(t.Credentials().RealKUID.In(tg.Leader().UserNamespace()).OrOverflow()))
   177  				// See note above regarding ESRCH race above.
   178  				if err := tg.SendSignal(info); !linuxerr.Equals(linuxerr.ESRCH, err) {
   179  					lastErr = err
   180  				}
   181  			}
   182  		}
   183  
   184  		return 0, nil, lastErr
   185  	}
   186  }
   187  
   188  func tkillSigInfo(sender, receiver *kernel.Task, sig linux.Signal) *linux.SignalInfo {
   189  	info := &linux.SignalInfo{
   190  		Signo: int32(sig),
   191  		Code:  linux.SI_TKILL,
   192  	}
   193  	info.SetPID(int32(receiver.PIDNamespace().IDOfThreadGroup(sender.ThreadGroup())))
   194  	info.SetUID(int32(sender.Credentials().RealKUID.In(receiver.UserNamespace()).OrOverflow()))
   195  	return info
   196  }
   197  
   198  // Tkill implements linux syscall tkill(2).
   199  func Tkill(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   200  	tid := kernel.ThreadID(args[0].Int())
   201  	sig := linux.Signal(args[1].Int())
   202  
   203  	// N.B. Inconsistent with man page, linux actually rejects calls with
   204  	// tid <=0 by EINVAL. This isn't the same for all signal calls.
   205  	if tid <= 0 {
   206  		return 0, nil, linuxerr.EINVAL
   207  	}
   208  
   209  	target := t.PIDNamespace().TaskWithID(tid)
   210  	if target == nil {
   211  		return 0, nil, syserror.ESRCH
   212  	}
   213  
   214  	if !mayKill(t, target, sig) {
   215  		return 0, nil, linuxerr.EPERM
   216  	}
   217  	return 0, nil, target.SendSignal(tkillSigInfo(t, target, sig))
   218  }
   219  
   220  // Tgkill implements linux syscall tgkill(2).
   221  func Tgkill(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   222  	tgid := kernel.ThreadID(args[0].Int())
   223  	tid := kernel.ThreadID(args[1].Int())
   224  	sig := linux.Signal(args[2].Int())
   225  
   226  	// N.B. Inconsistent with man page, linux actually rejects calls with
   227  	// tgid/tid <=0 by EINVAL. This isn't the same for all signal calls.
   228  	if tgid <= 0 || tid <= 0 {
   229  		return 0, nil, linuxerr.EINVAL
   230  	}
   231  
   232  	targetTG := t.PIDNamespace().ThreadGroupWithID(tgid)
   233  	target := t.PIDNamespace().TaskWithID(tid)
   234  	if targetTG == nil || target == nil || target.ThreadGroup() != targetTG {
   235  		return 0, nil, syserror.ESRCH
   236  	}
   237  
   238  	if !mayKill(t, target, sig) {
   239  		return 0, nil, linuxerr.EPERM
   240  	}
   241  	return 0, nil, target.SendSignal(tkillSigInfo(t, target, sig))
   242  }
   243  
   244  // RtSigaction implements linux syscall rt_sigaction(2).
   245  func RtSigaction(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   246  	sig := linux.Signal(args[0].Int())
   247  	newactarg := args[1].Pointer()
   248  	oldactarg := args[2].Pointer()
   249  	sigsetsize := args[3].SizeT()
   250  
   251  	if sigsetsize != linux.SignalSetSize {
   252  		return 0, nil, linuxerr.EINVAL
   253  	}
   254  
   255  	var newactptr *linux.SigAction
   256  	if newactarg != 0 {
   257  		var newact linux.SigAction
   258  		if _, err := newact.CopyIn(t, newactarg); err != nil {
   259  			return 0, nil, err
   260  		}
   261  		newactptr = &newact
   262  	}
   263  	oldact, err := t.ThreadGroup().SetSigAction(sig, newactptr)
   264  	if err != nil {
   265  		return 0, nil, err
   266  	}
   267  	if oldactarg != 0 {
   268  		if _, err := oldact.CopyOut(t, oldactarg); err != nil {
   269  			return 0, nil, err
   270  		}
   271  	}
   272  	return 0, nil, nil
   273  }
   274  
   275  // Sigreturn implements linux syscall sigreturn(2).
   276  func Sigreturn(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   277  	ctrl, err := t.SignalReturn(false)
   278  	return 0, ctrl, err
   279  }
   280  
   281  // RtSigreturn implements linux syscall rt_sigreturn(2).
   282  func RtSigreturn(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   283  	ctrl, err := t.SignalReturn(true)
   284  	return 0, ctrl, err
   285  }
   286  
   287  // RtSigprocmask implements linux syscall rt_sigprocmask(2).
   288  func RtSigprocmask(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   289  	how := args[0].Int()
   290  	setaddr := args[1].Pointer()
   291  	oldaddr := args[2].Pointer()
   292  	sigsetsize := args[3].SizeT()
   293  
   294  	if sigsetsize != linux.SignalSetSize {
   295  		return 0, nil, linuxerr.EINVAL
   296  	}
   297  	oldmask := t.SignalMask()
   298  	if setaddr != 0 {
   299  		mask, err := CopyInSigSet(t, setaddr, sigsetsize)
   300  		if err != nil {
   301  			return 0, nil, err
   302  		}
   303  
   304  		switch how {
   305  		case linux.SIG_BLOCK:
   306  			t.SetSignalMask(oldmask | mask)
   307  		case linux.SIG_UNBLOCK:
   308  			t.SetSignalMask(oldmask &^ mask)
   309  		case linux.SIG_SETMASK:
   310  			t.SetSignalMask(mask)
   311  		default:
   312  			return 0, nil, linuxerr.EINVAL
   313  		}
   314  	}
   315  	if oldaddr != 0 {
   316  		return 0, nil, copyOutSigSet(t, oldaddr, oldmask)
   317  	}
   318  
   319  	return 0, nil, nil
   320  }
   321  
   322  // Sigaltstack implements linux syscall sigaltstack(2).
   323  func Sigaltstack(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   324  	setaddr := args[0].Pointer()
   325  	oldaddr := args[1].Pointer()
   326  
   327  	alt := t.SignalStack()
   328  	if oldaddr != 0 {
   329  		if _, err := alt.CopyOut(t, oldaddr); err != nil {
   330  			return 0, nil, err
   331  		}
   332  	}
   333  	if setaddr != 0 {
   334  		if _, err := alt.CopyIn(t, setaddr); err != nil {
   335  			return 0, nil, err
   336  		}
   337  		// The signal stack cannot be changed if the task is currently
   338  		// on the stack. This is enforced at the lowest level because
   339  		// these semantics apply to changing the signal stack via a
   340  		// ucontext during a signal handler.
   341  		if !t.SetSignalStack(alt) {
   342  			return 0, nil, linuxerr.EPERM
   343  		}
   344  	}
   345  
   346  	return 0, nil, nil
   347  }
   348  
   349  // Pause implements linux syscall pause(2).
   350  func Pause(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   351  	return 0, nil, syserror.ConvertIntr(t.Block(nil), syserror.ERESTARTNOHAND)
   352  }
   353  
   354  // RtSigpending implements linux syscall rt_sigpending(2).
   355  func RtSigpending(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   356  	addr := args[0].Pointer()
   357  	pending := t.PendingSignals()
   358  	_, err := pending.CopyOut(t, addr)
   359  	return 0, nil, err
   360  }
   361  
   362  // RtSigtimedwait implements linux syscall rt_sigtimedwait(2).
   363  func RtSigtimedwait(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   364  	sigset := args[0].Pointer()
   365  	siginfo := args[1].Pointer()
   366  	timespec := args[2].Pointer()
   367  	sigsetsize := args[3].SizeT()
   368  
   369  	mask, err := CopyInSigSet(t, sigset, sigsetsize)
   370  	if err != nil {
   371  		return 0, nil, err
   372  	}
   373  
   374  	var timeout time.Duration
   375  	if timespec != 0 {
   376  		d, err := copyTimespecIn(t, timespec)
   377  		if err != nil {
   378  			return 0, nil, err
   379  		}
   380  		if !d.Valid() {
   381  			return 0, nil, linuxerr.EINVAL
   382  		}
   383  		timeout = time.Duration(d.ToNsecCapped())
   384  	} else {
   385  		timeout = time.Duration(math.MaxInt64)
   386  	}
   387  
   388  	si, err := t.Sigtimedwait(mask, timeout)
   389  	if err != nil {
   390  		return 0, nil, err
   391  	}
   392  
   393  	if siginfo != 0 {
   394  		si.FixSignalCodeForUser()
   395  		if _, err := si.CopyOut(t, siginfo); err != nil {
   396  			return 0, nil, err
   397  		}
   398  	}
   399  	return uintptr(si.Signo), nil, nil
   400  }
   401  
   402  // RtSigqueueinfo implements linux syscall rt_sigqueueinfo(2).
   403  func RtSigqueueinfo(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   404  	pid := kernel.ThreadID(args[0].Int())
   405  	sig := linux.Signal(args[1].Int())
   406  	infoAddr := args[2].Pointer()
   407  
   408  	// Copy in the info.
   409  	//
   410  	// We must ensure that the Signo is set (Linux overrides this in the
   411  	// same way), and that the code is in the allowed set. This same logic
   412  	// appears below in RtSigtgqueueinfo and should be kept in sync.
   413  	var info linux.SignalInfo
   414  	if _, err := info.CopyIn(t, infoAddr); err != nil {
   415  		return 0, nil, err
   416  	}
   417  	info.Signo = int32(sig)
   418  
   419  	// This must loop to handle the race with execve described in Kill.
   420  	for {
   421  		// Deliver to the given task's thread group.
   422  		target := t.PIDNamespace().TaskWithID(pid)
   423  		if target == nil {
   424  			return 0, nil, syserror.ESRCH
   425  		}
   426  
   427  		// If the sender is not the receiver, it can't use si_codes used by the
   428  		// kernel or SI_TKILL.
   429  		if (info.Code >= 0 || info.Code == linux.SI_TKILL) && target != t {
   430  			return 0, nil, linuxerr.EPERM
   431  		}
   432  
   433  		if !mayKill(t, target, sig) {
   434  			return 0, nil, linuxerr.EPERM
   435  		}
   436  
   437  		if err := target.SendGroupSignal(&info); !linuxerr.Equals(linuxerr.ESRCH, err) {
   438  			return 0, nil, err
   439  		}
   440  	}
   441  }
   442  
   443  // RtTgsigqueueinfo implements linux syscall rt_tgsigqueueinfo(2).
   444  func RtTgsigqueueinfo(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   445  	tgid := kernel.ThreadID(args[0].Int())
   446  	tid := kernel.ThreadID(args[1].Int())
   447  	sig := linux.Signal(args[2].Int())
   448  	infoAddr := args[3].Pointer()
   449  
   450  	// N.B. Inconsistent with man page, linux actually rejects calls with
   451  	// tgid/tid <=0 by EINVAL. This isn't the same for all signal calls.
   452  	if tgid <= 0 || tid <= 0 {
   453  		return 0, nil, linuxerr.EINVAL
   454  	}
   455  
   456  	// Copy in the info. See RtSigqueueinfo above.
   457  	var info linux.SignalInfo
   458  	if _, err := info.CopyIn(t, infoAddr); err != nil {
   459  		return 0, nil, err
   460  	}
   461  	info.Signo = int32(sig)
   462  
   463  	// Deliver to the given task.
   464  	targetTG := t.PIDNamespace().ThreadGroupWithID(tgid)
   465  	target := t.PIDNamespace().TaskWithID(tid)
   466  	if targetTG == nil || target == nil || target.ThreadGroup() != targetTG {
   467  		return 0, nil, syserror.ESRCH
   468  	}
   469  
   470  	// If the sender is not the receiver, it can't use si_codes used by the
   471  	// kernel or SI_TKILL.
   472  	if (info.Code >= 0 || info.Code == linux.SI_TKILL) && target != t {
   473  		return 0, nil, linuxerr.EPERM
   474  	}
   475  
   476  	if !mayKill(t, target, sig) {
   477  		return 0, nil, linuxerr.EPERM
   478  	}
   479  	return 0, nil, target.SendSignal(&info)
   480  }
   481  
   482  // RtSigsuspend implements linux syscall rt_sigsuspend(2).
   483  func RtSigsuspend(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   484  	sigset := args[0].Pointer()
   485  
   486  	// Copy in the signal mask.
   487  	var mask linux.SignalSet
   488  	if _, err := mask.CopyIn(t, sigset); err != nil {
   489  		return 0, nil, err
   490  	}
   491  	mask &^= kernel.UnblockableSignals
   492  
   493  	// Swap the mask.
   494  	oldmask := t.SignalMask()
   495  	t.SetSignalMask(mask)
   496  	t.SetSavedSignalMask(oldmask)
   497  
   498  	// Perform the wait.
   499  	return 0, nil, syserror.ConvertIntr(t.Block(nil), syserror.ERESTARTNOHAND)
   500  }
   501  
   502  // RestartSyscall implements the linux syscall restart_syscall(2).
   503  func RestartSyscall(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   504  	if r := t.SyscallRestartBlock(); r != nil {
   505  		n, err := r.Restart(t)
   506  		return n, nil, err
   507  	}
   508  	// The restart block should never be nil here, but it's possible
   509  	// ERESTART_RESTARTBLOCK was set by ptrace without the current syscall
   510  	// setting up a restart block. If ptrace didn't manipulate the return value,
   511  	// finding a nil restart block is a bug. Linux ensures that the restart
   512  	// function is never null by (re)initializing it with one that translates
   513  	// the restart into EINTR. We'll emulate that behaviour.
   514  	t.Debugf("Restart block missing in restart_syscall(2). Did ptrace inject a return value of ERESTART_RESTARTBLOCK?")
   515  	return 0, nil, syserror.EINTR
   516  }
   517  
   518  // sharedSignalfd is shared between the two calls.
   519  func sharedSignalfd(t *kernel.Task, fd int32, sigset hostarch.Addr, sigsetsize uint, flags int32) (uintptr, *kernel.SyscallControl, error) {
   520  	// Copy in the signal mask.
   521  	mask, err := CopyInSigSet(t, sigset, sigsetsize)
   522  	if err != nil {
   523  		return 0, nil, err
   524  	}
   525  
   526  	// Always check for valid flags, even if not creating.
   527  	if flags&^(linux.SFD_NONBLOCK|linux.SFD_CLOEXEC) != 0 {
   528  		return 0, nil, linuxerr.EINVAL
   529  	}
   530  
   531  	// Is this a change to an existing signalfd?
   532  	//
   533  	// The spec indicates that this should adjust the mask.
   534  	if fd != -1 {
   535  		file := t.GetFile(fd)
   536  		if file == nil {
   537  			return 0, nil, linuxerr.EBADF
   538  		}
   539  		defer file.DecRef(t)
   540  
   541  		// Is this a signalfd?
   542  		if s, ok := file.FileOperations.(*signalfd.SignalOperations); ok {
   543  			s.SetMask(mask)
   544  			return 0, nil, nil
   545  		}
   546  
   547  		// Not a signalfd.
   548  		return 0, nil, linuxerr.EINVAL
   549  	}
   550  
   551  	// Create a new file.
   552  	file, err := signalfd.New(t, mask)
   553  	if err != nil {
   554  		return 0, nil, err
   555  	}
   556  	defer file.DecRef(t)
   557  
   558  	// Set appropriate flags.
   559  	file.SetFlags(fs.SettableFileFlags{
   560  		NonBlocking: flags&linux.SFD_NONBLOCK != 0,
   561  	})
   562  
   563  	// Create a new descriptor.
   564  	fd, err = t.NewFDFrom(0, file, kernel.FDFlags{
   565  		CloseOnExec: flags&linux.SFD_CLOEXEC != 0,
   566  	})
   567  	if err != nil {
   568  		return 0, nil, err
   569  	}
   570  
   571  	// Done.
   572  	return uintptr(fd), nil, nil
   573  }
   574  
   575  // Signalfd implements the linux syscall signalfd(2).
   576  func Signalfd(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   577  	fd := args[0].Int()
   578  	sigset := args[1].Pointer()
   579  	sigsetsize := args[2].SizeT()
   580  	return sharedSignalfd(t, fd, sigset, sigsetsize, 0)
   581  }
   582  
   583  // Signalfd4 implements the linux syscall signalfd4(2).
   584  func Signalfd4(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
   585  	fd := args[0].Int()
   586  	sigset := args[1].Pointer()
   587  	sigsetsize := args[2].SizeT()
   588  	flags := args[3].Int()
   589  	return sharedSignalfd(t, fd, sigset, sigsetsize, flags)
   590  }