** Description changed:

  [ Impact ]
  
-  * Tmux server crashes with SIGSEGV when a control mode client that has
-    subscriptions and the wait-exit flag detaches.
+  * Running kill-session on a sesion whose window is zoomed crashes the tmux
+    server with SIGSEGV.
  
-  * This affects iTerm2 with the tmux integration active. Closing an iTerm2 
tmux
-    window over ssh can bring down the remote ssh server.
+  * This is fixed upstream in tmux 3.5, and the issue does not manifest in
+    versions before 3.4. Therefore, only Noble is affected.
  
-  * This bug is fixed by backporting an upstream patch that checks for a null
-    session.
+  * This bug is fixed by cherry-picking the upstream patch.
  
  [ Test Plan ]
  
   * Run the following script:
  
- #!/bin/sh
- # Reproducer: tmux server SIGSEGV in control_check_subs_timer after a
- # control client with subscriptions and wait-exit detaches.
- TMUX_BIN=${TMUX_BIN:-tmux}
- T="$TMUX_BIN -L subs-repro -f /dev/null"
+   unset TMUX
+   export TMUX_TMPDIR=$(mktemp -d)
+   T="tmux -f /dev/null -L sru"
+   $T new-session -d -s anchor -x 80 -y 24
+   $T new-session -d -s a -x 80 -y 24
+   $T split-window -t =a:
+   $T resize-pane -Z -t =a:
+   $T kill-session -t =a
+   sleep 1
+   $T list-sessions
  
- $T kill-server 2>/dev/null
- $T new-session -d -s keep          # a second session, so the server has no 
reason to exit
- $T new-session -d -s a
- PID=$($T display-message -p '#{pid}')
+  * On an unpatched tmux, this outputs `server exited unexpectedly`
  
- # Control client: add a subscription, enable wait-exit (as iTerm2 does),
- # then detach. After %exit the client waits for an empty line on stdin,
- # which we never send - like a terminal that is slow to answer.
- {
-   printf '%s\n' "refresh-client -B 'foo:%*:#{pane_id}'"
-   printf '%s\n' 'refresh-client -f wait-exit'
-   sleep 2
-   printf '%s\n' 'detach-client'
-   sleep 5
- } | $T -C attach-session -t a >/dev/null &
- 
- sleep 5
- case "$(ps -o stat= -p "$PID")" in
-   ""|Z*) echo "server $PID died (crash)" ;;
-   *)     echo "server $PID alive" ;;
- esac
- wait
- $T kill-server 2>/dev/null
- 
-  * On an unpatched tmux, this shows `server <pid> died (crash)`
- 
-  * On the fixed version, this shows `server <pid> alive`
+  * On the fixed version, the server does not exit and the script outputs the
+    anchor session.
  
  [ Where problems could occur ]
  
-  * The backported patch only touches the subscription timer callback code 
path.
-    Regressions would manifest in that area, possibly also related to the 
iTerm2
-    integration.
+  * Regressions could appear in other instances of window teardown: 
kill-window,
+    kill-pane, etc.
  
  [ Other Info ]
  
   * The original report (copied below) was itself a SRU bug template. I decided
     to not edit it directly. Hope this is OK.
  
- [Original Report]
- 
- Release and package (output of `lsb_release -rd` and `apt-cache policy tmux`
- on the affected server):
- 
-     No LSB modules are available.
-     Description:      Ubuntu 24.04.5 LTS
-     Release:  24.04
-     tmux:
-       Installed: 3.4-1ubuntu0.2
-       Candidate: 3.4-1ubuntu0.2
-       Version table:
-      *** 3.4-1ubuntu0.2 500
-             500 http://se.archive.ubuntu.com/ubuntu noble-updates/main amd64 
Packages
-             100 /var/lib/dpkg/status
-          3.4-1build1 500
-             500 http://se.archive.ubuntu.com/ubuntu noble/main amd64 Packages
- 
- Expected: closing an iTerm2 tmux -CC window detaches the client and the
- tmux server keeps running.
- Actual: the tmux server crashes with SIGSEGV and all sessions are lost.
+ [ Original Report ]
  
  [Impact]
  
- On noble, the tmux server crashes with SIGSEGV when a control mode client that
- has subscriptions and the wait-exit flag detaches. Every session and every
- process running in them is lost.
+ On tmux 3.4-1ubuntu0.2 (noble), running kill-session on a session whose
+ window is zoomed crashes the tmux server with SIGSEGV. One server
+ normally holds all of a user's sessions, so every session on it ends,
+ along with every process running in them. There is no warning and
+ nothing can be recovered. It reproduces with no configuration file.
  
- iTerm2's tmux integration (`tmux -CC`) sets both. It sends
- `refresh-client -fpause-after=0,wait-exit` and subscribes with
- `refresh-client -B`. So closing an iTerm2 tmux window over ssh can bring down
- the whole server. We hit it three times in three days on a noble server.
+ Zooming a pane (C-b z) is a common action, and ending a session is too.
+ Scripts that manage sessions can reach this without the user doing
+ anything unusual.
  
- Kernel log, the same instruction every time (offset 0xf0 is
- `struct session` member `windows` and 0x9f8 is `struct client` member
- `session` in the 3.4-1ubuntu0.2 debug symbols, so this is the
- `%*`/`@*` subscription path that iTerm2 uses):
+ Upstream fixed this in tmux 3.5. The bug report is
+ https://github.com/tmux/tmux/issues/3857 ("Zoomed windows crash tmux
+ after killing session with `x` on tree mode"), which reproduces it from
+ the keyboard: split with C-b %, zoom with C-b z, open tree mode with C-b
+ s, press x on the session, confirm with y. The fix is
+ https://github.com/tmux/tmux/pull/3860 ("Don't notify when unzooming
+ windows from window_destroy()", by Romain Francoise), whose branch
+ commit is 5363a5475a1dd4158c1ddb23de2da34e88738673. The maintainer
+ applied it through OpenBSD, so the hash on tmux's master may differ; I
+ haven't confirmed it. 3.5's CHANGES lists it as "Do not notify window-
+ layout-changed if the window is about to be destroyed". The pull request
+ says the bug came in with commit 36e1ac6. I've read the 3.5a source but
+ haven't built or run it.
  
-     tmux: server[1057941]: segfault at f0 ip 0000593fe1c9db25 sp
- 00007ffe794273f0 error 4 in tmux[593fe1c6e000+af000]
+ Backtrace, from a core dump with tmux-dbgsym 3.4-1ubuntu0.2:
  
- Cause: on MSG_EXITING the server clears c->session. With wait-exit the client
- then stays connected until the terminal sends an empty line. If the
- one-second subscription timer fires in that window, control_check_subs_timer()
- walks s->windows with s == NULL:
+   #0 options_tree_RB_MINMAX   options.c:90
+   #1 options_free             options.c:186
+   #2 window_destroy           window.c:360
+   #3 window_remove_ref        window.c:398   (references now 0)
+   #4 notify_callback          notify.c:165   (ne->name 
"window-layout-changed", ne->window the same window)
+   #5 cmdq_next ... server_loop
  
-     #0  winlinks_RB_MINMAX ()
-     #1  control_check_subs_timer ()
-     #2  ?? () from /lib/x86_64-linux-gnu/libevent_core-2.1.so.7
-     #3  event_base_loop ()
-     #4  proc_loop ()
-     #5  server_start ()
- 
- The same NULL session is also reachable when the attached session is destroyed
- with no replacement (server_destroy_session) and on server exit
- (server_send_exit).
- 
- Upstream: there is no targeted fix. The crash went away in tmux 3.8 as a side
- effect of moving subscriptions into
- monitor.c (commit 8e03310a, "Move monitor stuff out of control.c into its own
- file for reuse"). The new code checks for a NULL session before evaluating.
- That rewrite is too large to backport. The attached debdiff adds the
- equivalent three-line check to control_check_subs_timer() instead.
+ How it happens, from reading 3.4's window.c and notify.c, and consistent with 
the core:
+ 1. The last reference to a zoomed window goes, so window_destroy starts.
+ 2. window_destroy calls window_unzoom, which calls 
notify_window("window-layout-changed", w). That takes a new reference and 
queues a callback.
+ 3. window_destroy carries on and frees w.
+ 4. The queued callback drops its reference on freed memory, reaches 0, and 
calls window_destroy again.
  
  [Test Plan]
  
- No terminal is needed. The attached `tmux-subs-repro.sh` starts a private
- server (`-L subs-repro -f /dev/null`), attaches a control client on a pipe,
- subscribes, sets wait-exit and detaches, and then never sends the empty line:
+ As an ordinary user, on a private socket so no existing tmux server is
+ touched:
  
-     sh tmux-subs-repro.sh
+   unset TMUX
+   export TMUX_TMPDIR=$(mktemp -d)
+   T="tmux -f /dev/null -L sru"
+   $T new-session -d -s anchor -x 80 -y 24
+   $T new-session -d -s a -x 80 -y 24
+   $T split-window -t =a:
+   $T resize-pane -Z -t =a:
+   $T kill-session -t =a
+   sleep 1
+   $T list-sessions
  
- Expected with the fix: `server <pid> alive`. Without it: `server <pid> died
- (crash)`.
+ Broken: "server exited unexpectedly" from kill-session, then "no server 
running on ..." from list-sessions.
+ Fixed: list-sessions prints the "anchor" session.
  
- Results (run in an Ubuntu 24.04 container):
+ To clean up: $T kill-server; rm -rf "$TMUX_TMPDIR"
  
- | Build                                | Crashes                              
         |
- | ------------------------------------ | 
--------------------------------------------- |
- | 3.4-1ubuntu0.2                       | 3/3, 1/2 (it is a race against the 1 
s timer) |
- | 3.4-1ubuntu0.2 + attached patch      | 0/5                                  
         |
- | upstream 3.6a                        | 5/5                                  
         |
- | upstream 3.8 and master (2026-10-30) | 0/5 each                             
         |
+ The same steps without the resize-pane line leave "anchor" alive, on the
+ broken version too.
  
- Also checked with the patched build: subscriptions still report changes
- (`%subscription-changed` for a pane title change), and the destroyed-session
- path (kill-session while a control client with subscriptions has queued
- output, detach-on-destroy on) no longer crashes (0/3). Without the patch it
- crashes.
+ Results on 3.4-1ubuntu0.2, Ubuntu 24.04.5: broken 3 runs of 3 with these
+ exact steps, and 8 of 8 in an earlier scripted run; without the zoom, 0
+ of 3 and 0 of 8.
  
  [Where problems could occur]
  
- The change only returns early from the subscription timer callback while the
- control client has no session. The timer stays armed, so a client that gets a
- session again resumes its subscriptions. A client without a session has
- nothing its subscriptions could report, since every subscription type is
- relative to the client's session. A regression would show up as missing
- `%subscription-changed` notifications in control mode clients such as iTerm2.
+ The fix changes what happens when a zoomed window is destroyed, and whether 
window-layout-changed fires then.
+ - A regression could appear as a crash or a leak elsewhere in window 
teardown: kill-window, kill-pane, a pane's last process exiting, or a server 
shutting down with zoomed windows.
+ - Hooks and control-mode clients listening for window-layout-changed would no 
longer see that event for a window being destroyed. Anything relying on it 
would notice.
+ - Unzooming on ordinary paths (resize-pane -Z, select-pane -Z) must keep 
firing the notification and keep the layout; if the change reaches further than 
destruction, zoom behaviour would be where it shows.
+ 
+ Regression testing should cover zoom and unzoom, kill-window and kill-
+ pane on zoomed windows, and a hook on window-layout-changed.
  
  [Other Info]
  
- - Workaround: none that is reliable. `detach-on-destroy off` covers only the
-   destroyed-session path, not the detach path that iTerm2 triggers.
- - The same timer code is present in upstream 3.5a, 3.6a and 3.7c. I have
-   tested only noble.
+ Other routes to the same crash, same setup: an ungrouped session with a
+ zoomed window, with destroy-unattached set, when its last client
+ disconnects. Killing the zoomed window or pane directly (kill-window,
+ kill-pane) did not crash in my runs, 8 of 8.
+ 
+ Workaround: unzoom before kill-session.
+ 
+ I searched for an existing report and didn't find one. I have not
+ prepared a debdiff.

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172659

Title:
  tmux server crashes (SIGSEGV in control_check_subs_timer) when an
  iTerm2 tmux -CC client detaches

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/tmux/+bug/2172659/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to