summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2019-04-08 16:31:06 -0700
committerShentubot <shentubot@google.com>2019-04-08 16:32:11 -0700
commit9471c013483b0709479c51d470ac840621ae7d46 (patch)
tree651bfe7529c28e69320dbe1c9540250e103ba5db
parent218a7b54494b263001ed791ca13857c12d37ded6 (diff)
Export kernel.SignalInfoPriv.
Also add kernel.SignalInfoNoInfo, and use it in RLIMIT_FSIZE checks. PiperOrigin-RevId: 242562428 Change-Id: I4887c0e1c8f5fddcabfe6d4281bf76d2f2eafe90
-rw-r--r--pkg/sentry/fs/host/tty.go7
-rw-r--r--pkg/sentry/kernel/fasync/BUILD1
-rw-r--r--pkg/sentry/kernel/fasync/fasync.go7
-rw-r--r--pkg/sentry/kernel/sessions.go4
-rw-r--r--pkg/sentry/kernel/signal.go16
-rw-r--r--pkg/sentry/kernel/task_run.go2
-rw-r--r--pkg/sentry/kernel/task_sched.go10
-rw-r--r--pkg/sentry/kernel/task_signals.go2
-rw-r--r--pkg/sentry/kernel/task_syscall.go8
-rw-r--r--pkg/sentry/kernel/thread_group.go2
-rw-r--r--pkg/sentry/syscalls/linux/error.go7
-rw-r--r--test/syscalls/linux/write.cc17
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());