<term><option>--tmpfs</option></term>
<listitem>
- <para>Create and mount a new temporary file system on <replaceable>WHERE</replaceable>, with an
- optional <replaceable>NAME</replaceable> that defaults to <literal>tmpfs</literal>.</para>
+ <para>Create and mount a new <constant>tmpfs</constant> file system on
+ <replaceable>WHERE</replaceable>, with an optional <replaceable>NAME</replaceable> that defaults to
+ <literal>tmpfs</literal>.</para>
+
+ <para>The file system is mounted with the top-level directory mode determined by the
+ <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> setting
+ of the caller, i.e. <constant>rwxrwxrwx</constant> masked by the umask of the caller. This matches
+ what
+ <citerefentry project='man-pages'><refentrytitle>mkdir</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ does, but is different from the kernel default of <literal>rwxrwxrwxt</literal>, i.e. a
+ world-writable directory with the sticky bit set.</para>
</listitem>
</varlistentry>
#include "stat-util.h"
#include "strv.h"
#include "terminal-util.h"
+#include "umask-util.h"
#include "unit-def.h"
#include "unit-name.h"
#include "user-util.h"
}
static int transient_mount_set_properties(sd_bus_message *m) {
- _cleanup_free_ char *options = NULL;
int r;
assert(m);
return r;
}
+ _cleanup_free_ char *options = NULL;
+
/* Prepend uid=…,gid=… if arg_uid is set */
if (arg_uid != UID_INVALID) {
- r = asprintf(&options,
- "uid=" UID_FMT ",gid=" GID_FMT "%s%s",
- arg_uid, arg_gid,
- arg_mount_options ? "," : "", strempty(arg_mount_options));
+ r = strextendf_with_separator(&options, ",",
+ "uid="UID_FMT",gid="GID_FMT, arg_uid, arg_gid);
+ if (r < 0)
+ return r;
+ }
+
+ /* Override the default for tmpfs mounts. The kernel sets the sticky bit on the root directory by
+ * default. This makes sense for the case when the user does 'mount -t tmpfs tmpfs /tmp', but less so
+ * for other directories.
+ *
+ * Let's also set some reasonable limits. We use the current umask, to match what a command to create
+ * directory would use, e.g. mkdir. */
+ if (arg_tmpfs) {
+ mode_t mask;
+
+ r = get_process_umask(0, &mask);
+ if (r < 0)
+ return r;
+
+ assert((mask & ~0777) == 0);
+ r = strextendf_with_separator(&options, ",",
+ "mode=0%o,nodev,nosuid%s", 0777 & ~mask, NESTED_TMPFS_LIMITS);
if (r < 0)
- return -ENOMEM;
+ return r;
}
- if (options || arg_mount_options) {
- log_debug("Using mount options: %s", options ?: arg_mount_options);
+ if (arg_mount_options)
+ if (!strextend_with_separator(&options, ",", arg_mount_options))
+ return r;
- r = sd_bus_message_append(m, "(sv)", "Options", "s", options ?: arg_mount_options);
+ if (options) {
+ log_debug("Using mount options: %s", options);
+ r = sd_bus_message_append(m, "(sv)", "Options", "s", options);
if (r < 0)
return r;
} else