12

I've been trying to make a temporary named fifo and after referencing Bash: create anonymous fifo I see they are using mktemp -u to get the file name for the fifo. The man page states this is unsafe.

-u, --dry-run
       do not create anything; merely print a name (unsafe)

Why is this unsafe and how do I use this technique responsibly?

2 Answers 2

9

What they meant by "unsafe" above is the following. Say you have this scenario:

  • You run mktemp -u
  • It prints a name, say /tmp/tmp.njxOsokU9u
  • You save that name somewhere, presumably in a bash variable (e.g. tmp)
  • Your script does some work unrelated to that file
  • Your script then attempts to use the temporary file (echo hello > $tmp)

Nothing wrong, yes? Here's a similar scenario:

  • You run mktemp -u
  • It prints a name, say /tmp/tmp.njxOsokU9u
  • You save that name somewhere, presumably in a bash variable (e.g. tmp)
  • Your script does some work unrelated to that file
  • Some other process unrelated to your script creates the file with the same name (i.e. /tmp/tmp.njxOsokU9u)
  • Your script then attempts to use the temporary file (echo hello > $tmp)

Now your script and the other process could be writing to the same file, which likely will not end up well. That's why it's marked unsafe.

6
  • 4
    But how does the latter scenario differ from one where mktemp is invoked without -u? Even if the file is created (as opposed to just the name), nothing prevents another process from writing to the same file once it has been created. May 21, 2017 at 16:29
  • 2
    If mktemp in your script creates the file, mktemp in the other script wouldn't use the same filename because the file would already exist. It's not trying to protect against malicious scripts, just against accidentally using the same name. Feb 24, 2018 at 22:27
  • 2
    @stephenwade that's not the key reason, I think. The problem is detailed in owasp.org/index.php/Insecure_Temporary_File . One key reason is that if another process guesses the name, and they have lower privileges than you, they can create a file of that name as a symlink pointing to an important system file. Then your code will overwrite that important system file unwittingly.
    – Clément
    Mar 20, 2019 at 3:14
  • @Clément Good point. That page is a good overview of the risks associated with mktemp -u and similar functions. Mar 20, 2019 at 15:28
  • 2
    The owasp link @Clément posted has rotted. I was able to find the new location for what I assume is the same page: owasp.org/www-community/vulnerabilities/Insecure_Temporary_File
    – Cory Gross
    May 11, 2020 at 8:04
5

In the context of mktemp, "safe" means protected from inadvertent interference from other programs, especially as a result of name collision. mktemp tries to give you some assurance that even though your file is in a file system shared with numerous other programs, your script will probably be the only one interacting with the file. mktemp handles this for you in three ways:

  1. It creates names with random characters so they are unlikely to have the same name as other programs (or other running instances of the same script).
  2. It sets the permissions on the file so that it is only readable and writable by its owner, limiting the number of other programs which could disrupt it.
  3. It checks that the name isn't already in use. In other words, it checks that the file doesn't already exist.

A dry-run of mktemp can't handle permissions for you (#2), but that's easy enough to do yourself with chmod if you want.

The problem the mktemp documentation is warning you about is #3. While the invocation of mktemp in the current script will ensure the name isn't in use yet, it doesn't communicate this to other programs. Therefore, another program, or another invocation of the same script running concurrently, may invoke mktemp again and get the same temporary file path.

The only time you may want to use mktemp --dry-run is is for some rare programs which will not allow their output file or directory to exist already. In these circumstances, you may want to decrease the likelihood of name collision through:

  1. Increasing the number of random characters in the filename (mktemp function #1, above).
  2. Minimize the amount of time between the invocation of mktemp and the moment when the file is created. Similarly, you can let mktemp create the file, and delete it just before another command will create a file at the temporary path.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .