summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFilipe Brandenburger <filbranden@google.com>2018-06-04 14:23:14 -0700
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commitcca09ee8d6ece8e22b638efd05c4c0eb49e91b91 (patch)
tree4d0ab3b118e181df7c5bb2b3d2ea4d27097aecde /src
parentc4c4363b1f9e385d45824ed2b6849df7c0e54bd2 (diff)
copy: only check for traversing mount points on directories
This fixes the copy routines on overlay filesystem, which typically returns the underlying st_dev for files, symlinks, etc. The value of st_dev is guaranteed to be the same for directories, so checking it on directories only fixes this code on overlay filesystem and still keeps it from traversing mount points (which was the original intent.) There's a small side effect here, by which regular (non-directory) files with bind mounts will be copied by the new logic (while they were skipped by the previous logic.) Tested: ./build/test-copy with an overlay on /tmp. Fixes: #9134
Diffstat (limited to 'src')
-rw-r--r--src/basic/copy.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/src/basic/copy.c b/src/basic/copy.c
index 18eea64a9..5962e4ce7 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -533,13 +533,12 @@ static int fd_copy_directory(
continue;
}
- if (buf.st_dev != original_device)
- continue;
-
- if (S_ISREG(buf.st_mode))
- q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
- else if (S_ISDIR(buf.st_mode))
+ if (S_ISDIR(buf.st_mode)) {
+ if (buf.st_dev != original_device)
+ continue;
q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, override_uid, override_gid, copy_flags);
+ } else if (S_ISREG(buf.st_mode))
+ q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISLNK(buf.st_mode))
q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
else if (S_ISFIFO(buf.st_mode))