Skip to content

Commit f08373f

Browse files
hashseedtargos
authored andcommitted
deps: cherry-pick 64-bit hash seed commits from V8
This serves as mitigation for the so-called HashWick vulnerability. Original commit messages: commit d5686a74d56fbb6985b22663ddadd66eb7b91519 Author: Yang Guo <[email protected]> Date: Mon Jul 16 11:19:42 2018 Extend hash seed to 64 bits [email protected], [email protected] Bug: chromium:680662 Change-Id: I5e1486ad2a42db2998d5485a0c4e711378678e6c Reviewed-on: https://chromium-review.googlesource.com/1136034 Reviewed-by: Marja Hölttä <[email protected]> Reviewed-by: Ulan Degenbaev <[email protected]> Reviewed-by: Benedikt Meurer <[email protected]> Commit-Queue: Yang Guo <[email protected]> Cr-Commit-Position: refs/heads/master@{#54460} commit 3833fef57368c53c6170559ffa524c8c69f16ee5 Author: Yang Guo <[email protected]> Date: Thu Sep 20 11:43:13 2018 Refactor integer hashing function names We now clearly differentiate between: - unseeded hash for 32-bit integers - unseeded hash for 64-bit integers - seeded hash for 32-bit integers - seeded hash for strings [email protected] Bug: chromium:680662 Change-Id: I7459958c4158ee3501c962943dff8f33258bb5ce Reviewed-on: https://chromium-review.googlesource.com/1235973 Commit-Queue: Yang Guo <[email protected]> Reviewed-by: Benedikt Meurer <[email protected]> Cr-Commit-Position: refs/heads/master@{#56068} commit 95a979e02d7154e45b293261a6998c99d71fc238 Author: Yang Guo <[email protected]> Date: Thu Sep 20 14:34:48 2018 Call into C++ to compute seeded integer hash [email protected] Bug: chromium:680662 Change-Id: I8dace89d576dfcc5833fd539ce698a9ade1cb5a0 Reviewed-on: https://chromium-review.googlesource.com/1235928 Commit-Queue: Yang Guo <[email protected]> Reviewed-by: Benedikt Meurer <[email protected]> Cr-Commit-Position: refs/heads/master@{#56091} commit 2c2af0022d5feb9e525a00a76cb15db9f3e38dba Author: Yang Guo <[email protected]> Date: Thu Sep 27 16:37:57 2018 Use 64-bit for seeded integer hashes [email protected] Bug: chromium:680662 Change-Id: If48d1043dbe1e1bb695ec890c23e103a6cacf2d4 Reviewed-on: https://chromium-review.googlesource.com/1244220 Commit-Queue: Yang Guo <[email protected]> Reviewed-by: Peter Marshall <[email protected]> Cr-Commit-Position: refs/heads/master@{#56271} Refs: #23259 PR-URL: #23260 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ali Ijaz Sheikh <[email protected]>
1 parent 77de1be commit f08373f

40 files changed

+172
-140
lines changed

common.gypi

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525
'uv_library%': 'static_library',
2626

2727
'clang%': 0,
28-
28+
2929
'openssl_fips%': '',
3030

3131
# Default to -O0 for debug builds.
3232
'v8_optimized_debug%': 0,
3333

3434
# Reset this number to 0 on major V8 upgrades.
3535
# Increment by one for each non-official patch applied to deps/v8.
36-
'v8_embedder_string': '-node.32',
36+
'v8_embedder_string': '-node.33',
3737

3838
# Enable disassembler for `--print-code` v8 options
3939
'v8_enable_disassembler': 1,

deps/v8/src/ast/ast-value-factory.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ std::forward_list<const AstRawString*> AstConsString::ToRawStrings() const {
182182
return result;
183183
}
184184

185-
AstStringConstants::AstStringConstants(Isolate* isolate, uint32_t hash_seed)
185+
AstStringConstants::AstStringConstants(Isolate* isolate, uint64_t hash_seed)
186186
: zone_(isolate->allocator(), ZONE_NAME),
187187
string_table_(AstRawString::Compare),
188188
hash_seed_(hash_seed) {

deps/v8/src/ast/ast-value-factory.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,22 @@ class AstBigInt {
240240

241241
class AstStringConstants final {
242242
public:
243-
AstStringConstants(Isolate* isolate, uint32_t hash_seed);
243+
AstStringConstants(Isolate* isolate, uint64_t hash_seed);
244244

245245
#define F(name, str) \
246246
const AstRawString* name##_string() const { return name##_string_; }
247247
AST_STRING_CONSTANTS(F)
248248
#undef F
249249

250-
uint32_t hash_seed() const { return hash_seed_; }
250+
uint64_t hash_seed() const { return hash_seed_; }
251251
const base::CustomMatcherHashMap* string_table() const {
252252
return &string_table_;
253253
}
254254

255255
private:
256256
Zone zone_;
257257
base::CustomMatcherHashMap string_table_;
258-
uint32_t hash_seed_;
258+
uint64_t hash_seed_;
259259

260260
#define F(name, str) AstRawString* name##_string_;
261261
AST_STRING_CONSTANTS(F)
@@ -267,7 +267,7 @@ class AstStringConstants final {
267267
class AstValueFactory {
268268
public:
269269
AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
270-
uint32_t hash_seed)
270+
uint64_t hash_seed)
271271
: string_table_(string_constants->string_table()),
272272
strings_(nullptr),
273273
strings_end_(&strings_),
@@ -354,7 +354,7 @@ class AstValueFactory {
354354

355355
Zone* zone_;
356356

357-
uint32_t hash_seed_;
357+
uint64_t hash_seed_;
358358
};
359359
} // namespace internal
360360
} // namespace v8

deps/v8/src/builtins/builtins-collections-gen.cc

+5-6
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler {
684684
Node* key_tagged, Variable* result,
685685
Label* entry_found,
686686
Label* not_found);
687-
Node* ComputeIntegerHashForString(Node* context, Node* string_key);
687+
Node* ComputeStringHash(Node* context, Node* string_key);
688688
void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key,
689689
Label* if_same, Label* if_not_same);
690690

@@ -828,8 +828,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey(
828828
Node* table, Node* smi_key, Variable* result, Label* entry_found,
829829
Label* not_found) {
830830
Node* const key_untagged = SmiUntag(smi_key);
831-
Node* const hash =
832-
ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0)));
831+
Node* const hash = ChangeInt32ToIntPtr(ComputeUnseededHash(key_untagged));
833832
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0)));
834833
result->Bind(hash);
835834
FindOrderedHashTableEntry<CollectionType>(
@@ -844,7 +843,7 @@ template <typename CollectionType>
844843
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey(
845844
Node* context, Node* table, Node* key_tagged, Variable* result,
846845
Label* entry_found, Label* not_found) {
847-
Node* const hash = ComputeIntegerHashForString(context, key_tagged);
846+
Node* const hash = ComputeStringHash(context, key_tagged);
848847
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0)));
849848
result->Bind(hash);
850849
FindOrderedHashTableEntry<CollectionType>(
@@ -902,8 +901,8 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForOtherKey(
902901
result, entry_found, not_found);
903902
}
904903

905-
Node* CollectionsBuiltinsAssembler::ComputeIntegerHashForString(
906-
Node* context, Node* string_key) {
904+
Node* CollectionsBuiltinsAssembler::ComputeStringHash(Node* context,
905+
Node* string_key) {
907906
VARIABLE(var_result, MachineType::PointerRepresentation());
908907

909908
Label hash_not_computed(this), done(this, &var_result);

deps/v8/src/code-stub-assembler.cc

+18-14
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,6 @@ HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR);
230230
HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST);
231231
#undef HEAP_CONSTANT_TEST
232232

233-
TNode<Int32T> CodeStubAssembler::HashSeed() {
234-
return LoadAndUntagToWord32Root(Heap::kHashSeedRootIndex);
235-
}
236-
237233
Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) {
238234
if (mode == SMI_PARAMETERS) {
239235
return SmiConstant(value);
@@ -7094,14 +7090,9 @@ template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
70947090
TNode<GlobalDictionary>, TNode<Name>, Label*, TVariable<IntPtrT>*, Label*,
70957091
int, LookupMode);
70967092

7097-
Node* CodeStubAssembler::ComputeIntegerHash(Node* key) {
7098-
return ComputeIntegerHash(key, IntPtrConstant(kZeroHashSeed));
7099-
}
7100-
7101-
Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
7102-
// See v8::internal::ComputeIntegerHash()
7093+
Node* CodeStubAssembler::ComputeUnseededHash(Node* key) {
7094+
// See v8::internal::ComputeUnseededHash()
71037095
Node* hash = TruncateIntPtrToInt32(key);
7104-
hash = Word32Xor(hash, seed);
71057096
hash = Int32Add(Word32Xor(hash, Int32Constant(0xFFFFFFFF)),
71067097
Word32Shl(hash, Int32Constant(15)));
71077098
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
@@ -7112,6 +7103,21 @@ Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
71127103
return Word32And(hash, Int32Constant(0x3FFFFFFF));
71137104
}
71147105

7106+
Node* CodeStubAssembler::ComputeSeededHash(Node* key) {
7107+
Node* const function_addr =
7108+
ExternalConstant(ExternalReference::compute_integer_hash());
7109+
Node* const isolate_ptr =
7110+
ExternalConstant(ExternalReference::isolate_address(isolate()));
7111+
7112+
MachineType type_ptr = MachineType::Pointer();
7113+
MachineType type_uint32 = MachineType::Uint32();
7114+
7115+
Node* const result =
7116+
CallCFunction2(type_uint32, type_ptr, type_uint32, function_addr,
7117+
isolate_ptr, TruncateIntPtrToInt32(key));
7118+
return result;
7119+
}
7120+
71157121
void CodeStubAssembler::NumberDictionaryLookup(
71167122
TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index,
71177123
Label* if_found, TVariable<IntPtrT>* var_entry, Label* if_not_found) {
@@ -7122,9 +7128,7 @@ void CodeStubAssembler::NumberDictionaryLookup(
71227128
TNode<IntPtrT> capacity = SmiUntag(GetCapacity<NumberDictionary>(dictionary));
71237129
TNode<WordT> mask = IntPtrSub(capacity, IntPtrConstant(1));
71247130

7125-
TNode<Int32T> int32_seed = HashSeed();
7126-
TNode<WordT> hash =
7127-
ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
7131+
TNode<WordT> hash = ChangeUint32ToWord(ComputeSeededHash(intptr_index));
71287132
Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
71297133

71307134
// See Dictionary::FirstProbe().

deps/v8/src/code-stub-assembler.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
221221
HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST)
222222
#undef HEAP_CONSTANT_TEST
223223

224-
TNode<Int32T> HashSeed();
225-
226224
Node* IntPtrOrSmiConstant(int value, ParameterMode mode);
227225
TNode<BoolT> BoolConstant(bool value) {
228226
return value ? Int32TrueConstant() : Int32FalseConstant();
@@ -1883,8 +1881,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
18831881
int inlined_probes = kInlinedDictionaryProbes,
18841882
LookupMode mode = kFindExisting);
18851883

1886-
Node* ComputeIntegerHash(Node* key);
1887-
Node* ComputeIntegerHash(Node* key, Node* seed);
1884+
Node* ComputeUnseededHash(Node* key);
1885+
Node* ComputeSeededHash(Node* key);
18881886

18891887
void NumberDictionaryLookup(TNode<NumberDictionary> dictionary,
18901888
TNode<IntPtrT> intptr_index, Label* if_found,

deps/v8/src/compiler/effect-control-linearizer.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -4583,8 +4583,8 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
45834583
}
45844584
}
45854585

4586-
Node* EffectControlLinearizer::ComputeIntegerHash(Node* value) {
4587-
// See v8::internal::ComputeIntegerHash()
4586+
Node* EffectControlLinearizer::ComputeUnseededHash(Node* value) {
4587+
// See v8::internal::ComputeUnseededHash()
45884588
value = __ Int32Add(__ Word32Xor(value, __ Int32Constant(0xFFFFFFFF)),
45894589
__ Word32Shl(value, __ Int32Constant(15)));
45904590
value = __ Word32Xor(value, __ Word32Shr(value, __ Int32Constant(12)));
@@ -4602,7 +4602,7 @@ Node* EffectControlLinearizer::LowerFindOrderedHashMapEntryForInt32Key(
46024602
Node* key = NodeProperties::GetValueInput(node, 1);
46034603

46044604
// Compute the integer hash code.
4605-
Node* hash = ChangeUint32ToUintPtr(ComputeIntegerHash(key));
4605+
Node* hash = ChangeUint32ToUintPtr(ComputeUnseededHash(key));
46064606

46074607
Node* number_of_buckets = ChangeSmiToIntPtr(__ LoadField(
46084608
AccessBuilder::ForOrderedHashTableBaseNumberOfBuckets(), table));

deps/v8/src/compiler/effect-control-linearizer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class V8_EXPORT_PRIVATE EffectControlLinearizer {
178178
Node* frame_state);
179179
Node* BuildFloat64RoundDown(Node* value);
180180
Node* BuildFloat64RoundTruncate(Node* input);
181-
Node* ComputeIntegerHash(Node* value);
181+
Node* ComputeUnseededHash(Node* value);
182182
Node* LowerStringComparison(Callable const& callable, Node* node);
183183
Node* IsElementsKindGreaterThan(Node* kind, ElementsKind reference_kind);
184184

deps/v8/src/external-reference.cc

+9
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,15 @@ ExternalReference ExternalReference::jsreceiver_create_identity_hash(
778778
return ExternalReference(Redirect(FUNCTION_ADDR(f)));
779779
}
780780

781+
static uint32_t ComputeSeededIntegerHash(Isolate* isolate, uint32_t key) {
782+
DisallowHeapAllocation no_gc;
783+
return ComputeSeededHash(key, isolate->heap()->HashSeed());
784+
}
785+
786+
ExternalReference ExternalReference::compute_integer_hash() {
787+
return ExternalReference(Redirect(FUNCTION_ADDR(ComputeSeededIntegerHash)));
788+
}
789+
781790
ExternalReference
782791
ExternalReference::copy_fast_number_jsarray_elements_to_typed_array() {
783792
return ExternalReference(

deps/v8/src/external-reference.h

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class StatsCounter;
8181
V(address_of_uint32_bias, "uint32_bias") \
8282
V(bytecode_size_table_address, "Bytecodes::bytecode_size_table_address") \
8383
V(check_object_type, "check_object_type") \
84+
V(compute_integer_hash, "ComputeSeededHash") \
8485
V(compute_output_frames_function, "Deoptimizer::ComputeOutputFrames()") \
8586
V(copy_fast_number_jsarray_elements_to_typed_array, \
8687
"copy_fast_number_jsarray_elements_to_typed_array") \

deps/v8/src/flag-definitions.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct MaybeBoolFlag {
162162
FLAG(MAYBE_BOOL, MaybeBoolFlag, nam, {false COMMA false}, cmt)
163163
#define DEFINE_INT(nam, def, cmt) FLAG(INT, int, nam, def, cmt)
164164
#define DEFINE_UINT(nam, def, cmt) FLAG(UINT, unsigned int, nam, def, cmt)
165+
#define DEFINE_UINT64(nam, def, cmt) FLAG(UINT64, uint64_t, nam, def, cmt)
165166
#define DEFINE_FLOAT(nam, def, cmt) FLAG(FLOAT, double, nam, def, cmt)
166167
#define DEFINE_SIZE_T(nam, def, cmt) FLAG(SIZE_T, size_t, nam, def, cmt)
167168
#define DEFINE_STRING(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt)
@@ -1019,9 +1020,9 @@ DEFINE_BOOL(randomize_hashes, true,
10191020
"(with snapshots this option cannot override the baked-in seed)")
10201021
DEFINE_BOOL(rehash_snapshot, true,
10211022
"rehash strings from the snapshot to override the baked-in seed")
1022-
DEFINE_INT(hash_seed, 0,
1023-
"Fixed seed to use to hash property keys (0 means random)"
1024-
"(with snapshots this option cannot override the baked-in seed)")
1023+
DEFINE_UINT64(hash_seed, 0,
1024+
"Fixed seed to use to hash property keys (0 means random)"
1025+
"(with snapshots this option cannot override the baked-in seed)")
10251026
DEFINE_INT(random_seed, 0,
10261027
"Default seed for initializing random generator "
10271028
"(0, the default, means to use system random).")

deps/v8/src/flags.cc

+27
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct Flag {
3939
TYPE_MAYBE_BOOL,
4040
TYPE_INT,
4141
TYPE_UINT,
42+
TYPE_UINT64,
4243
TYPE_FLOAT,
4344
TYPE_SIZE_T,
4445
TYPE_STRING,
@@ -78,6 +79,11 @@ struct Flag {
7879
return reinterpret_cast<unsigned int*>(valptr_);
7980
}
8081

82+
uint64_t* uint64_variable() const {
83+
DCHECK(type_ == TYPE_UINT64);
84+
return reinterpret_cast<uint64_t*>(valptr_);
85+
}
86+
8187
double* float_variable() const {
8288
DCHECK(type_ == TYPE_FLOAT);
8389
return reinterpret_cast<double*>(valptr_);
@@ -121,6 +127,11 @@ struct Flag {
121127
return *reinterpret_cast<const unsigned int*>(defptr_);
122128
}
123129

130+
uint64_t uint64_default() const {
131+
DCHECK(type_ == TYPE_UINT64);
132+
return *reinterpret_cast<const uint64_t*>(defptr_);
133+
}
134+
124135
double float_default() const {
125136
DCHECK(type_ == TYPE_FLOAT);
126137
return *reinterpret_cast<const double*>(defptr_);
@@ -152,6 +163,8 @@ struct Flag {
152163
return *int_variable() == int_default();
153164
case TYPE_UINT:
154165
return *uint_variable() == uint_default();
166+
case TYPE_UINT64:
167+
return *uint64_variable() == uint64_default();
155168
case TYPE_FLOAT:
156169
return *float_variable() == float_default();
157170
case TYPE_SIZE_T:
@@ -184,6 +197,9 @@ struct Flag {
184197
case TYPE_UINT:
185198
*uint_variable() = uint_default();
186199
break;
200+
case TYPE_UINT64:
201+
*uint64_variable() = uint64_default();
202+
break;
187203
case TYPE_FLOAT:
188204
*float_variable() = float_default();
189205
break;
@@ -217,6 +233,8 @@ static const char* Type2String(Flag::FlagType type) {
217233
case Flag::TYPE_INT: return "int";
218234
case Flag::TYPE_UINT:
219235
return "uint";
236+
case Flag::TYPE_UINT64:
237+
return "uint64";
220238
case Flag::TYPE_FLOAT: return "float";
221239
case Flag::TYPE_SIZE_T:
222240
return "size_t";
@@ -243,6 +261,9 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT
243261
case Flag::TYPE_UINT:
244262
os << *flag.uint_variable();
245263
break;
264+
case Flag::TYPE_UINT64:
265+
os << *flag.uint64_variable();
266+
break;
246267
case Flag::TYPE_FLOAT:
247268
os << *flag.float_variable();
248269
break;
@@ -464,6 +485,12 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
464485
return_code = j;
465486
}
466487
break;
488+
case Flag::TYPE_UINT64:
489+
if (!TryParseUnsigned(flag, arg, value, &endp,
490+
flag->uint64_variable())) {
491+
return_code = j;
492+
}
493+
break;
467494
case Flag::TYPE_FLOAT:
468495
*flag->float_variable() = strtod(value, &endp);
469496
break;

deps/v8/src/frames.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2146,7 +2146,7 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
21462146
InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
21472147
isolate_->counters()->pc_to_code()->Increment();
21482148
DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
2149-
uint32_t hash = ComputeIntegerHash(
2149+
uint32_t hash = ComputeUnseededHash(
21502150
ObjectAddressForHashing(reinterpret_cast<void*>(inner_pointer)));
21512151
uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
21522152
InnerPointerToCodeCacheEntry* entry = cache(index);

deps/v8/src/heap/heap-inl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,13 @@ Oddball* Heap::ToBoolean(bool condition) {
529529
return condition ? true_value() : false_value();
530530
}
531531

532-
uint32_t Heap::HashSeed() {
533-
uint32_t seed = static_cast<uint32_t>(hash_seed()->value());
532+
uint64_t Heap::HashSeed() {
533+
uint64_t seed;
534+
hash_seed()->copy_out(0, reinterpret_cast<byte*>(&seed), kInt64Size);
534535
DCHECK(FLAG_randomize_hashes || seed == 0);
535536
return seed;
536537
}
537538

538-
539539
int Heap::NextScriptId() {
540540
int last_id = last_script_id()->value();
541541
if (last_id == Smi::kMaxValue) last_id = v8::UnboundScript::kNoScriptId;

0 commit comments

Comments
 (0)