diff options
-rw-r--r-- | pkg/sentry/fs/host/tty.go | 7 | ||||
-rw-r--r-- | pkg/sentry/kernel/fasync/BUILD | 1 | ||||
-rw-r--r-- | pkg/sentry/kernel/fasync/fasync.go | 7 | ||||
-rw-r--r-- | pkg/sentry/kernel/sessions.go | 4 | ||||
-rw-r--r-- | pkg/sentry/kernel/signal.go | 16 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_run.go | 2 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_sched.go | 10 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_signals.go | 2 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_syscall.go | 8 | ||||
-rw-r--r-- | pkg/sentry/kernel/thread_group.go | 2 | ||||
-rw-r--r-- | pkg/sentry/syscalls/linux/error.go | 7 | ||||
-rw-r--r-- | test/syscalls/linux/write.cc | 17 |
12 files changed, 46 insertions, 37 deletions
diff --git a/pkg/sentry/fs/host/tty.go b/pkg/sentry/fs/host/tty.go index 21db0086e..c5cb75df7 100644 --- a/pkg/sentry/fs/host/tty.go +++ b/pkg/sentry/fs/host/tty.go @@ -344,11 +344,8 @@ func (t *TTYFileOperations) checkChange(ctx context.Context, sig linux.Signal) e // 040b6362d58f "tty: fix leakage of -ERESTARTSYS to userland" doesn't // apply: the sentry will handle -ERESTARTSYS in // kernel.runApp.execute() even if the kernel.Task isn't interrupted. - si := arch.SignalInfo{ - Code: arch.SignalInfoKernel, - Signo: int32(sig), - } + // // Linux ignores the result of kill_pgrp(). - _ = pg.SendSignal(&si) + _ = pg.SendSignal(kernel.SignalInfoPriv(sig)) return kernel.ERESTARTSYS } diff --git a/pkg/sentry/kernel/fasync/BUILD b/pkg/sentry/kernel/fasync/BUILD index 5faf95909..59b4a49e1 100644 --- a/pkg/sentry/kernel/fasync/BUILD +++ b/pkg/sentry/kernel/fasync/BUILD @@ -9,7 +9,6 @@ go_library( visibility = ["//:sandbox"], deps = [ "//pkg/abi/linux", - "//pkg/sentry/arch", "//pkg/sentry/fs", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", diff --git a/pkg/sentry/kernel/fasync/fasync.go b/pkg/sentry/kernel/fasync/fasync.go index aa4aac109..298d988ea 100644 --- a/pkg/sentry/kernel/fasync/fasync.go +++ b/pkg/sentry/kernel/fasync/fasync.go @@ -19,7 +19,6 @@ import ( "sync" "gvisor.googlesource.com/gvisor/pkg/abi/linux" - "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/auth" @@ -72,11 +71,7 @@ func (a *FileAsync) Callback(e *waiter.Entry) { a.requester.EffectiveKUID == c.RealKUID || a.requester.RealKUID == c.SavedKUID || a.requester.RealKUID == c.RealKUID { - t.SendSignal(&arch.SignalInfo{ - Signo: int32(linux.SIGIO), - // SEND_SIG_PRIV - Code: arch.SignalInfoKernel, - }) + t.SendSignal(kernel.SignalInfoPriv(linux.SIGIO)) } a.mu.Unlock() } diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index 65e2b73c4..070c2f930 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -219,8 +219,8 @@ func (pg *ProcessGroup) handleOrphan() { return } tg.signalHandlers.mu.Lock() - tg.leader.sendSignalLocked(sigPriv(linux.SIGHUP), true /* group */) - tg.leader.sendSignalLocked(sigPriv(linux.SIGCONT), true /* group */) + tg.leader.sendSignalLocked(SignalInfoPriv(linux.SIGHUP), true /* group */) + tg.leader.sendSignalLocked(SignalInfoPriv(linux.SIGCONT), true /* group */) tg.signalHandlers.mu.Unlock() }) diff --git a/pkg/sentry/kernel/signal.go b/pkg/sentry/kernel/signal.go index b066df132..22a56c6fc 100644 --- a/pkg/sentry/kernel/signal.go +++ b/pkg/sentry/kernel/signal.go @@ -56,11 +56,21 @@ func (k *Kernel) sendExternalSignal(info *arch.SignalInfo, context string) { } } -// sigPriv returns a SignalInfo representing a signal sent by the sentry. (The -// name reflects its equivalence to Linux's SEND_SIG_PRIV.) -func sigPriv(sig linux.Signal) *arch.SignalInfo { +// SignalInfoPriv returns a SignalInfo equivalent to Linux's SEND_SIG_PRIV. +func SignalInfoPriv(sig linux.Signal) *arch.SignalInfo { return &arch.SignalInfo{ Signo: int32(sig), Code: arch.SignalInfoKernel, } } + +// SignalInfoNoInfo returns a SignalInfo equivalent to Linux's SEND_SIG_NOINFO. +func SignalInfoNoInfo(sig linux.Signal, sender, receiver *Task) *arch.SignalInfo { + info := &arch.SignalInfo{ + Signo: int32(sig), + Code: arch.SignalInfoUser, + } + info.SetPid(int32(receiver.tg.pidns.IDOfThreadGroup(sender.tg))) + info.SetUid(int32(sender.Credentials().RealKUID.In(receiver.UserNamespace()).OrOverflow())) + return info +} diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index 359986b21..6b5fe7165 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -176,7 +176,7 @@ func (*runApp) execute(t *Task) taskRunState { if err := t.rseqCopyOutCPU(); err != nil { t.Warningf("Failed to copy CPU to %#x for RSEQ: %v", t.rseqCPUAddr, err) t.forceSignal(linux.SIGSEGV, false) - t.SendSignal(sigPriv(linux.SIGSEGV)) + t.SendSignal(SignalInfoPriv(linux.SIGSEGV)) // Re-enter the task run loop for signal delivery. return (*runApp)(nil) } diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index 3b3cdc24a..3d654bf93 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -394,7 +394,7 @@ func (ticker *kernelCPUClockTicker) Notify(exp uint64) { newItimerVirtSetting, exp := tg.itimerVirtSetting.At(tgVirtNow) tg.itimerVirtSetting = newItimerVirtSetting if exp != 0 { - virtReceiver.sendSignalLocked(sigPriv(linux.SIGVTALRM), true) + virtReceiver.sendSignalLocked(SignalInfoPriv(linux.SIGVTALRM), true) } } if profReceiver != nil { @@ -402,18 +402,18 @@ func (ticker *kernelCPUClockTicker) Notify(exp uint64) { newItimerProfSetting, exp := tg.itimerProfSetting.At(tgProfNow) tg.itimerProfSetting = newItimerProfSetting if exp != 0 { - profReceiver.sendSignalLocked(sigPriv(linux.SIGPROF), true) + profReceiver.sendSignalLocked(SignalInfoPriv(linux.SIGPROF), true) } // RLIMIT_CPU soft limit newRlimitCPUSoftSetting, exp := tg.rlimitCPUSoftSetting.At(tgProfNow) tg.rlimitCPUSoftSetting = newRlimitCPUSoftSetting if exp != 0 { - profReceiver.sendSignalLocked(sigPriv(linux.SIGXCPU), true) + profReceiver.sendSignalLocked(SignalInfoPriv(linux.SIGXCPU), true) } // RLIMIT_CPU hard limit rlimitCPUMax := tg.limits.Get(limits.CPU).Max if rlimitCPUMax != limits.Infinity && !tgProfNow.Before(ktime.FromSeconds(int64(rlimitCPUMax))) { - profReceiver.sendSignalLocked(sigPriv(linux.SIGKILL), true) + profReceiver.sendSignalLocked(SignalInfoPriv(linux.SIGKILL), true) } } tg.signalHandlers.mu.Unlock() @@ -471,7 +471,7 @@ func (t *Task) NotifyRlimitCPUUpdated() { tgcpu := t.tg.cpuStatsAtLocked(t.k.CPUClockNow()) tgProfNow := ktime.FromNanoseconds((tgcpu.UserTime + tgcpu.SysTime).Nanoseconds()) if !tgProfNow.Before(ktime.FromSeconds(int64(rlimitCPU.Max))) { - t.sendSignalLocked(sigPriv(linux.SIGKILL), true) + t.sendSignalLocked(SignalInfoPriv(linux.SIGKILL), true) } } t.tg.updateCPUTimersEnabledLocked() diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 6a204aa59..e177562d7 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -224,7 +224,7 @@ func (t *Task) deliverSignal(info *arch.SignalInfo, act arch.SignalAct) taskRunS // Send a forced SIGSEGV. If the signal that couldn't be delivered // was a SIGSEGV, force the handler to SIG_DFL. t.forceSignal(linux.SIGSEGV, linux.Signal(info.Signo) == linux.SIGSEGV /* unconditional */) - t.SendSignal(sigPriv(linux.SIGSEGV)) + t.SendSignal(SignalInfoPriv(linux.SIGSEGV)) } default: diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 9e43f089a..52f5fde8d 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -250,7 +250,7 @@ type runSyscallAfterSyscallEnterStop struct{} func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { if sig := linux.Signal(t.ptraceCode); sig.IsValid() { t.tg.signalHandlers.mu.Lock() - t.sendSignalLocked(sigPriv(sig), false /* group */) + t.sendSignalLocked(SignalInfoPriv(sig), false /* group */) t.tg.signalHandlers.mu.Unlock() } if t.killed() { @@ -270,7 +270,7 @@ type runSyscallAfterSysemuStop struct{} func (*runSyscallAfterSysemuStop) execute(t *Task) taskRunState { if sig := linux.Signal(t.ptraceCode); sig.IsValid() { t.tg.signalHandlers.mu.Lock() - t.sendSignalLocked(sigPriv(sig), false /* group */) + t.sendSignalLocked(SignalInfoPriv(sig), false /* group */) t.tg.signalHandlers.mu.Unlock() } if t.killed() { @@ -335,7 +335,7 @@ func (t *Task) doVsyscall(addr usermem.Addr, sysno uintptr) taskRunState { if _, err := t.CopyIn(usermem.Addr(t.Arch().Stack()), caller); err != nil { t.Debugf("vsyscall %d: error reading return address from stack: %v", sysno, err) t.forceSignal(linux.SIGSEGV, false /* unconditional */) - t.SendSignal(sigPriv(linux.SIGSEGV)) + t.SendSignal(SignalInfoPriv(linux.SIGSEGV)) return (*runApp)(nil) } @@ -405,7 +405,7 @@ func (t *Task) doVsyscallInvoke(sysno uintptr, args arch.SyscallArguments, calle t.Debugf("vsyscall %d, caller %x: emulated syscall returned error: %v", sysno, t.Arch().Value(caller), err) if err == syserror.EFAULT { t.forceSignal(linux.SIGSEGV, false /* unconditional */) - t.SendSignal(sigPriv(linux.SIGSEGV)) + t.SendSignal(SignalInfoPriv(linux.SIGSEGV)) // A return is not emulated in this case. return (*runApp)(nil) } diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 1b7b74319..58f3a7ec9 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -322,7 +322,7 @@ type itimerRealListener struct { // Notify implements ktime.TimerListener.Notify. func (l *itimerRealListener) Notify(exp uint64) { - l.tg.SendSignal(sigPriv(linux.SIGALRM)) + l.tg.SendSignal(SignalInfoPriv(linux.SIGALRM)) } // Destroy implements ktime.TimerListener.Destroy. diff --git a/pkg/sentry/syscalls/linux/error.go b/pkg/sentry/syscalls/linux/error.go index 9fd002955..e86bed313 100644 --- a/pkg/sentry/syscalls/linux/error.go +++ b/pkg/sentry/syscalls/linux/error.go @@ -19,9 +19,9 @@ import ( "sync" "syscall" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/metric" - "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/syserror" @@ -53,10 +53,7 @@ func handleIOError(t *kernel.Task, partialResult bool, err, intr error, op strin // // Do not consume the error and return it as EFBIG. // Simultaneously send a SIGXFSZ per setrlimit(2). - t.SendSignal(&arch.SignalInfo{ - Signo: int32(syscall.SIGXFSZ), - Code: arch.SignalInfoKernel, - }) + t.SendSignal(kernel.SignalInfoNoInfo(linux.SIGXFSZ, t, t)) return syscall.EFBIG case syserror.ErrInterrupted: // The syscall was interrupted. Return nil if it completed diff --git a/test/syscalls/linux/write.cc b/test/syscalls/linux/write.cc index ca6aafd18..432bd6066 100644 --- a/test/syscalls/linux/write.cc +++ b/test/syscalls/linux/write.cc @@ -17,6 +17,7 @@ #include <signal.h> #include <sys/resource.h> #include <sys/stat.h> +#include <sys/types.h> #include <time.h> #include <unistd.h> @@ -105,23 +106,33 @@ TEST_F(WriteTest, WriteExceedsRLimit) { EXPECT_THAT(write(fd, buf.data(), target_lim + 1), SyscallSucceedsWithValue(target_lim)); EXPECT_THAT(write(fd, buf.data(), 1), SyscallFailsWithErrno(EFBIG)); + siginfo_t info; struct timespec timelimit = {0, 0}; - EXPECT_THAT(RetryEINTR(sigtimedwait)(&filesize_mask, nullptr, &timelimit), + ASSERT_THAT(RetryEINTR(sigtimedwait)(&filesize_mask, &info, &timelimit), SyscallSucceedsWithValue(SIGXFSZ)); + EXPECT_EQ(info.si_code, SI_USER); + EXPECT_EQ(info.si_pid, getpid()); + EXPECT_EQ(info.si_uid, getuid()); EXPECT_THAT(pwrite(fd, buf.data(), target_lim + 1, 1), SyscallSucceedsWithValue(target_lim - 1)); EXPECT_THAT(pwrite(fd, buf.data(), 1, target_lim), SyscallFailsWithErrno(EFBIG)); - EXPECT_THAT(RetryEINTR(sigtimedwait)(&filesize_mask, nullptr, &timelimit), + ASSERT_THAT(RetryEINTR(sigtimedwait)(&filesize_mask, &info, &timelimit), SyscallSucceedsWithValue(SIGXFSZ)); + EXPECT_EQ(info.si_code, SI_USER); + EXPECT_EQ(info.si_pid, getpid()); + EXPECT_EQ(info.si_uid, getuid()); EXPECT_THAT(pwrite64(fd, buf.data(), target_lim + 1, 1), SyscallSucceedsWithValue(target_lim - 1)); EXPECT_THAT(pwrite64(fd, buf.data(), 1, target_lim), SyscallFailsWithErrno(EFBIG)); - EXPECT_THAT(RetryEINTR(sigtimedwait)(&filesize_mask, nullptr, &timelimit), + ASSERT_THAT(RetryEINTR(sigtimedwait)(&filesize_mask, &info, &timelimit), SyscallSucceedsWithValue(SIGXFSZ)); + EXPECT_EQ(info.si_code, SI_USER); + EXPECT_EQ(info.si_pid, getpid()); + EXPECT_EQ(info.si_uid, getuid()); ASSERT_THAT(sigprocmask(SIG_UNBLOCK, &filesize_mask, nullptr), SyscallSucceeds()); |