diff --git a/.gitignore b/.gitignore index 869130b..52ddd23 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/libostree-2022.1.tar.xz +SOURCES/libostree-2022.2.tar.xz diff --git a/.ostree.metadata b/.ostree.metadata index 7b8dd7f..56ab50b 100644 --- a/.ostree.metadata +++ b/.ostree.metadata @@ -1 +1 @@ -31380c30eeb93de7d9850fa8a071b3fbc3f3acee SOURCES/libostree-2022.1.tar.xz +9f1cc3796da8b7892a8ef930a5086d4ff42c475f SOURCES/libostree-2022.2.tar.xz diff --git a/SOURCES/0001-Add-an-ostree-boot-complete.service-to-propagate-sta.patch b/SOURCES/0001-Add-an-ostree-boot-complete.service-to-propagate-sta.patch new file mode 100644 index 0000000..2cf14d7 --- /dev/null +++ b/SOURCES/0001-Add-an-ostree-boot-complete.service-to-propagate-sta.patch @@ -0,0 +1,374 @@ +From a6d45dc165e48e2a463880ebb90f34c2b9d3c4ce Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Fri, 22 Apr 2022 18:46:28 -0400 +Subject: [PATCH 1/6] Add an `ostree-boot-complete.service` to propagate + staging failures + +Quite a while ago we added staged deployments, which solved +a bunch of issues around the `/etc` merge. However...a persistent +problem since then is that any failures in that process that +happened in the *previous* boot are not very visible. + +We ship custom code in `rpm-ostree status` to query the previous +journal. But that has a few problems - one is that on systems +that have been up a while, that failure message may even get +rotated out. And second, some systems may not even have a persistent +journal at all. + +A general thing we do in e.g. Fedora CoreOS testing is to check +for systemd unit failures. We do that both in our automated tests, +and we even ship code that displays them on ssh logins. And beyond +that obviously a lot of other projects do the same; it's easy via +`systemctl --failed`. + +So to make failures more visible, change our `ostree-finalize-staged.service` +to have an internal wrapper around the process that "catches" any +errors, and copies the error message into a file in `/boot/ostree`. + +Then, a new `ostree-boot-complete.service` looks for this file on +startup and re-emits the error message, and fails. + +It also deletes the file. The rationale is to avoid *continually* +warning. For example we need to handle the case when an upgrade +process creates a new staged deployment. Now, we could change the +ostree core code to delete the warning file when that happens instead, +but this is trying to be a conservative change. + +This should make failures here much more visible as is. +--- + Makefile-boot.am | 2 + + Makefile-ostree.am | 1 + + src/boot/ostree-boot-complete.service | 33 +++++++++++ + src/libostree/ostree-cmdprivate.c | 1 + + src/libostree/ostree-cmdprivate.h | 1 + + src/libostree/ostree-impl-system-generator.c | 2 + + src/libostree/ostree-sysroot-deploy.c | 62 ++++++++++++++++++-- + src/libostree/ostree-sysroot-private.h | 7 +++ + src/libostree/ostree-sysroot.c | 2 + + src/ostree/ot-admin-builtin-boot-complete.c | 58 ++++++++++++++++++ + src/ostree/ot-admin-builtins.h | 1 + + src/ostree/ot-builtin-admin.c | 3 + + tests/kolainst/destructive/staged-deploy.sh | 12 ++++ + 13 files changed, 181 insertions(+), 4 deletions(-) + create mode 100644 src/boot/ostree-boot-complete.service + create mode 100644 src/ostree/ot-admin-builtin-boot-complete.c + +diff --git a/Makefile-boot.am b/Makefile-boot.am +index ec10a0d6..e42e5180 100644 +--- a/Makefile-boot.am ++++ b/Makefile-boot.am +@@ -38,6 +38,7 @@ endif + if BUILDOPT_SYSTEMD + systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \ + src/boot/ostree-remount.service \ ++ src/boot/ostree-boot-complete.service \ + src/boot/ostree-finalize-staged.service \ + src/boot/ostree-finalize-staged.path \ + $(NULL) +@@ -64,6 +65,7 @@ endif + EXTRA_DIST += src/boot/dracut/module-setup.sh \ + src/boot/dracut/ostree.conf \ + src/boot/mkinitcpio \ ++ src/boot/ostree-boot-complete.service \ + src/boot/ostree-prepare-root.service \ + src/boot/ostree-finalize-staged.path \ + src/boot/ostree-remount.service \ +diff --git a/Makefile-ostree.am b/Makefile-ostree.am +index 82af1681..0fe2c5f8 100644 +--- a/Makefile-ostree.am ++++ b/Makefile-ostree.am +@@ -70,6 +70,7 @@ ostree_SOURCES += \ + src/ostree/ot-admin-builtin-diff.c \ + src/ostree/ot-admin-builtin-deploy.c \ + src/ostree/ot-admin-builtin-finalize-staged.c \ ++ src/ostree/ot-admin-builtin-boot-complete.c \ + src/ostree/ot-admin-builtin-undeploy.c \ + src/ostree/ot-admin-builtin-instutil.c \ + src/ostree/ot-admin-builtin-cleanup.c \ +diff --git a/src/boot/ostree-boot-complete.service b/src/boot/ostree-boot-complete.service +new file mode 100644 +index 00000000..5c09fdc9 +--- /dev/null ++++ b/src/boot/ostree-boot-complete.service +@@ -0,0 +1,33 @@ ++# Copyright (C) 2022 Red Hat, Inc. ++# ++# This library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2 of the License, or (at your option) any later version. ++# ++# This library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this library. If not, see . ++ ++[Unit] ++Description=OSTree Complete Boot ++Documentation=man:ostree(1) ++# For now, this is the only condition on which we start, but it's ++# marked as a triggering condition in case in the future we want ++# to do something else. ++ConditionPathExists=|/boot/ostree/finalize-failure.stamp ++RequiresMountsFor=/boot ++# Ensure that we propagate the failure into the current boot before ++# any further finalization attempts. ++Before=ostree-finalize-staged.service ++ ++[Service] ++Type=oneshot ++# To write to /boot while keeping it read-only ++MountFlags=slave ++RemainAfterExit=yes ++ExecStart=/usr/bin/ostree admin boot-complete +diff --git a/src/libostree/ostree-cmdprivate.c b/src/libostree/ostree-cmdprivate.c +index c9a6e2e1..f6c114f4 100644 +--- a/src/libostree/ostree-cmdprivate.c ++++ b/src/libostree/ostree-cmdprivate.c +@@ -51,6 +51,7 @@ ostree_cmd__private__ (void) + _ostree_repo_static_delta_delete, + _ostree_repo_verify_bindings, + _ostree_sysroot_finalize_staged, ++ _ostree_sysroot_boot_complete, + }; + + return &table; +diff --git a/src/libostree/ostree-cmdprivate.h b/src/libostree/ostree-cmdprivate.h +index 46452ebd..17f943c8 100644 +--- a/src/libostree/ostree-cmdprivate.h ++++ b/src/libostree/ostree-cmdprivate.h +@@ -33,6 +33,7 @@ typedef struct { + gboolean (* ostree_static_delta_delete) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error); + gboolean (* ostree_repo_verify_bindings) (const char *collection_id, const char *ref_name, GVariant *commit, GError **error); + gboolean (* ostree_finalize_staged) (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); ++ gboolean (* ostree_boot_complete) (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); + } OstreeCmdPrivateVTable; + + /* Note this not really "public", we just export the symbol, but not the header */ +diff --git a/src/libostree/ostree-impl-system-generator.c b/src/libostree/ostree-impl-system-generator.c +index 769f0cbd..92d71605 100644 +--- a/src/libostree/ostree-impl-system-generator.c ++++ b/src/libostree/ostree-impl-system-generator.c +@@ -134,6 +134,8 @@ require_internal_units (const char *normal_dir, + return FALSE; + if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-finalize-staged.path", normal_dir_dfd, "multi-user.target.wants/ostree-finalize-staged.path") < 0) + return glnx_throw_errno_prefix (error, "symlinkat"); ++ if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-boot-complete.service", normal_dir_dfd, "multi-user.target.wants/ostree-boot-complete.service") < 0) ++ return glnx_throw_errno_prefix (error, "symlinkat"); + + return TRUE; + #else +diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c +index b7cc232f..fc5916d8 100644 +--- a/src/libostree/ostree-sysroot-deploy.c ++++ b/src/libostree/ostree-sysroot-deploy.c +@@ -3255,10 +3255,10 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self, + } + + /* Invoked at shutdown time by ostree-finalize-staged.service */ +-gboolean +-_ostree_sysroot_finalize_staged (OstreeSysroot *self, +- GCancellable *cancellable, +- GError **error) ++static gboolean ++_ostree_sysroot_finalize_staged_inner (OstreeSysroot *self, ++ GCancellable *cancellable, ++ GError **error) + { + /* It's totally fine if there's no staged deployment; perhaps down the line + * though we could teach the ostree cmdline to tell systemd to activate the +@@ -3355,9 +3355,63 @@ _ostree_sysroot_finalize_staged (OstreeSysroot *self, + if (!ostree_sysroot_prepare_cleanup (self, cancellable, error)) + return FALSE; + ++ // Cleanup will have closed some FDs, re-ensure writability ++ if (!_ostree_sysroot_ensure_writable (self, error)) ++ return FALSE; ++ + return TRUE; + } + ++/* Invoked at shutdown time by ostree-finalize-staged.service */ ++gboolean ++_ostree_sysroot_finalize_staged (OstreeSysroot *self, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ g_autoptr(GError) finalization_error = NULL; ++ if (!_ostree_sysroot_ensure_boot_fd (self, error)) ++ return FALSE; ++ if (!_ostree_sysroot_finalize_staged_inner (self, cancellable, &finalization_error)) ++ { ++ g_autoptr(GError) writing_error = NULL; ++ g_assert_cmpint (self->boot_fd, !=, -1); ++ if (!glnx_file_replace_contents_at (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, ++ (guint8*)finalization_error->message, -1, ++ 0, cancellable, &writing_error)) ++ { ++ // We somehow failed to write the failure message...that's not great. Maybe ENOSPC on /boot. ++ g_printerr ("Failed to write %s: %s\n", _OSTREE_FINALIZE_STAGED_FAILURE_PATH, writing_error->message); ++ } ++ g_propagate_error (error, g_steal_pointer (&finalization_error)); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++/* Invoked at bootup time by ostree-boot-complete.service */ ++gboolean ++_ostree_sysroot_boot_complete (OstreeSysroot *self, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ if (!_ostree_sysroot_ensure_boot_fd (self, error)) ++ return FALSE; ++ ++ glnx_autofd int failure_fd = -1; ++ if (!ot_openat_ignore_enoent (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, &failure_fd, error)) ++ return FALSE; ++ // If we didn't find a failure log, then there's nothing to do right now. ++ // (Actually this unit shouldn't even be invoked, but we may do more in the future) ++ if (failure_fd == -1) ++ return TRUE; ++ g_autofree char *failure_data = glnx_fd_readall_utf8 (failure_fd, NULL, cancellable, error); ++ if (failure_data == NULL) ++ return glnx_prefix_error (error, "Reading from %s", _OSTREE_FINALIZE_STAGED_FAILURE_PATH); ++ // Remove the file; we don't want to continually error out. ++ (void) unlinkat (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, 0); ++ return glnx_throw (error, "ostree-finalize-staged.service failed on previous boot: %s", failure_data); ++} ++ + /** + * ostree_sysroot_deployment_set_kargs: + * @self: Sysroot +diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h +index cb34eeb3..a49a406c 100644 +--- a/src/libostree/ostree-sysroot-private.h ++++ b/src/libostree/ostree-sysroot-private.h +@@ -96,6 +96,9 @@ struct OstreeSysroot { + #define _OSTREE_SYSROOT_BOOT_INITRAMFS_OVERLAYS "ostree/initramfs-overlays" + #define _OSTREE_SYSROOT_INITRAMFS_OVERLAYS "boot/" _OSTREE_SYSROOT_BOOT_INITRAMFS_OVERLAYS + ++// Relative to /boot, consumed by ostree-boot-complete.service ++#define _OSTREE_FINALIZE_STAGED_FAILURE_PATH "ostree/finalize-failure.stamp" ++ + gboolean + _ostree_sysroot_ensure_writable (OstreeSysroot *self, + GError **error); +@@ -142,6 +145,10 @@ gboolean + _ostree_sysroot_finalize_staged (OstreeSysroot *self, + GCancellable *cancellable, + GError **error); ++gboolean ++_ostree_sysroot_boot_complete (OstreeSysroot *self, ++ GCancellable *cancellable, ++ GError **error); + + OstreeDeployment * + _ostree_sysroot_deserialize_deployment_from_variant (GVariant *v, +diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c +index 266a2975..f083f950 100644 +--- a/src/libostree/ostree-sysroot.c ++++ b/src/libostree/ostree-sysroot.c +@@ -356,6 +356,8 @@ _ostree_sysroot_ensure_writable (OstreeSysroot *self, + ostree_sysroot_unload (self); + if (!ensure_sysroot_fd (self, error)) + return FALSE; ++ if (!_ostree_sysroot_ensure_boot_fd (self, error)) ++ return FALSE; + + return TRUE; + } +diff --git a/src/ostree/ot-admin-builtin-boot-complete.c b/src/ostree/ot-admin-builtin-boot-complete.c +new file mode 100644 +index 00000000..6e1052f5 +--- /dev/null ++++ b/src/ostree/ot-admin-builtin-boot-complete.c +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. ++ * ++ * SPDX-License-Identifier: LGPL-2.0+ ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see . ++ */ ++ ++#include "config.h" ++ ++#include ++ ++#include "ot-main.h" ++#include "ot-admin-builtins.h" ++#include "ot-admin-functions.h" ++#include "ostree.h" ++#include "otutil.h" ++ ++#include "ostree-cmdprivate.h" ++ ++static GOptionEntry options[] = { ++ { NULL } ++}; ++ ++gboolean ++ot_admin_builtin_boot_complete (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) ++{ ++ /* Just a sanity check; we shouldn't be called outside of the service though. ++ */ ++ struct stat stbuf; ++ if (fstatat (AT_FDCWD, OSTREE_PATH_BOOTED, &stbuf, 0) < 0) ++ return TRUE; ++ // We must have been invoked via systemd which should have set up a mount namespace. ++ g_assert (getenv ("INVOCATION_ID")); ++ ++ g_autoptr(GOptionContext) context = g_option_context_new (""); ++ g_autoptr(OstreeSysroot) sysroot = NULL; ++ if (!ostree_admin_option_context_parse (context, options, &argc, &argv, ++ OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER, ++ invocation, &sysroot, cancellable, error)) ++ return FALSE; ++ ++ if (!ostree_cmd__private__()->ostree_boot_complete (sysroot, cancellable, error)) ++ return FALSE; ++ ++ return TRUE; ++} +diff --git a/src/ostree/ot-admin-builtins.h b/src/ostree/ot-admin-builtins.h +index d32b617e..8d9451be 100644 +--- a/src/ostree/ot-admin-builtins.h ++++ b/src/ostree/ot-admin-builtins.h +@@ -39,6 +39,7 @@ BUILTINPROTO(deploy); + BUILTINPROTO(cleanup); + BUILTINPROTO(pin); + BUILTINPROTO(finalize_staged); ++BUILTINPROTO(boot_complete); + BUILTINPROTO(unlock); + BUILTINPROTO(status); + BUILTINPROTO(set_origin); +diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c +index e0d2a60c..af09a614 100644 +--- a/src/ostree/ot-builtin-admin.c ++++ b/src/ostree/ot-builtin-admin.c +@@ -43,6 +43,9 @@ static OstreeCommand admin_subcommands[] = { + { "finalize-staged", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, + ot_admin_builtin_finalize_staged, + "Internal command to run at shutdown time" }, ++ { "boot-complete", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN, ++ ot_admin_builtin_boot_complete, ++ "Internal command to run at boot after an update was applied" }, + { "init-fs", OSTREE_BUILTIN_FLAG_NO_REPO, + ot_admin_builtin_init_fs, + "Initialize a root filesystem" }, diff --git a/SOURCES/0002-libarchive-Handle-archive_entry_symlink-returning-NU.patch b/SOURCES/0002-libarchive-Handle-archive_entry_symlink-returning-NU.patch new file mode 100644 index 0000000..7c283e9 --- /dev/null +++ b/SOURCES/0002-libarchive-Handle-archive_entry_symlink-returning-NU.patch @@ -0,0 +1,40 @@ +From e5b45f861a4d5738679f37d46ebca6e171bb3212 Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Mon, 4 Apr 2022 10:25:35 -0400 +Subject: [PATCH 2/6] libarchive: Handle `archive_entry_symlink()` returning + NULL + +The `archive_entry_symlink()` API can definitely return `NULL`, +reading through the libarchive sources. + +I hit this in the wild when using old ostree-ext to try to unpack +a chunked archive. + +I didn't try to characterize this more, and sorry no unit test right +now. +--- + src/libostree/ostree-repo-libarchive.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c +index 679aa44d..631c6d4b 100644 +--- a/src/libostree/ostree-repo-libarchive.c ++++ b/src/libostree/ostree-repo-libarchive.c +@@ -146,8 +146,12 @@ file_info_from_archive_entry (struct archive_entry *entry) + + g_autoptr(GFileInfo) info = _ostree_stbuf_to_gfileinfo (&stbuf); + if (S_ISLNK (stbuf.st_mode)) +- g_file_info_set_attribute_byte_string (info, "standard::symlink-target", +- archive_entry_symlink (entry)); ++ { ++ const char *target = archive_entry_symlink (entry); ++ if (target != NULL) ++ g_file_info_set_attribute_byte_string (info, "standard::symlink-target", ++ target); ++ } + + return g_steal_pointer (&info); + } +-- +2.31.1 + diff --git a/SOURCES/0003-repo-Factor-out-_ostree_repo_auto_transaction_new.patch b/SOURCES/0003-repo-Factor-out-_ostree_repo_auto_transaction_new.patch new file mode 100644 index 0000000..69c5548 --- /dev/null +++ b/SOURCES/0003-repo-Factor-out-_ostree_repo_auto_transaction_new.patch @@ -0,0 +1,82 @@ +From 4a997ae08605ebe6ca02d9f422082f954e667a6c Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Sat, 30 Apr 2022 12:20:11 +0100 +Subject: [PATCH 3/6] repo: Factor out _ostree_repo_auto_transaction_new() + +This will allow the direct allocation in +ostree_repo_prepare_transaction() to be replaced with a call to this +function, avoiding breaking encapsulation. + +Signed-off-by: Simon McVittie +(cherry picked from commit 540e60c3e3ace66dd4e6cf825488fc918260a642) +--- + src/libostree/ostree-repo-private.h | 4 ++++ + src/libostree/ostree-repo.c | 32 ++++++++++++++++++++++++----- + 2 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h +index 988c2179..96253e77 100644 +--- a/src/libostree/ostree-repo-private.h ++++ b/src/libostree/ostree-repo-private.h +@@ -554,4 +554,8 @@ GType _ostree_repo_auto_transaction_get_type (void); + + G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_unref); + ++/* Internal function to break a circular dependency: ++ * should not be made into public API, even if the rest is */ ++OstreeRepoAutoTransaction *_ostree_repo_auto_transaction_new (OstreeRepo *repo); ++ + G_END_DECLS +diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c +index a27591b3..f6bffd60 100644 +--- a/src/libostree/ostree-repo.c ++++ b/src/libostree/ostree-repo.c +@@ -709,6 +709,32 @@ ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *auto_lock) + } + } + ++/** ++ * _ostree_repo_auto_transaction_new: ++ * @repo: (not nullable): an #OsreeRepo object ++ * @cancellable: Cancellable ++ * @error: a #GError ++ * ++ * Return a guard for a transaction in @repo. ++ * ++ * Do not call this function outside the OstreeRepo transaction implementation. ++ * Use _ostree_repo_auto_transaction_start() instead. ++ * ++ * Returns: (transfer full): an #OstreeRepoAutoTransaction guard on success, ++ * %NULL otherwise. ++ */ ++OstreeRepoAutoTransaction * ++_ostree_repo_auto_transaction_new (OstreeRepo *repo) ++{ ++ g_assert (repo != NULL); ++ ++ OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction)); ++ txn->atomic_refcount = 1; ++ txn->repo = g_object_ref (repo); ++ ++ return g_steal_pointer (&txn); ++} ++ + /** + * _ostree_repo_auto_transaction_start: + * @repo: (not nullable): an #OsreeRepo object +@@ -730,11 +756,7 @@ _ostree_repo_auto_transaction_start (OstreeRepo *repo, + if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) + return NULL; + +- OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction)); +- txn->atomic_refcount = 1; +- txn->repo = g_object_ref (repo); +- +- return g_steal_pointer (&txn); ++ return _ostree_repo_auto_transaction_new (repo); + } + + /** +-- +2.31.1 + diff --git a/SOURCES/0004-repo-Correctly-initialize-refcount-of-temporary-tran.patch b/SOURCES/0004-repo-Correctly-initialize-refcount-of-temporary-tran.patch new file mode 100644 index 0000000..3e8c33b --- /dev/null +++ b/SOURCES/0004-repo-Correctly-initialize-refcount-of-temporary-tran.patch @@ -0,0 +1,39 @@ +From 51c7960bea081446ad217e9725408ce5cb531157 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Sat, 30 Apr 2022 12:53:42 +0100 +Subject: [PATCH 4/6] repo: Correctly initialize refcount of temporary + transaction + +Previously, the reference count was left uninitialized as a result of +bypassing the constructor, and the intended abort-on-error usually +wouldn't have happened. + +Fixes: 8a9737a "repo/private: move OstreeRepoAutoTransaction to a boxed type" +Resolves: https://github.com/ostreedev/ostree/issues/2592 +Signed-off-by: Simon McVittie +(cherry picked from commit 71304e854cdb344adb8b1ae7866929fbdde6c327) +--- + src/libostree/ostree-repo-commit.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c +index 5b16be5b..dba98c32 100644 +--- a/src/libostree/ostree-repo-commit.c ++++ b/src/libostree/ostree-repo-commit.c +@@ -1688,10 +1688,10 @@ ostree_repo_prepare_transaction (OstreeRepo *self, + g_debug ("Preparing transaction in repository %p", self); + + /* Set up to abort the transaction if we return early from this function. +- * This needs to be manually built here due to a circular dependency. */ +- g_autoptr(OstreeRepoAutoTransaction) txn = g_malloc(sizeof(OstreeRepoAutoTransaction)); ++ * We can't call _ostree_repo_auto_transaction_start() here, because that ++ * would be a circular dependency; use the lower-level version instead. */ ++ g_autoptr(OstreeRepoAutoTransaction) txn = _ostree_repo_auto_transaction_new (self); + g_assert (txn != NULL); +- txn->repo = self; + + memset (&self->txn.stats, 0, sizeof (OstreeRepoTransactionStats)); + +-- +2.31.1 + diff --git a/SOURCES/0005-deploy-Try-to-rebuild-policy-in-new-deployment-if-ne.patch b/SOURCES/0005-deploy-Try-to-rebuild-policy-in-new-deployment-if-ne.patch new file mode 100644 index 0000000..59f86fb --- /dev/null +++ b/SOURCES/0005-deploy-Try-to-rebuild-policy-in-new-deployment-if-ne.patch @@ -0,0 +1,172 @@ +From 62e62bcfd8a1770b906faed083d11e451a50f566 Mon Sep 17 00:00:00 2001 +From: Ondrej Mosnacek +Date: Wed, 9 Mar 2022 15:27:11 +0100 +Subject: [PATCH 5/6] deploy: Try to rebuild policy in new deployment if needed + +Whenever the user has SELinux enabled and has any local +modules/modifications installed, it is necessary to rebuild the policy +in the final deployment, otherwise ostree will leave the binary policy +files unchanged from last deployment as it detects difference against +the base content (in rpm-ostree case this is the RPM content). + +To avoid the situation where the policy binaries go stale once any local +customization of the policy is made, try to rebuild the policy as part +of sysroot_finalize_deployment(). Use the special +--rebuild-if-modules-changed switch, which detects if the input module +files have changed relative to last time the policy was built and skips +the most time-consuming part of the rebuild process if modules are +unchanged (thus making this a relatively cheap operation if the user +hasn't made any modifications to the shipped policy). + +As suggested by Jonathan Lebon, this uses bubblewrap (via +g_spawn_sync()) to perform the rebuild inside the deployment's +filesystem tree, which also means that ostree will have a runtime +dependency on bubblewrap. + +Partially addresses: https://github.com/coreos/fedora-coreos-tracker/issues/701 + +Signed-off-by: Ondrej Mosnacek +(cherry picked from commit edb4f3893474736156c654aa43bdbf3784991811) +--- + ci/gh-install.sh | 1 + + src/libostree/ostree-sysroot-deploy.c | 117 ++++++++++++++++++++++++++ + 2 files changed, 118 insertions(+) + +diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c +index fc5916d8..a44721d8 100644 +--- a/src/libostree/ostree-sysroot-deploy.c ++++ b/src/libostree/ostree-sysroot-deploy.c +@@ -2830,6 +2830,118 @@ get_var_dfd (OstreeSysroot *self, + return glnx_opendirat (base_dfd, base_path, TRUE, ret_fd, error); + } + ++#ifdef HAVE_SELINUX ++static void ++child_setup_fchdir (gpointer data) ++{ ++ int fd = (int) (uintptr_t) data; ++ int rc __attribute__((unused)); ++ ++ rc = fchdir (fd); ++} ++ ++/* ++ * Derived from rpm-ostree's rust/src/bwrap.rs ++ */ ++static gboolean ++run_in_deployment (int deployment_dfd, ++ const gchar * const *child_argv, ++ gsize child_argc, ++ gint *exit_status, ++ gchar **stdout, ++ GError **error) ++{ ++ static const gchar * const COMMON_ARGV[] = { ++ "/usr/bin/bwrap", ++ "--dev", "/dev", "--proc", "/proc", "--dir", "/run", "--dir", "/tmp", ++ "--chdir", "/", ++ "--die-with-parent", ++ "--unshare-pid", ++ "--unshare-uts", ++ "--unshare-ipc", ++ "--unshare-cgroup-try", ++ "--ro-bind", "/sys/block", "/sys/block", ++ "--ro-bind", "/sys/bus", "/sys/bus", ++ "--ro-bind", "/sys/class", "/sys/class", ++ "--ro-bind", "/sys/dev", "/sys/dev", ++ "--ro-bind", "/sys/devices", "/sys/devices", ++ "--bind", "usr", "/usr", ++ "--bind", "etc", "/etc", ++ "--bind", "var", "/var", ++ "--symlink", "/usr/lib", "/lib", ++ "--symlink", "/usr/lib32", "/lib32", ++ "--symlink", "/usr/lib64", "/lib64", ++ "--symlink", "/usr/bin", "/bin", ++ "--symlink", "/usr/sbin", "/sbin", ++ }; ++ static const gsize COMMON_ARGC = sizeof (COMMON_ARGV) / sizeof (*COMMON_ARGV); ++ ++ gsize i; ++ GPtrArray *args = g_ptr_array_sized_new (COMMON_ARGC + child_argc + 1); ++ g_autofree gchar **args_raw = NULL; ++ ++ for (i = 0; i < COMMON_ARGC; i++) ++ g_ptr_array_add (args, (gchar *) COMMON_ARGV[i]); ++ ++ for (i = 0; i < child_argc; i++) ++ g_ptr_array_add (args, (gchar *) child_argv[i]); ++ ++ g_ptr_array_add (args, NULL); ++ ++ args_raw = (gchar **) g_ptr_array_free (args, FALSE); ++ ++ return g_spawn_sync (NULL, args_raw, NULL, 0, &child_setup_fchdir, ++ (gpointer) (uintptr_t) deployment_dfd, ++ stdout, NULL, exit_status, error); ++} ++ ++/* ++ * Run semodule to check if the module content changed after merging /etc ++ * and rebuild the policy if needed. ++ */ ++static gboolean ++sysroot_finalize_selinux_policy (int deployment_dfd, GError **error) ++{ ++ struct stat stbuf; ++ gint exit_status; ++ g_autofree gchar *stdout = NULL; ++ ++ if (!glnx_fstatat_allow_noent (deployment_dfd, "etc/selinux/config", &stbuf, ++ AT_SYMLINK_NOFOLLOW, error)) ++ return FALSE; ++ ++ /* Skip the SELinux policy refresh if /etc/selinux/config doesn't exist. */ ++ if (errno != 0) ++ return TRUE; ++ ++ /* ++ * Skip the SELinux policy refresh if the --rebuild-if-modules-changed ++ * flag is not supported by semodule. ++ */ ++ static const gchar * const SEMODULE_HELP_ARGV[] = { ++ "semodule", "--help" ++ }; ++ static const gsize SEMODULE_HELP_ARGC = sizeof (SEMODULE_HELP_ARGV) / sizeof (*SEMODULE_HELP_ARGV); ++ if (!run_in_deployment (deployment_dfd, SEMODULE_HELP_ARGV, ++ SEMODULE_HELP_ARGC, &exit_status, &stdout, error)) ++ return FALSE; ++ if (!g_spawn_check_exit_status (exit_status, error)) ++ return FALSE; ++ if (!strstr(stdout, "--rebuild-if-modules-changed")) ++ return TRUE; ++ ++ static const gchar * const SEMODULE_REBUILD_ARGV[] = { ++ "semodule", "-N", "--rebuild-if-modules-changed" ++ }; ++ static const gsize SEMODULE_REBUILD_ARGC = sizeof (SEMODULE_REBUILD_ARGV) / sizeof (*SEMODULE_REBUILD_ARGV); ++ ++ if (!run_in_deployment (deployment_dfd, SEMODULE_REBUILD_ARGV, ++ SEMODULE_REBUILD_ARGC, &exit_status, NULL, error)) ++ return FALSE; ++ return g_spawn_check_exit_status (exit_status, error); ++} ++#endif /* HAVE_SELINUX */ ++ + static gboolean + sysroot_finalize_deployment (OstreeSysroot *self, + OstreeDeployment *deployment, +@@ -2866,6 +2978,11 @@ sysroot_finalize_deployment (OstreeSysroot *self, + return FALSE; + } + ++#ifdef HAVE_SELINUX ++ if (!sysroot_finalize_selinux_policy(deployment_dfd, error)) ++ return FALSE; ++#endif /* HAVE_SELINUX */ ++ + const char *osdeploypath = glnx_strjoina ("ostree/deploy/", ostree_deployment_get_osname (deployment)); + glnx_autofd int os_deploy_dfd = -1; + if (!glnx_opendirat (self->sysroot_fd, osdeploypath, TRUE, &os_deploy_dfd, error)) +-- +2.31.1 + diff --git a/SOURCES/0006-deploy-Be-a-bit-more-verbose-about-SELinux-bits.patch b/SOURCES/0006-deploy-Be-a-bit-more-verbose-about-SELinux-bits.patch new file mode 100644 index 0000000..f963cb5 --- /dev/null +++ b/SOURCES/0006-deploy-Be-a-bit-more-verbose-about-SELinux-bits.patch @@ -0,0 +1,35 @@ +From dd194eca7272afa457541abb2d8c25f90c4f478a Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Mon, 28 Mar 2022 17:46:59 -0400 +Subject: [PATCH 6/6] deploy: Be a bit more verbose about SELinux bits + +Let's log when we don't find the expected CLI argument which +will help debug things. + +(cherry picked from commit c58a4fe661d9d3bf2c515aa5605b1e094c0a62ca) +--- + src/libostree/ostree-sysroot-deploy.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c +index a44721d8..404f336f 100644 +--- a/src/libostree/ostree-sysroot-deploy.c ++++ b/src/libostree/ostree-sysroot-deploy.c +@@ -2926,9 +2926,12 @@ sysroot_finalize_selinux_policy (int deployment_dfd, GError **error) + SEMODULE_HELP_ARGC, &exit_status, &stdout, error)) + return FALSE; + if (!g_spawn_check_exit_status (exit_status, error)) +- return FALSE; ++ return glnx_prefix_error (error, "failed to run semodule"); + if (!strstr(stdout, "--rebuild-if-modules-changed")) +- return TRUE; ++ { ++ ot_journal_print (LOG_INFO, "semodule does not have --rebuild-if-modules-changed"); ++ return TRUE; ++ } + + static const gchar * const SEMODULE_REBUILD_ARGV[] = { + "semodule", "-N", "--rebuild-if-modules-changed" +-- +2.31.1 + diff --git a/SOURCES/0007-backport-GH2694-secure-execution-enablement-s390x.patch b/SOURCES/0007-backport-GH2694-secure-execution-enablement-s390x.patch new file mode 100644 index 0000000..3bf792d --- /dev/null +++ b/SOURCES/0007-backport-GH2694-secure-execution-enablement-s390x.patch @@ -0,0 +1,298 @@ +From 00697be199c08242e54c02e4557e20834030aaf3 Mon Sep 17 00:00:00 2001 +From: Nikita Dubrovskii +Date: Mon, 4 Apr 2022 16:09:50 +0200 +Subject: [PATCH 1/5] s390x: generate sd-boot at its own partition + +Signed-off-by: Nikita Dubrovskii +--- + src/libostree/ostree-bootloader-zipl.c | 36 ++++++++++++++++++++++---- + src/libostree/s390x-se-luks-gencpio | 4 +-- + 2 files changed, 33 insertions(+), 7 deletions(-) + +diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c +index 02c10826c3..fe024d8046 100644 +--- a/src/libostree/ostree-bootloader-zipl.c ++++ b/src/libostree/ostree-bootloader-zipl.c +@@ -21,12 +21,17 @@ + #include "ostree-bootloader-zipl.h" + #include "ostree-deployment-private.h" + #include "otutil.h" ++#include ++#include + #include + +-#define SECURE_EXECUTION_BOOT_IMAGE "/boot/sd-boot" ++#define SECURE_EXECUTION_PARTITION "/dev/disk/by-label/se" ++#define SECURE_EXECUTION_MOUNTPOINT "/sysroot/se" ++#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sd-boot" + #define SECURE_EXECUTION_HOSTKEY_PATH "/etc/se-hostkeys/" + #define SECURE_EXECUTION_HOSTKEY_PREFIX "ibm-z-hostkey" + #define SECURE_EXECUTION_LUKS_ROOT_KEY "/etc/luks/root" ++#define SECURE_EXECUTION_LUKS_BOOT_KEY "/etc/luks/boot" + #define SECURE_EXECUTION_LUKS_CONFIG "/etc/crypttab" + #define SECURE_EXECUTION_RAMDISK_TOOL PKGLIBEXECDIR "/s390x-se-luks-gencpio" + +@@ -67,6 +72,25 @@ _ostree_bootloader_zipl_get_name (OstreeBootloader *bootloader) + return "zipl"; + } + ++static gboolean ++_ostree_secure_execution_mount(GError **error) ++{ ++ const char *device = realpath (SECURE_EXECUTION_PARTITION, NULL); ++ if (device == NULL) ++ return glnx_throw_errno_prefix(error, "s390x SE: resolving %s", SECURE_EXECUTION_PARTITION); ++ if (mount (device, SECURE_EXECUTION_MOUNTPOINT, "ext4", 0, NULL) < 0) ++ return glnx_throw_errno_prefix (error, "s390x SE: Mounting %s", device); ++ return TRUE; ++} ++ ++static gboolean ++_ostree_secure_execution_umount(GError **error) ++{ ++ if (umount (SECURE_EXECUTION_MOUNTPOINT) < 0) ++ return glnx_throw_errno_prefix (error, "s390x SE: Unmounting %s", SECURE_EXECUTION_MOUNTPOINT); ++ return TRUE; ++} ++ + static gboolean + _ostree_bootloader_zipl_write_config (OstreeBootloader *bootloader, + int bootversion, +@@ -152,8 +176,8 @@ _ostree_secure_execution_get_bls_config (OstreeBootloaderZipl *self, + static gboolean + _ostree_secure_execution_luks_key_exists (void) + { +- return (access(SECURE_EXECUTION_LUKS_ROOT_KEY, F_OK) == 0 && +- access(SECURE_EXECUTION_LUKS_CONFIG, F_OK) == 0); ++ return (access(SECURE_EXECUTION_LUKS_CONFIG, F_OK) == 0 && ++ (access(SECURE_EXECUTION_LUKS_ROOT_KEY, F_OK) == 0 || access(SECURE_EXECUTION_LUKS_BOOT_KEY, F_OK) == 0)); + } + + static gboolean +@@ -250,7 +274,7 @@ static gboolean + _ostree_secure_execution_call_zipl (GError **error) + { + int status = 0; +- const char *const zipl_argv[] = {"zipl", "-V", "-t", "/boot", "-i", SECURE_EXECUTION_BOOT_IMAGE, NULL}; ++ const char *const zipl_argv[] = {"zipl", "-V", "-t", SECURE_EXECUTION_MOUNTPOINT, "-i", SECURE_EXECUTION_BOOT_IMAGE, NULL}; + if (!g_spawn_sync (NULL, (char**)zipl_argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL, &status, error)) + return glnx_prefix_error(error, "s390x SE: spawning zipl"); +@@ -274,9 +298,11 @@ _ostree_secure_execution_enable (OstreeBootloaderZipl *self, + g_autofree gchar* options = NULL; + + gboolean rc = ++ _ostree_secure_execution_mount (error) && + _ostree_secure_execution_get_bls_config (self, bootversion, &vmlinuz, &initramfs, &options, cancellable, error) && + _ostree_secure_execution_generate_sdboot (vmlinuz, initramfs, options, keys, error) && +- _ostree_secure_execution_call_zipl (error); ++ _ostree_secure_execution_call_zipl (error) && ++ _ostree_secure_execution_umount (error); + + return rc; + } +diff --git a/src/libostree/s390x-se-luks-gencpio b/src/libostree/s390x-se-luks-gencpio +index f0ad24eb32..7d62258a31 100755 +--- a/src/libostree/s390x-se-luks-gencpio ++++ b/src/libostree/s390x-se-luks-gencpio +@@ -12,11 +12,11 @@ gzip -cd ${old_initrd} | cpio -imd --quiet + + # Adding LUKS root key and crypttab config + mkdir -p etc/luks +-cp -f /etc/luks/root etc/luks/ ++cp -f /etc/luks/* etc/luks/ + cp -f /etc/crypttab etc/ + + # Creating new initramdisk image +-find . | cpio --quiet -H newc -o | gzip -9 -n >> ${new_initrd} ++find . -mindepth 1 | cpio --quiet -H newc -o | gzip -9 -n >> ${new_initrd} + + # Cleanup + rm -rf ${workdir} + +From 91e71022ebc2422f278c285e55f4c88d7f572eeb Mon Sep 17 00:00:00 2001 +From: Nikita Dubrovskii +Date: Mon, 23 May 2022 17:28:54 +0200 +Subject: [PATCH 2/5] s390x: ensure SecureExecution is enabled before sd-boot + generation + +Signed-off-by: Nikita Dubrovskii +--- + src/libostree/ostree-bootloader-zipl.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c +index fe024d8046..348dfe036d 100644 +--- a/src/libostree/ostree-bootloader-zipl.c ++++ b/src/libostree/ostree-bootloader-zipl.c +@@ -25,6 +25,7 @@ + #include + #include + ++#define SECURE_EXECUTION_SYSFS_FLAG "/sys/firmware/uv/prot_virt_guest" + #define SECURE_EXECUTION_PARTITION "/dev/disk/by-label/se" + #define SECURE_EXECUTION_MOUNTPOINT "/sysroot/se" + #define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sd-boot" +@@ -109,6 +110,14 @@ _ostree_bootloader_zipl_write_config (OstreeBootloader *bootloader, + return TRUE; + } + ++static gboolean _ostree_secure_execution_is_enabled (GCancellable *cancellable) { ++ gsize len = 0; ++ g_autofree char *data = glnx_file_get_contents_utf8_at (-1, SECURE_EXECUTION_SYSFS_FLAG, &len, cancellable, NULL); ++ if (!data) ++ return FALSE; ++ return strstr (data, "1") != NULL; ++} ++ + static gboolean + _ostree_secure_execution_get_keys (GPtrArray **keys, + GCancellable *cancellable, +@@ -329,12 +338,15 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, + return TRUE; + + /* Try with Secure Execution */ +- g_autoptr(GPtrArray) keys = NULL; +- if (!_ostree_secure_execution_get_keys (&keys, cancellable, error)) +- return FALSE; +- if (keys && keys->len) +- return _ostree_secure_execution_enable (self, bootversion, keys, cancellable, error); +- ++ if ( _ostree_secure_execution_is_enabled (cancellable) ) ++ { ++ g_autoptr(GPtrArray) keys = NULL; ++ if (!_ostree_secure_execution_get_keys (&keys, cancellable, error)) ++ return FALSE; ++ if (!keys || keys->len == 0) ++ return glnx_throw (error, "s390x SE: no keys"); ++ return _ostree_secure_execution_enable (self, bootversion, keys, cancellable, error); ++ } + /* Fallback to non-SE setup */ + const char *const zipl_argv[] = {"zipl", NULL}; + int estatus; + +From 2e2854239189044cc1ffd100959b7c7bfe92b0f9 Mon Sep 17 00:00:00 2001 +From: Nikita Dubrovskii +Date: Tue, 24 May 2022 19:30:35 +0200 +Subject: [PATCH 3/5] s390x: fail on error during reading of SecureExecution + sysfs flag + +--- + src/libostree/ostree-bootloader-zipl.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c +index 348dfe036d..87b9b67aec 100644 +--- a/src/libostree/ostree-bootloader-zipl.c ++++ b/src/libostree/ostree-bootloader-zipl.c +@@ -110,12 +110,21 @@ _ostree_bootloader_zipl_write_config (OstreeBootloader *bootloader, + return TRUE; + } + +-static gboolean _ostree_secure_execution_is_enabled (GCancellable *cancellable) { +- gsize len = 0; +- g_autofree char *data = glnx_file_get_contents_utf8_at (-1, SECURE_EXECUTION_SYSFS_FLAG, &len, cancellable, NULL); ++static gboolean _ostree_secure_execution_is_enabled (gboolean *out_enabled, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ *out_enabled = FALSE; ++ glnx_autofd int fd = -1; ++ if (!ot_openat_ignore_enoent (AT_FDCWD, SECURE_EXECUTION_SYSFS_FLAG, &fd, error)) ++ return FALSE; ++ if (fd == -1) ++ return TRUE; //ENOENT --> SecureExecution is disabled ++ g_autofree char *data = glnx_fd_readall_utf8 (fd, NULL, cancellable, error); + if (!data) + return FALSE; +- return strstr (data, "1") != NULL; ++ *out_enabled = strstr (data, "1") != NULL; ++ return TRUE; + } + + static gboolean +@@ -338,13 +347,16 @@ _ostree_bootloader_zipl_post_bls_sync (OstreeBootloader *bootloader, + return TRUE; + + /* Try with Secure Execution */ +- if ( _ostree_secure_execution_is_enabled (cancellable) ) ++ gboolean se_enabled = FALSE; ++ if ( !_ostree_secure_execution_is_enabled (&se_enabled, cancellable, error)) ++ return FALSE; ++ if (se_enabled) + { + g_autoptr(GPtrArray) keys = NULL; + if (!_ostree_secure_execution_get_keys (&keys, cancellable, error)) + return FALSE; + if (!keys || keys->len == 0) +- return glnx_throw (error, "s390x SE: no keys"); ++ return glnx_throw (error, "s390x SE: no keys"); + return _ostree_secure_execution_enable (self, bootversion, keys, cancellable, error); + } + /* Fallback to non-SE setup */ + +From 89ed46e8a9f584e2a6c1966fbf4c99f0fe51424e Mon Sep 17 00:00:00 2001 +From: Nikita Dubrovskii +Date: Fri, 27 May 2022 09:13:18 +0200 +Subject: [PATCH 4/5] s390x: do not unpack existing initrd, just append LUKS + keys to its copy + +Signed-off-by: Nikita Dubrovskii +--- + src/libostree/s390x-se-luks-gencpio | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/libostree/s390x-se-luks-gencpio b/src/libostree/s390x-se-luks-gencpio +index 7d62258a31..f444198a40 100755 +--- a/src/libostree/s390x-se-luks-gencpio ++++ b/src/libostree/s390x-se-luks-gencpio +@@ -4,19 +4,19 @@ set -euo pipefail + + old_initrd=$1 + new_initrd=$2 ++currdir=$PWD + +-# Unpacking existing initramdisk ++# Copying existing initramdisk ++cp ${old_initrd} ${new_initrd} ++ ++# Appending LUKS root keys and crypttab config to the end of initrd + workdir=$(mktemp -d -p /tmp se-initramfs-XXXXXX) + cd ${workdir} +-gzip -cd ${old_initrd} | cpio -imd --quiet +- +-# Adding LUKS root key and crypttab config + mkdir -p etc/luks + cp -f /etc/luks/* etc/luks/ + cp -f /etc/crypttab etc/ +- +-# Creating new initramdisk image + find . -mindepth 1 | cpio --quiet -H newc -o | gzip -9 -n >> ${new_initrd} + + # Cleanup ++cd ${currdir} + rm -rf ${workdir} + +From 2c8d5b95c7f2fee90e73bdd9222e002c44e797b7 Mon Sep 17 00:00:00 2001 +From: Nikita Dubrovskii +Date: Thu, 23 Jun 2022 15:54:04 +0200 +Subject: [PATCH 5/5] s390x: rename sd-boot to sdboot + +Signed-off-by: Nikita Dubrovskii +--- + src/libostree/ostree-bootloader-zipl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libostree/ostree-bootloader-zipl.c b/src/libostree/ostree-bootloader-zipl.c +index 87b9b67aec..0ff350f942 100644 +--- a/src/libostree/ostree-bootloader-zipl.c ++++ b/src/libostree/ostree-bootloader-zipl.c +@@ -28,7 +28,7 @@ + #define SECURE_EXECUTION_SYSFS_FLAG "/sys/firmware/uv/prot_virt_guest" + #define SECURE_EXECUTION_PARTITION "/dev/disk/by-label/se" + #define SECURE_EXECUTION_MOUNTPOINT "/sysroot/se" +-#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sd-boot" ++#define SECURE_EXECUTION_BOOT_IMAGE SECURE_EXECUTION_MOUNTPOINT "/sdboot" + #define SECURE_EXECUTION_HOSTKEY_PATH "/etc/se-hostkeys/" + #define SECURE_EXECUTION_HOSTKEY_PREFIX "ibm-z-hostkey" + #define SECURE_EXECUTION_LUKS_ROOT_KEY "/etc/luks/root" diff --git a/SOURCES/0008-backport-GH2696-ed25519-verify-signatures-minimum-length.patch b/SOURCES/0008-backport-GH2696-ed25519-verify-signatures-minimum-length.patch new file mode 100644 index 0000000..041e33d --- /dev/null +++ b/SOURCES/0008-backport-GH2696-ed25519-verify-signatures-minimum-length.patch @@ -0,0 +1,32 @@ +From 56820e54392efc5dd59032f8872aaf219190ad4f Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Thu, 14 Jul 2022 14:42:19 -0400 +Subject: [PATCH] sign/ed25519: Verify signatures are minimum length + +The ed25519 signature verification code does not +check that the signature is a minimum/correct length. +As a result, if the signature is too short, libsodium will end up +reading a few bytes out of bounds. + +Reported-by: Demi Marie Obenour +Co-authored-by: Demi Marie Obenour + +Closes: https://github.com/ostreedev/ostree/security/advisories/GHSA-gqf4-p3gv-g8vw +--- + src/libostree/ostree-sign-ed25519.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/libostree/ostree-sign-ed25519.c b/src/libostree/ostree-sign-ed25519.c +index 809ffe8790..f271fd49e0 100644 +--- a/src/libostree/ostree-sign-ed25519.c ++++ b/src/libostree/ostree-sign-ed25519.c +@@ -209,6 +209,9 @@ gboolean ostree_sign_ed25519_data_verify (OstreeSign *self, + g_autoptr (GVariant) child = g_variant_get_child_value (signatures, i); + g_autoptr (GBytes) signature = g_variant_get_data_as_bytes(child); + ++ if (g_bytes_get_size (signature) != crypto_sign_BYTES) ++ return glnx_throw (error, "Invalid signature length of %" G_GSIZE_FORMAT " bytes, expected %" G_GSIZE_FORMAT, (gsize) g_bytes_get_size (signature), (gsize) crypto_sign_BYTES); ++ + g_autofree char * hex = g_malloc0 (crypto_sign_PUBLICKEYBYTES*2 + 1); + + g_debug("Read signature %d: %s", (gint)i, g_variant_print(child, TRUE)); diff --git a/SPECS/ostree.spec b/SPECS/ostree.spec index 6bec58c..9919712 100644 --- a/SPECS/ostree.spec +++ b/SPECS/ostree.spec @@ -7,12 +7,23 @@ Summary: Tool for managing bootable, immutable filesystem trees Name: ostree -Version: 2022.1 -Release: 2%{?dist} +Version: 2022.2 +Release: 5%{?dist} Source0: https://github.com/ostreedev/%{name}/releases/download/v%{version}/libostree-%{version}.tar.xz License: LGPLv2+ URL: https://ostree.readthedocs.io/en/latest/ +# We now track the rhel8 branch upstream, these are the patches +# since the 2022.2 release. +Patch0: 0001-Add-an-ostree-boot-complete.service-to-propagate-sta.patch +Patch1: 0002-libarchive-Handle-archive_entry_symlink-returning-NU.patch +Patch2: 0003-repo-Factor-out-_ostree_repo_auto_transaction_new.patch +Patch3: 0004-repo-Correctly-initialize-refcount-of-temporary-tran.patch +Patch4: 0005-deploy-Try-to-rebuild-policy-in-new-deployment-if-ne.patch +Patch5: 0006-deploy-Be-a-bit-more-verbose-about-SELinux-bits.patch +Patch6: 0007-backport-GH2694-secure-execution-enablement-s390x.patch +Patch7: 0008-backport-GH2696-ed25519-verify-signatures-minimum-length.patch + BuildRequires: make BuildRequires: git # We always run autogen.sh @@ -163,6 +174,22 @@ find %{buildroot} -name '*.la' -delete %endif %changelog +* Tue Aug 23 2022 Luca BRUNO - 2022.2-5 +- Backport enablement patches for Secure Execution on s390x + https://github.com/ostreedev/ostree/pull/2694 + Resolves: rhbz#2120522 +- Backport security fix to verify signatures are minimum length (advisory GHSA-gqf4-p3gv-g8vw) + https://github.com/ostreedev/ostree/pull/2696 + Resolves: rhbz#2119444 + +* Wed May 04 2022 Colin Walters - 2022.2-4 +- Backport patches from 2022.3, particularly SELinux + Resolves: rhbz#2057497 + +* Tue Apr 19 2022 Colin Walters - 2022.2-3 +- https://github.com/ostreedev/ostree/releases/tag/v2022.2 + Resolves: rhbz#2057497 + * Mon Jan 10 2022 Colin Walters - 2022.1-2 - Rebase to 2022.1 Resolves: rhbz#2032593