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