diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h index d8b93b29..22d725a0 100644 --- a/src/libostree/ostree-core-private.h +++ b/src/libostree/ostree-core-private.h @@ -141,6 +141,12 @@ _ostree_validate_bareuseronly_mode_finfo (GFileInfo *finfo, return _ostree_validate_bareuseronly_mode (content_mode, checksum, error); } +gboolean +_ostree_compare_object_checksum (OstreeObjectType objtype, + const char *expected, + const char *actual, + GError **error); + gboolean _ostree_parse_delta_name (const char *delta_name, char **out_from, diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 542c54bf..50a2e4fa 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -1004,6 +1004,22 @@ ostree_checksum_file_async_finish (GFile *f, return TRUE; } +/* Common helper to compare checksums for an object, so we have a consistent + * error message. + */ +gboolean +_ostree_compare_object_checksum (OstreeObjectType objtype, + const char *expected, + const char *actual, + GError **error) +{ + if (!g_str_equal (expected, actual)) + return glnx_throw (error, "Corrupted %s object; checksum expected='%s' actual='%s'", + ostree_object_type_to_string (objtype), + expected, actual); + return TRUE; +} + /** * ostree_create_directory_metadata: * @dir_info: a #GFileInfo containing directory information diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 2bcf6ed7..140ea34f 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -685,10 +685,12 @@ write_content_object (OstreeRepo *self, else { actual_checksum = actual_checksum_owned = ot_checksum_instream_get_string (checksum_input); - if (expected_checksum && strcmp (actual_checksum, expected_checksum) != 0) - return glnx_throw (error, "Corrupted %s object %s (actual checksum is %s)", - ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE), - expected_checksum, actual_checksum); + if (expected_checksum) + { + if (!_ostree_compare_object_checksum (OSTREE_OBJECT_TYPE_FILE, expected_checksum, actual_checksum, + error)) + return FALSE; + } } g_assert (actual_checksum != NULL); /* Pacify static analysis */ @@ -954,10 +956,11 @@ write_metadata_object (OstreeRepo *self, return TRUE; } - if (expected_checksum && strcmp (actual_checksum, expected_checksum) != 0) - return glnx_throw (error, "Corrupted %s object %s (actual checksum is %s)", - ostree_object_type_to_string (objtype), - expected_checksum, actual_checksum); + if (expected_checksum) + { + if (!_ostree_compare_object_checksum (objtype, expected_checksum, actual_checksum, error)) + return FALSE; + } } /* Ok, checksum is known, let's get the data */ diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index bcfd15d5..2e9b0bd7 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1005,13 +1005,8 @@ content_fetch_on_write_complete (GObject *object, checksum_obj = ostree_object_to_string (checksum, objtype); g_debug ("write of %s complete", checksum_obj); - if (strcmp (checksum, expected_checksum) != 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Corrupted content object; checksum expected='%s' actual='%s'", - expected_checksum, checksum); - goto out; - } + if (!_ostree_compare_object_checksum (objtype, expected_checksum, checksum, error)) + goto out; pull_data->n_fetched_content++; /* Was this a delta fallback? */ @@ -1256,13 +1251,8 @@ meta_fetch_on_complete (GObject *object, char hexdigest[OSTREE_SHA256_STRING_LEN+1]; ot_checksum_get_hexdigest (&hasher, hexdigest, sizeof (hexdigest)); - if (strcmp (checksum, hexdigest) != 0) - { - (void) glnx_throw (error, "Corrupted %s object %s (actual checksum is %s)", - ostree_object_type_to_string (objtype), - checksum, hexdigest); - goto out; - } + if (!_ostree_compare_object_checksum (objtype, checksum, hexdigest, error)) + goto out; /* Do GPG verification. `detached_data` may be NULL if no detached * metadata was found during pull; that's handled by diff --git a/tests/test-pull-corruption.sh b/tests/test-pull-corruption.sh index 3696acc4..ea29a87c 100755 --- a/tests/test-pull-corruption.sh +++ b/tests/test-pull-corruption.sh @@ -89,7 +89,7 @@ if ! skip_one_without_user_xattrs; then if ${CMD_PREFIX} ostree --repo=repo pull-local --untrusted ostree-srv/gnomerepo main 2>err.txt; then assert_not_reached "pull-local --untrusted worked?" fi - assert_file_has_content err.txt "Corrupted commit object ${corruptrev}.*actual checksum is ${rev}" + assert_file_has_content_literal err.txt "Corrupted commit object; checksum expected='${corruptrev}' actual='${rev}'" rm repo err.txt -rf ostree_repo_init repo --mode=bare-user @@ -97,6 +97,6 @@ if ! skip_one_without_user_xattrs; then if ${CMD_PREFIX} ostree --repo=repo pull origin main 2>err.txt; then assert_not_reached "pull unexpectedly succeeded!" fi - assert_file_has_content err.txt "Corrupted commit object ${corruptrev}.*actual checksum is ${rev}" + assert_file_has_content_literal err.txt "Corrupted commit object; checksum expected='${corruptrev}' actual='${rev}'" echo "ok pull commit corruption" fi