@@ -291,6 +291,10 @@ struct mount_attr_s
291
291
# define MOUNT_ATTR_RDONLY 0x00000001 /* Mount read-only */
292
292
#endif
293
293
294
+ #ifndef MOUNT_ATTR_IDMAP
295
+ # define MOUNT_ATTR_IDMAP 0x00100000 /* Idmap mount to @userns_fd in struct mount_attr. */
296
+ #endif
297
+
294
298
static int
295
299
syscall_mount_setattr (int dfd , const char * path , unsigned int flags ,
296
300
struct mount_attr_s * attr )
@@ -359,6 +363,42 @@ make_mount_rro (const char *target, int targetfd, libcrun_error_t *err)
359
363
return 0 ;
360
364
}
361
365
366
+ static int
367
+ get_idmapped_mount (const char * src , pid_t pid , libcrun_error_t * err )
368
+ {
369
+ cleanup_close int open_tree_fd = -1 ;
370
+ cleanup_close int fd = -1 ;
371
+ int ret ;
372
+ char proc_path [64 ];
373
+ struct mount_attr_s attr = {
374
+ 0 ,
375
+ };
376
+
377
+ sprintf (proc_path , "/proc/%d/ns/user" , pid );
378
+ fd = open (proc_path , O_RDONLY );
379
+ if (UNLIKELY (fd < 0 ))
380
+ return crun_make_error (err , errno , "open `%s`" , proc_path );
381
+
382
+ open_tree_fd = syscall_open_tree (-1 , src ,
383
+ AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE );
384
+ if (UNLIKELY (open_tree_fd < 0 ))
385
+ return crun_make_error (err , errno , "open `/%s`" , src );
386
+
387
+ attr .attr_set = MOUNT_ATTR_IDMAP ;
388
+ attr .userns_fd = fd ;
389
+
390
+ ret = syscall_mount_setattr (open_tree_fd , "" , AT_EMPTY_PATH , & attr );
391
+ if (UNLIKELY (ret < 0 ))
392
+ return crun_make_error (err , errno , "mount_setattr `%s`" , src );
393
+
394
+ /*
395
+ ret = syscall_fsmount (open_tree_fd, FSMOUNT_CLOEXEC, 0);
396
+ if (UNLIKELY (ret < 0))
397
+ return crun_make_error (err, errno, "fsmount `%s`", src);
398
+ */
399
+ return get_and_reset (& open_tree_fd );
400
+ }
401
+
362
402
int
363
403
libcrun_create_keyring (const char * name , const char * label , libcrun_error_t * err )
364
404
{
@@ -432,8 +472,11 @@ enum
432
472
{
433
473
OPTION_TMPCOPYUP = (1 << 0 ),
434
474
OPTION_RRO = (1 << 1 ),
475
+ OPTION_IDMAP = (1 << 2 ),
435
476
};
436
477
478
+ #define IDMAP "idmap"
479
+
437
480
static struct propagation_flags_s propagation_flags [] = { { "defaults" , 0 , 0 , 0 },
438
481
{ "bind" , 0 , MS_BIND , 0 },
439
482
{ "rbind" , 0 , MS_REC | MS_BIND , 0 },
@@ -470,6 +513,7 @@ static struct propagation_flags_s propagation_flags[] = { { "defaults", 0, 0, 0
470
513
471
514
{ "tmpcopyup" , 0 , 0 , OPTION_TMPCOPYUP },
472
515
{ "rro" , 0 , 0 , OPTION_RRO },
516
+ { IDMAP , 0 , 0 , OPTION_IDMAP },
473
517
474
518
{ NULL , 0 , 0 , 0 } };
475
519
@@ -1658,7 +1702,8 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
1658
1702
ret = fs_move_mount_to (mfd , targetfd , NULL );
1659
1703
if (LIKELY (ret == 0 ))
1660
1704
{
1661
- ret = do_mount (container , NULL , mfd , target , NULL , flags , data , LABEL_NONE , err );
1705
+ /* Force no MS_BIND flag to not attempt again the bind mount. */
1706
+ ret = do_mount (container , NULL , mfd , target , NULL , flags & ~MS_BIND , data , LABEL_NONE , err );
1662
1707
if (UNLIKELY (ret < 0 ))
1663
1708
return ret ;
1664
1709
mounted = true;
@@ -1711,17 +1756,20 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
1711
1756
return ret ;
1712
1757
}
1713
1758
1714
- if (extra_flags & OPTION_RRO )
1759
+ if (extra_flags & ( OPTION_RRO | OPTION_IDMAP ) )
1715
1760
{
1716
1761
cleanup_close int dfd = -1 ;
1717
1762
1718
1763
dfd = safe_openat (rootfsfd , rootfs , rootfs_len , target , O_DIRECTORY , 0 , err );
1719
1764
if (UNLIKELY (dfd < 0 ))
1720
1765
return crun_make_error (err , errno , "open mount target `/%s`" , target );
1721
1766
1722
- ret = make_mount_rro (target , dfd , err );
1723
- if (UNLIKELY (ret < 0 ))
1724
- return ret ;
1767
+ if (extra_flags & OPTION_RRO )
1768
+ {
1769
+ ret = make_mount_rro (target , dfd , err );
1770
+ if (UNLIKELY (ret < 0 ))
1771
+ return ret ;
1772
+ }
1725
1773
}
1726
1774
}
1727
1775
return 0 ;
@@ -3257,6 +3305,17 @@ get_fd_map (libcrun_container_t *container)
3257
3305
return mount_fds ;
3258
3306
}
3259
3307
3308
+ static bool
3309
+ is_idmapped (runtime_spec_schema_defs_mount * mnt )
3310
+ {
3311
+ size_t i ;
3312
+
3313
+ for (i = 0 ; i < mnt -> options_len ; i ++ )
3314
+ if (strcmp (mnt -> options [i ], IDMAP ) == 0 )
3315
+ return true;
3316
+ return false;
3317
+ }
3318
+
3260
3319
static int
3261
3320
prepare_and_send_mounts (libcrun_container_t * container , struct init_status_s * init_status ,
3262
3321
pid_t pid , int sync_socket_host , libcrun_error_t * err )
@@ -3274,6 +3333,17 @@ prepare_and_send_mounts (libcrun_container_t *container, struct init_status_s *i
3274
3333
3275
3334
for (i = 0 ; i < def -> mounts_len ; i ++ )
3276
3335
{
3336
+ if (is_idmapped (def -> mounts [i ]))
3337
+ {
3338
+ int fd ;
3339
+
3340
+ fd = get_idmapped_mount (def -> mounts [i ]-> source , pid , err );
3341
+ if (UNLIKELY (fd < 0 ))
3342
+ return fd ;
3343
+
3344
+ mount_fds -> fds [i ] = fd ;
3345
+ }
3346
+
3277
3347
if (mount_fds -> fds [i ] >= 0 )
3278
3348
how_many ++ ;
3279
3349
}
0 commit comments