@@ -168,6 +168,9 @@ cleanup_private_data (void *private_data)
168
168
if (p -> dev_fds )
169
169
cleanup_close_mapp (& (p -> dev_fds ));
170
170
171
+ if (p -> rootfsfd >= 0 )
172
+ close (p -> rootfsfd );
173
+
171
174
free (p -> unified_cgroup_path );
172
175
free (p -> host_notify_socket_path );
173
176
free (p -> container_notify_socket_path );
@@ -1028,7 +1031,6 @@ do_masked_or_readonly_path (libcrun_container_t *container, const char *rel_path
1028
1031
{
1029
1032
unsigned long mount_flags = 0 ;
1030
1033
const char * rootfs = get_private_data (container )-> rootfs ;
1031
- int rootfsfd = get_private_data (container )-> rootfsfd ;
1032
1034
cleanup_close int pathfd = -1 ;
1033
1035
struct statfs sfs ;
1034
1036
int ret ;
@@ -1037,7 +1039,7 @@ do_masked_or_readonly_path (libcrun_container_t *container, const char *rel_path
1037
1039
if (rel_path [0 ] == '/' )
1038
1040
rel_path ++ ;
1039
1041
1040
- pathfd = safe_openat (rootfsfd , rootfs , rel_path , O_PATH | O_CLOEXEC , 0 , err );
1042
+ pathfd = safe_openat (get_private_data ( container ) -> rootfsfd , rootfs , rel_path , O_PATH | O_CLOEXEC , 0 , err );
1041
1043
if (UNLIKELY (pathfd < 0 ))
1042
1044
{
1043
1045
if (errno != ENOENT && errno != EACCES )
@@ -1226,6 +1228,17 @@ do_mount (libcrun_container_t *container, const char *source, int targetfd,
1226
1228
if (UNLIKELY (fd < 0 ))
1227
1229
return fd ;
1228
1230
1231
+ /* We are replacing the rootfs, reopen it. */
1232
+ if (is_empty_string (target ))
1233
+ {
1234
+ int tmp = dup (fd );
1235
+ if (UNLIKELY (tmp < 0 ))
1236
+ return crun_make_error (err , errno , "dup" );
1237
+
1238
+ TEMP_FAILURE_RETRY (close (get_private_data (container )-> rootfsfd ));
1239
+ get_private_data (container )-> rootfsfd = tmp ;
1240
+ }
1241
+
1229
1242
#ifdef HAVE_FGETXATTR
1230
1243
if (label_how == LABEL_XATTR )
1231
1244
{
@@ -1586,7 +1599,6 @@ libcrun_create_dev (libcrun_container_t *container, int devfd, int srcfd,
1586
1599
mode_t type = (device -> type [0 ] == 'b' ) ? S_IFBLK : ((device -> type [0 ] == 'p' ) ? S_IFIFO : S_IFCHR );
1587
1600
const char * fullname = device -> path ;
1588
1601
cleanup_close int fd = -1 ;
1589
- int rootfsfd = get_private_data (container )-> rootfsfd ;
1590
1602
const char * rootfs = get_private_data (container )-> rootfs ;
1591
1603
if (is_empty_string (fullname ))
1592
1604
return crun_make_error (err , EINVAL , "device path is empty" );
@@ -1617,7 +1629,7 @@ libcrun_create_dev (libcrun_container_t *container, int devfd, int srcfd,
1617
1629
{
1618
1630
const char * rel_path = consume_slashes (normalized_path );
1619
1631
1620
- fd = crun_safe_create_and_open_ref_at (false, rootfsfd , rootfs , rel_path , 0755 , err );
1632
+ fd = crun_safe_create_and_open_ref_at (false, get_private_data ( container ) -> rootfsfd , rootfs , rel_path , 0755 , err );
1621
1633
if (UNLIKELY (fd < 0 ))
1622
1634
return fd ;
1623
1635
}
@@ -1682,18 +1694,18 @@ libcrun_create_dev (libcrun_container_t *container, int devfd, int srcfd,
1682
1694
1683
1695
if (dirname [0 ] == '\0' )
1684
1696
{
1685
- dirfd = dup (rootfsfd );
1697
+ dirfd = dup (get_private_data ( container ) -> rootfsfd );
1686
1698
if (UNLIKELY (dirfd < 0 ))
1687
1699
return crun_make_error (err , errno , "dup fd for `%s`" , rootfs );
1688
1700
}
1689
1701
else
1690
1702
{
1691
- dirfd = safe_openat (rootfsfd , rootfs , dirname , O_DIRECTORY | O_PATH | O_CLOEXEC , 0 , err );
1703
+ dirfd = safe_openat (get_private_data ( container ) -> rootfsfd , rootfs , dirname , O_DIRECTORY | O_PATH | O_CLOEXEC , 0 , err );
1692
1704
if (dirfd < 0 && ensure_parent_dir )
1693
1705
{
1694
1706
crun_error_release (err );
1695
1707
1696
- dirfd = crun_safe_create_and_open_ref_at (true, rootfsfd , rootfs , dirname , 0755 , err );
1708
+ dirfd = crun_safe_create_and_open_ref_at (true, get_private_data ( container ) -> rootfsfd , rootfs , dirname , 0755 , err );
1697
1709
}
1698
1710
if (UNLIKELY (dirfd < 0 ))
1699
1711
return dirfd ;
@@ -1749,13 +1761,12 @@ create_missing_devs (libcrun_container_t *container, bool binds, libcrun_error_t
1749
1761
cleanup_close int devfd = -1 ;
1750
1762
runtime_spec_schema_config_schema * def = container -> container_def ;
1751
1763
const char * rootfs = get_private_data (container )-> rootfs ;
1752
- int rootfsfd = get_private_data (container )-> rootfsfd ;
1753
1764
cleanup_close_map struct libcrun_fd_map * dev_fds = NULL ;
1754
1765
1755
1766
dev_fds = get_private_data (container )-> dev_fds ;
1756
1767
get_private_data (container )-> dev_fds = NULL ;
1757
1768
1758
- devfd = openat (rootfsfd , "dev" , O_CLOEXEC | O_PATH | O_DIRECTORY );
1769
+ devfd = openat (get_private_data ( container ) -> rootfsfd , "dev" , O_CLOEXEC | O_PATH | O_DIRECTORY );
1759
1770
if (UNLIKELY (devfd < 0 ))
1760
1771
return crun_make_error (err , errno , "open `/dev` directory in `%s`" , rootfs );
1761
1772
@@ -1910,7 +1921,6 @@ static int
1910
1921
append_tmpfs_mode_if_missing (libcrun_container_t * container , runtime_spec_schema_defs_mount * mount , char * * data , libcrun_error_t * err )
1911
1922
{
1912
1923
const char * rootfs = get_private_data (container )-> rootfs ;
1913
- int rootfsfd = get_private_data (container )-> rootfsfd ;
1914
1924
bool empty_data = is_empty_string (* data );
1915
1925
cleanup_close int fd = -1 ;
1916
1926
struct stat st ;
@@ -1919,7 +1929,7 @@ append_tmpfs_mode_if_missing (libcrun_container_t *container, runtime_spec_schem
1919
1929
if (* data != NULL && strstr (* data , "mode=" ))
1920
1930
return 0 ;
1921
1931
1922
- fd = safe_openat (rootfsfd , rootfs , mount -> destination , O_CLOEXEC | O_RDONLY , 0 , err );
1932
+ fd = safe_openat (get_private_data ( container ) -> rootfsfd , rootfs , mount -> destination , O_CLOEXEC | O_RDONLY , 0 , err );
1923
1933
if (fd < 0 )
1924
1934
{
1925
1935
if (crun_error_get_errno (err ) != ENOENT )
@@ -2046,13 +2056,13 @@ get_force_cgroup_v1_annotation (libcrun_container_t *container)
2046
2056
}
2047
2057
2048
2058
static int
2049
- do_mounts (libcrun_container_t * container , int rootfsfd , const char * rootfs , libcrun_error_t * err )
2059
+ do_mounts (libcrun_container_t * container , const char * rootfs , libcrun_error_t * err )
2050
2060
{
2051
- size_t i ;
2052
- int ret ;
2053
2061
runtime_spec_schema_config_schema * def = container -> container_def ;
2054
2062
const char * systemd_cgroup_v1 = get_force_cgroup_v1_annotation (container );
2055
2063
cleanup_close_map struct libcrun_fd_map * mount_fds = NULL ;
2064
+ size_t i ;
2065
+ int ret ;
2056
2066
2057
2067
mount_fds = get_private_data (container )-> mount_fds ;
2058
2068
get_private_data (container )-> mount_fds = NULL ;
@@ -2134,7 +2144,7 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, lib
2134
2144
if (UNLIKELY (len < 0 ))
2135
2145
return len ;
2136
2146
2137
- ret = safe_create_symlink (rootfsfd , rootfs , target , def -> mounts [i ]-> destination , err );
2147
+ ret = safe_create_symlink (get_private_data ( container ) -> rootfsfd , rootfs , target , def -> mounts [i ]-> destination , err );
2138
2148
if (UNLIKELY (ret < 0 ))
2139
2149
return ret ;
2140
2150
@@ -2143,20 +2153,20 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, lib
2143
2153
else if (is_sysfs_or_proc )
2144
2154
{
2145
2155
/* Enforce sysfs and proc to be mounted on a regular directory. */
2146
- ret = openat (rootfsfd , target , O_CLOEXEC | O_NOFOLLOW | O_DIRECTORY );
2156
+ ret = openat (get_private_data ( container ) -> rootfsfd , target , O_CLOEXEC | O_NOFOLLOW | O_DIRECTORY );
2147
2157
if (UNLIKELY (ret < 0 ))
2148
2158
{
2149
2159
if (errno == ENOENT )
2150
2160
{
2151
2161
if (strchr (target , '/' ))
2152
2162
return crun_make_error (err , 0 , "invalid target `%s`: it must be mounted at the root" , target );
2153
2163
2154
- ret = mkdirat (rootfsfd , target , 0755 );
2164
+ ret = mkdirat (get_private_data ( container ) -> rootfsfd , target , 0755 );
2155
2165
if (UNLIKELY (ret < 0 ))
2156
2166
return crun_make_error (err , errno , "mkdirat `%s`" , target );
2157
2167
2158
2168
/* Try opening it again. */
2159
- ret = openat (rootfsfd , target , O_CLOEXEC | O_NOFOLLOW | O_DIRECTORY );
2169
+ ret = openat (get_private_data ( container ) -> rootfsfd , target , O_CLOEXEC | O_NOFOLLOW | O_DIRECTORY );
2160
2170
}
2161
2171
else if (errno == ENOTDIR )
2162
2172
return crun_make_error (err , errno , "the target `/%s` is invalid" , target );
@@ -2172,7 +2182,7 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, lib
2172
2182
bool is_dir = S_ISDIR (src_mode );
2173
2183
2174
2184
/* Make sure any other directory/file is created and take a O_PATH reference to it. */
2175
- ret = crun_safe_create_and_open_ref_at (is_dir , rootfsfd , rootfs , target , is_dir ? 01755 : 0755 , err );
2185
+ ret = crun_safe_create_and_open_ref_at (is_dir , get_private_data ( container ) -> rootfsfd , rootfs , target , is_dir ? 01755 : 0755 , err );
2176
2186
if (UNLIKELY (ret < 0 ))
2177
2187
return ret ;
2178
2188
@@ -2245,7 +2255,7 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, lib
2245
2255
{
2246
2256
int destfd , tmpfd ;
2247
2257
2248
- destfd = safe_openat (rootfsfd , rootfs , target , O_CLOEXEC | O_DIRECTORY , 0 , err );
2258
+ destfd = safe_openat (get_private_data ( container ) -> rootfsfd , rootfs , target , O_CLOEXEC | O_DIRECTORY , 0 , err );
2249
2259
if (UNLIKELY (destfd < 0 ))
2250
2260
return crun_error_wrap (err , "open `%s` to write for tmpcopyup" , target );
2251
2261
@@ -2262,7 +2272,7 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, lib
2262
2272
const bool is_dir = S_ISDIR (src_mode );
2263
2273
cleanup_close int dfd = -1 ;
2264
2274
2265
- dfd = safe_openat (rootfsfd , rootfs , target , O_RDONLY | O_PATH | O_CLOEXEC | (is_dir ? O_DIRECTORY : 0 ), 0 , err );
2275
+ dfd = safe_openat (get_private_data ( container ) -> rootfsfd , rootfs , target , O_RDONLY | O_PATH | O_CLOEXEC | (is_dir ? O_DIRECTORY : 0 ), 0 , err );
2266
2276
if (UNLIKELY (dfd < 0 ))
2267
2277
return crun_make_error (err , errno , "open mount target `/%s`" , target );
2268
2278
@@ -2283,7 +2293,6 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, lib
2283
2293
int
2284
2294
libcrun_container_do_bind_mount (libcrun_container_t * container , char * mount_source , char * mount_destination , char * * mount_options , size_t mount_options_len , libcrun_error_t * err )
2285
2295
{
2286
- int ret , rootfsfd ;
2287
2296
const char * target = consume_slashes (mount_destination );
2288
2297
cleanup_free char * data = NULL ;
2289
2298
unsigned long flags = 0 ;
@@ -2293,9 +2302,9 @@ libcrun_container_do_bind_mount (libcrun_container_t *container, char *mount_sou
2293
2302
uint64_t rec_clear = 0 ;
2294
2303
uint64_t rec_set = 0 ;
2295
2304
const char * rootfs = get_private_data (container )-> rootfs ;
2296
- rootfsfd = get_private_data ( container ) -> rootfsfd ;
2305
+ int ret ;
2297
2306
2298
- if ((rootfsfd < 0 ) || (rootfs == NULL ))
2307
+ if ((get_private_data ( container ) -> rootfsfd < 0 ) || (rootfs == NULL ))
2299
2308
return crun_make_error (err , 0 , "invalid rootfs state while performing bind mount from external plugin or handler" );
2300
2309
2301
2310
if (mount_options == NULL )
@@ -2321,7 +2330,7 @@ libcrun_container_do_bind_mount (libcrun_container_t *container, char *mount_sou
2321
2330
}
2322
2331
2323
2332
/* Make sure any other directory/file is created and take a O_PATH reference to it. */
2324
- ret = crun_safe_create_and_open_ref_at (is_dir , rootfsfd , rootfs , target , is_dir ? 01755 : 0755 , err );
2333
+ ret = crun_safe_create_and_open_ref_at (is_dir , get_private_data ( container ) -> rootfsfd , rootfs , target , is_dir ? 01755 : 0755 , err );
2325
2334
if (UNLIKELY (ret < 0 ))
2326
2335
return ret ;
2327
2336
@@ -2577,9 +2586,7 @@ int
2577
2586
libcrun_set_mounts (struct container_entrypoint_s * entrypoint_args , libcrun_container_t * container , const char * rootfs , set_mounts_cb_t cb , void * cb_data , libcrun_error_t * err )
2578
2587
{
2579
2588
runtime_spec_schema_config_schema * def = container -> container_def ;
2580
- cleanup_close int rootfsfd_cleanup = -1 ;
2581
2589
unsigned long rootfs_propagation = 0 ;
2582
- int rootfsfd = -1 ;
2583
2590
int cgroup_mode ;
2584
2591
int is_user_ns = 0 ;
2585
2592
int ret = 0 ;
@@ -2610,12 +2617,12 @@ libcrun_set_mounts (struct container_entrypoint_s *entrypoint_args, libcrun_cont
2610
2617
return ret ;
2611
2618
}
2612
2619
2613
- rootfsfd = rootfsfd_cleanup = open (rootfs , O_PATH | O_CLOEXEC );
2614
- if (UNLIKELY (rootfsfd < 0 ))
2620
+ ret = open (rootfs , O_PATH | O_CLOEXEC );
2621
+ if (UNLIKELY (ret < 0 ))
2615
2622
return crun_make_error (err , errno , "open `%s`" , rootfs );
2616
2623
2624
+ get_private_data (container )-> rootfsfd = ret ;
2617
2625
get_private_data (container )-> rootfs = rootfs ;
2618
- get_private_data (container )-> rootfsfd = rootfsfd ;
2619
2626
2620
2627
// configure handler mounts
2621
2628
ret = libcrun_container_notify_handler (entrypoint_args , HANDLER_CONFIGURE_MOUNTS , container , rootfs , err );
@@ -2628,7 +2635,7 @@ libcrun_set_mounts (struct container_entrypoint_s *entrypoint_args, libcrun_cont
2628
2635
unsigned long remount_flags = MS_REMOUNT | MS_BIND | MS_RDONLY ;
2629
2636
int fd ;
2630
2637
2631
- fd = dup (rootfsfd );
2638
+ fd = dup (get_private_data ( container ) -> rootfsfd );
2632
2639
if (UNLIKELY (fd < 0 ))
2633
2640
return crun_make_error (err , errno , "dup fd for `%s`" , rootfs );
2634
2641
@@ -2656,7 +2663,7 @@ libcrun_set_mounts (struct container_entrypoint_s *entrypoint_args, libcrun_cont
2656
2663
if (UNLIKELY (ret < 0 ))
2657
2664
return ret ;
2658
2665
2659
- ret = do_mounts (container , rootfsfd , rootfs , err );
2666
+ ret = do_mounts (container , rootfs , err );
2660
2667
if (UNLIKELY (ret < 0 ))
2661
2668
return ret ;
2662
2669
@@ -2692,7 +2699,7 @@ libcrun_set_mounts (struct container_entrypoint_s *entrypoint_args, libcrun_cont
2692
2699
libcrun_error_t tmp_err = NULL ;
2693
2700
const char * rel_cwd = consume_slashes (def -> process -> cwd );
2694
2701
/* Ignore errors here and let it fail later. */
2695
- (void ) crun_safe_ensure_directory_at (rootfsfd , rootfs , rel_cwd , 0755 , & tmp_err );
2702
+ (void ) crun_safe_ensure_directory_at (get_private_data ( container ) -> rootfsfd , rootfs , rel_cwd , 0755 , & tmp_err );
2696
2703
crun_error_release (& tmp_err );
2697
2704
}
2698
2705
@@ -2709,7 +2716,7 @@ libcrun_set_mounts (struct container_entrypoint_s *entrypoint_args, libcrun_cont
2709
2716
if (UNLIKELY (ret < 0 ))
2710
2717
return crun_make_error (err , errno , "failed configuring mounts for handler at phase: HANDLER_CONFIGURE_AFTER_MOUNTS" );
2711
2718
2712
- get_private_data (container )-> rootfsfd = -1 ;
2719
+ close_and_reset ( & ( get_private_data (container )-> rootfsfd )) ;
2713
2720
2714
2721
return 0 ;
2715
2722
}
@@ -4304,7 +4311,7 @@ prepare_and_send_dev_mounts (libcrun_container_t *container, int sync_socket_hos
4304
4311
return ret ;
4305
4312
4306
4313
ret = mkdir (devs_path , 0700 );
4307
- if (UNLIKELY (ret < 0 ) && errno != EEXIST )
4314
+ if (UNLIKELY (ret < 0 && errno != EEXIST ) )
4308
4315
return crun_make_error (err , errno , "mkdir `%s`" , devs_path );
4309
4316
4310
4317
current_mountns = open ("/proc/self/ns/mnt" , O_RDONLY | O_CLOEXEC );
0 commit comments