V OpenBSD i tmuxu od 2. 10. 2026 Oprava chyby v tmuxu v upstreamu
tmux: pád serveru při copy-mode -S bez připojeného klienta
BudgetScan odhalil chybějící kontrolu NULL ukazatele v obsluze copy-mode -S v tmuxu, celosvětově používaném terminálovém multiplexeru. Při vyvolání v kontextu serveru bez připojeného terminálového klienta (například z hooků nebo front příkazů na pozadí) vedla chybějící kontrola k pádu serveru tmux daného uživatele na SIGSEGV, což ukončilo všechny jeho relace i programy, které v nich běžely. Nicholas Marriott, autor a hlavní správce tmuxu, přijal naši zprávu a začlenil opravu přímo do CVS OpenBSD.
Co bylo špatně
Příkaz copy-mode nabízí přepínač -S pro posouvání historie pomocí událostí posuvníku myši. Při provádění funkce cmd_copy_mode_exec() získává tmux odkaz na aktivního klienta příkazu voláním cmdq_get_client(item).
Pokud příkaz spustí interaktivní terminálový klient, ukazuje c na strukturu klienta a jeho terminál (c->tty). Příkazy v tmuxu však mohou být vyvolány také na úrovni serveru zcela bez připojeného terminálu — například z konfiguračního souboru ~/.tmux.conf, přes automatizaci na pozadí nebo ze systémových hooků jako pane-died (set-hook -g pane-died "copy-mode -S").
V těchto situacích bez klienta je c rovno NULL. Zatímco sousední větev pro myš (-M) tento stav správně ošetřila:
if (c == NULL || c->session != s)
return (CMD_RETURN_NORMAL);
ve větvi -S tato kontrola zcela chyběla. Kód okamžitě předal &c->tty do funkce tty_window_offset(), což vedlo k okamžitému pádu na neplatnou paměť (SIGSEGV). Jeden serverový proces tmuxu obsluhuje všechny relace daného uživatele (ve výchozím nastavení má každý uživatel vlastní server a socket), takže pád ukončil všechna okna a panely tohoto serveru i programy, které v nich běžely. Spouštěčem je příkaz bez klienta, třeba z hooku ve vlastní konfiguraci uživatele, takže jde o opravu robustnosti, ne o bezpečnostní zranitelnost.
Jak to bylo opraveno
Odeslali jsme pull request s defenzivní kontrolou ukazatele a automatickým regresním testem reprodukujícím pád bez připojeného klienta:
Index: src/usr.bin/tmux/cmd-copy-mode.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/cmd-copy-mode.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -p -r1.54 -r1.55
--- src/usr.bin/tmux/cmd-copy-mode.c 14 Jul 2026 17:17:17 -0000 1.54
+++ src/usr.bin/tmux/cmd-copy-mode.c 2 Oct 2026 12:12:51 -0000 1.55
@@ -103,6 +103,8 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'd'))
window_copy_pagedown(wp, 0, args_has(args, 'e'));
if (args_has(args, 'S')) {
+ if (c == NULL)
+ return (CMD_RETURN_NORMAL);
tty_window_offset(&c->tty, &tty_ox, &tty_oy, &tty_sx, &tty_sy);
window_copy_scroll(wp, c->tty.mouse_slider_mpos, event->m.y,
tty_oy, args_has(args, 'e'));
Přiložený regresní test (regress/copy-mode-no-client-scroll.sh) vyvolá copy-mode -S z hooku pane-died bez připojeného klienta. Na původním kódu test okamžitě reprodukoval segmentation fault; s nasazenou opravou server příkaz bezpečně ignoroval a test doběhl zelený.
Správce Nicholas Marriott opravu přijal a začlenil revizi 1.55 přímo do stromu OpenBSD:
„Applied to OpenBSD now, will be in GitHub later. Thanks!“
A tak se i stalo: týž den odpoledne se změna přenesla do tmuxu na GitHubu jako commit 5932140.
Časová osa
- 1. 10. 2026. BudgetScan upozornil na nechráněný ukazatel na klienta v
cmd-copy-mode.c. Manuální audit zdrojového kódu potvrdil vektor pádu serveru přes hooky. Otevřeli jsme pull request #5670 s opravou a regresním testem. - 2. 10. (12:12 UTC). Autor a hlavní správce tmuxu Nicholas Marriott (
nicm) pull request zhodnotil, odpověděl na GitHubu a začlenil revizi 1.55 do CVS OpenBSD: „Do not use client for copy-mode -S if NULL, reported by Martin Vlach.“ - 2. 10. (14:10 UTC). Změna se z OpenBSD přenesla do repozitáře tmux na GitHubu jako commit 5932140.
Jak to číst
Skener poukázal na nechráněný ukazatel jako na konkrétní podnět. Inženýr prověřil řídicí tok, izoloval spuštění přes hooky, napsal reprodukovatelný test a připravil opravu. Upstreamový správce Nicholas Marriott ji zvalidoval a začlenil do OpenBSD. Přesně tak má automatizované skenování fungovat: nálezy slouží lidem k prověření, nikoli jako nezpochybnitelné ortely. Velké díky patří Nicholasi Marriottovi za okamžitou, vstřícnou reakci a bezproblémové začlenění do OpenBSD.
Zdroje
- Záznamy v CVS OpenBSD pro cmd-copy-mode.c
- Diff v CVS OpenBSD (revize 1.54 → 1.55)
- Commit 5932140 v repozitáři tmux na GitHubu
- GitHub Pull Request (tmux/tmux#5670)
- Komentář správce Nicholase Marriotta na GitHubu
- Doplňující komentář v pull requestu s odkazem na commit
- Oficiální repozitář tmux na GitHubu