From 27eb6c57c57d8c925839000f23f4ca31a069b111 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Fri, 25 Jul 2025 00:05:06 +0000 Subject: [PATCH] mount-v2: enter the mount namesapce to propagation properties A kernel change (commit 12f147ddd6de, "do_change_type(): refuse to operate on unmounted/not ours mounts") modified how mount propagation properties can be changed. Previously, these properties could be changed from any mount namespace. Now, they can only be modified from the specific mount namespace where the target mount is actually mounted This commit addresses this new restriction by ensuring that CRIU enters the correct mount namespace before attempting to restore mount propagation properties (MS_SLAVE or MS_SHARED) for a mount. Signed-off-by: Andrei Vagin --- criu/mount-v2.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/criu/mount-v2.c b/criu/mount-v2.c index eb4dd8119..1e33ac12a 100644 --- a/criu/mount-v2.c +++ b/criu/mount-v2.c @@ -933,8 +933,12 @@ static int move_mount_set_group(int src_id, char *source, int dst_id) static int restore_one_sharing(struct sharing_group *sg, struct mount_info *target) { + int nsfd = -1, orig_nsfd = -1, exit_code = -1; char target_path[PATH_MAX]; - int target_fd; + int target_fd = -1; + + if (!sg->master_id && !sg->shared_id) + return 0; target_fd = fdstore_get(target->mnt_fd_id); BUG_ON(target_fd < 0); @@ -949,8 +953,7 @@ static int restore_one_sharing(struct sharing_group *sg, struct mount_info *targ first = get_first_mount(sg->parent); if (move_mount_set_group(first->mnt_fd_id, NULL, target->mnt_fd_id)) { pr_err("Failed to copy sharing from %d to %d\n", first->mnt_id, target->mnt_id); - close(target_fd); - return -1; + goto err; } } else { /* @@ -962,16 +965,23 @@ static int restore_one_sharing(struct sharing_group *sg, struct mount_info *targ */ if (move_mount_set_group(-1, sg->source, target->mnt_fd_id)) { pr_err("Failed to copy sharing from source %s to %d\n", sg->source, target->mnt_id); - close(target_fd); - return -1; + goto err; } } + } + nsfd = fdstore_get(target->nsid->mnt.nsfd_id); + if (nsfd < 0) + goto err; + + if (switch_ns_by_fd(nsfd, &mnt_ns_desc, &orig_nsfd)) + goto err; + + if (sg->master_id) { /* Convert shared_id to master_id */ if (mount(NULL, target_path, NULL, MS_SLAVE, NULL)) { pr_perror("Failed to make mount %d slave", target->mnt_id); - close(target_fd); - return -1; + goto err; } } @@ -979,13 +989,16 @@ static int restore_one_sharing(struct sharing_group *sg, struct mount_info *targ if (sg->shared_id) { if (mount(NULL, target_path, NULL, MS_SHARED, NULL)) { pr_perror("Failed to make mount %d shared", target->mnt_id); - close(target_fd); - return -1; + goto err; } } - close(target_fd); - - return 0; + exit_code = 0; +err: + close_safe(&target_fd); + close_safe(&nsfd); + if (orig_nsfd >= 0 && restore_ns(orig_nsfd, &mnt_ns_desc)) + exit_code = -1; + return exit_code; } static int restore_one_sharing_group(struct sharing_group *sg)