forked from Mirrors/flatpak-builder
update: Only allow downgrades if a commit is explicitly specified
If you run "flatpak update" then we will never update to a commit that is older than the currently installed one. This protects against a man-in-the-middle attack that would otherwise let the attacker downgrade to a previously signed version that may have some vulnerability.tingping/wmclass
parent
266b9cb6f0
commit
3ff6d312de
|
@ -1769,6 +1769,7 @@ repo_pull_one_dir (OstreeRepo *self,
|
|||
const char **dirs_to_pull,
|
||||
const char *ref_to_fetch,
|
||||
const char *rev_to_fetch,
|
||||
FlatpakPullFlags flatpak_flags,
|
||||
OstreeRepoPullFlags flags,
|
||||
OstreeAsyncProgress *progress,
|
||||
GCancellable *cancellable,
|
||||
|
@ -1776,7 +1777,11 @@ repo_pull_one_dir (OstreeRepo *self,
|
|||
{
|
||||
GVariantBuilder builder;
|
||||
gboolean force_disable_deltas = FALSE;
|
||||
g_autofree char *remote_and_branch = NULL;
|
||||
g_autofree char *current_checksum = NULL;
|
||||
g_autoptr(GVariant) options = NULL;
|
||||
g_autoptr(GVariant) old_commit = NULL;
|
||||
g_autoptr(GVariant) new_commit = NULL;
|
||||
const char *refs_to_fetch[2];
|
||||
const char *revs_to_fetch[2];
|
||||
gboolean res;
|
||||
|
@ -1811,9 +1816,33 @@ repo_pull_one_dir (OstreeRepo *self,
|
|||
g_variant_new_variant (g_variant_new_strv ((const char * const *) revs_to_fetch, -1)));
|
||||
|
||||
options = g_variant_ref_sink (g_variant_builder_end (&builder));
|
||||
|
||||
remote_and_branch = g_strdup_printf ("%s:%s", remote_name, ref_to_fetch);
|
||||
if (!ostree_repo_resolve_rev (self, remote_and_branch, TRUE, ¤t_checksum, error))
|
||||
return FALSE;
|
||||
if (current_checksum != NULL &&
|
||||
!ostree_repo_load_commit (self, current_checksum, &old_commit, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
res = ostree_repo_pull_with_options (self, remote_name, options,
|
||||
progress, cancellable, error);
|
||||
|
||||
if (old_commit &&
|
||||
(flatpak_flags & FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE) == 0)
|
||||
{
|
||||
guint64 old_timestamp;
|
||||
guint64 new_timestamp;
|
||||
|
||||
if (!ostree_repo_load_commit (self, rev_to_fetch, &new_commit, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
old_timestamp = ostree_commit_get_timestamp (old_commit);
|
||||
new_timestamp = ostree_commit_get_timestamp (new_commit);
|
||||
|
||||
if (new_timestamp < old_timestamp)
|
||||
return flatpak_fail (error, "Update is older then current version");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2376,7 +2405,7 @@ flatpak_dir_pull (FlatpakDir *self,
|
|||
|
||||
if (!repo_pull_one_dir (repo, repository,
|
||||
subdirs_arg ? (const char **)subdirs_arg->pdata : NULL,
|
||||
ref, rev, flags,
|
||||
ref, rev, flatpak_flags, flags,
|
||||
progress,
|
||||
cancellable, error))
|
||||
{
|
||||
|
@ -5080,15 +5109,19 @@ flatpak_dir_update (FlatpakDir *self,
|
|||
/* We're pulling from a remote source, we do the network mirroring pull as a
|
||||
user and hand back the resulting data to the system-helper, that trusts us
|
||||
due to the GPG signatures in the repo */
|
||||
FlatpakPullFlags flatpak_flags;
|
||||
|
||||
child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error);
|
||||
if (child_repo == NULL)
|
||||
return FALSE;
|
||||
|
||||
flatpak_flags = FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA;
|
||||
if (checksum_or_latest != NULL)
|
||||
flatpak_flags |= FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE;
|
||||
|
||||
if (!flatpak_dir_pull (self, remote_name, ref, rev, subpaths,
|
||||
child_repo,
|
||||
FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA | FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA,
|
||||
OSTREE_REPO_PULL_FLAGS_MIRROR,
|
||||
flatpak_flags, OSTREE_REPO_PULL_FLAGS_MIRROR,
|
||||
progress, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ typedef enum {
|
|||
FLATPAK_PULL_FLAGS_NONE = 0,
|
||||
FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA = 1 << 0,
|
||||
FLATPAK_PULL_FLAGS_SIDELOAD_EXTRA_DATA = 1 << 1,
|
||||
FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE = 1 << 2,
|
||||
} FlatpakPullFlags;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -24,7 +24,7 @@ set -euo pipefail
|
|||
skip_without_bwrap
|
||||
skip_without_user_xattrs
|
||||
|
||||
echo "1..9"
|
||||
echo "1..10"
|
||||
|
||||
setup_repo
|
||||
install_repo
|
||||
|
@ -206,6 +206,19 @@ assert_file_has_content hello_out '^Hello world, from a sandboxUPDATED$'
|
|||
|
||||
echo "ok update"
|
||||
|
||||
ostree --repo=repos/test reset app/org.test.Hello/$ARCH/master "$OLD_COMMIT"
|
||||
update_repo
|
||||
|
||||
if ${FLATPAK} ${U} update org.test.Hello; then
|
||||
assert_not_reached "Should not be able to update to older commit"
|
||||
fi
|
||||
|
||||
NEW_NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
|
||||
|
||||
assert_streq "$NEW_COMMIT" "$NEW_NEW_COMMIT"
|
||||
|
||||
echo "ok backwards update"
|
||||
|
||||
DIR=`mktemp -d`
|
||||
${FLATPAK} build-init ${DIR} org.test.Split org.test.Platform org.test.Platform
|
||||
|
||||
|
|
Loading…
Reference in New Issue