]> git.ipfire.org Git - thirdparty/systemd.git/blob - docs/TEMPORARY_DIRECTORIES.md
firstboot: Check if the given shell exists
[thirdparty/systemd.git] / docs / TEMPORARY_DIRECTORIES.md
1 ---
2 title: Using /tmp/ And /var/tmp/ Safely
3 category: Interfaces
4 layout: default
5 ---
6
7 # Using `/tmp/` And `/var/tmp/` Safely
8
9 `/tmp/` and `/var/tmp/` are two world-writable directories Linux systems
10 provide for temporary files. The former is typically on `tmpfs` and thus
11 backed by RAM/swap, and flushed out on each reboot. The latter is typically a
12 proper, persistent file system, and thus backed by physical storage. This
13 means:
14
15 1. `/tmp/` should be used for smaller, size-bounded files only; `/var/tmp/`
16 should be used for everything else.
17
18 2. Data that shall survive a boot cycle shouldn't be placed in `/tmp/`.
19
20 If the `$TMPDIR` environment variable is set, use that path, and neither use
21 `/tmp/` nor `/var/tmp/` directly.
22
23 See
24 [file-hierarchy(7)](https://www.freedesktop.org/software/systemd/man/file-hierarchy.html)
25 for details about these two (and most other) directories of a Linux system.
26
27 ## Common Namespace
28
29 Note that `/tmp/` and `/var/tmp/` each define a common namespace shared by all
30 local software. This means guessable file or directory names below either
31 directory directly translate into a 🚨 Denial-of-Service (DoS) 🚨 vulnerability
32 or worse: if some software creates a file or directory `/tmp/foo` then any
33 other software that wants to create the same file or directory `/tmp/foo`
34 either will fail (as the file already exists) or might be tricked into using
35 untrusted files. Hence: do not use guessable names in `/tmp/` or `/var/tmp/` —
36 if you do you open yourself up to a local DoS exploit or worse. (You can get
37 away with using guessable names, if you pre-create subdirectories below `/tmp/`
38 for them, like X11 does with `/tmp/.X11-unix/` through `tmpfiles.d/`
39 drop-ins. However this is not recommended, as it is fully safe only if these
40 directories are pre-created during early boot, and thus problematic if package
41 installation during runtime is permitted.)
42
43 To protect yourself against these kinds of attacks Linux provides a couple of
44 APIs that help you avoiding guessable names. Specifically:
45
46 1. Use [`mkstemp()`](http://man7.org/linux/man-pages/man3/mkstemp.3.html)
47 (POSIX), `mkostemp()` (glibc),
48 [`mkdtemp()`](http://man7.org/linux/man-pages/man3/mkdtemp.3.html) (POSIX),
49 [`tmpfile()`](http://man7.org/linux/man-pages/man3/tmpfile.3.html) (C89)
50
51 2. Use [`open()`](http://man7.org/linux/man-pages/man2/open.2.html) with
52 `O_TMPFILE` (Linux)
53
54 3. [`memfd_create()`](http://man7.org/linux/man-pages/man2/memfd_create.2.html)
55 (Linux; this doesn't bother with `/tmp/` or `/var/tmp/` at all, but uses the
56 same RAM/swap backing as `tmpfs` uses, hence is very similar to `/tmp/`
57 semantics.)
58
59 For system services systemd provides the `PrivateTmp=` boolean setting. If
60 turned on for a service (👍 which is highly recommended), `/tmp/` and
61 `/var/tmp/` are replaced by private sub-directories, implemented through Linux
62 file system namespacing and bind mounts. This means from the service's point of
63 view `/tmp/` and `/var/tmp/` look and behave like they normally do, but in
64 reality they are private sub-directories of the host's real `/tmp/` and
65 `/var/tmp/`, and thus not system-wide locations anymore, but service-specific
66 ones. This reduces the surface for local DoS attacks substantially. While it is
67 recommended to turn this option on, it's highly recommended for applications
68 not to rely on this solely to avoid DoS vulnerabilities, because this option is
69 not available in environments where file system namespaces are prohibited, for
70 example in certain container environments. This option is hence an extra line
71 of defense, but should not be used as an excuse to rely on guessable names in
72 `/tmp/` and `/var/tmp/`. When this option is used, the per-service temporary
73 directories are removed whenever the service shuts down, hence the lifecycle of
74 temporary files stored in it is substantially different from the case where
75 this option is not used. Also note that some applications use `/tmp/` and
76 `/var/tmp/` for sharing files and directories. If this option is turned on this
77 is not possible anymore as after all each service gets its own instances of
78 both directories.
79
80 ## Automatic Clean-Up
81
82 By default, `systemd-tmpfiles` will apply a concept of ⚠️ "ageing" to all files
83 and directories stored in `/tmp/` and `/var/tmp/`. This means that files that
84 have neither been changed nor read within a specific time frame are
85 automatically removed in regular intervals. (This concept is not new to
86 `systemd-tmpfiles` btw, it's inherited from previous subsystems such as
87 `tmpwatch`.) By default files in `/tmp/` are cleaned up after 10 days, and
88 those in `/var/tmp` after 30 days.
89
90 This automatic clean-up is important to ensure disk usage of these temporary
91 directories doesn't grow without bounds, even when programs abort unexpectedly
92 or otherwise don't clean up the temporary files/directories they create. On the
93 other hand it creates problems for long-running software that does not expect
94 temporary files it operates on to be suddenly removed. There are a couple of
95 strategies to avoid these issues:
96
97 1. Make sure to always keep a file descriptor to the temporary files you
98 operate on open, and only access the files through them. This way it doesn't
99 matter whether the files have been unlinked from the file system: as long as
100 you have the file descriptor open you can still access the file for both
101 reading and writing. When operating this way it is recommended to delete the
102 files right after creating them to ensure that on unexpected program
103 termination the files or directories are implicitly released by the kernel.
104
105 2. 🥇 Use `memfd_create()` or `O_TMPFILE`. This is an extension of the
106 suggestion above: files created this way are never linked under a filename
107 in the file system. This means they are not subject to ageing (as they come
108 unlinked out of the box), and there's no time window where a directory entry
109 for the file exists in the file system, and thus behaviour is fully robust
110 towards unexpected program termination as there are never files on disk that
111 need to be explicitly deleted.
112
113 3. 🥇 Operate below a sub-directory of `/tmp/` and `/var/tmp/` you created, and
114 take a BSD file lock ([`flock(dir_fd,
115 LOCK_SH)`](http://man7.org/linux/man-pages/man2/flock.2.html)) on that
116 sub-directory. This is particularly interesting when operating on more than
117 a single file, or on file nodes that are not plain regular files, for
118 example when extracting a tarball to a temporary directory. The ageing
119 algorithm will skip all directories (and everything below them) that are
120 locked through a BSD file lock. As BSD file locks are automatically released
121 when the file descriptor they are taken on is closed, and all file
122 descriptors opened by a process are implicitly closed when it exits, this is
123 a robust mechanism that ensures all temporary files are subject to ageing
124 when the program that owns them dies, but not while it is still running. Use
125 this when decompressing tarballs that contain files with old
126 modification/access times, as extracted files are otherwise immediately
127 candidates for deletion by the ageing algorithm. The
128 [`flock`](http://man7.org/linux/man-pages/man1/flock.1.html) tool of the
129 `util-linux` packages makes this concept available to shell scripts. Note
130 that `systemd-tmpfiles` only checks for BSD file locks on directories, locks
131 on other types of file nodes (including regular files) are not considered.
132
133 4. Keep the access time of all temporary files created current. In regular
134 intervals, use `utimensat()` or a related call to update the access time
135 ("atime") of all files that shall be kept around. Since the ageing algorithm
136 looks at the access time of files when deciding whether to delete them, it's
137 sufficient to update their access times in sufficiently frequent intervals to
138 ensure the files are not deleted. Since most applications (and tools such as
139 `ls`) primarily care for the modification time (rather than the access time)
140 using the access time for this purpose should be acceptable.
141
142 5. Set the "sticky" bit on regular files. The ageing logic skips deletion of
143 all regular files that have the sticky bit (`chmod +t`) set. This is
144 honoured for regular files only however, and has no effect on directories as
145 the sticky bit has a different meaning for them.
146
147 6. Don't use `/tmp/` or `/var/tmp/`, but use your own sub-directory under
148 `/run/` or `$XDG_RUNTIME_DIRECTORY` (the former if privileged, the latter if
149 unprivileged), or `/var/lib/` and `~/.config/` (similar, but with
150 persistency and suitable for larger data). The two temporary directories
151 `/tmp/` and `/var/tmp/` come with the implicit clean-up semantics described
152 above. When this is not desired, it's possible to create private per-package
153 runtime or state directories, and place all temporary files there. However,
154 do note that this means opting out of any kind of automatic clean-up, and it
155 is hence particularly essential that the program cleans up generated files
156 in these directories when they are no longer needed, in particular when the
157 program dies unexpectedly. Note: this strategy is only really suitable for
158 packages that operate in a "system wide singleton" fashion with "long"
159 persistence of its data or state, i.e. as opposed to programs that run in
160 multiple parallel or short-living instances. This is because a private
161 directory under `/run` (and the other mentioned directories) is itself
162 system and package specific singleton with greater longevity.
163
164 5. Exclude your temporary files from clean-ups via a `tmpfiles.d/` drop-in
165 (which includes drop-ins in the runtime-only directory
166 `/run/tmpfiles.d/`). The `x`/`X` line types may be used to exclude files
167 matching the specified globbing patterns from the ageing logic. If this is
168 used, automatic clean-up is not done for matching files and directory, and
169 much like with the previous option it's hence essential that the program
170 generating these temporary files carefully removes the temporary files it
171 creates again, and in particular so if it dies unexpectedly.
172
173 🥇 The semantics of options 2 (in case you only deal with temporary files, not
174 directories) and 3 (in case you deal with both) in the list above are in most
175 cases the most preferable. It is thus recommended to stick to these two
176 options.
177
178 While the ageing logic is very useful as a safety concept to ensure unused
179 files and directories are eventually removed a well written program avoids even
180 creating files that need such a clean-up. In particular:
181
182 1. Use `memfd_create()` or `O_TMPFILE` when creating temporary files.
183
184 2. `unlink()` temporary files right after creating them. This is very similar
185 to `O_TMPFILE` behaviour: consider deleting temporary files right after
186 creating them, while keeping open a file descriptor to them. Unlike
187 `O_TMPFILE` this method also works on older Linux systems and other OSes
188 that do not implement `O_TMPFILE`.
189
190 ## Disk Quota
191
192 Generally, files allocated from `/tmp/` and `/var/tmp/` are allocated from a
193 pool shared by all local users. Moreover the space available in `/tmp/` is
194 generally more restricted than `/var/tmp/`. This means, that in particular in
195 `/tmp/` space should be considered scarce, and programs need to be prepared
196 that no space is available. Essential programs might require a fallback logic
197 using a different location for storing temporary files hence. Non-essential
198 programs at least need to be prepared for `ENOSPC` errors and generate useful,
199 actionable error messages.
200
201 Some setups employ per-user quota on `/var/tmp/` and possibly `/tmp/`, to make
202 `ENOSPC` situations less likely, and harder to trigger from unprivileged
203 users. However, in the general case no such per-user quota is implemented
204 though, in particular not when `tmpfs` is used as backing file system, because
205 — even today — `tmpfs` still provides no native quota support in the kernel.
206
207 ## Early Boot Considerations
208
209 Both `/tmp/` and `/var/tmp/` are not necessarily available during early boot,
210 or — if they are available early — are not writable. This means software that
211 is intended to run during early boot (i.e. before `basic.target` — or more
212 specifically `local-fs.target` — is up) should not attempt to make use of
213 either. Interfaces such as `memfd_create()` or files below a package-specific
214 directory in `/run/` are much better options in this case. (Note that some
215 packages instead use `/dev/shm/` for temporary files during early boot; this is
216 not advisable however, as it offers no benefits over a private directory in
217 `/run/` as both are backed by the same concept: `tmpfs`. The directory
218 `/dev/shm/` exists to back POSIX shared memory (see
219 [`shm_open()`](http://man7.org/linux/man-pages/man3/shm_open.3.html) and
220 related calls), and not as a place for temporary files. `/dev/shm` is
221 problematic as it is world-writable and there's no automatic clean-up logic in
222 place.)