Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libostree for openSUSE:Factory checked in at 2025-01-02 19:19:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libostree (Old) and /work/SRC/openSUSE:Factory/.libostree.new.1881 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libostree" Thu Jan 2 19:19:20 2025 rev:43 rq:1233958 version:2024.10 Changes: -------- --- /work/SRC/openSUSE:Factory/libostree/libostree.changes 2024-12-03 20:46:51.222148445 +0100 +++ /work/SRC/openSUSE:Factory/.libostree.new.1881/libostree.changes 2025-01-02 19:19:36.747985355 +0100 @@ -1,0 +2,13 @@ +Sat Dec 21 18:40:13 UTC 2024 - Andreas Stieger <andreas.stie...@gmx.de> + +- Update to version 2024.10: + + composefs: Ensure buffer is suitably aligned for struct + fsverity_digest + + core: Always sort incoming xattrs + + sign-ed25519: Fix error message of validate_length + + rofiles-fuse: when fuse execution fails, rofiles-fuse still + returns exit code 0 + + libostree/deploy: enable composefs by default + + documentation updates + +------------------------------------------------------------------- Old: ---- libostree-2024.9.tar.xz New: ---- libostree-2024.10.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libostree.spec ++++++ --- /var/tmp/diff_new_pack.Xw4v3Y/_old 2025-01-02 19:19:37.292007745 +0100 +++ /var/tmp/diff_new_pack.Xw4v3Y/_new 2025-01-02 19:19:37.292007745 +0100 @@ -24,7 +24,7 @@ %bcond_without ed25519 %bcond_with tests Name: libostree -Version: 2024.9 +Version: 2024.10 Release: 0 Summary: Git for operating system binaries License: LGPL-2.0-or-later ++++++ libostree-2024.9.tar.xz -> libostree-2024.10.tar.xz ++++++ ++++ 7778 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/README.md new/libostree-2024.10/README.md --- old/libostree-2024.9/README.md 2024-06-03 17:08:17.000000000 +0200 +++ new/libostree-2024.10/README.md 2024-12-19 21:09:39.000000000 +0100 @@ -94,7 +94,7 @@ [QtOTA](http://doc.qt.io/QtOTA/) is Qt's over-the-air update framework which uses libostree. -The [BuildStream](https://gitlab.com/BuildStream/buildstream) build and +The [BuildStream](https://github.com/apache/buildstream/) build and integration tool supports importing and exporting from libostree repos. [fedora-iot/otto](https://github.com/fedora-iot/otto) is a tool that helps diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/apidoc/html/ostree-ostree-version.html new/libostree-2024.10/apidoc/html/ostree-ostree-version.html --- old/libostree-2024.9/apidoc/html/ostree-ostree-version.html 2024-11-05 16:12:25.000000000 +0100 +++ new/libostree-2024.10/apidoc/html/ostree-ostree-version.html 2024-12-19 21:11:10.000000000 +0100 @@ -125,7 +125,7 @@ <hr> <div class="refsect2"> <a name="OSTREE-RELEASE-VERSION:CAPS"></a><h3>OSTREE_RELEASE_VERSION</h3> -<pre class="programlisting">#define OSTREE_RELEASE_VERSION (9) +<pre class="programlisting">#define OSTREE_RELEASE_VERSION (10) </pre> <p>ostree release version component (e.g. 2 if <a class="link" href="ostree-ostree-version.html#OSTREE-VERSION:CAPS" title="OSTREE_VERSION"><code class="literal">OSTREE_VERSION</code></a> is 2017.2)</p> <p class="since">Since: 2017.4</p> @@ -133,7 +133,7 @@ <hr> <div class="refsect2"> <a name="OSTREE-VERSION:CAPS"></a><h3>OSTREE_VERSION</h3> -<pre class="programlisting">#define OSTREE_VERSION (2024.9) +<pre class="programlisting">#define OSTREE_VERSION (2024.10) </pre> <p>ostree version.</p> <p class="since">Since: 2017.4</p> @@ -141,7 +141,7 @@ <hr> <div class="refsect2"> <a name="OSTREE-VERSION-S:CAPS"></a><h3>OSTREE_VERSION_S</h3> -<pre class="programlisting">#define OSTREE_VERSION_S "2024.9" +<pre class="programlisting">#define OSTREE_VERSION_S "2024.10" </pre> <p>ostree version, encoded as a string, useful for printing and concatenation.</p> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/config.h.in new/libostree-2024.10/config.h.in --- old/libostree-2024.9/config.h.in 2024-11-05 16:12:24.000000000 +0100 +++ new/libostree-2024.10/config.h.in 2024-12-19 21:10:52.000000000 +0100 @@ -27,31 +27,31 @@ /* The system grub2-mkconfig executable name */ #undef GRUB2_MKCONFIG_PATH -/* Define to 1 if you have the `archive_read_support_filter_all' function. */ +/* Define to 1 if you have the 'archive_read_support_filter_all' function. */ #undef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL /* Define if we have avahi-client.pc and avahi-glib.pc */ #undef HAVE_AVAHI -/* Define to 1 if you have the `clock_gettime' function. */ +/* Define to 1 if you have the 'clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define if we have libcomposefs */ #undef HAVE_COMPOSEFS -/* Define to 1 if you have the declaration of `copy_file_range', and to 0 if +/* Define to 1 if you have the declaration of 'copy_file_range', and to 0 if you don't. */ #undef HAVE_DECL_COPY_FILE_RANGE -/* Define to 1 if you have the declaration of `memfd_create', and to 0 if you +/* Define to 1 if you have the declaration of 'memfd_create', and to 0 if you don't. */ #undef HAVE_DECL_MEMFD_CREATE -/* Define to 1 if you have the declaration of `renameat2', and to 0 if you +/* Define to 1 if you have the declaration of 'renameat2', and to 0 if you don't. */ #undef HAVE_DECL_RENAMEAT2 -/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. +/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't. */ #undef HAVE_DECL_TZNAME @@ -103,10 +103,10 @@ /* Define to 1 if you have the <minix/config.h> header file. */ #undef HAVE_MINIX_CONFIG_H -/* Define to 1 if you have the `mnt_unref_cache' function. */ +/* Define to 1 if you have the 'mnt_unref_cache' function. */ #undef HAVE_MNT_UNREF_CACHE -/* Define to 1 if you have the `nanotime' function. */ +/* Define to 1 if you have the 'nanotime' function. */ #undef HAVE_NANOTIME /* Define if we have openssl */ @@ -130,7 +130,7 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H -/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */ #undef HAVE_STRUCT_TM_TM_ZONE /* Define to 1 if you have the <sys/stat.h> header file. */ @@ -139,12 +139,12 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #undef HAVE_SYS_TYPES_H -/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use - `HAVE_STRUCT_TM_TM_ZONE' instead. */ +/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use + 'HAVE_STRUCT_TM_TM_ZONE' instead. */ #undef HAVE_TM_ZONE -/* Define to 1 if you don't have `tm_zone' but do have the external array - `tzname'. */ +/* Define to 1 if you don't have 'tm_zone' but do have the external array + 'tzname'. */ #undef HAVE_TZNAME /* Define to 1 if you have the <unistd.h> header file. */ @@ -177,7 +177,7 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Define to 1 if all of the C90 standard headers exist (not just the ones +/* Define to 1 if all of the C89 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS @@ -185,13 +185,13 @@ /* "unit path" */ #undef SYSTEM_DATA_UNIT_PATH -/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +/* Define to 1 if your <sys/time.h> declares 'struct tm'. */ #undef TM_IN_SYS_TIME /* Define if using internal ostree-grub-generator */ #undef USE_BUILTIN_GRUB2_MKCONFIG -/* Enable extensions on AIX 3, Interix. */ +/* Enable extensions on AIX, Interix, z/OS. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif @@ -252,11 +252,15 @@ #ifndef __STDC_WANT_IEC_60559_DFP_EXT__ # undef __STDC_WANT_IEC_60559_DFP_EXT__ #endif +/* Enable extensions specified by C23 Annex F. */ +#ifndef __STDC_WANT_IEC_60559_EXT__ +# undef __STDC_WANT_IEC_60559_EXT__ +#endif /* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ #ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ # undef __STDC_WANT_IEC_60559_FUNCS_EXT__ #endif -/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */ #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ # undef __STDC_WANT_IEC_60559_TYPES_EXT__ #endif @@ -288,5 +292,11 @@ /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS -/* Define for large files, on AIX-style hosts. */ +/* Define to 1 on platforms where this makes off_t a 64-bit type. */ #undef _LARGE_FILES + +/* Number of bits in time_t, on hosts where this is settable. */ +#undef _TIME_BITS + +/* Define to 1 on platforms where this makes time_t a 64-bit type. */ +#undef __MINGW_USE_VC2005_COMPAT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/configure.ac new/libostree-2024.10/configure.ac --- old/libostree-2024.9/configure.ac 2024-11-05 16:11:29.000000000 +0100 +++ new/libostree-2024.10/configure.ac 2024-12-19 21:10:11.000000000 +0100 @@ -1,7 +1,7 @@ AC_PREREQ([2.63]) dnl To perform a release, follow the instructions in `docs/CONTRIBUTING.md`. m4_define([year_version], [2024]) -m4_define([release_version], [9]) +m4_define([release_version], [10]) m4_define([package_version], [year_version.release_version]) AC_INIT([libostree], [package_version], [walt...@verbum.org]) is_release_build=yes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/man/ostree-prepare-root.xml new/libostree-2024.10/man/ostree-prepare-root.xml --- old/libostree-2024.9/man/ostree-prepare-root.xml 2024-11-05 16:11:23.000000000 +0100 +++ new/libostree-2024.10/man/ostree-prepare-root.xml 2024-12-19 21:09:39.000000000 +0100 @@ -138,10 +138,15 @@ <varlistentry> <term><varname>composefs.enabled</varname></term> <listitem><para>This can be <literal>yes</literal>, <literal>no</literal>, <literal>maybe</literal>, - or <literal>signed</literal>. The default is <literal>no</literal>. If set to <literal>yes</literal> or - <literal>signed</literal>, then composefs is always used, and the boot fails if it is not - available. Additionally if set to <literal>signed</literal>, boot will fail if the image cannot be - validated by a public key. Setting this to <literal>maybe</literal> is currently equivalent to <literal>no</literal>. + <literal>signed</literal>, or <literal>verity</literal>. The default is <literal>no</literal>. + If set to <literal>yes</literal>, <literal>signed</literal>, or <literal>verity</literal>, + then composefs is always used, and the boot fails if it is not available. + If set to <literal>signed</literal> or <literal>verity</literal>, + before the content of a file is read, + the integrity of its backing OSTree object is validated by the digest stored in the image. + Additionally, if set to <literal>signed</literal>, boot will fail if the image cannot be + validated by a public key. + Setting this to <literal>maybe</literal> is currently equivalent to <literal>no</literal>. </para></listitem> </varlistentry> <varlistentry> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libostree/ostree-core.c new/libostree-2024.10/src/libostree/ostree-core.c --- old/libostree-2024.9/src/libostree/ostree-core.c 2024-10-16 14:52:01.000000000 +0200 +++ new/libostree-2024.10/src/libostree/ostree-core.c 2024-12-03 15:34:13.000000000 +0100 @@ -43,6 +43,7 @@ G_STATIC_ASSERT (OSTREE_REPO_MODE_BARE_SPLIT_XATTRS == 4); static GBytes *variant_to_lenprefixed_buffer (GVariant *variant); +static GVariant *canonicalize_xattrs (GVariant *xattrs); #define ALIGN_VALUE(this, boundary) \ ((((unsigned long)(this)) + (((unsigned long)(boundary)) - 1)) \ @@ -302,6 +303,47 @@ return TRUE; } +static int +compare_xattrs (const void *a_pp, const void *b_pp) +{ + GVariant *a = *(GVariant **)a_pp; + GVariant *b = *(GVariant **)b_pp; + const char *name_a; + const char *name_b; + g_variant_get (a, "(^&ay@ay)", &name_a, NULL); + g_variant_get (b, "(^&ay@ay)", &name_b, NULL); + + return strcmp (name_a, name_b); +} + +// Sort xattrs by name +static GVariant * +canonicalize_xattrs (GVariant *xattrs) +{ + // We always need to provide data, so NULL is canonicalized to the empty array + if (xattrs == NULL) + return g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); + + g_autoptr (GPtrArray) xattr_array + = g_ptr_array_new_with_free_func ((GDestroyNotify)g_variant_unref); + + const guint n = g_variant_n_children (xattrs); + for (guint i = 0; i < n; i++) + { + GVariant *child = g_variant_get_child_value (xattrs, i); + g_ptr_array_add (xattr_array, child); + } + + g_ptr_array_sort (xattr_array, compare_xattrs); + + GVariantBuilder builder; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); + for (guint i = 0; i < xattr_array->len; i++) + g_variant_builder_add_value (&builder, xattr_array->pdata[i]); + + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + /* The file header is part of the "object stream" format * that's not compressed. It's comprised of uid,gid,mode, * and possibly symlink targets from @file_info, as well @@ -321,13 +363,12 @@ else symlink_target = ""; - g_autoptr (GVariant) tmp_xattrs = NULL; - if (xattrs == NULL) - tmp_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); + // We always sort the xattrs now to ensure everything is in normal/canonical form. + g_autoptr (GVariant) tmp_xattrs = canonicalize_xattrs (xattrs); g_autoptr (GVariant) ret = g_variant_new ("(uuuus@a(ayay))", GUINT32_TO_BE (uid), GUINT32_TO_BE (gid), - GUINT32_TO_BE (mode), 0, symlink_target, xattrs ?: tmp_xattrs); + GUINT32_TO_BE (mode), 0, symlink_target, tmp_xattrs); return variant_to_lenprefixed_buffer (g_variant_ref_sink (ret)); } @@ -1111,11 +1152,13 @@ { GVariant *ret_metadata = NULL; + // We always sort the xattrs now to ensure everything is in normal/canonical form. + g_autoptr (GVariant) tmp_xattrs = canonicalize_xattrs (xattrs); + ret_metadata = g_variant_new ( "(uuu@a(ayay))", GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::uid")), GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::gid")), - GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::mode")), - xattrs ? xattrs : g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0)); + GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::mode")), tmp_xattrs); g_variant_ref_sink (ret_metadata); return ret_metadata; @@ -2278,21 +2321,30 @@ } /* Currently ostree imposes no restrictions on xattrs on its own; - * they can e.g. be arbitrariliy sized or in number. - * However, we do validate the key is non-empty, as that is known - * to always fail. + * they can e.g. be arbitrariliy sized or in number. The xattrs + * must be sorted by name (without duplicates), and keys cannot be empty. */ gboolean _ostree_validate_structureof_xattrs (GVariant *xattrs, GError **error) { const guint n = g_variant_n_children (xattrs); + const char *previous = NULL; for (guint i = 0; i < n; i++) { - const guint8 *name; + const char *name; g_autoptr (GVariant) value = NULL; g_variant_get_child (xattrs, i, "(^&ay@ay)", &name, &value); if (!*name) return glnx_throw (error, "Invalid xattr name (empty or missing NUL) index=%d", i); + if (previous) + { + int cmp = strcmp (previous, name); + if (cmp == 0) + return glnx_throw (error, "Duplicate xattr name, index=%d", i); + else if (cmp > 0) + return glnx_throw (error, "Incorrectly sorted xattr name, index=%d", i); + } + previous = name; i++; } return TRUE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libostree/ostree-repo-composefs.c new/libostree-2024.10/src/libostree/ostree-repo-composefs.c --- old/libostree-2024.9/src/libostree/ostree-repo-composefs.c 2024-10-29 21:49:03.000000000 +0100 +++ new/libostree-2024.10/src/libostree/ostree-repo-composefs.c 2024-12-19 21:09:39.000000000 +0100 @@ -327,19 +327,22 @@ * This is the typical case when we're pulled into the target * system repo with verity on and are recreating the composefs * image during deploy. */ - char buf[sizeof (struct fsverity_digest) + OSTREE_SHA256_DIGEST_LEN]; + union + { + struct fsverity_digest d; + char buf[sizeof (struct fsverity_digest) + OSTREE_SHA256_DIGEST_LEN]; + } result; guchar *known_digest = NULL; if (G_IS_UNIX_INPUT_STREAM (input)) { int content_fd = g_unix_input_stream_get_fd (G_UNIX_INPUT_STREAM (input)); - struct fsverity_digest *d = (struct fsverity_digest *)&buf; - d->digest_size = OSTREE_SHA256_DIGEST_LEN; + result.d.digest_size = OSTREE_SHA256_DIGEST_LEN; - if (ioctl (content_fd, FS_IOC_MEASURE_VERITY, d) == 0 - && d->digest_size == OSTREE_SHA256_DIGEST_LEN - && d->digest_algorithm == FS_VERITY_HASH_ALG_SHA256) - known_digest = d->digest; + if (ioctl (content_fd, FS_IOC_MEASURE_VERITY, &result) == 0 + && result.d.digest_size == OSTREE_SHA256_DIGEST_LEN + && result.d.digest_algorithm == FS_VERITY_HASH_ALG_SHA256) + known_digest = result.d.digest; } #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libostree/ostree-sign-ed25519.c new/libostree-2024.10/src/libostree/ostree-sign-ed25519.c --- old/libostree-2024.9/src/libostree/ostree-sign-ed25519.c 2024-07-10 23:25:22.000000000 +0200 +++ new/libostree-2024.10/src/libostree/ostree-sign-ed25519.c 2024-12-19 21:09:39.000000000 +0100 @@ -103,7 +103,7 @@ return TRUE; return glnx_throw ( error, "Ill-formed input: expected %" G_GSIZE_FORMAT " bytes, got %" G_GSIZE_FORMAT " bytes", - found, expected); + expected, found); } static gboolean diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libostree/ostree-sysroot-deploy.c new/libostree-2024.10/src/libostree/ostree-sysroot-deploy.c --- old/libostree-2024.9/src/libostree/ostree-sysroot-deploy.c 2024-10-29 21:49:03.000000000 +0100 +++ new/libostree-2024.10/src/libostree/ostree-sysroot-deploy.c 2024-12-19 21:09:39.000000000 +0100 @@ -640,9 +640,6 @@ if (!glnx_opendirat (osdeploy_dfd, checkout_target_name, TRUE, &ret_deployment_dfd, error)) return FALSE; - guint64 composefs_start_time = 0; - guint64 composefs_end_time = 0; -#ifdef HAVE_COMPOSEFS /* TODO: Consider changing things in the future to parse the deployment config from memory, and * if composefs is enabled, then we can check out in "user mode" (i.e. only have suid binaries * enabled in composefs, etc.) @@ -667,7 +664,11 @@ g_debug ("composefs enabled by config: %d repo: %d", composefs_enabled, repo->composefs_wanted); if (repo->composefs_wanted == OT_TRISTATE_YES) composefs_enabled = repo->composefs_wanted; - if (composefs_enabled == OT_TRISTATE_YES) + + guint64 composefs_start_time = 0; + guint64 composefs_end_time = 0; +#ifdef HAVE_COMPOSEFS + if (composefs_enabled != OT_TRISTATE_NO) { composefs_start_time = g_get_monotonic_time (); // TODO: Clean up our mess around composefs/fsverity...we have duplication @@ -680,7 +681,7 @@ g_auto (GVariantBuilder) cfs_checkout_opts_builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); guint32 composefs_requested = 1; - if (composefs_config->is_signed) + if (composefs_config->require_verity) composefs_requested = 2; g_variant_builder_add (&cfs_checkout_opts_builder, "{sv}", "verity", g_variant_new_uint32 (composefs_requested)); @@ -694,6 +695,9 @@ } else g_debug ("not using composefs"); +#else + if (composefs_enabled == OT_TRISTATE_YES) + return glnx_throw (error, "composefs: enabled at runtime, but support is not compiled in"); #endif *checkout_elapsed = (checkout_end_time - checkout_start_time); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libostree/ostree-version.h new/libostree-2024.10/src/libostree/ostree-version.h --- old/libostree-2024.9/src/libostree/ostree-version.h 2024-11-05 16:12:23.000000000 +0100 +++ new/libostree-2024.10/src/libostree/ostree-version.h 2024-12-19 21:11:03.000000000 +0100 @@ -41,7 +41,7 @@ * * Since: 2017.4 */ -#define OSTREE_RELEASE_VERSION (9) +#define OSTREE_RELEASE_VERSION (10) /** * OSTREE_VERSION @@ -50,7 +50,7 @@ * * Since: 2017.4 */ -#define OSTREE_VERSION (2024.9) +#define OSTREE_VERSION (2024.10) /** * OSTREE_VERSION_S: @@ -60,7 +60,7 @@ * * Since: 2017.4 */ -#define OSTREE_VERSION_S "2024.9" +#define OSTREE_VERSION_S "2024.10" #define OSTREE_ENCODE_VERSION(year,release) \ ((year) << 16 | (release)) @@ -99,5 +99,5 @@ * Since: 2019.3 */ #ifndef __GI_SCANNER__ -#define OSTREE_BUILT_FEATURES "inode64 initial-var libcurl libsoup3 gpgme composefs ex-fsverity libarchive selinux openssl sign-ed25519 libmount systemd release p2p" +#define OSTREE_BUILT_FEATURES "inode64 initial-var libsoup3 gpgme composefs ex-fsverity libarchive selinux libmount systemd release p2p" #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libotcore/otcore-prepare-root.c new/libostree-2024.10/src/libotcore/otcore-prepare-root.c --- old/libostree-2024.9/src/libotcore/otcore-prepare-root.c 2024-11-04 19:50:55.000000000 +0100 +++ new/libostree-2024.10/src/libotcore/otcore-prepare-root.c 2024-12-19 21:09:39.000000000 +0100 @@ -178,8 +178,15 @@ if (g_strcmp0 (enabled, "signed") == 0) { ret->enabled = OT_TRISTATE_YES; + ret->require_verity = true; ret->is_signed = true; } + else if (g_strcmp0 (enabled, "verity") == 0) + { + ret->enabled = OT_TRISTATE_YES; + ret->require_verity = true; + ret->is_signed = false; + } else if (!ot_keyfile_get_tristate_with_default (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY, OTCORE_PREPARE_ROOT_ENABLED_KEY, OT_TRISTATE_MAYBE, &ret->enabled, error)) @@ -227,6 +234,7 @@ { ret->enabled = OT_TRISTATE_YES; ret->is_signed = true; + ret->require_verity = true; } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/libotcore/otcore.h new/libostree-2024.10/src/libotcore/otcore.h --- old/libostree-2024.9/src/libotcore/otcore.h 2024-07-12 02:40:13.000000000 +0200 +++ new/libostree-2024.10/src/libotcore/otcore.h 2024-12-19 21:09:39.000000000 +0100 @@ -52,6 +52,7 @@ typedef struct { OtTristate enabled; + gboolean require_verity; gboolean is_signed; char *signature_pubkey; GPtrArray *pubkeys; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/rofiles-fuse/main.c new/libostree-2024.10/src/rofiles-fuse/main.c --- old/libostree-2024.9/src/rofiles-fuse/main.c 2024-02-27 19:27:11.000000000 +0100 +++ new/libostree-2024.10/src/rofiles-fuse/main.c 2024-12-19 21:09:39.000000000 +0100 @@ -756,7 +756,6 @@ exit (EXIT_FAILURE); } - fuse_main (args.argc, args.argv, &callback_oper, NULL); - - return 0; + // Refer to https://man.openbsd.org/fuse_main.3 + return (fuse_main (args.argc, args.argv, &callback_oper, NULL)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/src/switchroot/ostree-prepare-root.c new/libostree-2024.10/src/switchroot/ostree-prepare-root.c --- old/libostree-2024.9/src/switchroot/ostree-prepare-root.c 2024-10-27 15:37:55.000000000 +0100 +++ new/libostree-2024.10/src/switchroot/ostree-prepare-root.c 2024-12-19 21:09:39.000000000 +0100 @@ -452,10 +452,15 @@ expected_digest = g_malloc (OSTREE_SHA256_STRING_LEN + 1); ot_bin2hex (expected_digest, cfs_digest_buf, g_variant_get_size (cfs_digest_v)); + g_assert (composefs_config->require_verity); cfs_options.flags |= LCFS_MOUNT_FLAGS_REQUIRE_VERITY; g_print ("composefs: Verifying digest: %s\n", expected_digest); cfs_options.expected_fsverity_digest = expected_digest; } + else if (composefs_config->require_verity) + { + cfs_options.flags |= LCFS_MOUNT_FLAGS_REQUIRE_VERITY; + } if (lcfs_mount_image (OSTREE_COMPOSEFS_NAME, TMP_SYSROOT, &cfs_options) == 0) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/tests/admin-test.sh new/libostree-2024.10/tests/admin-test.sh --- old/libostree-2024.9/tests/admin-test.sh 2024-06-03 17:08:17.000000000 +0200 +++ new/libostree-2024.10/tests/admin-test.sh 2024-12-19 21:09:39.000000000 +0100 @@ -71,9 +71,10 @@ assert_not_file_has_content status.txt "rollback" validate_bootloader -# Someday probably soon we'll turn this on by default, but for now -if test -f sysroot/ostree/deploy/testos/deploy/*.0/.ostree.cfs; then - fatal "found composefs unexpectedly" +if has_ostree_feature composefs; then + if ! test -f sysroot/ostree/deploy/testos/deploy/*.0/.ostree.cfs; then + fatal "missing composefs" + fi fi # Test the bootable and linux keys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/tests/test-admin-deploy-composefs.sh new/libostree-2024.10/tests/test-admin-deploy-composefs.sh --- old/libostree-2024.9/tests/test-admin-deploy-composefs.sh 2024-05-02 02:25:21.000000000 +0200 +++ new/libostree-2024.10/tests/test-admin-deploy-composefs.sh 2024-12-19 21:09:39.000000000 +0100 @@ -26,14 +26,32 @@ # Exports OSTREE_SYSROOT so --sysroot not needed. setup_os_repository "archive" "syslinux" +# check disablement cd osdata mkdir -p usr/lib/ostree cat > usr/lib/ostree/prepare-root.conf << 'EOF' [composefs] +enabled=false +EOF +cd - + +${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.composefs -b testos/buildmain/x86_64-runtime osdata +${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime + +${CMD_PREFIX} ostree admin deploy --os=testos --karg=root=LABEL=foo --karg=testkarg=1 testos:testos/buildmain/x86_64-runtime +if test -f sysroot/ostree/deploy/testos/deploy/*.0/.ostree.cfs; then + fatal "found composefs unexpectedly" +fi + +# check explicit enablement +cd osdata +cat > usr/lib/ostree/prepare-root.conf << 'EOF' +[composefs] enabled=true EOF -${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.composefs -b testos/buildmain/x86_64-runtime cd - + +${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.composefs -b testos/buildmain/x86_64-runtime osdata ${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime ${CMD_PREFIX} ostree admin deploy --os=testos --karg=root=LABEL=foo --karg=testkarg=1 testos:testos/buildmain/x86_64-runtime diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libostree-2024.9/tests/test-basic-c.c new/libostree-2024.10/tests/test-basic-c.c --- old/libostree-2024.9/tests/test-basic-c.c 2024-06-05 01:38:18.000000000 +0200 +++ new/libostree-2024.10/tests/test-basic-c.c 2024-12-02 15:50:45.000000000 +0100 @@ -130,12 +130,12 @@ } static gboolean -hi_content_stream_new (GInputStream **out_stream, guint64 *out_length, GError **error) +basic_regfile_content_stream_new (const char *contents, GVariant *xattr, GInputStream **out_stream, + guint64 *out_length, GError **error) { - static const char hi[] = "hi"; - const size_t len = sizeof (hi) - 1; + const size_t len = strlen (contents); g_autoptr (GMemoryInputStream) hi_memstream - = (GMemoryInputStream *)g_memory_input_stream_new_from_data (hi, len, NULL); + = (GMemoryInputStream *)g_memory_input_stream_new_from_data (contents, len, NULL); g_autoptr (GFileInfo) finfo = g_file_info_new (); g_file_info_set_attribute_uint32 (finfo, "standard::type", G_FILE_TYPE_REGULAR); g_file_info_set_attribute_boolean (finfo, "standard::is-symlink", FALSE); @@ -147,6 +147,12 @@ out_length, NULL, error); } +static gboolean +hi_content_stream_new (GInputStream **out_stream, guint64 *out_length, GError **error) +{ + return basic_regfile_content_stream_new ("hi", NULL, out_stream, out_length, error); +} + static void test_validate_remotename (void) { @@ -174,6 +180,8 @@ static const char hi_sha256[] = "2301b5923720c3edc1f0467addb5c287fd5559e3e0cd1396e7f1edb6b01be9f0"; + static const char invalid_hi_sha256[] + = "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"; /* Successful content write */ { @@ -193,12 +201,68 @@ hi_content_stream_new (&hi_memstream, &len, &error); g_assert_no_error (error); g_autofree guchar *csum = NULL; - static const char invalid_hi_sha256[] - = "cafebabecafebabecafebabecafebabecafebabecafebabecafebabecafebabe"; g_assert (!ostree_repo_write_content (repo, invalid_hi_sha256, hi_memstream, len, &csum, NULL, &error)); g_assert (error); g_assert (strstr (error->message, "Corrupted file object")); + g_clear_error (&error); + } + + /* Test a basic regfile inline write, no xattrs */ + g_assert (ostree_repo_write_regfile_inline (repo, hi_sha256, 0, 0, S_IFREG | 0644, NULL, + (guint8 *)"hi", 2, NULL, &error)); + g_assert_no_error (error); + + /* Test a basic regfile inline write, erroring on checksum */ + g_assert (!ostree_repo_write_regfile_inline (repo, invalid_hi_sha256, 0, 0, S_IFREG | 0644, NULL, + (guint8 *)"hi", 2, NULL, &error)); + g_assert (error != NULL); + g_clear_error (&error); + + static const char expected_sha256_with_xattrs[] + = "72473a9e8ace75f89f1504137cfb134feb5372bc1d97e04eb5300e24ad836153"; + + GVariantBuilder builder; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); + g_variant_builder_add (&builder, "(^ay^ay)", "security.selinux", "foo_t"); + g_variant_builder_add (&builder, "(^ay^ay)", "user.blah", "somedata"); + g_autoptr (GVariant) inorder_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)")); + g_variant_builder_add (&builder, "(^ay^ay)", "user.blah", "somedata"); + g_variant_builder_add (&builder, "(^ay^ay)", "security.selinux", "foo_t"); + g_autoptr (GVariant) unsorted_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder)); + + /* Now test with xattrs */ + g_assert (ostree_repo_write_regfile_inline (repo, expected_sha256_with_xattrs, 0, 0, + S_IFREG | 0644, inorder_xattrs, (guint8 *)"hi", 2, + NULL, &error)); + g_assert_no_error (error); + + /* And now with a swapped order */ + g_assert (ostree_repo_write_regfile_inline (repo, expected_sha256_with_xattrs, 0, 0, + S_IFREG | 0644, unsorted_xattrs, (guint8 *)"hi", 2, + NULL, &error)); + g_assert_no_error (error); + + /* Tests of directory metadata */ + static const char expected_dirmeta_sha256[] + = "f773ab98198d8e46f77be6ffff5fc1920888c0af5794426c3b1461131d509f34"; + g_autoptr (GFileInfo) fi = g_file_info_new (); + g_file_info_set_attribute_uint32 (fi, "unix::uid", 0); + g_file_info_set_attribute_uint32 (fi, "unix::gid", 0); + g_file_info_set_attribute_uint32 (fi, "unix::mode", (0755 | S_IFDIR)); + { + g_autoptr (GVariant) dirmeta = ostree_create_directory_metadata (fi, inorder_xattrs); + ostree_repo_write_metadata (repo, OSTREE_OBJECT_TYPE_DIR_META, expected_dirmeta_sha256, dirmeta, + NULL, NULL, &error); + g_assert_no_error (error); + } + /* And now with unsorted xattrs */ + { + g_autoptr (GVariant) dirmeta = ostree_create_directory_metadata (fi, unsorted_xattrs); + ostree_repo_write_metadata (repo, OSTREE_OBJECT_TYPE_DIR_META, expected_dirmeta_sha256, dirmeta, + NULL, NULL, &error); + g_assert_no_error (error); } }