Suppress recovery files when editing sensitive files in vi, nvi, and vim

nvivivim

I'm writing an application that maintains an encrypted database containing extremely sensitive information including cryptographic keys and passwords. The application is paranoid about using memlock, blocking ptrace, preventing coredumps, etc., but has a command to let the database owner edit the contents of the database. This command writes the entire database to a temporary file in human-readable ASCII format and lets the user edit it. Specifically, it creates a new file in a newly created directory /tmp/XXXXXXXX/ (where /tmp is ideally a memory file system), then runs the user's preferred editor on the file. When the editor exits, the application parses the file contents and shreds the file and anything else under /tmp/XXXXXXXX/ before finally deleting the directory.

Unfortunately, this strategy doesn't work very well with any of the vi variants, because the editor ends up writing copies of the file to /var/tmp/vi.recover, where they will likely persist on disk even after vi deletes them. (The data contains high-value private keys, for which it would be easy to search an entire raw partition.) I'm looking for a generic way to suppress these recovery files, or at the very least move them to /tmp/XXXXXXXX/.

My ideal solution would work for most vi variants, but I'm also happy parsing the EDITOR environment variable and doing something different for each editor. Hence, if you have a solution that works for vim but not the others, that's at least a good start. (I already special-case vim to re-open the editor to the exact column number of a parse error, whereas other vi variants can only be opened to the appropriate line.)

Because this is an application to be distributed to other people, the one thing I cannot do is solve the problem by editing people's .exrc or .vimrc files. In an absolute pinch, I suppose I could change the HOME environment variable before exec'ing the editor and create a temporary .vimrc that merges the user's real one with some recovery-suppression commands. However, I would far prefer a command-line or comment solution.

The closest I can come to a minimal working example is to share what I do for emacs, which is to append the following comment at the end of the file:

# Local Variables:
# make-backup-files: nil
# auto-save-default: nil
# End:

Though the easiest is a command-line option, if some equivalent comment can work for vim or any of the other vi variants, that would be great, too.

update:

After some experimentation with strace, it seems the following command might do what I want for vim:

vim -n -c 'set viminfo=' /tmp/XXX/secret.ini

However, it does not work with --cmd, which was the option suggested, but only with -c. Moreover, I don't really understand what -n does, but just noticed that the man page said it will break recovery. So I'd still love to hear an answer from someone knowledgeable about vim, if indeed this even works. And of course solutions for the other vi variants would be welcome.

update 2:

The EXINIT environment variable might work for vi and nvi, if I set it to EXINIT=set dir=/tmp/XXX|set recdir=. nvi gives a warning about lack of recovery on startup, which is encouraging, while vi does drop files into the file system, but at least they are in /tmp which is often a memory file system.

Best Answer

For vim you can move the location of the recovery file with the directory option.

set directory=/tmp/XXXXXXXX

This can be added to the command line for a single instance like this

mkdir -m700 /tmp/xyz
vim --cmd "set directory=/tmp/xyz" /path/to/secure.file