** Description changed:
+ [ Impact ]
+
+ * Tmux server crashes with SIGSEGV when a control mode client that has
+ subscriptions and the wait-exit flag detaches.
+
+ * This affects iTerm2 with the tmux integration active. Closing an iTerm2
tmux
+ window over ssh can bring down the remote ssh server.
+
+ * This bug is fixed by backporting an upstream patch that checks for a null
+ session.
+
+ [ 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"
+
+ $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}')
+
+ # 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`
+
+ [ 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.
+
+ [ 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
+ 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.
[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.
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.
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):
- tmux: server[1057941]: segfault at f0 ip 0000593fe1c9db25 sp
+ tmux: server[1057941]: segfault at f0 ip 0000593fe1c9db25 sp
00007ffe794273f0 error 4 in tmux[593fe1c6e000+af000]
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 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 ()
+ #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.
[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:
- sh tmux-subs-repro.sh
+ sh tmux-subs-repro.sh
Expected with the fix: `server <pid> alive`. Without it: `server <pid> died
(crash)`.
Results (run in an Ubuntu 24.04 container):
| 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
|
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.
[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.
[Other Info]
- Workaround: none that is reliable. `detach-on-destroy off` covers only the
- destroyed-session path, not the detach path that iTerm2 triggers.
+ 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.
+ tested only noble.
** Changed in: tmux (Ubuntu Resolute)
Status: Triaged => In Progress
** Changed in: tmux (Ubuntu Jammy)
Status: Triaged => In Progress
** Changed in: tmux (Ubuntu Noble)
Status: Triaged => In Progress
--
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