1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-28 02:50:16 +03:00

mkfs-util: Skip non files/directories when calling mcopy

Only files and directories are supported by vfat. When we pass a
symlink to mcopy, it will try to dereference them and copy what the
symlink points at into the vfat partition instead. Let's avoid this
by skipping all unsupported file types when establishing the list of
top level targets that mcopy should copy.

We also use RECURSE_DIR_SORT everywhere when iterating directories
to make things more reproducible.
This commit is contained in:
Daan De Meyer 2022-11-23 14:12:38 +01:00
parent a0a4c57818
commit c75cf0164c

View File

@ -129,7 +129,8 @@ static int setup_userns(uid_t uid, gid_t gid) {
static int do_mcopy(const char *node, const char *root) {
_cleanup_strv_free_ char **argv = NULL;
_cleanup_closedir_ DIR *rootdir = NULL;
_cleanup_close_ int rfd = -1;
_cleanup_free_ DirectoryEntries *de = NULL;
struct stat st;
int r;
@ -147,15 +148,24 @@ static int do_mcopy(const char *node, const char *root) {
/* mcopy copies the top level directory instead of everything in it so we have to pass all
* the subdirectories to mcopy instead to end up with the correct directory structure. */
rootdir = opendir(root);
if (!rootdir)
return log_error_errno(errno, "Failed to open directory '%s'", root);
rfd = open(root, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
if (rfd < 0)
return log_error_errno(errno, "Failed to open directory '%s': %m", root);
FOREACH_DIRENT(de, rootdir, return -errno) {
char *p = path_join(root, de->d_name);
r = readdir_all(rfd, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE, &de);
if (r < 0)
return log_error_errno(r, "Failed to read '%s' contents: %m", root);
for (size_t i = 0; i < de->n_entries; i++) {
char *p = path_join(root, de->entries[i]->d_name);
if (!p)
return log_oom();
if (!IN_SET(de->entries[i]->d_type, DT_REG, DT_DIR)) {
log_debug("%s is not a file/directory which are the only file types supported by vfat, ignoring", p);
continue;
}
r = strv_consume(&argv, TAKE_PTR(p));
if (r < 0)
return log_oom();
@ -165,7 +175,7 @@ static int do_mcopy(const char *node, const char *root) {
if (r < 0)
return log_oom();
if (fstat(dirfd(rootdir), &st) < 0)
if (fstat(rfd, &st) < 0)
return log_error_errno(errno, "Failed to stat '%s': %m", root);
r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_NEW_USERNS|FORK_CLOSE_ALL_FDS, NULL);
@ -262,7 +272,7 @@ static int make_protofile(const char *root, char **ret) {
"0 0\n"
"d--755 0 0\n", f);
r = recurse_dir_at(AT_FDCWD, root, STATX_TYPE|STATX_MODE, UINT_MAX, 0, protofile_print_item, f);
r = recurse_dir_at(AT_FDCWD, root, STATX_TYPE|STATX_MODE, UINT_MAX, RECURSE_DIR_SORT, protofile_print_item, f);
if (r < 0)
return log_error_errno(r, "Failed to recurse through %s: %m", root);