Repository navigation
fix(desktop): frame each tmux format record so a newline in a field cannot forge a pane - #8725
Conversation
…annot forge a pane tmux prints a newline inside a `-F` field as is. A pane whose working directory (or window name, or session name) held a newline followed by separator-joined text ended its own record early and forged another: any target, command and path, while the real pane disappeared from `panes`. Every `-F` read (list-clients, list-panes, the active pane) now frames each record with a marker made fresh for that call, and only lines framed whole by it are read. Nobody outside the call knows the marker, so no field can forge a record, and the halves of a record a newline split are each dropped.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Turn on auto-fix | Re-trigger cubic
|
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
… can set
The per-call frame is not a secret: on macOS `ps` shows any process's
arguments, and on Linux `/proc/<pid>/cmdline` is world-readable, so someone
who owns the directory a pane sits in can read the frame and rename the
directory before tmux reads it.
tmux now replaces each newline with `<NL>` itself (`#{s/\n/<NL>/:…}`) in the
fields someone other than the user can set: the pane's directory, its
command, and the window title a program sets. A record is then one line, and
the frame stays as a second line of defence. tmux output is also decoded as a
stream, so a character split across two chunks arrives whole.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
-Ffield as is. Suppose a pane's working directory (or its window title, or its command's name) holds a newline followed by separator-joined text, such asa+ newline +user:0.0<~sim~>forged<~sim~>rm -rf<~sim~>home.panes.paneargument then sends input to, or closes, the wrong pane.<NL>itself (#{s/<newline>/<NL>/:…}). Those fields are the pane's directory, its command's name, and the window title a program sets with an escape sequence. A record is then always one line.-Fread (list-clients, list-panes, and the active-pane lookup) wraps each record in a marker made fresh for that call, and only lines framed whole are read.psshows any process's arguments, and on Linux/proc/<pid>/cmdlineis world-readable. So the marker is a second line of defence for fields tmux prints raw, not the protection itself.Type of Change
Testing
rm -rfrow is read; with it, the pane is one line and nothing is forged.listPanesreturns nothing for the forging session, and a directory holding just a newline lists as one pane with<NL>in its path.activePanestill resolves.Checklist