tag 542915 +patch
usertags 542915 -in-progress +patch-in-git
thanks

Attached is my minimal patch solving the problem of data loss in
bind-mounted directories.  It provides a safety net that, in the event that
*anything* is still mounted inside the chroot, no attempt to delete anything
will be made.  Whilst this may, in some corner cases, result in failure to
cleanup a chroot when previously (most) things would have been deleted, it
should never effect most users.

I've exercised this patch in every way I can think of (bind-mounting things
left and right, regular mounts, symlinks to mounts, etc) and I haven't been
able to get it to actually delete anything any more.

Jakub, I'd appreciate it if you would be able to apply the patch to your
local pbuilder installation (it should go onto pbuilder-modulers in-situ,
without a need for a rebuild) and see if you can find any ways to break it.

- Matt
>From b13d3b8a9757da6bd84fd374b7948919fff1df80 Mon Sep 17 00:00:00 2001
From: Matt Palmer <mpal...@hezmatt.org>
Date: Wed, 15 Dec 2010 07:21:00 +1100
Subject: [PATCH] Ensure that nothing is still mounted before deleting the build chroot.  Closes: #542915

Whilst pbuilder is quite careful to minimise the risk of accidental data
removal (with find -xdev, unmounting everything it mounts, etc), there is
one case that it doesn't handle -- directories on the same filesystem as the
chroot being bind-mounted into the chroot, because -xdev doesn't recognise
the mount as a separate filesystem and pbuilder doesn't know to unmount it
because it didn't mount it in the first place.

This patch acts as a final safety net, to avoid attempting to delete
anything if there is anything at all still mounted in the chroot.
---
 pbuilder-modules |   20 +++++++++++++++++---
 1 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/pbuilder-modules b/pbuilder-modules
index db6988b..8e23cdb 100644
--- a/pbuilder-modules
+++ b/pbuilder-modules
@@ -319,9 +319,23 @@ function cleanbuildplace () {
 	log "W: Aborting with an error";
     fi
     if [ "${INTERNAL_BUILD_UML}" != "yes" ]; then
-	if [ -d "$BUILDPLACE" ]; then 
-	    log "I: cleaning the build env "
-	    clean_subdirectories "$BUILDPLACE"
+        if [ -d "$BUILDPLACE" ]; then
+            # A directory on the same partition as $BUILDPLACE, bind-mounted
+            # into $BUILDPLACE, will be cleaned out by clean_subdirectories
+            # (because -xdev doesn't know about bind mounts).  To avoid that
+            # potential disaster (and also to avoid ugly error messages from
+            # rmdir otherwise), we want to make sure that there is *nothing*
+            # mounted under the chroot before we do our bulldozer routine.
+            #
+            # The readlink -f is a simple way to canonicalize the path for
+            # $BUILDPLACE (no dirty double slashes for *us*), so it matches
+            # what will be in the output of mount.
+            if mount |grep -q $(readlink -f $BUILDPLACE)/; then
+                log "E: Something is still mounted under ${BUILDPLACE}; unmount and remove ${BUILDPLACE} manually"
+            else
+                log "I: cleaning the build env "
+                clean_subdirectories "$BUILDPLACE"
+            fi
 	fi;
     fi
 }
-- 
1.5.6.5

Reply via email to