/* ProtectHome=tmpfs table */
static const MountEntry protect_home_tmpfs_table[] = {
- { "/home", TMPFS, true, .read_only = true, .options_const = "mode=0755", .flags = MS_NODEV|MS_STRICTATIME },
- { "/run/user", TMPFS, true, .read_only = true, .options_const = "mode=0755", .flags = MS_NODEV|MS_STRICTATIME },
- { "/root", TMPFS, true, .read_only = true, .options_const = "mode=0700", .flags = MS_NODEV|MS_STRICTATIME },
+ { "/home", TMPFS, true, .read_only = true, .options_const = "mode=0755" TMPFS_LIMITS_EMPTY_OR_ALMOST, .flags = MS_NODEV|MS_STRICTATIME },
+ { "/run/user", TMPFS, true, .read_only = true, .options_const = "mode=0755" TMPFS_LIMITS_EMPTY_OR_ALMOST, .flags = MS_NODEV|MS_STRICTATIME },
+ { "/root", TMPFS, true, .read_only = true, .options_const = "mode=0700" TMPFS_LIMITS_EMPTY_OR_ALMOST, .flags = MS_NODEV|MS_STRICTATIME },
};
/* ProtectHome=yes table */
.mode = EMPTY_DIR,
.ignore = false,
.read_only = true,
- .options_const = "mode=755",
+ .options_const = "mode=755" TMPFS_LIMITS_EMPTY_OR_ALMOST,
.flags = MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
};
}
"Path is not absolute: %s",
t->path);
- str = strjoin("mode=0755,", t->options);
+ str = strjoin("mode=0755" TMPFS_LIMITS_TEMPORARY_FS ",", t->options);
if (!str)
return -ENOMEM;
}
/* We're about to fallback to bind-mounting the device
- * node. So create a dummy bind-mount target. */
- mac_selinux_create_file_prepare(d, 0);
+ * node. So create a dummy bind-mount target.
+ * Do not prepare device-node SELinux label (see issue 13762) */
r = mknod(dn, S_IFREG, 0);
- mac_selinux_create_file_clear();
if (r < 0 && errno != EEXIST)
return log_debug_errno(errno, "mknod() fallback failed for '%s': %m", d);
dev = strjoina(temporary_mount, "/dev");
(void) mkdir(dev, 0755);
- if (mount("tmpfs", dev, "tmpfs", DEV_MOUNT_OPTIONS, "mode=755") < 0) {
+ if (mount("tmpfs", dev, "tmpfs", DEV_MOUNT_OPTIONS, "mode=755" TMPFS_LIMITS_DEV) < 0) {
r = log_debug_errno(errno, "Failed to mount tmpfs on '%s': %m", dev);
goto fail;
}
+ r = label_fix_container(dev, "/dev", 0);
+ if (r < 0) {
+ log_debug_errno(errno, "Failed to fix label of '%s' as /dev: %m", dev);
+ goto fail;
+ }
devpts = strjoina(temporary_mount, "/dev/pts");
(void) mkdir(devpts, 0755);
r = dev_setup(temporary_mount, UID_INVALID, GID_INVALID);
if (r < 0)
- log_debug_errno(r, "Failed to setup basic device tree at '%s', ignoring: %m", temporary_mount);
+ log_debug_errno(r, "Failed to set up basic device tree at '%s', ignoring: %m", temporary_mount);
/* Create the /dev directory if missing. It is more likely to be
* missing when the service is started with RootDirectory. This is
return 0;
}
-/* Change per-mount flags on an existing mount */
-static int bind_remount_one(const char *path, unsigned long orig_flags, unsigned long new_flags, unsigned long flags_mask) {
- if (mount(NULL, path, NULL, (orig_flags & ~flags_mask) | MS_REMOUNT | MS_BIND | new_flags, NULL) < 0)
- return -errno;
-
- return 0;
-}
-
static int make_read_only(const MountEntry *m, char **blacklist, FILE *proc_self_mountinfo) {
unsigned long new_flags = 0, flags_mask = 0;
bool submounts = false;
if (submounts)
r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), new_flags, flags_mask, blacklist, proc_self_mountinfo);
else
- r = bind_remount_one(mount_entry_path(m), m->flags, new_flags, flags_mask);
+ r = bind_remount_one_with_mountinfo(mount_entry_path(m), new_flags, flags_mask, proc_self_mountinfo);
/* Not that we only turn on the MS_RDONLY flag here, we never turn it off. Something that was marked
* read-only already stays this way. This improves compatibility with container managers, where we
size_t n_temporary_filesystems,
const char* tmp_dir,
const char* var_tmp_dir,
+ const char* log_namespace,
ProtectHome protect_home,
ProtectSystem protect_system) {
(ns_info->protect_control_groups ? 1 : 0) +
protect_home_cnt + protect_system_cnt +
(ns_info->protect_hostname ? 2 : 0) +
- (namespace_info_mount_apivfs(ns_info) ? ELEMENTSOF(apivfs_table) : 0);
+ (namespace_info_mount_apivfs(ns_info) ? ELEMENTSOF(apivfs_table) : 0) +
+ !!log_namespace;
}
static void normalize_mounts(const char *root_directory, MountEntry *mounts, size_t *n_mounts) {
if (protect_system == PROTECT_SYSTEM_STRICT)
return true;
- if (path_strv_contains(read_only_paths, "/"))
+ if (prefixed_path_strv_contains(read_only_paths, "/"))
return true;
return false;
if (protect_home != PROTECT_HOME_NO)
return true;
- if (path_strv_contains(read_only_paths, "/home") ||
- path_strv_contains(inaccessible_paths, "/home") ||
- path_strv_contains(empty_directories, "/home"))
+ if (prefixed_path_strv_contains(read_only_paths, "/home") ||
+ prefixed_path_strv_contains(inaccessible_paths, "/home") ||
+ prefixed_path_strv_contains(empty_directories, "/home"))
return true;
for (i = 0; i < n_temporary_filesystems; i++)
size_t n_temporary_filesystems,
const char* tmp_dir,
const char* var_tmp_dir,
+ const char *log_namespace,
ProtectHome protect_home,
ProtectSystem protect_system,
unsigned long mount_flags,
n_bind_mounts,
n_temporary_filesystems,
tmp_dir, var_tmp_dir,
+ log_namespace,
protect_home, protect_system);
if (n_mounts > 0) {
};
}
+ if (log_namespace) {
+ _cleanup_free_ char *q;
+
+ q = strjoin("/run/systemd/journal.", log_namespace);
+ if (!q) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ *(m++) = (MountEntry) {
+ .path_const = "/run/systemd/journal",
+ .mode = BIND_MOUNT_RECURSIVE,
+ .read_only = true,
+ .source_malloc = TAKE_PTR(q),
+ };
+ }
+
assert(mounts + n_mounts == m);
/* Prepend the root directory where that's necessary */
r = 0;
finish:
- for (m = mounts; m < mounts + n_mounts; m++)
- mount_entry_done(m);
+ if (n_mounts > 0)
+ for (m = mounts; m < mounts + n_mounts; m++)
+ mount_entry_done(m);
free(mounts);