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