** 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