@@ -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,37 @@ 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
+ return get_and_reset (& open_tree_fd );
394
+ }
395
+
361
396
int
362
397
libcrun_create_keyring (const char * name , const char * label , libcrun_error_t * err )
363
398
{
@@ -431,8 +466,11 @@ enum
431
466
{
432
467
OPTION_TMPCOPYUP = (1 << 0 ),
433
468
OPTION_RRO = (1 << 1 ),
469
+ OPTION_IDMAP = (1 << 2 ),
434
470
};
435
471
472
+ #define IDMAP "idmap"
473
+
436
474
static struct propagation_flags_s propagation_flags [] = { { "defaults" , 0 , 0 , 0 },
437
475
{ "bind" , 0 , MS_BIND , 0 },
438
476
{ "rbind" , 0 , MS_REC | MS_BIND , 0 },
@@ -469,6 +507,7 @@ static struct propagation_flags_s propagation_flags[] = { { "defaults", 0, 0, 0
469
507
470
508
{ "tmpcopyup" , 0 , 0 , OPTION_TMPCOPYUP },
471
509
{ "rro" , 0 , 0 , OPTION_RRO },
510
+ { IDMAP , 0 , 0 , OPTION_IDMAP },
472
511
473
512
{ NULL , 0 , 0 , 0 } };
474
513
@@ -1657,7 +1696,8 @@ do_mounts (libcrun_container_t *container, int rootfsfd, const char *rootfs, con
1657
1696
ret = fs_move_mount_to (mfd , targetfd , NULL );
1658
1697
if (LIKELY (ret == 0 ))
1659
1698
{
1660
- ret = do_mount (container , NULL , mfd , target , NULL , flags , data , LABEL_NONE , err );
1699
+ /* Force no MS_BIND flag to not attempt again the bind mount. */
1700
+ ret = do_mount (container , NULL , mfd , target , NULL , flags & ~MS_BIND , data , LABEL_NONE , err );
1661
1701
if (UNLIKELY (ret < 0 ))
1662
1702
return ret ;
1663
1703
mounted = true;
@@ -3256,6 +3296,17 @@ get_fd_map (libcrun_container_t *container)
3256
3296
return mount_fds ;
3257
3297
}
3258
3298
3299
+ static bool
3300
+ is_idmapped (runtime_spec_schema_defs_mount * mnt )
3301
+ {
3302
+ size_t i ;
3303
+
3304
+ for (i = 0 ; i < mnt -> options_len ; i ++ )
3305
+ if (strcmp (mnt -> options [i ], IDMAP ) == 0 )
3306
+ return true;
3307
+ return false;
3308
+ }
3309
+
3259
3310
static int
3260
3311
prepare_and_send_mounts (libcrun_container_t * container , pid_t pid , int sync_socket_host , libcrun_error_t * err )
3261
3312
{
@@ -3272,6 +3323,17 @@ prepare_and_send_mounts (libcrun_container_t *container, pid_t pid, int sync_soc
3272
3323
3273
3324
for (i = 0 ; i < def -> mounts_len ; i ++ )
3274
3325
{
3326
+ if (is_idmapped (def -> mounts [i ]))
3327
+ {
3328
+ int fd ;
3329
+
3330
+ fd = get_idmapped_mount (def -> mounts [i ]-> source , pid , err );
3331
+ if (UNLIKELY (fd < 0 ))
3332
+ return fd ;
3333
+
3334
+ mount_fds -> fds [i ] = fd ;
3335
+ }
3336
+
3275
3337
if (mount_fds -> fds [i ] >= 0 )
3276
3338
how_many ++ ;
3277
3339
}
0 commit comments