diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 5d356d4d..6af259f2 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -4107,6 +4107,21 @@ _ostree_sysroot_boot_complete (OstreeSysroot *self, GCancellable *cancellable, G if (!_ostree_sysroot_ensure_boot_fd (self, error)) return FALSE; + for (guint i = 0; i < self->deployments->len; i++) + { + OstreeDeployment *deployment = self->deployments->pdata[i]; + g_autofree char *backing_relpath + = _ostree_sysroot_get_deployment_backing_relpath (deployment); + glnx_autofd int backing_dfd = -1; + if (!glnx_opendirat (self->sysroot_fd, backing_relpath, FALSE, &backing_dfd, error)) + return FALSE; + + // We explicitly don't want this data to persist. + if (!glnx_shutil_rm_rf_at (backing_dfd, OSTREE_DEPLOYMENT_USR_TRANSIENT_DIR, cancellable, + error)) + return FALSE; + } + glnx_autofd int failure_fd = -1; g_assert_cmpint (self->boot_fd, !=, -1); if (!ot_openat_ignore_enoent (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, &failure_fd, diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 3968c38f..b47638fc 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -2108,6 +2108,8 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, OstreeDeployment *deploym if (!glnx_opendirat (self->sysroot_fd, deployment_path, TRUE, &deployment_dfd, error)) return FALSE; + g_autofree char *backing_relpath = _ostree_sysroot_get_deployment_backing_relpath (deployment); + g_autoptr (OstreeSePolicy) sepolicy = ostree_sepolicy_new_at (deployment_dfd, cancellable, error); if (!sepolicy) return FALSE; @@ -2121,7 +2123,7 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, OstreeDeployment *deploym usr_mode = stbuf.st_mode; } - const char *ovl_options = NULL; + g_autofree char *ovl_options = NULL; static const char hotfix_ovl_options[] = "lowerdir=usr,upperdir=.usr-ovl-upper,workdir=.usr-ovl-work"; g_autofree char *unlock_ovldir = NULL; @@ -2141,18 +2143,22 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, OstreeDeployment *deploym return FALSE; if (!mkdir_unmasked (deployment_dfd, ".usr-ovl-work", usr_mode, cancellable, error)) return FALSE; - ovl_options = hotfix_ovl_options; + ovl_options = g_strdup (hotfix_ovl_options); } break; case OSTREE_DEPLOYMENT_UNLOCKED_DEVELOPMENT: case OSTREE_DEPLOYMENT_UNLOCKED_TRANSIENT: { - unlock_ovldir = g_strdup ("/var/tmp/ostree-unlock-ovl.XXXXXX"); - /* We're just doing transient development/hacking? Okay, - * stick the overlayfs bits in /var/tmp. - */ - const char *development_ovl_upper; - const char *development_ovl_work; + // Holds the overlay backing data in the deployment backing dir, which + // ensures that (unlike our previous usage of /var/tmp) that it's on the same + // physical filesystem. It's valid to make /var/tmp a separate FS, but for + // this data it needs to scale to the root. + g_autofree char *usrovldir_relative + = g_build_filename (backing_relpath, OSTREE_DEPLOYMENT_USR_TRANSIENT_DIR, NULL); + // We explicitly don't want this data to persist, so if it happened + // to leak from a previous boot, ensure the dir is cleaned now. + if (!glnx_shutil_rm_rf_at (self->sysroot_fd, usrovldir_relative, cancellable, error)) + return FALSE; /* Ensure that the directory is created with the same label as `/usr` */ { @@ -2163,18 +2169,26 @@ ostree_sysroot_deployment_unlock (OstreeSysroot *self, OstreeDeployment *deploym if (!_ostree_sepolicy_preparefscreatecon (&con, sepolicy, "/usr", usr_mode, error)) return FALSE; - if (g_mkdtemp_full (unlock_ovldir, 0755) == NULL) - return glnx_throw_errno_prefix (error, "mkdtemp"); + // Create a new backing dir. + if (!mkdir_unmasked (self->sysroot_fd, usrovldir_relative, usr_mode, cancellable, error)) + return FALSE; } - development_ovl_upper = glnx_strjoina (unlock_ovldir, "/upper"); - if (!mkdir_unmasked (AT_FDCWD, development_ovl_upper, usr_mode, cancellable, error)) + // Open a fd for our new dir + int ovldir_fd = -1; + if (!glnx_opendirat (self->sysroot_fd, usrovldir_relative, FALSE, &ovldir_fd, error)) return FALSE; - development_ovl_work = glnx_strjoina (unlock_ovldir, "/work"); - if (!mkdir_unmasked (AT_FDCWD, development_ovl_work, usr_mode, cancellable, error)) + + // Create the work and upper dirs there + if (!mkdir_unmasked (ovldir_fd, "upper", usr_mode, cancellable, error)) return FALSE; - ovl_options = glnx_strjoina ("lowerdir=usr,upperdir=", development_ovl_upper, - ",workdir=", development_ovl_work); + if (!mkdir_unmasked (ovldir_fd, "work", usr_mode, cancellable, error)) + return FALSE; + + // TODO investigate depending on the new mount API with overlayfs + ovl_options = g_strdup_printf ("lowerdir=usr,upperdir=/proc/self/fd/%d/upper" + ",workdir=/proc/self/fd/%d/work", + ovldir_fd, ovldir_fd); } } diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h index ceeb1a92..5003d47d 100644 --- a/src/libotcore/otcore.h +++ b/src/libotcore/otcore.h @@ -89,6 +89,8 @@ ComposefsConfig *otcore_load_composefs_config (const char *cmdline, GKeyFile *co #define OSTREE_DEPLOYMENT_BACKING_DIR "backing" // The directory holding the root overlayfs #define OSTREE_DEPLOYMENT_ROOT_TRANSIENT_DIR "root-transient" +// The directory holding overlayfs for /usr (ostree admin unlock) +#define OSTREE_DEPLOYMENT_USR_TRANSIENT_DIR "usr-transient" // Written by ostree admin unlock --hotfix, read by ostree-prepare-root #define OTCORE_HOTFIX_USR_OVL_WORK ".usr-ovl-work"