@@ -274,6 +274,97 @@ static bool contains_mount(const char **config_mounts, unsigned len, const char
274274 return false;
275275}
276276
277+ /*
278+ * Move specified mount to temporary directory
279+ */
280+ static int move_mount_to_runtmp (const char * rootfs , const char * run_tmp_dir , const char * mount_dir )
281+ {
282+ int rc ;
283+ _cleanup_free_ char * src = NULL ;
284+ _cleanup_free_ char * dest = NULL ;
285+ _cleanup_free_ char * post = NULL ;
286+ const char * ptr = NULL ;
287+
288+ rc = asprintf (& src , "%s/%s" , rootfs , mount_dir );
289+ if (rc < 0 ) {
290+ pr_perror ("Failed to allocate memory for src" );
291+ return -1 ;
292+ }
293+
294+ /* Find the second '/' to get the postfix */
295+ ptr = strchr (mount_dir , '/' );
296+ ptr ++ ;
297+ ptr = strchr (ptr , '/' );
298+ post = strdup (ptr );
299+ if (!post ) {
300+ pr_perror ("Failed to allocate memory for postfix" );
301+ return -1 ;
302+ }
303+
304+ rc = asprintf (& dest , "%s/%s" , run_tmp_dir , post );
305+ if (rc < 0 ) {
306+ pr_perror ("Failed to allocate memory for dest" );
307+ return -1 ;
308+ }
309+
310+ if (makepath (dest , 0755 ) == -1 ) {
311+ if (errno != EEXIST ) {
312+ pr_perror ("Failed to mkdir new dest" );
313+ return -1 ;
314+ }
315+ }
316+
317+ /* Move the mount to temporary directory */
318+ if ((mount (src , dest , "" , MS_MOVE , "" ) == -1 )) {
319+ pr_perror ("Failed to move mount %s to %s" , src , dest );
320+ return -1 ;
321+ }
322+
323+ return 0 ;
324+ }
325+
326+ #define RUN_PREFIX "/run/"
327+
328+ /*
329+ * Move the mounts under /run to temporary directory under /tmp (on the host)
330+ */
331+ static int adjust_run_mounts (const char * rootfs ,
332+ const char * run_tmp_dir ,
333+ const char * * config_mounts ,
334+ unsigned len )
335+ {
336+ int rc = -1 ;
337+ struct stat st = {0 };
338+ _cleanup_free_ char * run_secrets_dir = NULL ;
339+
340+ rc = asprintf (& run_secrets_dir , "%s/%s" , rootfs , "run/secrets" );
341+ if (rc < 0 ) {
342+ pr_perror ("Failed to allocate memory for run_secrets_dir" );
343+ return -1 ;
344+ }
345+
346+ /* Move /runc/secrets to temporary directory if it exists */
347+ if (stat (run_secrets_dir , & st ) == 0 && (S_ISDIR (st .st_mode ))) {
348+ if (move_mount_to_runtmp (rootfs , run_tmp_dir , "/run/secrets" ) < 0 ) {
349+ pr_perror ("Failed to move %s to %s" , run_secrets_dir , run_tmp_dir );
350+ return -1 ;
351+ }
352+ }
353+
354+ /* Move other user specified mounts under /run to temporary directory */
355+ for (unsigned i = 0 ; i < len ; i ++ ) {
356+ /* Match destinations that begin with /run/ */
357+ if (!strncmp (RUN_PREFIX , config_mounts [i ], strlen (RUN_PREFIX ))) {
358+ if (move_mount_to_runtmp (rootfs , run_tmp_dir , config_mounts [i ]) < 0 ) {
359+ pr_perror ("Failed to move %s to %s" , config_mounts [i ], run_tmp_dir );
360+ return -1 ;
361+ }
362+ }
363+ }
364+
365+ return 0 ;
366+ }
367+
277368static int prestart (const char * rootfs ,
278369 const char * id ,
279370 int pid ,
@@ -311,6 +402,15 @@ static int prestart(const char *rootfs,
311402 char run_dir [PATH_MAX ];
312403 snprintf (run_dir , PATH_MAX , "%s/run" , rootfs );
313404
405+ /* Create a temporary directory to move the /run mounts to */
406+ char temp_template [] = "/tmp/runtmp.XXXXXX" ;
407+
408+ char * run_tmp_dir = mkdtemp (temp_template );
409+ if (run_tmp_dir == NULL ) {
410+ pr_perror ("Failed to create temporary directory for /run mounts" );
411+ return -1 ;
412+ }
413+
314414 /* Create the /run directory */
315415 if (!contains_mount (config_mounts , config_mounts_len , "/run" )) {
316416 if (mkdir (run_dir , 0755 ) == -1 ) {
@@ -330,11 +430,29 @@ static int prestart(const char *rootfs,
330430 return -1 ;
331431 }
332432
333- /* Mount tmpfs at /run for systemd */
334- if (mount ("tmpfs" , run_dir , "tmpfs" , MS_NODEV |MS_NOSUID |MS_NOEXEC , options ) == -1 ) {
335- pr_perror ("Failed to mount tmpfs at /run" );
433+ /* Mount tmpfs at new temp directory */
434+ if (mount ("tmpfs" , run_tmp_dir , "tmpfs" , MS_NODEV |MS_NOSUID |MS_NOEXEC , options ) == -1 ) {
435+ pr_perror ("Failed to mount tmpfs at %s" , run_tmp_dir );
336436 return -1 ;
337437 }
438+
439+ /* Adjust the mount heirarchy under /run */
440+ if (adjust_run_mounts (rootfs , run_tmp_dir , config_mounts , config_mounts_len ) < 0 ) {
441+ pr_perror ("Failed to set heirarchy under /run" );
442+ return -1 ;
443+ }
444+
445+ /* Move temporary directory to /run */
446+ if ((mount (run_tmp_dir , run_dir , "" , MS_MOVE , "" ) == -1 )) {
447+ pr_perror ("Failed to move mount %s to %s" , run_tmp_dir , run_dir );
448+ return -1 ;
449+ }
450+ }
451+
452+ /* Remove the temp directory for /run */
453+ if (rmdir (run_tmp_dir ) < 0 ) {
454+ pr_perror ("Failed to remove %s" , run_tmp_dir );
455+ return -1 ;
338456 }
339457
340458 _cleanup_free_ char * memory_cgroup_path = NULL ;
0 commit comments