Skip to content

Strip terminal escape sequences from the Command column - #951

Open
carfeii wants to merge 1 commit into
dalance:masterfrom
carfeii:fix/command-escape-sanitization
Open

Strip terminal escape sequences from the Command column#951
carfeii wants to merge 1 commit into
dalance:masterfrom
carfeii:fix/command-escape-sanitization

Conversation

@carfeii

@carfeii carfeii commented Aug 6, 2026

Copy link
Copy Markdown

Fixes #950.

Summary

Command::add (src/columns/command.rs) read each process's command line
and only replaced newline and tab characters before displaying it, with
no handling of other control characters or ANSI/terminal escape
sequences. Since a process's command line (including argv[0]) is fully
controlled by whichever user started it, and /proc/<pid>/cmdline is
world-readable on Linux regardless of process ownership, any local
unprivileged user could plant a process whose command line contains a
raw escape sequence. That sequence would then be printed unmodified to
any other user's terminal the moment they ran procs, since displaying
every visible process is the tool's whole purpose, not an action taken
with awareness of viewing untrusted content the way opening a specific
file is.

Fix

Adds util::sanitize_display, which replaces control characters
(including the ESC byte, 0x1b) with the Unicode replacement
character, and applies it to the final command-line string in all four
platform variants of Command::add (Linux/Android, macOS, Windows,
FreeBSD). The existing newline/tab-to-space replacement is kept as-is;
this is an additional pass on top of it.

Testing

  • cargo test --release passes in full (15 passed, up from 13 with the
    2 new tests, 0 failed).
  • Added sanitize_display_strips_escape_sequences and
    sanitize_display_preserves_normal_text to src/util.rs.
  • Manually reproduced the issue against an unpatched build: spawned a
    detached process (subprocess.Popen with a crafted argv[0] containing
    a raw OSC 52 escape sequence, executable= pointing at sleep so the
    actual command run was harmless), ran procs against it, and confirmed
    the exact injected byte sequence appeared unmodified in procs's raw
    output. Repeated against this branch and confirmed the ESC/BEL
    bytes are replaced with the Unicode replacement character instead.

Command::add read each process's command line and only replaced
newline and tab characters before displaying it, with no handling of
other control characters or ANSI/terminal escape sequences. Since a
process's command line (including argv[0]) is fully controlled by
whichever user started it, and /proc/<pid>/cmdline is world-readable on
Linux regardless of process ownership, any local unprivileged user
could plant a process whose command line contains a raw escape
sequence, which would then be printed unmodified to any other user's
terminal when they run `procs`, a routine action that displays every
visible process.

Add util::sanitize_display, which replaces control characters (including
ESC) with the Unicode replacement character, and apply it to the final
command-line string in all four platform variants of Command::add
(Linux/Android, macOS, Windows, FreeBSD).

See dalance#950.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Command column does not strip terminal escape sequences from process command lines, allowing injection via a crafted argv0

1 participant