From ca79199a587267dd4d0ee85b30a38da442aecdca Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 7 Jun 2021 12:34:39 -0700 Subject: [PATCH] cryptfs: try harder to unmount subdirectory mounts ensure_subdirectory_unmounted() was ignoring the return value from umount(), so it wasn't possible to tell whether it succeeded or failed. Make it log an error message on failure. Also, there might be cases where ensure_subdirectory_unmounted() fails initially but would succeed later, e.g. due to files in a subdirectory mount being open and requiring processes to be killed. To make this more robust, keep calling ensure_subdirectory_unmounted() before each attempt of umount("/data"). I'm not sure whether this will actually fix bug 189250652, as it hasn't been root-caused yet, but this might help. Bug: 189250652 Change-Id: I979b12d3c6a88fe3335ff548b1f8a5db43683c4f (cherry picked from commit 895343006417e62b82ba6f758cf43643f529af2f) Merged-In: I979b12d3c6a88fe3335ff548b1f8a5db43683c4f --- cryptfs.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cryptfs.cpp b/cryptfs.cpp index a0ee3cd..3c6ed15 100644 --- a/cryptfs.cpp +++ b/cryptfs.cpp @@ -1744,20 +1744,23 @@ static void ensure_subdirectory_unmounted(const char *prefix) { [](const std::string& s1, const std::string& s2) {return s1.length() > s2.length(); }); for (std::string& mount_point : umount_points) { - umount(mount_point.c_str()); - SLOGW("umount sub-directory mount %s\n", mount_point.c_str()); + SLOGW("unmounting sub-directory mount %s\n", mount_point.c_str()); + if (umount(mount_point.c_str()) != 0) { + SLOGE("unmounting %s failed: %s\n", mount_point.c_str(), strerror(errno)); + } } } static int wait_and_unmount(const char* mountpoint) { int i, err, rc; - // Subdirectory mount will cause a failure of umount. - ensure_subdirectory_unmounted(mountpoint); #define WAIT_UNMOUNT_COUNT 200 /* Now umount the tmpfs filesystem */ for (i = 0; i < WAIT_UNMOUNT_COUNT; i++) { + // Subdirectory mount will cause a failure of umount. + ensure_subdirectory_unmounted(mountpoint); + if (umount(mountpoint) == 0) { break; }