5

Systemd has a nice feature that is private temporary directory (/tmp). But it is not clear from the dense manual what are the correct ways to use it and implementation gotchas (get the feeling the manual is more a spec for devs and contributors)

Enabling this setting has the side effect of adding Requires= and After= dependencies on all mount units necessary to access /tmp and /var/tmp.

From https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp=

This is a little cryptic for non-systemd-insiders. I am assuming my filesystem, which for simplicity sake let's say I only have /, will receive a Requires=, guess it is left as an exercise to figure out what it will require… maybe I should put the homework tag here? :)

Starting on here.

But that doesn't sound right. It says that Requires= on mount units are only for hierarchy. I guess.

Let's move on to this.

But this also does not explain anything. It only says that one unit may require another. I guess.

I'm (wildly) guessing it uses this. So in my example, the systemd unit mount for / will have a Requires=[BindPaths=[/tmp/systemd-noise,/tmp]] or however one writes that in systemd-speak?

Let's ask systemd:

# systemctl show httpd
...
Requires=system.slice sysinit.target -.mount tmp.mount
...
RequiresMountsFor=/tmp /var/tmp

Not very helpful either.

I'm trying to wrap my head, mostly on:

  1. How exactly systemd denies access to the actual /tmp on the filesystem. And

  2. How the process (let's say a CGI running from a systemd started Apache) can figure out where the /tmp it has access to is at?

Pablo A
  • 177
  • 1
  • 9
gcb
  • 344
  • 1
  • 4
  • 18
  • If your final goal is to access /tmp from the host, that's easy: ls /proc/1234/root/tmp/ (where 1234 is the pid of the process) – A.B Apr 01 '20 at 07:39
  • but that assumes the process is running and that i can get the PID by parsing running processes and matching the cmd line, which is as troublesome to implement as guessing the service directory from the /tmp/systemd.*.$(service) – gcb Apr 01 '20 at 19:34
  • Related, from systemd.io: [Using `/tmp/` and `/var/tmp/` safely](https://systemd.io/TEMPORARY_DIRECTORIES/) – Pablo A Aug 22 '23 at 21:46

1 Answers1

2

How exactly systemd denies access to the actual /tmp on the filesystem.

It doesn't, really. It just "replaces" /tmp from the perspective of the process.

It runs the process in a mount namespace where the path /tmp is not the same as the global /tmp directory. You can do this yourself with the following sequence of commands:

# run a shell in a new mount namespace
unshare -m

# create an empty directory
mkdir /tmp/my-private-tmp

# bind mount that directory on /tmp
mount -o bind /tmp/my-private-tmp /tmp

After running those commands, in the same shell, take a look at /tmp and you'll see it's empty:

# ls /tmp
total 0

Create a file in /tmp:

touch /tmp/testfile

From a different terminal, you'll see that this was actually created in /tmp/my-private-tmp:

# ls -l /tmp/my-private-tmp

From a different terminal, you'll see that this was actually created in /tmp/my-private-tmp:

total 0
-rw-r--r-- 1 root root 0 Aug 27 21:53 testfile

How the process (let's say a CGI running from a systemd started Apache) can figure out where the /tmp it has access to is at?

It just uses /tmp. It doesn't need to know where the actual directory is located.


For more reading on this topic:

larsks
  • 43,623
  • 14
  • 121
  • 180