#1028409 vim: insecure use of /var/tmp when editing .gz files

Package:
vim
Source:
vim
Description:
Vi IMproved - enhanced vi editor
Submitter:
Jakub Wilk
Date:
2023-01-13 14:30:02 UTC
Severity:
normal
Tags:
#1028409#3
Date:
2023-01-10 17:58:15 UTC
From:
To:
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, even when this
file already exist and is owned by somebody else. 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).

#1028409#8
Date:
2023-01-13 03:11:53 UTC
From:
To:
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.

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.

Cheers,

#1028409#13
Date:
2023-01-13 14:18:24 UTC
From:
To:
This reminds me that the default value for 'directory' is not good for a
multi-user system.  However, it's not so easy to come up with an
alternative that will work everywhere.

It will still need to write a file, so that the uncompress command can
read it.

If the file exist then Vim will use ".swo" instead of ".swp".  Anyway,
it would still be in the public "tmp" directory, thus this is just a
detail.

Also, others can read the swap file, something the user probably isn't
aware of.