diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index b579e3be26..d1208e4678 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -45,6 +45,7 @@ #include "strv.h" #include "sync-util.h" #include "tmpfile-util.h" +#include "user-util.h" /* Round down to the nearest 4K size. Given that newer hardware generally prefers 4K sectors, let's align our * partitions to that too. In the worst case we'll waste 3.5K per partition that way, but I think I can live @@ -1989,6 +1990,7 @@ int home_create_luks( host_size = 0, partition_offset = 0, partition_size = 0; /* Unnecessary initialization to appease gcc */ _cleanup_(user_record_unrefp) UserRecord *new_home = NULL; sd_id128_t partition_uuid, fs_uuid, luks_uuid, disk_uuid; + _cleanup_close_ int mount_fd = -1; const char *fstype, *ip; struct statfs sfs; int r; @@ -2237,6 +2239,19 @@ int home_create_luks( if (setup->root_fd < 0) return log_error_errno(errno, "Failed to open user directory in mounted image file: %m"); + (void) home_shift_uid(setup->root_fd, NULL, UID_NOBODY, h->uid, &mount_fd); + + if (mount_fd >= 0) { + /* If we have established a new mount, then we can use that as new root fd to our home directory. */ + safe_close(setup->root_fd); + + setup->root_fd = fd_reopen(mount_fd, O_RDONLY|O_CLOEXEC|O_DIRECTORY); + if (setup->root_fd < 0) + return log_error_errno(setup->root_fd, "Unable to convert mount fd into proper directory fd: %m"); + + mount_fd = safe_close(mount_fd); + } + r = home_populate(h, setup->root_fd); if (r < 0) return r; diff --git a/src/home/homework-mount.c b/src/home/homework-mount.c index 5758e85839..82b461a987 100644 --- a/src/home/homework-mount.c +++ b/src/home/homework-mount.c @@ -84,7 +84,17 @@ int home_unshare_and_mount(const char *node, const char *fstype, bool discard, u if (r < 0) return r; - return home_mount_node(node, fstype, discard, flags); + r = home_mount_node(node, fstype, discard, flags); + if (r < 0) + return r; + + r = mount_nofollow_verbose(LOG_ERR, NULL, HOME_RUNTIME_WORK_DIR, NULL, MS_PRIVATE, NULL); + if (r < 0) { + (void) umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW); + return r; + } + + return 0; } int home_move_mount(const char *mount_suffix, const char *target) { @@ -111,9 +121,9 @@ int home_move_mount(const char *mount_suffix, const char *target) { if (r < 0) return r; - r = umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW); + r = umount_recursive(HOME_RUNTIME_WORK_DIR, 0); if (r < 0) - return r; + return log_error_errno(r, "Failed to unmount %s: %m", HOME_RUNTIME_WORK_DIR); log_info("Moving to final mount point %s completed.", target); return 0; diff --git a/src/home/homework.c b/src/home/homework.c index 7a2d816e59..a5da4cf54b 100644 --- a/src/home/homework.c +++ b/src/home/homework.c @@ -306,9 +306,15 @@ int home_setup_undo_mount(HomeSetup *setup, int level) { if (!setup->undo_mount) return 0; - r = umount_verbose(level, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW); - if (r < 0) - return r; + r = umount_recursive(HOME_RUNTIME_WORK_DIR, 0); + if (r < 0) { + if (level >= LOG_DEBUG) /* umount_recursive() does debug level logging anyway, no need to + * repeat that here */ + return r; + + /* If a higher log level is requested, the generate a non-debug mesage here too. */ + return log_full_errno(level, r, "Failed to unmount mount tree below %s: %m", HOME_RUNTIME_WORK_DIR); + } setup->undo_mount = false; return 1;