OstreeRepoFinderConfig: Fix guint/gsize confusion
authorSimon McVittie <smcv@debian.org>
Sun, 24 Jun 2018 11:56:49 +0000 (12:56 +0100)
committerAtomic Bot <atomic-devel@projectatomic.io>
Wed, 27 Jun 2018 15:24:18 +0000 (15:24 +0000)
If a function has a guint "out argument", passing a pointer to a gsize
is not, in general, valid. On an ILP64 platform there is no problem
since guint and gsize are identical, but on an LP64 platform it will
overwrite only the first word of the gsize, leaving the second word
unaffected. On little-endian machines, if the second word is
zero-initialized (as it is here), the result is numerically equal to
the guint, but on big-endian machines the result is around 4 billion
times what it should be, resulting in
ostree_repo_finder_config_resolve_async() reading past the end of
the array and causing undefined behaviour.

In practice this caused assertion failures (and consequently test
failures) on Debian's s390x (z/Architecture), ppc64 (64-bit PowerPC)
and sparc64 (64-bit SPARC) ports.

Closes: #1640
Signed-off-by: Simon McVittie <smcv@debian.org>
Closes: #1641
Approved by: cgwalters

src/libostree/ostree-repo-finder-config.c

index 4366d72a75c64671f5323893f5d1d153716526b3..06f61657fa66118818fefdbb51b3c4e7f553a6e7 100644 (file)
@@ -96,7 +96,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder                  *find
   GHashTableIter iter;
   const gchar *remote_name;
   g_auto(GStrv) remotes = NULL;
-  gsize n_remotes = 0;
+  guint n_remotes = 0;
 
   task = g_task_new (finder, cancellable, callback, user_data);
   g_task_set_source_tag (task, ostree_repo_finder_config_resolve_async);
@@ -106,9 +106,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder                  *find
 
   /* List all remotes in this #OstreeRepo and see which of their ref lists
    * intersect with @refs. */
-  remotes = ostree_repo_remote_list (parent_repo, (guint *) &n_remotes);
+  remotes = ostree_repo_remote_list (parent_repo, &n_remotes);
 
-  g_debug ("%s: Checking %" G_GSIZE_FORMAT " remotes", G_STRFUNC, n_remotes);
+  g_debug ("%s: Checking %u remotes", G_STRFUNC, n_remotes);
 
   for (i = 0; i < n_remotes; i++)
     {