On Tue, Jan 10, 2023 at 06:58:15PM +0100, Jakub Wilk wrote:
> If you edit a foo.gz file from a directory which is not writable by you, Vim
> tries to use /var/tmp/foo.gz.swp as the swap file,

Vim prefers to use ~/tmp/foo.gz.swp, but it won't create ~/tmp for you.

As for why this is happening with .gz files, I think it's because
gzip#read does end up writing a file.  Refactoring the plugin to use
the BufReadCmd, BufWriteCmd, etc. might help avoid this.

> even when this file
> already exist and is owned by somebody else.

One of the main purposes of swap files is to detect when someone else is
editing the same file and warn you.  Therefore, Vim has to try reading
the potential swapfile.

Vim could try checking for non-regular files first, which would swap the
naive problem here with one that requires a race to replace the file
after it's checked.

Arguably, Vim should use the // form for any directory other than ".":

        - For Unix and Win32, if a directory ends in two path separators "//",
          the swap file name will be built from the complete path to the file
          with all path separators replaced by percent '%' signs (including
          the colon following the drive letter on Win32). This will ensure
          file name uniqueness in the preserve directory.

However, this just reduces chance of collisions, not the overall gist
behind your reproduction.

> This can be exploited for
> denial of service, maybe worse.
> 
> To reproduce, run:
> 
>     mkfifo -m 666 /var/tmp/changelog.gz.swp
> 
> Then, as another user:
> 
>     vim /usr/share/doc/vim/changelog.gz
> 
> Vim will hang forever (and can't be killed easily).

Cheers,
-- 
James
GPG Key: 4096R/91BF BF4D 6956 BD5D F7B7  2D23 DFE6 91AE 331B A3DB

Reply via email to