37

According to FHS-3.0, /tmp is for temporary files and /run is for run-time variable data. Data in /run must be deleted at next boot, which is not required for /tmp, but still programs must not assume that the data in /tmp will be available at the next program start. All this seems quite similar to me.

So, what is the difference between the two? By which criterion should a program decide whether to put temporary data into /tmp or into /run?

According to the FHS:

Programs may have a subdirectory of /run; this is encouraged for programs that use more than one run-time file.

This indicates that the distinction between "system programs" and "ordinary programs" is not a criterion, neither is the lifetime of the program (like, long-running vs. short-running process).

Although the following rationale is not given in the FHS, /run was introduced to overcome the problem that /var was mounted too late such that dirty tricks were needed to make /var/run available early enough. However, now with /run being introduced, and given its description in the FHS, there does not seem to be a clear reason to have both /run and /tmp.

  • 10
    /tmp is the *nix standard location for temporary data. /run is the Poettering standard location for temporary data. – Mark Oct 13 '16 at 21:13
  • Backward compatibilty is always a reason... – Bakuriu Oct 14 '16 at 9:36
14

No reason to have both /run and /tmp

I think you're right. /tmp is essentially deprecated now we have /run. If your program is in a position to do so (which requires that it was installed as a privileged operation), then nowadays you would use a sub-directory of /run. This is for security reasons.

E.g. the CUPS printing daemon does not run as root, but is generally installed from an OS package. The package installs /usr/lib/tmpfiles.d/cups.conf, and systemd-tmpfiles creates a directory it can access. Since the directory is under /run, the name cannot have been maliciously claimed by an unprivileged user, unlike /tmp which is world-writable.

"Unprivileged programs" which can't use /run directly

The real distinction is if your program is being run by an arbitrary unprivileged user, under their own user ID. But you still generally don't want to use /tmp, because it can be accessed by other unprivileged users. You would prefer to use $XDG_RUNTIME_DIR. Typically this is implemented as /run/user/$(id -u) - so it happens to be a subdirectory of /run as well. The location isn't guaranteed though; programs should always use the environment variable.

/tmp would only be useful for ad-hoc co-operation between different unprivileged users on the system. Such ad-hoc systems are vulnerable to a malicious user refusing to co-operate and spoiling things for everyone :). One example would be unprivileged users deciding to run a version of the talk daemon, using a unix socket.

Original information from Lennart Poettering

Note, Poettering's checklist below claimed that /tmp would be useful for "small files", whereas /run should only be used for "communication primitives". I don't think this distinction is true either. The poster-boy for /run is udev, and I'm pretty sure /run/udev includes internal databases . Once you have a /run directory, I don't think anyone wants to follow the claimed distinction and create another directory, to clutter /tmp. So in practice we just use /run nowadays.

Usage of world-writable shared namespaces [like /tmp] for communication purposes has always been problematic, since to establish communication you need stable names, but stable names open the doors for DoS attacks. This can be corrected partially, by establishing protected per-app directories for certain services during early boot (like we do for X11), but this only fixes the problem partially, since this only works correctly if every package installation is followed by a reboot.

...

Another Fedora feature (for Fedora 17) changed the semantics of /tmp for many system services to make them more secure, by isolating the /tmp namespaces of the various services

...

Because /tmp is no longer necessarily a shared namespace it is generally unsuitable as a location for communication primitives.

...

[/run] is guaranteed to be a tmpfs and is hence automatically flushed at boots. No automatic clean-up is done beyond that.

...

Here's a rough guide how we suggest you (a Linux application developer) pick the right directory to use:

  1. You need a place to put your socket (or other communication primitive) and your code runs privileged: use a subdirectory beneath /run. (Or beneath /var/run for extra compatibility.)
  2. You need a place to put your socket (or other communication primitive) and your code runs unprivileged: use a subdirectory beneath $XDG_RUNTIME_DIR.
  3. You need a place to put your larger downloads and downloads in progress and run unprivileged: use $XDG_DOWNLOAD_DIR.
  4. You need a place to put cache files which should be persistent and run unprivileged: use $XDG_CACHE_HOME.
  5. Nothing of the above applies and you need to place a small file that needs no persistency: use $TMPDIR with a fallback on /tmp. And use mkstemp(), and mkdtemp() and nothing homegrown.
  6. Otherwise use $TMPDIR with a fallback on /var/tmp. Also use mkstemp()/mkdtemp().

Note that these rules above are only suggested by us. These rules take into account everything we know about this topic and avoid problems with current and future distributions, as far as we can see them. Please consider updating your projects to follow these rules, and keep them in mind if you write new code.

One thing we'd like to stress is that /tmp and /var/tmp more often than not are actually not the right choice for your usecase. There are valid uses of these directories, but quite often another directory might actually be the better place. So, be careful, consider the other options, but if you do go for /tmp or /var/tmp then at least make sure to use mkstemp()/mkdtemp().

We kind of get away with the legacy /tmp socket used by the X window system, as described above. I misread tmpfiles.d/x11.conf. Looks more like it relies on co-operation :). I assume the code's been audited, such that denial of service is the worst that can happen.

  • 8
    This answer is all kinds of wrong. – R.. Oct 13 '16 at 22:27
  • @R.., care to expand on that? – Wildcard Oct 13 '16 at 22:39
  • Yes, I already did in an answer. (Started as a comment but I realized it was more of an answer.) – R.. Oct 13 '16 at 23:09
  • I think the main weakness in my current answer, which I think you were working towards, is that while technically, correct handling of XDG_RUNTIME_DIR is required to be portable to any *nix ("fall back to a replacement directory with similar capabilities"), it's very vague what this means in practice. For portable utility programs, it's better to use the well-defined standard for /tmp ("the only APIs for using it should be mkstemp(), mkdtemp() (and friends) to be entirely safe"). – sourcejedi Oct 14 '16 at 8:37
  • The answer miss also common case: /var/run is system wide (e.g. to communicate to local database), /tmp/ now is ofter created per user. Historically, also the quota of /tmp was set different. And the answer misses that a semantic distinction of use is also important. – Giacomo Catenazzi Oct 18 '16 at 14:05
22

The directories /tmp and /usr/tmp (later /var/tmp) used to be the dumping ground for everything and everybody. The only protection mechanism for files in these directories is the sticky bit which restricts deletion or renaming of files there to their owners. As marcelm pointed out in a comment, there's in principle nothing that prevents someone to create files with names that are used by services (such as nginx.pid or sshd.pid). (In practice, the startup scripts could remove such bogus files first, though.)

/run was established for non-persistent runtime data of long lived services such as locks, sockets, pid files and the like. Since it is not writable for the public, it shields service runtime data from the mess in /tmp and jobs that clean up there. Indeed: Two distributions that I run (no pun intended) have permissions 755 on /run, while /tmp and /var/tmp (and /dev/shm for that matter) have permissions 1777.

  • 3
    it is simply there to separate service runtime data from the mess in /tmp - Also to provide a safe harbor for said data from the various cleanup jobs that trample throughout /tmp. – Satō Katsura Oct 13 '16 at 12:34
  • Thanks for the info about the permissions. However, according to FHS "Programs may have a subdirectory of /run; this is encouraged for programs that use more than one run-time file." - this seems to contradict both the "long lived services" criterion as well as the inability of programs to create their subdirectories due to limited permissions. – Dirk Herrmann Oct 13 '16 at 12:34
  • @DirkHerrmann No it doesn't. Have a look at /run and check out the complex (well...) directory structure caused by udev, udisk etc. I am not an expert on this particular issue, but I guess the boot scripts (which are run as superuser) set everything up. – countermode Oct 13 '16 at 13:22
  • 2
    "/run is technically not necessary, it is simply there to separate service runtime data from the mess in /tmp." - Good thing too, so unprivileged processes can't squat names system services want to use. Kinda sucks if nginx wants to use /tmp/nginx.pid but it already exists because of some misbehaving program. /run/ prevents this by requiring privileges to write to. – marcelm Oct 13 '16 at 14:45
16

/tmp is the location for creation of temporary files and directories. It's not usable for storing "well-known names" (i.e. names another process could be aware of without you having to convey the name to it somehow) because nobody has ownership over the namespace; anyone can create files there. As such you generally use it when you have a utility that needs a file (i.e. not a pipe or such) as input or output, where any (randomly generated) name will work as long as you pass the name in.

Historically, some things (like X) violated this principle and put well-known names (like .X11-unix) in /tmp. This is of course buggy and allows any user to DoS the service needing to do so simply by racing to create a file by the desired name first. Such things belong under /run (or equivalently /var/run if you don't subscribe to Freedesktop.org revisionism). Of course even better would be to fix them not to use well-known names in a global namespace but instead pass around a pathname.

  • Thanks for some more definition on "temporary files". Though I don't think "pass around a pathname" explains how to establish a co-ordination point. I.e. usually you would use an environment variable. Looks like there's few enough sockets and pipes (in general use) to let it work. (Partly because a lot of things will run over the same dbus socket). Seems like it would be annoying to set the environment if programs didn't default to a hardcoded path though. You could add a new key to systemd .socket files... but that doesn't help for whole directories, nor for newly installed services – sourcejedi Oct 14 '16 at 7:57
  • 2
    /run/ itself was adopted by FHS, I can't see how it has anything to do with fd.o. Unless what we really meant to complain about is unspecified development efforts that have contributed to both. – sourcejedi Oct 14 '16 at 8:06
  • I do think the initial answer here is the best answer here for the question as written. I think it would be improved further by considering: _When software has write access to a dedicated directory e.g. under /run, it might chose to avoid cluttering the shared /tmp directory with yet more files. – sourcejedi Oct 14 '16 at 8:22
  • What is "fd.o"? – TRiG Oct 14 '16 at 10:48
  • @TRiG an object file about file descriptors, obviously. /s – cat Oct 14 '16 at 11:07
7

According to the Filesystem Hierarchy Standard,

  • /run is for runtime variable data i.e. information about the running system since reboot
  • /tmp is a generic place for temporary files.

So anything concerning daemon status, logged-in users, mounted removable devices etc. would go in /run while temporary files created by a program would go into /tmp.

Edit: as pointed out by @JdeBP in the comment below,

The FHS allows for things like the conventional setup of cron jobs that regularly purge /tmp of "old" files; with no such mechanisms intended for /run. Hence the draconian limit on what programs can expect of the lifetime of anything put in /tmp. Whilst programs can expect files to live longer in /run on a continuously-up system, they are also expected to tidy up after themselves more there.

  • 4
    One thing not pointed out in this or any other answer, but noted in the FHS, and which you might like to improve your answer with: The FHS allows for things like the conventional setup of cron jobs that regularly purge /tmp of "old" files; with no such mechanisms intended for /run. Hence the draconian limit on what programs can expect of the lifetime of anything put in /tmp. Whilst programs can expect files to live longer in /run on a continuously-up system, they are also expected to tidy up after themselves more there. – JdeBP Oct 13 '16 at 20:14
  • 1
    It would be nice to have a per-process directory of stuff that disappeared (or was permitted to be deleted by some roving garbage daemon) as soon as the process died. – Omnifarious Mar 4 '17 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.