From a547fffe1ef53957470c440a4dbe9702ee1389be Mon Sep 17 00:00:00 2001 From: Wim Date: Sun, 19 Feb 2023 17:08:17 +0100 Subject: [PATCH 1/4] Support some PTY control characters --- pkg/sentry/fsimpl/devpts/line_discipline.go | 12 ++++++++++++ pkg/sentry/fsimpl/devpts/terminal.go | 3 +++ 2 files changed, 15 insertions(+) diff --git a/pkg/sentry/fsimpl/devpts/line_discipline.go b/pkg/sentry/fsimpl/devpts/line_discipline.go index 4b0f3fd3b..266cfbab3 100644 --- a/pkg/sentry/fsimpl/devpts/line_discipline.go +++ b/pkg/sentry/fsimpl/devpts/line_discipline.go @@ -111,6 +111,10 @@ type lineDiscipline struct { // replicaWaiter is used to wait on the replica end of the TTY. replicaWaiter waiter.Queue + + // fgProcessGroup is the foreground process group that is currently + // connected to this TTY. + fgProcessGroup *kernel.ProcessGroup } func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline { @@ -120,6 +124,10 @@ func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline { return &ld } +func (l *lineDiscipline) SetForegroundProcessGroup(pg *kernel.ProcessGroup) { + l.fgProcessGroup = pg +} + // getTermios gets the linux.Termios for the tty. func (l *lineDiscipline) getTermios(task *kernel.Task, args arch.SyscallArguments) (uintptr, error) { l.termiosMu.RLock() @@ -393,6 +401,10 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) if l.termios.IEnabled(linux.INLCR) { cBytes[0] = '\r' } + case l.termios.ControlCharacters[linux.VINTR]: // ctrl-c + l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGINT)) + case l.termios.ControlCharacters[linux.VSUSP]: // ctrl-z + l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGTSTP)) } // In canonical mode, we discard non-terminating characters diff --git a/pkg/sentry/fsimpl/devpts/terminal.go b/pkg/sentry/fsimpl/devpts/terminal.go index d9e0164a6..6c153f9c8 100644 --- a/pkg/sentry/fsimpl/devpts/terminal.go +++ b/pkg/sentry/fsimpl/devpts/terminal.go @@ -105,6 +105,9 @@ func (tm *Terminal) setForegroundProcessGroup(ctx context.Context, args arch.Sys return 0, err } + // Put the processgroup also in line discipline for further signal handling + tm.ld.SetForegroundProcessGroup(task.ThreadGroup().ProcessGroup()) + ret, err := task.ThreadGroup().SetForegroundProcessGroup(tm.tty(isMaster), kernel.ProcessGroupID(pgid)) return uintptr(ret), err } From 56458440b3292b86aeeebb86703234ee6a9a083d Mon Sep 17 00:00:00 2001 From: Wim Date: Sun, 19 Feb 2023 20:00:26 +0100 Subject: [PATCH 2/4] Support SIGQUIT --- pkg/sentry/fsimpl/devpts/line_discipline.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/sentry/fsimpl/devpts/line_discipline.go b/pkg/sentry/fsimpl/devpts/line_discipline.go index 266cfbab3..3fd90db84 100644 --- a/pkg/sentry/fsimpl/devpts/line_discipline.go +++ b/pkg/sentry/fsimpl/devpts/line_discipline.go @@ -405,6 +405,8 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGINT)) case l.termios.ControlCharacters[linux.VSUSP]: // ctrl-z l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGTSTP)) + case l.termios.ControlCharacters[linux.VQUIT]: // ctrl-\ + l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGQUIT)) } // In canonical mode, we discard non-terminating characters From 1dc92a8c71c32fc82a6938a25c7e9dbca435abb0 Mon Sep 17 00:00:00 2001 From: Wim Date: Wed, 22 Feb 2023 22:32:34 +0100 Subject: [PATCH 3/4] Add reference to terminal in lineDiscipline --- pkg/sentry/fsimpl/devpts/line_discipline.go | 15 +++++++-------- pkg/sentry/fsimpl/devpts/terminal.go | 9 +++++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/pkg/sentry/fsimpl/devpts/line_discipline.go b/pkg/sentry/fsimpl/devpts/line_discipline.go index 3fd90db84..3ca11a985 100644 --- a/pkg/sentry/fsimpl/devpts/line_discipline.go +++ b/pkg/sentry/fsimpl/devpts/line_discipline.go @@ -112,9 +112,8 @@ type lineDiscipline struct { // replicaWaiter is used to wait on the replica end of the TTY. replicaWaiter waiter.Queue - // fgProcessGroup is the foreground process group that is currently - // connected to this TTY. - fgProcessGroup *kernel.ProcessGroup + // terminal is the terminal linked to this lineDiscipline + terminal *Terminal } func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline { @@ -124,8 +123,8 @@ func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline { return &ld } -func (l *lineDiscipline) SetForegroundProcessGroup(pg *kernel.ProcessGroup) { - l.fgProcessGroup = pg +func (l *lineDiscipline) SetTerminal(tm *Terminal) { + l.terminal = tm } // getTermios gets the linux.Termios for the tty. @@ -402,11 +401,11 @@ func (*inputQueueTransformer) transform(l *lineDiscipline, q *queue, buf []byte) cBytes[0] = '\r' } case l.termios.ControlCharacters[linux.VINTR]: // ctrl-c - l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGINT)) + l.terminal.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGINT)) case l.termios.ControlCharacters[linux.VSUSP]: // ctrl-z - l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGTSTP)) + l.terminal.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGTSTP)) case l.termios.ControlCharacters[linux.VQUIT]: // ctrl-\ - l.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGQUIT)) + l.terminal.fgProcessGroup.SendSignal(kernel.SignalInfoPriv(linux.SIGQUIT)) } // In canonical mode, we discard non-terminating characters diff --git a/pkg/sentry/fsimpl/devpts/terminal.go b/pkg/sentry/fsimpl/devpts/terminal.go index 6c153f9c8..ed03ffda0 100644 --- a/pkg/sentry/fsimpl/devpts/terminal.go +++ b/pkg/sentry/fsimpl/devpts/terminal.go @@ -39,6 +39,10 @@ type Terminal struct { // replicaKTTY contains the controlling process of the replica end of this // terminal. This field is immutable. replicaKTTY *kernel.TTY + + // fgProcessGroup is the foreground process group that is currently + // connected to this TTY. + fgProcessGroup *kernel.ProcessGroup } func newTerminal(n uint32) *Terminal { @@ -49,6 +53,8 @@ func newTerminal(n uint32) *Terminal { masterKTTY: &kernel.TTY{Index: n}, replicaKTTY: &kernel.TTY{Index: n}, } + + t.ld.SetTerminal(&t) return &t } @@ -105,8 +111,7 @@ func (tm *Terminal) setForegroundProcessGroup(ctx context.Context, args arch.Sys return 0, err } - // Put the processgroup also in line discipline for further signal handling - tm.ld.SetForegroundProcessGroup(task.ThreadGroup().ProcessGroup()) + tm.fgProcessGroup = task.ThreadGroup().ProcessGroup() ret, err := task.ThreadGroup().SetForegroundProcessGroup(tm.tty(isMaster), kernel.ProcessGroupID(pgid)) return uintptr(ret), err From a88680b76554ebac18d42d8d609984ecf95fdd86 Mon Sep 17 00:00:00 2001 From: Wim Date: Thu, 23 Feb 2023 13:09:02 +0100 Subject: [PATCH 4/4] Implement code review remarks --- pkg/sentry/fsimpl/devpts/line_discipline.go | 6 +----- pkg/sentry/fsimpl/devpts/terminal.go | 8 +++++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pkg/sentry/fsimpl/devpts/line_discipline.go b/pkg/sentry/fsimpl/devpts/line_discipline.go index 3ca11a985..9b58051db 100644 --- a/pkg/sentry/fsimpl/devpts/line_discipline.go +++ b/pkg/sentry/fsimpl/devpts/line_discipline.go @@ -112,7 +112,7 @@ type lineDiscipline struct { // replicaWaiter is used to wait on the replica end of the TTY. replicaWaiter waiter.Queue - // terminal is the terminal linked to this lineDiscipline + // terminal is the terminal linked to this lineDiscipline. terminal *Terminal } @@ -123,10 +123,6 @@ func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline { return &ld } -func (l *lineDiscipline) SetTerminal(tm *Terminal) { - l.terminal = tm -} - // getTermios gets the linux.Termios for the tty. func (l *lineDiscipline) getTermios(task *kernel.Task, args arch.SyscallArguments) (uintptr, error) { l.termiosMu.RLock() diff --git a/pkg/sentry/fsimpl/devpts/terminal.go b/pkg/sentry/fsimpl/devpts/terminal.go index ed03ffda0..a3068f8a4 100644 --- a/pkg/sentry/fsimpl/devpts/terminal.go +++ b/pkg/sentry/fsimpl/devpts/terminal.go @@ -54,7 +54,8 @@ func newTerminal(n uint32) *Terminal { replicaKTTY: &kernel.TTY{Index: n}, } - t.ld.SetTerminal(&t) + t.ld.terminal = &t + return &t } @@ -111,9 +112,10 @@ func (tm *Terminal) setForegroundProcessGroup(ctx context.Context, args arch.Sys return 0, err } - tm.fgProcessGroup = task.ThreadGroup().ProcessGroup() - ret, err := task.ThreadGroup().SetForegroundProcessGroup(tm.tty(isMaster), kernel.ProcessGroupID(pgid)) + if err == nil { + tm.fgProcessGroup = task.PIDNamespace().ProcessGroupWithID(kernel.ProcessGroupID(pgid)) + } return uintptr(ret), err }