From: Lennart Poettering Date: Fri, 1 Oct 2021 13:56:27 +0000 (+0200) Subject: mount-setup: port from nftw() to recurse_dir() X-Git-Tag: v250-rc1~550^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aea0fe53ae4874ca7ba4fb78e59349d8f90f77c9;p=thirdparty%2Fsystemd.git mount-setup: port from nftw() to recurse_dir() --- diff --git a/src/shared/mount-setup.c b/src/shared/mount-setup.c index ae148541d7d..7057a8763ed 100644 --- a/src/shared/mount-setup.c +++ b/src/shared/mount-setup.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include #include #include #include @@ -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) { - - /* No need to label /dev twice in a row... */ - if (_unlikely_(ftwbuf->level == 0)) - return FTW_CONTINUE; - - (void) label_fix(fpath, 0); - - /* /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; - - return FTW_CONTINUE; -}; +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) { + + switch (event) { + + 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; + + 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; + + _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();