From 575563abc59a62b08402d46f7f0076e59f947423 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 10 Jul 2024 16:38:48 -0400 Subject: [PATCH] prepare-root: Add `ostree.prepare-root.composefs` We have a use case for overriding the composefs state via the kernel commandline; see e.g. https://gitlab.com/fedora/bootc/tracker/-/issues/27 Signed-off-by: Colin Walters --- man/ostree-prepare-root.xml | 12 ++++++++++++ src/libostree/ostree-sysroot-deploy.c | 2 +- src/libotcore/otcore-prepare-root.c | 23 ++++++++++++++++++++++- src/libotcore/otcore.h | 2 +- src/switchroot/ostree-prepare-root.c | 2 +- tests/inst/src/composefs.rs | 24 +++++++++++++++++++++++- 6 files changed, 60 insertions(+), 5 deletions(-) diff --git a/man/ostree-prepare-root.xml b/man/ostree-prepare-root.xml index 9117c340bd..8a682e7315 100644 --- a/man/ostree-prepare-root.xml +++ b/man/ostree-prepare-root.xml @@ -153,6 +153,18 @@ License along with this library. If not, see . commit must match the target composefs image. + + + The following kernel commandline parameters are also parsed: + + + + ostree.prepare-root.composefs + This accepts the same values as composefs.enabled above, and overrides the config file (if present). + For example, specifying ostree.prepare-root.composefs=0 will disable composefs, even if it is enabled by default in the initrd config. + + + diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index f7ca2dd4a3..4efaae6e86 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -655,7 +655,7 @@ checkout_deployment_tree (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeploy // However, we don't load the keys here, because they may not exist, such // as in the initial deploy g_autoptr (ComposefsConfig) composefs_config - = otcore_load_composefs_config (prepare_root_config, FALSE, error); + = otcore_load_composefs_config ("", prepare_root_config, FALSE, error); if (!composefs_config) return glnx_prefix_error (error, "Reading composefs config"); diff --git a/src/libotcore/otcore-prepare-root.c b/src/libotcore/otcore-prepare-root.c index f76db04a33..2c09b916e8 100644 --- a/src/libotcore/otcore-prepare-root.c +++ b/src/libotcore/otcore-prepare-root.c @@ -161,8 +161,11 @@ otcore_free_composefs_config (ComposefsConfig *config) // Parse the [composefs] section of the prepare-root.conf. ComposefsConfig * -otcore_load_composefs_config (GKeyFile *config, gboolean load_keys, GError **error) +otcore_load_composefs_config (const char *cmdline, GKeyFile *config, gboolean load_keys, GError **error) { + g_assert (cmdline); + g_assert (config); + GLNX_AUTO_PREFIX_ERROR ("Loading composefs config", error); g_autoptr (ComposefsConfig) ret = g_new0 (ComposefsConfig, 1); @@ -214,5 +217,23 @@ otcore_load_composefs_config (GKeyFile *config, gboolean load_keys, GError **err return glnx_null_throw (error, "public key file specified, but no public keys found"); } + g_autofree char *ostree_composefs + = otcore_find_proc_cmdline_key (cmdline, "ostree.prepare-root.composefs"); + if (ostree_composefs) + { + if (g_strcmp0 (ostree_composefs, "signed") == 0) + { + ret->enabled = OT_TRISTATE_YES; + ret->is_signed = true; + } + else + { + // The other states force off signatures + ret->is_signed = false; + if (!_ostree_parse_tristate (ostree_composefs, &ret->enabled, error)) + return FALSE; + } + } + return g_steal_pointer (&ret); } diff --git a/src/libotcore/otcore.h b/src/libotcore/otcore.h index fc6b81ca1a..39b9d98c7e 100644 --- a/src/libotcore/otcore.h +++ b/src/libotcore/otcore.h @@ -59,7 +59,7 @@ typedef struct void otcore_free_composefs_config (ComposefsConfig *config); G_DEFINE_AUTOPTR_CLEANUP_FUNC (ComposefsConfig, otcore_free_composefs_config) -ComposefsConfig *otcore_load_composefs_config (GKeyFile *config, gboolean load_keys, +ComposefsConfig *otcore_load_composefs_config (const char *cmdline, GKeyFile *config, gboolean load_keys, GError **error); // Our directory with transient state (eventually /run/ostree-booted should be a link to diff --git a/src/switchroot/ostree-prepare-root.c b/src/switchroot/ostree-prepare-root.c index c2bee87d5c..7d1b8ac822 100644 --- a/src/switchroot/ostree-prepare-root.c +++ b/src/switchroot/ostree-prepare-root.c @@ -290,7 +290,7 @@ main (int argc, char *argv[]) // We always parse the composefs config, because we want to detect and error // out if it's enabled, but not supported at compile time. g_autoptr (ComposefsConfig) composefs_config - = otcore_load_composefs_config (config, TRUE, &error); + = otcore_load_composefs_config (kernel_cmdline, config, TRUE, &error); if (!composefs_config) errx (EXIT_FAILURE, "%s", error->message); diff --git a/tests/inst/src/composefs.rs b/tests/inst/src/composefs.rs index fa6d3d374a..eddccd1d6e 100644 --- a/tests/inst/src/composefs.rs +++ b/tests/inst/src/composefs.rs @@ -131,6 +131,19 @@ fn verify_composefs_signed(sh: &xshell::Shell, metadata: &glib::VariantDict) -> Ok(()) } +fn verify_disable_composefs(sh: &xshell::Shell, metadata: &glib::VariantDict) -> Result<()> { + assert_eq!( + metadata + .lookup::("composefs") + .unwrap() + .unwrap_or_default(), + false + ); + let fstype = cmd!(sh, "findmnt -n -o FSTYPE /").read()?; + assert_ne!(fstype.as_str(), "overlay"); + Ok(()) +} + pub(crate) fn itest_composefs() -> Result<()> { let sh = &xshell::Shell::new()?; let mark = match crate::test::get_reboot_mark()? { @@ -165,7 +178,16 @@ pub(crate) fn itest_composefs() -> Result<()> { Err(reboot("2"))?; Ok(()) } - "2" => verify_composefs_signed(sh, &metadata), + "2" => { + verify_composefs_signed(sh, &metadata)?; + cmd!( + sh, + "rpm-ostree kargs --append=ostree.prepare-root.composefs=0" + ) + .run()?; + Err(reboot("3")) + } + "3" => verify_disable_composefs(sh, &metadata), o => anyhow::bail!("Unrecognized reboot mark {o}"), } }