@@ -130,6 +130,7 @@ typedef enum {
130130 SETUP_OVERLAY_SRC ,
131131 SETUP_MOUNT_PROC ,
132132 SETUP_MOUNT_DEV ,
133+ SETUP_MOUNT_SYS ,
133134 SETUP_MOUNT_TMPFS ,
134135 SETUP_MOUNT_MQUEUE ,
135136 SETUP_MAKE_DIR ,
@@ -175,6 +176,7 @@ enum {
175176 PRIV_SEP_OP_BIND_MOUNT ,
176177 PRIV_SEP_OP_OVERLAY_MOUNT ,
177178 PRIV_SEP_OP_PROC_MOUNT ,
179+ PRIV_SEP_OP_SYS_MOUNT ,
178180 PRIV_SEP_OP_TMPFS_MOUNT ,
179181 PRIV_SEP_OP_DEVPTS_MOUNT ,
180182 PRIV_SEP_OP_MQUEUE_MOUNT ,
@@ -352,6 +354,7 @@ usage (int ecode, FILE *out)
352354 " --file-label LABEL File label for temporary sandbox content\n"
353355 " --proc DEST Mount new procfs on DEST\n"
354356 " --dev DEST Mount new dev on DEST\n"
357+ " --sys DEST Mount new sysfs on DEST\n"
355358 " --tmpfs DEST Mount new tmpfs on DEST\n"
356359 " --mqueue DEST Mount new mqueue on DEST\n"
357360 " --dir DEST Create dir at DEST\n"
@@ -1122,6 +1125,11 @@ privileged_op (int privileged_op_socket,
11221125 die_with_mount_error ("Can't mount proc on %s" , arg1 );
11231126 break ;
11241127
1128+ case PRIV_SEP_OP_SYS_MOUNT :
1129+ if (mount ("sysfs" , arg1 , "sysfs" , MS_NOSUID | MS_NOEXEC | MS_NODEV , NULL ) != 0 )
1130+ die_with_mount_error ("Can't mount sys on %s" , arg1 );
1131+ break ;
1132+
11251133 case PRIV_SEP_OP_TMPFS_MOUNT :
11261134 {
11271135 cleanup_free char * mode = NULL ;
@@ -1191,6 +1199,7 @@ setup_newroot (bool unshare_pid,
11911199{
11921200 SetupOp * op ;
11931201 int tmp_overlay_idx = 0 ;
1202+ struct stat sbuf ;
11941203
11951204 for (op = ops ; op != NULL ; op = op -> next )
11961205 {
@@ -1443,6 +1452,36 @@ setup_newroot (bool unshare_pid,
14431452
14441453 break ;
14451454
1455+ case SETUP_MOUNT_SYS :
1456+ if (ensure_dir (dest , 0755 ) != 0 )
1457+ die_with_error ("Can't mkdir %s" , op -> dest );
1458+
1459+ if (unshare_pid || opt_pidns_fd != -1 )
1460+ {
1461+ /* Our own sysfs */
1462+ privileged_op (privileged_op_socket ,
1463+ PRIV_SEP_OP_SYS_MOUNT , 0 , 0 , 0 ,
1464+ dest , NULL );
1465+
1466+ /* In case the host utilizes SELinux, /sys/fs/selinux should be shared with the sandbox */
1467+ char * selinux_src_dir = "oldroot/sys/fs/selinux" ;
1468+ cleanup_free char * selinux_dest_dir = strconcat (dest , "/fs/selinux" );
1469+ if (stat (selinux_src_dir , & sbuf ) == 0 && stat (selinux_dest_dir , & sbuf ) == 0 )
1470+ {
1471+ privileged_op (privileged_op_socket ,
1472+ PRIV_SEP_OP_BIND_MOUNT , 0 , 0 , 0 ,
1473+ selinux_src_dir , selinux_dest_dir );
1474+ }
1475+ }
1476+ else
1477+ {
1478+ /* Use system sysfs, as we share pid namespace anyway */
1479+ privileged_op (privileged_op_socket ,
1480+ PRIV_SEP_OP_BIND_MOUNT , 0 , 0 , 0 ,
1481+ "oldroot/sys" , dest );
1482+ }
1483+ break ;
1484+
14461485 case SETUP_MOUNT_TMPFS :
14471486 assert (dest != NULL );
14481487 assert (op -> perms >= 0 );
@@ -1642,6 +1681,7 @@ resolve_symlinks_in_ops (void)
16421681 case SETUP_TMP_OVERLAY_MOUNT :
16431682 case SETUP_MOUNT_PROC :
16441683 case SETUP_MOUNT_DEV :
1684+ case SETUP_MOUNT_SYS :
16451685 case SETUP_MOUNT_TMPFS :
16461686 case SETUP_MOUNT_MQUEUE :
16471687 case SETUP_MAKE_DIR :
@@ -2100,6 +2140,17 @@ parse_args_recurse (int *argcp,
21002140 op = setup_op_new (SETUP_MOUNT_PROC );
21012141 op -> dest = argv [1 ];
21022142
2143+ argv += 1 ;
2144+ argc -= 1 ;
2145+ }
2146+ else if (strcmp (arg , "--sys" ) == 0 )
2147+ {
2148+ if (argc < 2 )
2149+ die ("--sys takes an argument" );
2150+
2151+ op = setup_op_new (SETUP_MOUNT_SYS );
2152+ op -> dest = argv [1 ];
2153+
21032154 argv += 1 ;
21042155 argc -= 1 ;
21052156 }
0 commit comments