923a60
From 025eb38eeb31ca07c98d2e41ce90d05016afc0f4 Mon Sep 17 00:00:00 2001
923a60
From: Frantisek Sumsal <fsumsal@redhat.com>
923a60
Date: Mon, 14 Jan 2019 11:20:52 +0100
923a60
Subject: [PATCH] copy: only check for traversing mount points on directories
923a60
923a60
This fixes the copy routines on overlay filesystem, which typically
923a60
returns the underlying st_dev for files, symlinks, etc.
923a60
923a60
The value of st_dev is guaranteed to be the same for directories, so
923a60
checking it on directories only fixes this code on overlay filesystem
923a60
and still keeps it from traversing mount points (which was the original
923a60
intent.)
923a60
923a60
There's a small side effect here, by which regular (non-directory) files
923a60
with bind mounts will be copied by the new logic (while they were
923a60
skipped by the previous logic.)
923a60
923a60
Tested: ./build/test-copy with an overlay on /tmp.
923a60
923a60
Cherry-picked from: ef202b848bb6635dec17d3ec0041b04cd2301bed
923a60
---
923a60
 src/shared/copy.c | 11 +++++------
923a60
 1 file changed, 5 insertions(+), 6 deletions(-)
923a60
923a60
diff --git a/src/shared/copy.c b/src/shared/copy.c
923a60
index 2a0cb28080..0a7ee47f99 100644
923a60
--- a/src/shared/copy.c
923a60
+++ b/src/shared/copy.c
923a60
@@ -271,13 +271,12 @@ static int fd_copy_directory(
923a60
                         continue;
923a60
                 }
923a60
 
923a60
-                if (buf.st_dev != original_device)
923a60
-                        continue;
923a60
-
923a60
-                if (S_ISREG(buf.st_mode))
923a60
-                        q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name);
923a60
-                else if (S_ISDIR(buf.st_mode))
923a60
+                if (S_ISDIR(buf.st_mode)) {
923a60
+                        if (buf.st_dev != original_device)
923a60
+                                continue;
923a60
                         q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, merge);
923a60
+                } else if (S_ISREG(buf.st_mode))
923a60
+                        q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name);
923a60
                 else if (S_ISLNK(buf.st_mode))
923a60
                         q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name);
923a60
                 else if (S_ISFIFO(buf.st_mode))