@@ -2097,4 +2097,74 @@ TEST_F(mount_setattr, two_detached_subtrees_of_same_anonymous_mount_namespace)
2097
2097
ASSERT_EQ (move_mount (fd_tree1 , "" , - EBADF , "/tmp/target1" , MOVE_MOUNT_F_EMPTY_PATH ), 0 );
2098
2098
}
2099
2099
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
+
2100
2170
TEST_HARNESS_MAIN
0 commit comments