dbus-hash: Fix a potential shift by a negative integer 18/199018/1
authorPhilip Withnall <withnall@endlessm.com>
Thu, 2 Feb 2017 10:14:55 +0000 (10:14 +0000)
committersanghyeok.oh <sanghyeok.oh@samsung.com>
Fri, 1 Feb 2019 01:20:31 +0000 (10:20 +0900)
As a hash table becomes unbelievably large and full, the down_shift
tends towards 0. The overflow detection code in rebuild_table() does not
prevent down_shift becoming negative, which then causes undefined
behaviour in RANDOM_INDEX for int-keyed tables.

Note that this can only happen with approaching INT_MAX entries in the
hash table, at which point we’ve almost certainly hit OOM somewhere, so
this is vanishingly unlikely to happen. This is why I can’t add a test
for the bug.

As always, thanks to Coverity.

Coverity ID: 54682
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=99641
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Change-Id: Iac3047fc0bff11b3d08c2938c0fda292bddb1466

dbus/dbus-hash.c

index 8f7d04b..1a66705 100644 (file)
@@ -941,7 +941,7 @@ rebuild_table (DBusHashTable *table)
     {
       /* overflow paranoia */
       if (table->n_buckets < _DBUS_INT_MAX / 4 &&
-          table->down_shift >= 0)
+          table->down_shift >= 2)
         new_buckets = table->n_buckets * 4;
       else
         return; /* can't grow anymore */
@@ -993,6 +993,7 @@ rebuild_table (DBusHashTable *table)
   
   _dbus_assert (table->lo_rebuild_size >= 0);
   _dbus_assert (table->hi_rebuild_size > table->lo_rebuild_size);
+  _dbus_assert (table->down_shift >= 0);
   _dbus_assert (table->mask != 0);
   /* the mask is essentially the max index */
   _dbus_assert (table->mask < table->n_buckets);