Don't create our own temporary mount point for pivot_root

An attacker could pre-create /tmp/.bubblewrap-$UID and make it a
non-directory, non-symlink (in which case mounting our tmpfs would fail,
causing denial of service), or make it a symlink under their control
(potentially allowing bad things if the protected_symlinks sysctl is
not enabled).

Instead, temporarily mount the tmpfs on a directory that we are sure
exists and is not attacker-controlled. /tmp (the directory itself, not
a subdirectory) will do.

Fixes: #304
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923557
Signed-off-by: Simon McVittie <smcv@debian.org>

Closes: #305
Approved by: cgwalters
usage (int ecode, FILE *out)
{
  fprintf (out, "usage: %s [OPTIONS...] [--] COMMAND [ARGS...]\n\n", argv0);

  fprintf (out,
           "    --help                       Print this help\n"
           "    --version                    Print version\n"
           "    --args FD                    Parse NUL-separated args from FD\n"
           "    --unshare-all                Unshare every namespace we support by default\n"
           "    --share-net                  Retain the network namespace (can only combine with --unshare-all)\n"
           "    --unshare-user               Create new user namespace (may be automatically implied if not setuid)\n"
           "    --unshare-user-try           Create new user namespace if possible else continue by skipping it\n"
           "    --unshare-ipc                Create new ipc namespace\n"
           "    --unshare-pid                Create new pid namespace\n"
           "    --unshare-net                Create new network namespace\n"
           "    --unshare-uts                Create new uts namespace\n"
           "    --unshare-cgroup             Create new cgroup namespace\n"
           "    --unshare-cgroup-try         Create new cgroup namespace if possible else continue by skipping it\n"
           "    --uid UID                    Custom uid in the sandbox (requires --unshare-user)\n"
           "    --gid GID                    Custom gid in the sandbox (requires --unshare-user)\n"
           "    --hostname NAME              Custom hostname in the sandbox (requires --unshare-uts)\n"
           "    --chdir DIR                  Change directory to DIR\n"
           "    --setenv VAR VALUE           Set an environment variable\n"
           "    --unsetenv VAR               Unset an environment variable\n"
           "    --lock-file DEST             Take a lock on DEST while sandbox is running\n"
           "    --sync-fd FD                 Keep this fd open while sandbox is running\n"
           "    --bind SRC DEST              Bind mount the host path SRC on DEST\n"
           "    --bind-try SRC DEST          Equal to --bind but ignores non-existent SRC\n"
           "    --dev-bind SRC DEST          Bind mount the host path SRC on DEST, allowing device access\n"
           "    --dev-bind-try SRC DEST      Equal to --dev-bind but ignores non-existent SRC\n"
           "    --ro-bind SRC DEST           Bind mount the host path SRC readonly on DEST\n"
           "    --ro-bind-try SRC DEST       Equal to --ro-bind but ignores non-existent SRC\n"
           "    --remount-ro DEST            Remount DEST as readonly; does not recursively remount\n"
           "    --exec-label LABEL           Exec label for the sandbox\n"
           "    --file-label LABEL           File label for temporary sandbox content\n"
           "    --proc DEST                  Mount new procfs on DEST\n"
           "    --dev DEST                   Mount new dev on DEST\n"
           "    --tmpfs DEST                 Mount new tmpfs on DEST\n"
           "    --mqueue DEST                Mount new mqueue on DEST\n"
           "    --dir DEST                   Create dir at DEST\n"
           "    --file FD DEST               Copy from FD to destination DEST\n"
           "    --bind-data FD DEST          Copy from FD to file which is bind-mounted on DEST\n"
           "    --ro-bind-data FD DEST       Copy from FD to file which is readonly bind-mounted on DEST\n"
           "    --symlink SRC DEST           Create symlink at DEST with target SRC\n"
           "    --seccomp FD                 Load and use seccomp rules from FD\n"
           "    --block-fd FD                Block on FD until some data to read is available\n"
           "    --userns-block-fd FD         Block on FD until the user namespace is ready\n"
           "    --info-fd FD                 Write information about the running container to FD\n"
           "    --json-status-fd FD          Write container status to FD as multiple JSON documents\n"
           "    --new-session                Create a new terminal session\n"
           "    --die-with-parent            Kills with SIGKILL child process (COMMAND) when bwrap or bwrap's parent dies.\n"
           "    --as-pid-1                   Do not install a reaper process with PID=1\n"
           "    --cap-add CAP                Add cap CAP when running as privileged user\n"
           "    --cap-drop CAP               Drop cap CAP when running as privileged user\n"
          );
  exit (ecode);
}

usage (int ecode, FILE *out)
{
  fprintf (out, "usage: %s [OPTIONS...] [--] COMMAND [ARGS...]\n\n", argv0);

  fprintf (out,
           "    --help                       Print this help\n"
           "    --version                    Print version\n"
           "    --args FD                    Parse NUL-separated args from FD\n"
           "    --unshare-all                Unshare every namespace we support by default\n"
           "    --share-net                  Retain the network namespace (can only combine with --unshare-all)\n"
           "    --unshare-user               Create new user namespace (may be automatically implied if not setuid)\n"
           "    --unshare-user-try           Create new user namespace if possible else continue by skipping it\n"
           "    --unshare-ipc                Create new ipc namespace\n"
           "    --unshare-pid                Create new pid namespace\n"
           "    --unshare-net                Create new network namespace\n"
           "    --unshare-uts                Create new uts namespace\n"
           "    --unshare-cgroup             Create new cgroup namespace\n"
           "    --unshare-cgroup-try         Create new cgroup namespace if possible else continue by skipping it\n"
           "    --uid UID                    Custom uid in the sandbox (requires --unshare-user)\n"
           "    --gid GID                    Custom gid in the sandbox (requires --unshare-user)\n"
           "    --hostname NAME              Custom hostname in the sandbox (requires --unshare-uts)\n"
           "    --chdir DIR                  Change directory to DIR\n"
           "    --setenv VAR VALUE           Set an environment variable\n"
           "    --unsetenv VAR               Unset an environment variable\n"
           "    --lock-file DEST             Take a lock on DEST while sandbox is running\n"
           "    --sync-fd FD                 Keep this fd open while sandbox is running\n"
           "    --bind SRC DEST              Bind mount the host path SRC on DEST\n"
           "    --bind-try SRC DEST          Equal to --bind but ignores non-existent SRC\n"
           "    --dev-bind SRC DEST          Bind mount the host path SRC on DEST, allowing device access\n"
           "    --dev-bind-try SRC DEST      Equal to --dev-bind but ignores non-existent SRC\n"
           "    --ro-bind SRC DEST           Bind mount the host path SRC readonly on DEST\n"
           "    --ro-bind-try SRC DEST       Equal to --ro-bind but ignores non-existent SRC\n"
           "    --remount-ro DEST            Remount DEST as readonly; does not recursively remount\n"
           "    --exec-label LABEL           Exec label for the sandbox\n"
           "    --file-label LABEL           File label for temporary sandbox content\n"
           "    --proc DEST                  Mount new procfs on DEST\n"
           "    --dev DEST                   Mount new dev on DEST\n"
           "    --tmpfs DEST                 Mount new tmpfs on DEST\n"
           "    --mqueue DEST                Mount new mqueue on DEST\n"
           "    --dir DEST                   Create dir at DEST\n"
           "    --file FD DEST               Copy from FD to destination DEST\n"
           "    --bind-data FD DEST          Copy from FD to file which is bind-mounted on DEST\n"
           "    --ro-bind-data FD DEST       Copy from FD to file which is readonly bind-mounted on DEST\n"
           "    --symlink SRC DEST           Create symlink at DEST with target SRC\n"
           "    --seccomp FD                 Load and use seccomp rules from FD\n"
           "    --block-fd FD                Block on FD until some data to read is available\n"
           "    --userns-block-fd FD         Block on FD until the user namespace is ready\n"
           "    --info-fd FD                 Write information about the running container to FD\n"
           "    --json-status-fd FD          Write container status to FD as multiple JSON documents\n"
           "    --new-session                Create a new terminal session\n"
           "    --die-with-parent            Kills with SIGKILL child process (COMMAND) when bwrap or bwrap's parent dies.\n"
           "    --as-pid-1                   Do not install a reaper process with PID=1\n"
           "    --cap-add CAP                Add cap CAP when running as privileged user\n"
           "    --cap-drop CAP               Drop cap CAP when running as privileged user\n"
          );
  exit (ecode);
}
