Ex Command Injection via Unescaped Buffer Name in sign_jump() in Vim < v9.2.1090
================================================================================

Date: 12.09.2026
Severity: Low
CVE: *requested, not yet assigned*
CWE: Improper Neutralization of Argument Delimiters in a Command ('Argument 
Injection') (CWE-88),
     Improper Control of Generation of Code ('Code Injection') (CWE-94)

## Summary

When jumping to a sign in a buffer that is not displayed in any window, Vim
re-opens that buffer by building an Ex command line from the buffer's file
name and executing it.  The file name is interpolated without escaping, so a
name containing the Ex command separator `|` is split into two commands, the
second of which is taken from the file name.

## Description

`sign_jump()` in `src/sign.c` handles the case where the buffer holding the
sign is not shown in any window:
```c
    char_u *cmd = alloc(STRLEN(buf->b_fname) + 25);
    if (cmd == NULL)
        return -1;

    sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname);
    do_cmdline_cmd(cmd);
```
`buf->b_fname` is stored as given and is not escaped via
`fnameescape()`. Unix permits `|` in a file name, and
`do_cmdline_cmd()` treats it as a command separator, so a buffer named
`pwn|:silent !cmd` results in two Ex commands being executed: the `:edit`,
which fails, and whatever follows the bar.

The branch is reached only when the buffer is not displayed in any window,
that is when `buf_jump_open_win()` returns NULL.  It is used by the
`:sign jump` command and by the `sign_jump()` function.

The issue has been addressed by opening the buffer by its number with
`do_ecmd()` instead of synthesizing a command line, so that no escaping is
required.

## Impact

Arbitrary Ex command execution, and through commands such as `:!` arbitrary
operating system command execution, in the context of the user running Vim.
Vim must be built with `+signs`, which is the default in normal builds.

The severity is rated Low.  Execution requires a buffer whose name contains
`|` or a newline, a sign placed in that buffer, the buffer not being shown in
any window, and `:sign jump` or `sign_jump()` being invoked on it.  These are
deliberate steps by the user rather than a consequence of opening a file, and
the commands run with no privilege beyond the user's own account.

## Acknowledgements

The Vim project would like to thank Ahmed Ibrahim (@skeletonsec) for
reporting the issue.

## References

The issue has been fixed as of Vim patch 
[v9.2.1090](https://github.com/vim/vim/releases/tag/v9.2.1090).

- 
[Commit](https://github.com/vim/vim/commit/2942c934ec7c68791b9da7ab6c29ae4987f7a2fb)
- [Github Security 
Advisory](https://github.com/vim/vim/security/advisories/GHSA-x9jf-rjm6-vxqh)


Best,
Christian
-- 
Sperma light = Macht schwanger, aber nicht dick!

Reply via email to