After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 694501 - hash resize broken for large sizes
hash resize broken for large sizes
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: ghashtable
2.54.x
Other All
: Normal major
: ---
Assigned To: gtkdev
gtkdev
: 789432 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2013-02-23 08:36 UTC by Deniz Yuret
Modified: 2018-05-24 15:03 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Deniz Yuret 2013-02-23 08:36:22 UTC
_GHashTable.size is a 32 bit signed integer.
The resize policy is to double the table size.
This is done updating size using a left shift (1 << shift), then allocating memory using g_new0.
When shift reaches 31, size becomes -2147483648, this is then interpreted as a 64 bit integer 18446744071562067968 and malloc gives the following cryptic error:

(process:47597): GLib-ERROR **: /build/buildd/glib2.0-2.32.3/./glib/gmem.c:382: overflow allocating 18446744071562067968*8 bytes
Trace/breakpoint trap (core dumped)

This condition should be detected and a more accurate error message should be given.  Ideally, in the longer term, with todays 64 bit computers and large RAM sizes, larger hashes and arrays should be allowed.


  • #0 g_logv
    at /build/buildd/glib2.0-2.32.3/./glib/gmessages.c line 765
  • #1 g_log
    at /build/buildd/glib2.0-2.32.3/./glib/gmessages.c line 792
  • #2 g_malloc0_n
    at /build/buildd/glib2.0-2.32.3/./glib/gmem.c line 381
  • #3 g_hash_table_resize
    at /build/buildd/glib2.0-2.32.3/./glib/ghash.c line 570
  • #4 g_hash_table_maybe_resize
    at /build/buildd/glib2.0-2.32.3/./glib/ghash.c line 630
  • #5 g_hash_table_insert_node
    at /build/buildd/glib2.0-2.32.3/./glib/ghash.c line 907
  • #6 g_hash_table_insert_internal
    at /build/buildd/glib2.0-2.32.3/./glib/ghash.c line 1153
  • #7 lmheap_count
  • #8 g_hash_table_foreach
    at /build/buildd/glib2.0-2.32.3/./glib/ghash.c line 1524
  • #9 lmheap_init
  • #10 fastsubs
  • #11 main

Comment 1 Philip Withnall 2017-10-25 09:37:07 UTC
*** Bug 789432 has been marked as a duplicate of this bug. ***
Comment 2 Daniel Boles 2017-10-25 09:49:42 UTC
The sizes in ghash.c being ints gives me immediate pause; wouldn't gsize be semantically and practically the right type to use? or at least some type of known fixed width, if we're going to deliberately limit the number of bits

Parallel to that, the check in maybe_resize() that if ((size > hash_table->nnodes * 4... seems like it should first check that hash_table->nnodes isn't too big to multiply up without overflow (at whatever fixed width is decided). And then yes, a useful diagnostic would be preferable.
Comment 3 Philip Withnall 2017-10-25 10:35:56 UTC
(In reply to Daniel Boles from comment #2)
> The sizes in ghash.c being ints gives me immediate pause; wouldn't gsize be
> semantically and practically the right type to use? or at least some type of
> known fixed width, if we're going to deliberately limit the number of bits
> 
> Parallel to that, the check in maybe_resize() that if ((size >
> hash_table->nnodes * 4... seems like it should first check that
> hash_table->nnodes isn't too big to multiply up without overflow (at
> whatever fixed width is decided). And then yes, a useful diagnostic would be
> preferable.

Basically:
 • GHashTable is from the era of writing C when everything was an int and nobody used types like size_t
 • It was never written to be overflow-safe

Ideally both of those would be fixed (without breaking backwards compatibility).
Comment 4 iosipos.mpekenmpaouer 2017-10-25 11:31:01 UTC
First of all, sorry for submitting duplicate bug report 789432. I searched but could not find this one.

Then, as I say in that bug report, the problem is that integer overflow occurs earlier than what someone would expect given that size is 32-bit integer. So someone would expect that at least her application would work correctly for up to 2^31, but the problem occurs at 2^29 due to the hash_table->nnodes * 4 expression.
Comment 5 GNOME Infrastructure Team 2018-05-24 15:03:26 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/672.