Skip to content

Commit

Permalink
[Security] HHVM Accelerated Thrift: Protect against infinte loop in d…
Browse files Browse the repository at this point in the history
…eserialization

Summary:
As reported in T22402076, a maliciously crafted serialized message can trigger an infinite loop in the deserialization code of HHVM accelerated Thrift.

The cause of the bug if an overflow of the computed capacity which never exit the loop.
`while (Capacity(scale) < n) scale *= 2;`

The added check is (I believe) negligle in performance as the branch will almost always be correctly predicted.

Reviewed By: alexeyt

Differential Revision: D6684202

fbshipit-source-id: ef5b72a67bbec9f6bda5db4b0bb5f3c7793bc5dd
  • Loading branch information
stevegury authored and fredemmott committed Jan 11, 2018
1 parent c5efa15 commit 7c61f20
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 1 deletion.
4 changes: 3 additions & 1 deletion hphp/runtime/base/hash-table-inl.h
Expand Up @@ -20,7 +20,9 @@ namespace array {


ALWAYS_INLINE ALWAYS_INLINE
uint32_t HashTableCommon::computeScaleFromSize(uint32_t n) { uint32_t HashTableCommon::computeScaleFromSize(uint32_t n) {
assert(n <= 0x7fffffffU); if (n >= MaxSize) {
return MaxScale;
}
auto scale = SmallScale; auto scale = SmallScale;
while (Capacity(scale) < n) scale *= 2; while (Capacity(scale) < n) scale *= 2;
return scale; return scale;
Expand Down
1 change: 1 addition & 0 deletions hphp/runtime/base/hash-table.h
Expand Up @@ -73,6 +73,7 @@ struct HashTableCommon {
static constexpr uint32_t MaxMask = MaxHashSize - 1; static constexpr uint32_t MaxMask = MaxHashSize - 1;
static constexpr uint32_t MaxSize = MaxMask - MaxMask / LoadScale; static constexpr uint32_t MaxSize = MaxMask - MaxMask / LoadScale;
static constexpr uint32_t MaxMakeSize = 4 * SmallSize; static constexpr uint32_t MaxMakeSize = 4 * SmallSize;
static constexpr uint32_t MaxScale = MaxHashSize / LoadScale;


constexpr static uint32_t HashSize(uint32_t scale) { return 4 * scale; } constexpr static uint32_t HashSize(uint32_t scale) { return 4 * scale; }
constexpr static uint32_t Capacity(uint32_t scale) { return 3 * scale; } constexpr static uint32_t Capacity(uint32_t scale) { return 3 * scale; }
Expand Down

0 comments on commit 7c61f20

Please sign in to comment.