diff options
author | Philip Withnall <withnall@endlessm.com> | 2017-02-02 10:14:55 +0000 |
---|---|---|
committer | sanghyeok.oh <sanghyeok.oh@samsung.com> | 2019-02-01 10:20:31 +0900 |
commit | edd92e4a605713739a7b1128a6d07afaf5c80105 (patch) | |
tree | 010003362adb04a9171c2893190af8e2f9cdca47 | |
parent | 65e5748e56976da5eb37436738625bbfb619e2a2 (diff) | |
download | dbus-edd92e4a605713739a7b1128a6d07afaf5c80105.tar.gz dbus-edd92e4a605713739a7b1128a6d07afaf5c80105.tar.bz2 dbus-edd92e4a605713739a7b1128a6d07afaf5c80105.zip |
dbus-hash: Fix a potential shift by a negative integer
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
-rw-r--r-- | dbus/dbus-hash.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/dbus/dbus-hash.c b/dbus/dbus-hash.c index 8f7d04bb..1a667056 100644 --- a/dbus/dbus-hash.c +++ b/dbus/dbus-hash.c @@ -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); |