summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/thread_group.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/kernel/thread_group.go')
-rw-r--r--pkg/sentry/kernel/thread_group.go179
1 files changed, 0 insertions, 179 deletions
diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go
index 0eef24bfb..2a97e3e8e 100644
--- a/pkg/sentry/kernel/thread_group.go
+++ b/pkg/sentry/kernel/thread_group.go
@@ -19,13 +19,10 @@ import (
"sync/atomic"
"gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/fs"
- "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
"gvisor.dev/gvisor/pkg/sentry/limits"
"gvisor.dev/gvisor/pkg/sentry/usage"
- "gvisor.dev/gvisor/pkg/syserror"
)
// A ThreadGroup is a logical grouping of tasks that has widespread
@@ -248,12 +245,6 @@ type ThreadGroup struct {
//
// mounts is immutable.
mounts *fs.MountNamespace
-
- // tty is the thread group's controlling terminal. If nil, there is no
- // controlling terminal.
- //
- // tty is protected by the signal mutex.
- tty *TTY
}
// newThreadGroup returns a new, empty thread group in PID namespace ns. The
@@ -333,176 +324,6 @@ func (tg *ThreadGroup) forEachChildThreadGroupLocked(fn func(*ThreadGroup)) {
}
}
-// SetControllingTTY sets tty as the controlling terminal of tg.
-func (tg *ThreadGroup) SetControllingTTY(tty *TTY, arg int32) error {
- tty.mu.Lock()
- defer tty.mu.Unlock()
-
- // We might be asked to set the controlling terminal of multiple
- // processes, so we lock both the TaskSet and SignalHandlers.
- tg.pidns.owner.mu.Lock()
- defer tg.pidns.owner.mu.Unlock()
- tg.signalHandlers.mu.Lock()
- defer tg.signalHandlers.mu.Unlock()
-
- // "The calling process must be a session leader and not have a
- // controlling terminal already." - tty_ioctl(4)
- if tg.processGroup.session.leader != tg || tg.tty != nil {
- return syserror.EINVAL
- }
-
- // "If this terminal is already the controlling terminal of a different
- // session group, then the ioctl fails with EPERM, unless the caller
- // has the CAP_SYS_ADMIN capability and arg equals 1, in which case the
- // terminal is stolen, and all processes that had it as controlling
- // terminal lose it." - tty_ioctl(4)
- if tty.tg != nil && tg.processGroup.session != tty.tg.processGroup.session {
- if !auth.CredentialsFromContext(tg.leader).HasCapability(linux.CAP_SYS_ADMIN) || arg != 1 {
- return syserror.EPERM
- }
- // Steal the TTY away. Unlike TIOCNOTTY, don't send signals.
- for othertg := range tg.pidns.owner.Root.tgids {
- // This won't deadlock by locking tg.signalHandlers
- // because at this point:
- // - We only lock signalHandlers if it's in the same
- // session as the tty's controlling thread group.
- // - We know that the calling thread group is not in
- // the same session as the tty's controlling thread
- // group.
- if othertg.processGroup.session == tty.tg.processGroup.session {
- othertg.signalHandlers.mu.Lock()
- othertg.tty = nil
- othertg.signalHandlers.mu.Unlock()
- }
- }
- }
-
- // Set the controlling terminal and foreground process group.
- tg.tty = tty
- tg.processGroup.session.foreground = tg.processGroup
- // Set this as the controlling process of the terminal.
- tty.tg = tg
-
- return nil
-}
-
-// ReleaseControllingTTY gives up tty as the controlling tty of tg.
-func (tg *ThreadGroup) ReleaseControllingTTY(tty *TTY) error {
- tty.mu.Lock()
- defer tty.mu.Unlock()
-
- // We might be asked to set the controlling terminal of multiple
- // processes, so we lock both the TaskSet and SignalHandlers.
- tg.pidns.owner.mu.RLock()
- defer tg.pidns.owner.mu.RUnlock()
-
- // Just below, we may re-lock signalHandlers in order to send signals.
- // Thus we can't defer Unlock here.
- tg.signalHandlers.mu.Lock()
-
- if tg.tty == nil || tg.tty != tty {
- tg.signalHandlers.mu.Unlock()
- return syserror.ENOTTY
- }
-
- // "If the process was session leader, then send SIGHUP and SIGCONT to
- // the foreground process group and all processes in the current
- // session lose their controlling terminal." - tty_ioctl(4)
- // Remove tty as the controlling tty for each process in the session,
- // then send them SIGHUP and SIGCONT.
-
- // If we're not the session leader, we don't have to do much.
- if tty.tg != tg {
- tg.tty = nil
- tg.signalHandlers.mu.Unlock()
- return nil
- }
-
- tg.signalHandlers.mu.Unlock()
-
- // We're the session leader. SIGHUP and SIGCONT the foreground process
- // group and remove all controlling terminals in the session.
- var lastErr error
- for othertg := range tg.pidns.owner.Root.tgids {
- if othertg.processGroup.session == tg.processGroup.session {
- othertg.signalHandlers.mu.Lock()
- othertg.tty = nil
- if othertg.processGroup == tg.processGroup.session.foreground {
- if err := othertg.leader.sendSignalLocked(&arch.SignalInfo{Signo: int32(linux.SIGHUP)}, true /* group */); err != nil {
- lastErr = err
- }
- if err := othertg.leader.sendSignalLocked(&arch.SignalInfo{Signo: int32(linux.SIGCONT)}, true /* group */); err != nil {
- lastErr = err
- }
- }
- othertg.signalHandlers.mu.Unlock()
- }
- }
-
- return lastErr
-}
-
-// ForegroundProcessGroup returns the process group ID of the foreground
-// process group.
-func (tg *ThreadGroup) ForegroundProcessGroup(tty *TTY) (int32, error) {
- tty.mu.Lock()
- defer tty.mu.Unlock()
-
- tg.pidns.owner.mu.Lock()
- defer tg.pidns.owner.mu.Unlock()
- tg.signalHandlers.mu.Lock()
- defer tg.signalHandlers.mu.Unlock()
-
- // "When fd does not refer to the controlling terminal of the calling
- // process, -1 is returned" - tcgetpgrp(3)
- if tg.tty != tty {
- return -1, syserror.ENOTTY
- }
-
- return int32(tg.processGroup.session.foreground.id), nil
-}
-
-// SetForegroundProcessGroup sets the foreground process group of tty to pgid.
-func (tg *ThreadGroup) SetForegroundProcessGroup(tty *TTY, pgid ProcessGroupID) (int32, error) {
- tty.mu.Lock()
- defer tty.mu.Unlock()
-
- tg.pidns.owner.mu.Lock()
- defer tg.pidns.owner.mu.Unlock()
- tg.signalHandlers.mu.Lock()
- defer tg.signalHandlers.mu.Unlock()
-
- // TODO(b/129283598): "If tcsetpgrp() is called by a member of a
- // background process group in its session, and the calling process is
- // not blocking or ignoring SIGTTOU, a SIGTTOU signal is sent to all
- // members of this background process group."
-
- // tty must be the controlling terminal.
- if tg.tty != tty {
- return -1, syserror.ENOTTY
- }
-
- // pgid must be positive.
- if pgid < 0 {
- return -1, syserror.EINVAL
- }
-
- // pg must not be empty. Empty process groups are removed from their
- // pid namespaces.
- pg, ok := tg.pidns.processGroups[pgid]
- if !ok {
- return -1, syserror.ESRCH
- }
-
- // pg must be part of this process's session.
- if tg.processGroup.session != pg.session {
- return -1, syserror.EPERM
- }
-
- tg.processGroup.session.foreground.id = pgid
- return 0, nil
-}
-
// itimerRealListener implements ktime.Listener for ITIMER_REAL expirations.
//
// +stateify savable