@@ -2097,4 +2097,74 @@ TEST_F(mount_setattr, two_detached_subtrees_of_same_anonymous_mount_namespace)
20972097 ASSERT_EQ (move_mount (fd_tree1 , "" , - EBADF , "/tmp/target1" , MOVE_MOUNT_F_EMPTY_PATH ), 0 );
20982098}
20992099
2100+ TEST_F (mount_setattr , detached_tree_propagation )
2101+ {
2102+ int fd_tree = - EBADF ;
2103+ struct statx stx1 , stx2 , stx3 , stx4 ;
2104+
2105+ ASSERT_EQ (unshare (CLONE_NEWNS ), 0 );
2106+ ASSERT_EQ (mount (NULL , "/mnt" , NULL , MS_REC | MS_SHARED , NULL ), 0 );
2107+
2108+ /*
2109+ * Copy the following mount tree:
2110+ *
2111+ * /mnt testing tmpfs
2112+ * |-/mnt/A testing tmpfs
2113+ * | `-/mnt/A/AA testing tmpfs
2114+ * | `-/mnt/A/AA/B testing tmpfs
2115+ * | `-/mnt/A/AA/B/BB testing tmpfs
2116+ * `-/mnt/B testing ramfs
2117+ */
2118+ fd_tree = sys_open_tree (- EBADF , "/mnt" ,
2119+ AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW |
2120+ AT_RECURSIVE | OPEN_TREE_CLOEXEC |
2121+ OPEN_TREE_CLONE );
2122+ ASSERT_GE (fd_tree , 0 );
2123+
2124+ ASSERT_EQ (statx (- EBADF , "/mnt/A" , 0 , 0 , & stx1 ), 0 );
2125+ ASSERT_EQ (statx (fd_tree , "A" , 0 , 0 , & stx2 ), 0 );
2126+
2127+ /*
2128+ * Copying the mount namespace like done above doesn't alter the
2129+ * mounts in any way so the filesystem mounted on /mnt must be
2130+ * identical even though the mounts will differ. Use the device
2131+ * information to verify that. Note that tmpfs will have a 0
2132+ * major number so comparing the major number is misleading.
2133+ */
2134+ ASSERT_EQ (stx1 .stx_dev_minor , stx2 .stx_dev_minor );
2135+
2136+ /* Mount a tmpfs filesystem over /mnt/A. */
2137+ ASSERT_EQ (mount (NULL , "/mnt/A" , "tmpfs" , 0 , NULL ), 0 );
2138+
2139+
2140+ ASSERT_EQ (statx (- EBADF , "/mnt/A" , 0 , 0 , & stx3 ), 0 );
2141+ ASSERT_EQ (statx (fd_tree , "A" , 0 , 0 , & stx4 ), 0 );
2142+
2143+ /*
2144+ * A new filesystem has been mounted on top of /mnt/A which
2145+ * means that the device information will be different for any
2146+ * statx() that was taken from /mnt/A before the mount compared
2147+ * to one after the mount.
2148+ *
2149+ * Since we already now that the device information between the
2150+ * stx1 and stx2 samples are identical we also now that stx2 and
2151+ * stx3 device information will necessarily differ.
2152+ */
2153+ ASSERT_NE (stx1 .stx_dev_minor , stx3 .stx_dev_minor );
2154+
2155+ /*
2156+ * If mount propagation worked correctly then the tmpfs mount
2157+ * that was created after the mount namespace was unshared will
2158+ * have propagated onto /mnt/A in the detached mount tree.
2159+ *
2160+ * Verify that the device information for stx3 and stx4 are
2161+ * identical. It is already established that stx3 is different
2162+ * from both stx1 and stx2 sampled before the tmpfs mount was
2163+ * done so if stx3 and stx4 are identical the proof is done.
2164+ */
2165+ ASSERT_EQ (stx3 .stx_dev_minor , stx4 .stx_dev_minor );
2166+
2167+ EXPECT_EQ (close (fd_tree ), 0 );
2168+ }
2169+
21002170TEST_HARNESS_MAIN
0 commit comments