1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-11 05:17:44 +03:00

mount-setup: port from nftw() to recurse_dir()

This commit is contained in:
Lennart Poettering 2021-10-01 15:56:27 +02:00
parent fef4fe1a84
commit aea0fe53ae

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <ftw.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/statvfs.h>
@ -9,9 +8,9 @@
#include "alloc-util.h"
#include "bus-util.h"
#include "cgroup-setup.h"
#include "cgroup-util.h"
#include "conf-files.h"
#include "cgroup-setup.h"
#include "dev-setup.h"
#include "dirent-util.h"
#include "efi-loader.h"
@ -27,6 +26,7 @@
#include "mountpoint-util.h"
#include "nulstr-util.h"
#include "path-util.h"
#include "recurse-dir.h"
#include "set.h"
#include "smack-util.h"
#include "strv.h"
@ -365,27 +365,46 @@ int mount_cgroup_controllers(void) {
}
#if HAVE_SELINUX || ENABLE_SMACK
static int nftw_cb(
const char *fpath,
const struct stat *sb,
int tflag,
struct FTW *ftwbuf) {
static int relabel_cb(
RecurseDirEvent event,
const char *path,
int dir_fd,
int inode_fd,
const struct dirent *de,
const struct statx *sx,
void *userdata) {
/* No need to label /dev twice in a row... */
if (_unlikely_(ftwbuf->level == 0))
return FTW_CONTINUE;
switch (event) {
(void) label_fix(fpath, 0);
case RECURSE_DIR_LEAVE:
case RECURSE_DIR_SKIP_MOUNT:
/* If we already saw this dirent when entering it or this is a dirent that on a different
* mount, don't relabel it. */
return RECURSE_DIR_CONTINUE;
/* /run/initramfs is static data and big, no need to
* dynamically relabel its contents at boot... */
if (_unlikely_(ftwbuf->level == 1 &&
tflag == FTW_D &&
streq(fpath, "/run/initramfs")))
return FTW_SKIP_SUBTREE;
case RECURSE_DIR_ENTER:
/* /run/initramfs is static data and big, no need to dynamically relabel its contents at boot... */
if (path_equal(path, "/run/initramfs"))
return RECURSE_DIR_SKIP_ENTRY;
return FTW_CONTINUE;
};
_fallthrough_;
default:
/* Otherwise, label it, even if we had trouble stat()ing it and similar. SELinux can figure this out */
(void) label_fix(path, 0);
return RECURSE_DIR_CONTINUE;
}
}
static int relabel_tree(const char *path) {
int r;
r = recurse_dir_at(AT_FDCWD, path, 0, UINT_MAX, RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_SAME_MOUNT, relabel_cb, NULL);
if (r < 0)
log_debug_errno(r, "Failed to recursively relabel '%s': %m", path);
return r;
}
static int relabel_cgroup_filesystems(void) {
int r;
@ -404,7 +423,7 @@ static int relabel_cgroup_filesystems(void) {
(void) mount_nofollow(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
(void) label_fix("/sys/fs/cgroup", 0);
(void) nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
(void) relabel_tree("/sys/fs/cgroup");
if (st.f_flags & ST_RDONLY)
(void) mount_nofollow(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
@ -468,7 +487,7 @@ static int relabel_extra(void) {
log_debug("Relabelling additional file/directory '%s'.", line);
(void) label_fix(line, 0);
(void) nftw(line, nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
(void) relabel_tree(line);
c++;
}
@ -505,7 +524,7 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
before_relabel = now(CLOCK_MONOTONIC);
FOREACH_STRING(i, "/dev", "/dev/shm", "/run")
(void) nftw(i, nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
(void) relabel_tree(i);
(void) relabel_cgroup_filesystems();