@@ -290,6 +290,10 @@ struct mount_attr_s
290
290
# define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */
291
291
#endif
292
292
293
+ #ifndef MOUNT_ATTR_IDMAP
294
+ # define MOUNT_ATTR_IDMAP 0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
295
+ #endif
296
+
293
297
static int
294
298
syscall_mount_setattr (int dfd , const char * path , unsigned int flags ,
295
299
struct mount_attr_s * attr )
@@ -358,6 +362,42 @@ make_mount_rro (const char *target, int targetfd, libcrun_error_t *err)
358
362
return 0 ;
359
363
}
360
364
365
+ static int
366
+ get_idmapped_mount (const char * src , pid_t pid , libcrun_error_t * err )
367
+ {
368
+ cleanup_close int open_tree_fd = -1 ;
369
+ cleanup_close int fd = -1 ;
370
+ int ret ;
371
+ char proc_path [64 ];
372
+ struct mount_attr_s attr = {
373
+ 0 ,
374
+ };
375
+
376
+ sprintf (proc_path , "/proc/%d/ns/user" , pid );
377
+ fd = open (proc_path , O_RDONLY );
378
+ if (UNLIKELY (fd < 0 ))
379
+ return crun_make_error (err , errno , "open `%s`" , proc_path );
380
+
381
+ open_tree_fd = syscall_open_tree (-1 , src ,
382
+ AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE );
383
+ if (UNLIKELY (open_tree_fd < 0 ))
384
+ return crun_make_error (err , errno , "open `/%s`" , src );
385
+
386
+ attr .attr_set = MOUNT_ATTR_IDMAP ;
387
+ attr .userns_fd = fd ;
388
+
389
+ ret = syscall_mount_setattr (open_tree_fd , "" , AT_EMPTY_PATH , & attr );
390
+ if (UNLIKELY (ret < 0 ))
391
+ return crun_make_error (err , errno , "mount_setattr `%s`" , src );
392
+
393
+ /*
394
+ ret = syscall_fsmount (open_tree_fd, FSMOUNT_CLOEXEC, 0);
395
+ if (UNLIKELY (ret < 0))
396
+ return crun_make_error (err, errno, "fsmount `%s`", src);
397
+ */
398
+ return get_and_reset (& open_tree_fd );
399
+ }
400
+
361
401
int
362
402
libcrun_create_keyring (const char * name , const char * label , libcrun_error_t * err )
363
403
{
@@ -431,8 +471,11 @@ enum
431
471
{
432
472
OPTION_TMPCOPYUP = (1 << 0 ),
433
473
OPTION_RRO = (1 << 1 ),
474
+ OPTION_IDMAP = (1 << 2 ),
434
475
};
435
476
477
+ #define IDMAP "idmap"
478
+
436
479
static struct propagation_flags_s propagation_flags [] = { { "defaults" , 0 , 0 , 0 },
437
480
{ "bind" , 0 , MS_BIND , 0 },
438
481
{ "rbind" , 0 , MS_REC | MS_BIND , 0 },
@@ -469,6 +512,7 @@ static struct propagation_flags_s propagation_flags[] = { { "defaults", 0, 0, 0
469
512
470
513
{ "tmpcopyup" , 0 , 0 , OPTION_TMPCOPYUP },
471
514
{ "rro" , 0 , 0 , OPTION_RRO },
515
+ { IDMAP , 0 , 0 , OPTION_IDMAP },
472
516
473
517
{ NULL , 0 , 0 , 0 } };
474
518
@@ -1657,7 +1701,8 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
1657
1701
ret = fs_move_mount_to (mfd , targetfd , NULL );
1658
1702
if (LIKELY (ret == 0 ))
1659
1703
{
1660
- ret = do_mount (container , NULL , mfd , target , NULL , flags , data , LABEL_NONE , err );
1704
+ /* Force no MS_BIND flag to not attempt again the bind mount. */
1705
+ ret = do_mount (container , NULL , mfd , target , NULL , flags & ~MS_BIND , data , LABEL_NONE , err );
1661
1706
if (UNLIKELY (ret < 0 ))
1662
1707
return ret ;
1663
1708
mounted = true;
@@ -3256,6 +3301,17 @@ get_fd_map (libcrun_container_t *container)
3256
3301
return mount_fds ;
3257
3302
}
3258
3303
3304
+ static bool
3305
+ is_idmapped (runtime_spec_schema_defs_mount * mnt )
3306
+ {
3307
+ size_t i ;
3308
+
3309
+ for (i = 0 ; i < mnt -> options_len ; i ++ )
3310
+ if (strcmp (mnt -> options [i ], IDMAP ) == 0 )
3311
+ return true;
3312
+ return false;
3313
+ }
3314
+
3259
3315
static int
3260
3316
prepare_and_send_mounts (libcrun_container_t * container , pid_t pid , int sync_socket_host , libcrun_error_t * err )
3261
3317
{
@@ -3272,6 +3328,17 @@ prepare_and_send_mounts (libcrun_container_t *container, pid_t pid, int sync_soc
3272
3328
3273
3329
for (i = 0 ; i < def -> mounts_len ; i ++ )
3274
3330
{
3331
+ if (is_idmapped (def -> mounts [i ]))
3332
+ {
3333
+ int fd ;
3334
+
3335
+ fd = get_idmapped_mount (def -> mounts [i ]-> source , pid , err );
3336
+ if (UNLIKELY (fd < 0 ))
3337
+ return fd ;
3338
+
3339
+ mount_fds -> fds [i ] = fd ;
3340
+ }
3341
+
3275
3342
if (mount_fds -> fds [i ] >= 0 )
3276
3343
how_many ++ ;
3277
3344
}
0 commit comments