From 1557bad96a3a756c4e6d0d4716f93d4fc3581539 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Sat, 3 May 2025 10:24:27 +0100 Subject: [PATCH 1/2] fix: fixes a possible deadlock in kube moderator joining This PR addresses a bug in the Kubernetes session join logic where a joined session could hang under specific conditions. The issue occurred when one or more peers triggered multiple terminal resize events in rapid succession. The client handling the resize was only performing a single resize operation and failing to respond to subsequent events, resulting in the terminal becoming unresponsive. This led to a state where session data was no longer displayed to moderators or observers, effectively freezing the shared session view. The fix ensures proper handling of repeated resize events to maintain session responsiveness and continuity. Signed-off-by: Tiago Silva --- lib/client/kubesession.go | 46 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/client/kubesession.go b/lib/client/kubesession.go index b55a9d79155ae..243b88765e74d 100644 --- a/lib/client/kubesession.go +++ b/lib/client/kubesession.go @@ -136,8 +136,7 @@ func NewKubeSession(ctx context.Context, cfg KubeSessionConfig) (*KubeSession, e stdout := utils.NewSyncWriter(term.Stdout()) - go handleOutgoingResizeEvents(ctx, stream, term) - go handleIncomingResizeEvents(ctx, stream, term) + go handleResizeEvents(ctx, stream, term) s := &KubeSession{stream, term, ctx, cancel, cfg.Tracker, sync.WaitGroup{}} if err := s.handleMFA(ctx, cfg.AuthClient, cfg.Ceremony, cfg.Mode, stdout); err != nil { @@ -170,29 +169,30 @@ func kubeSessionNetDialer(ctx context.Context, cfg KubeSessionConfig) client.Con ) } -func handleOutgoingResizeEvents(ctx context.Context, stream *streamproto.SessionStream, term *terminal.Terminal) { - queue := stream.ResizeQueue() - - select { - case <-ctx.Done(): - return - case size := <-queue: - if size == nil { - return - } - - term.Resize(int16(size.Width), int16(size.Height)) - } -} - -func handleIncomingResizeEvents(ctx context.Context, stream *streamproto.SessionStream, term *terminal.Terminal) { - events := term.Subscribe() - +func handleResizeEvents(ctx context.Context, stream *streamproto.SessionStream, term *terminal.Terminal) { + streamResizes := stream.ResizeQueue() + terminalResizes := term.Subscribe() + defer func() { + stream.Close() + }() for { select { case <-ctx.Done(): return - case event, more := <-events: + case size, more := <-streamResizes: + if !more { + return + } + if size == nil { + continue + } + if err := term.Resize(int16(size.Width), int16(size.Height)); err != nil { + fmt.Printf("Error attempting to resize terminal: %v\n\r", err) + } + case event, more := <-terminalResizes: + if !more { + return + } _, ok := event.(terminal.ResizeEvent) if ok { w, h, err := term.Size() @@ -205,10 +205,6 @@ func handleIncomingResizeEvents(ctx context.Context, stream *streamproto.Session fmt.Printf("Error attempting to resize terminal: %v\n\r", err) } } - - if !more { - return - } } } } From bdfc598a70377f7061d19873ec4ee68f9af62bea Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Mon, 5 May 2025 16:33:12 +0100 Subject: [PATCH 2/2] Update lib/client/kubesession.go Co-authored-by: Zac Bergquist --- lib/client/kubesession.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/client/kubesession.go b/lib/client/kubesession.go index 243b88765e74d..1037caf62269c 100644 --- a/lib/client/kubesession.go +++ b/lib/client/kubesession.go @@ -172,9 +172,7 @@ func kubeSessionNetDialer(ctx context.Context, cfg KubeSessionConfig) client.Con func handleResizeEvents(ctx context.Context, stream *streamproto.SessionStream, term *terminal.Terminal) { streamResizes := stream.ResizeQueue() terminalResizes := term.Subscribe() - defer func() { - stream.Close() - }() + defer stream.Close() for { select { case <-ctx.Done():