diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 14083894..858be409 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -2180,6 +2180,56 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion, return TRUE; } +/* Determine whether an existing directory implements the semantics described in + * https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-entry-keys + */ +static gboolean +is_bootconfig_type1_semantics (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +{ + struct stat stbuf; + + if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) + return FALSE; + + if (!glnx_fstatat_allow_noent (sysroot->boot_fd, "loader/entries.srel", &stbuf, + AT_SYMLINK_NOFOLLOW, error)) + return FALSE; + + if (errno == ENOENT) + { + g_debug ("Didn't find loader/entries.srel file"); + return FALSE; + } + else + { + /* Get semantics type by reading loader/entries.srel */ + gsize len; + g_autofree char *type = glnx_file_get_contents_utf8_at ( + sysroot->boot_fd, "loader/entries.srel", &len, cancellable, error); + if (type == NULL) + { + g_debug ("Invalid loader/entries.srel file"); + return FALSE; + } + + /* Remove trailing newline symbol if there is any */ + type[strcspn (type, "\n")] = 0; + + if (g_strcmp0 (type, "type1") == 0) + { + g_debug ("type1 semantics is found in loader/entries.srel file"); + return TRUE; + } + else + { + g_debug ("Unsupported semantics type ('%s') in loader/entries.srel file", type); + return FALSE; + } + } + + return FALSE; +} + /* We generate the symlink on disk, then potentially do a syncfs() to ensure * that it (and everything else we wrote) has hit disk. Only after that do we * rename it into place. @@ -2505,6 +2555,7 @@ write_deployments_bootswap (OstreeSysroot *self, GPtrArray *new_deployments, */ struct stat stbuf; gboolean loader_link = FALSE; + gboolean force_type1_semantics = is_bootconfig_type1_semantics (self, cancellable, error); if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; @@ -2528,6 +2579,9 @@ write_deployments_bootswap (OstreeSysroot *self, GPtrArray *new_deployments, else return FALSE; + if (force_type1_semantics && loader_link) + return glnx_throw_errno_prefix (error, "type1 semantics, but boot/loader is symlink"); + if (loader_link) { /* Default and when loader is a link is to swap links */