NEW 196935
Add an overflow check to HashTable
https://bugs.webkit.org/show_bug.cgi?id=196935
Summary Add an overflow check to HashTable
Ryosuke Niwa
Reported 2019-04-15 14:30:16 PDT
We should check for an integer overflow when expanding HashTable.
Attachments
Fixes the bug (11.30 KB, patch)
2019-04-15 20:32 PDT, Ryosuke Niwa
ggaren: review+
Ryosuke Niwa
Comment 1 2019-04-15 20:32:15 PDT
Created attachment 367492 [details] Fixes the bug
Radar WebKit Bug Importer
Comment 2 2019-04-15 20:33:01 PDT
Geoffrey Garen
Comment 3 2019-04-15 21:17:20 PDT
Comment on attachment 367492 [details] Fixes the bug View in context: https://bugs.webkit.org/attachment.cgi?id=367492&action=review r=me > Source/WTF/wtf/HashTable.h:1206 > + Checked<unsigned, CrashOnOverflow> bestTableSize = WTF::roundUpToPowerOfTwo(keyCount); > + if (bestTableSize.unsafeGet() < keyCount) > + bestTableSize.overflowed(); > + bestTableSize *= 2; If we needed a check here, I would recommend doing using Checked<T>. But we don't need this less-than check. roundUpToPowerOfTwo(2^32) is 2^32. There's no overflow case. I think I would write this as auto bestTableSize = Checked<unsigned, CrashOnOverflow>(WTF::roundUpToPowerOfTwo(keyCount)) * 2;
Ryosuke Niwa
Comment 4 2019-04-15 21:45:57 PDT
(In reply to Geoffrey Garen from comment #3) > Comment on attachment 367492 [details] > Fixes the bug > > View in context: > https://bugs.webkit.org/attachment.cgi?id=367492&action=review > > r=me > > > Source/WTF/wtf/HashTable.h:1206 > > + Checked<unsigned, CrashOnOverflow> bestTableSize = WTF::roundUpToPowerOfTwo(keyCount); > > + if (bestTableSize.unsafeGet() < keyCount) > > + bestTableSize.overflowed(); > > + bestTableSize *= 2; > > If we needed a check here, I would recommend doing using Checked<T>. > > But we don't need this less-than check. roundUpToPowerOfTwo(2^32) is 2^32. > There's no overflow case. Hm... roundUpToPowerOfTwo(0x8fffffff) is 0 though. Do we have some guarantee that 0x80000000 would be the maximum key count?
Geoffrey Garen
Comment 5 2019-04-16 10:55:41 PDT
> > If we needed a check here, I would recommend doing using Checked<T>. > > > > But we don't need this less-than check. roundUpToPowerOfTwo(2^32) is 2^32. > > There's no overflow case. > > Hm... roundUpToPowerOfTwo(0x8fffffff) is 0 though. Do we have some guarantee > that 0x80000000 would be the maximum key count? Eep! I have immortalized in Bugzilla my inability to do binary arithmetic. Don't tell Gavin. :) I think the problem input case is anything in the range (0x80000000, 0xffffffff], which is (2^31, 2^32-1]. In that case, the correct answer is 0x0000000100000000, which is not representable as uint32_t. And the implementation of roundUpToPowerOfTwo() will happen to return 0 (as you said). Maybe the right solution is to templatize roundUpToPowerOfTwo() to accept uint32_t or Checked<uint32_t>, so it can naturally catch the overflow to zero on the final ++ operation? I'm open to any solution that doesn't require an explicit check in the calling code. That's the primary benefit of Checked<T>.
Ryosuke Niwa
Comment 6 2019-04-16 21:03:35 PDT
Interesting, in the process of adding Checked<U, V> support to roundUpToPowerOfTwo, I found out that CachedTypes::malloc converts size_t to uint32_t that's probably a bug...
Note You need to log in before you can comment on or make changes to this bug.