Skip to content

Commit 7ab253f

Browse files
hashseedMylesBorins
authored andcommitted
deps: V8: cherry-pick 64-bit hash seed commits
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: #23274 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 104fbc6 commit 7ab253f

36 files changed

+180
-128
lines changed

deps/v8/include/v8-version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define V8_MAJOR_VERSION 6
1212
#define V8_MINOR_VERSION 2
1313
#define V8_BUILD_NUMBER 414
14-
#define V8_PATCH_LEVEL 68
14+
#define V8_PATCH_LEVEL 69
1515

1616
// Use 1 for candidates and 0 otherwise.
1717
// (Boolean macro values are not supported by all preprocessors.)

deps/v8/src/assembler.cc

+10
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,16 @@ ExternalReference ExternalReference::check_object_type(Isolate* isolate) {
14321432
return ExternalReference(Redirect(isolate, FUNCTION_ADDR(CheckObjectType)));
14331433
}
14341434

1435+
static uint32_t ComputeSeededIntegerHash(Isolate* isolate, uint32_t key) {
1436+
DisallowHeapAllocation no_gc;
1437+
return ComputeSeededHash(key, isolate->heap()->HashSeed());
1438+
}
1439+
1440+
ExternalReference ExternalReference::compute_integer_hash(Isolate* isolate) {
1441+
return ExternalReference(
1442+
Redirect(isolate, FUNCTION_ADDR(ComputeSeededIntegerHash)));
1443+
}
1444+
14351445
#ifdef V8_INTL_SUPPORT
14361446
ExternalReference ExternalReference::intl_convert_one_byte_to_lower(
14371447
Isolate* isolate) {

deps/v8/src/assembler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ class ExternalReference BASE_EMBEDDED {
979979
static ExternalReference try_internalize_string_function(Isolate* isolate);
980980

981981
static ExternalReference check_object_type(Isolate* isolate);
982-
982+
static ExternalReference compute_integer_hash(Isolate* isolate);
983983
#ifdef V8_INTL_SUPPORT
984984
static ExternalReference intl_convert_one_byte_to_lower(Isolate* isolate);
985985
static ExternalReference intl_to_latin1_lower_table(Isolate* isolate);

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

-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ bool AstValue::BooleanValue() const {
202202
UNREACHABLE();
203203
}
204204

205-
206205
void AstValue::Internalize(Isolate* isolate) {
207206
switch (type_) {
208207
case STRING:

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ class AstValue : public ZoneObject {
361361

362362
class AstStringConstants final {
363363
public:
364-
AstStringConstants(Isolate* isolate, uint32_t hash_seed)
364+
AstStringConstants(Isolate* isolate, uint64_t hash_seed)
365365
: zone_(isolate->allocator(), ZONE_NAME),
366366
string_table_(AstRawString::Compare),
367367
hash_seed_(hash_seed) {
@@ -391,15 +391,15 @@ class AstStringConstants final {
391391
STRING_CONSTANTS(F)
392392
#undef F
393393

394-
uint32_t hash_seed() const { return hash_seed_; }
394+
uint64_t hash_seed() const { return hash_seed_; }
395395
const base::CustomMatcherHashMap* string_table() const {
396396
return &string_table_;
397397
}
398398

399399
private:
400400
Zone zone_;
401401
base::CustomMatcherHashMap string_table_;
402-
uint32_t hash_seed_;
402+
uint64_t hash_seed_;
403403

404404
#define F(name, str) AstRawString* name##_string_;
405405
STRING_CONSTANTS(F)
@@ -418,7 +418,7 @@ class AstStringConstants final {
418418
class AstValueFactory {
419419
public:
420420
AstValueFactory(Zone* zone, const AstStringConstants* string_constants,
421-
uint32_t hash_seed)
421+
uint64_t hash_seed)
422422
: string_table_(string_constants->string_table()),
423423
values_(nullptr),
424424
strings_(nullptr),
@@ -535,7 +535,7 @@ class AstValueFactory {
535535

536536
Zone* zone_;
537537

538-
uint32_t hash_seed_;
538+
uint64_t hash_seed_;
539539

540540
#define F(name) AstValue* name##_;
541541
OTHER_CONSTANTS(F)

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

+5-6
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class CollectionsBuiltinsAssembler : public CodeStubAssembler {
9292
Node* key_tagged, Variable* result,
9393
Label* entry_found,
9494
Label* not_found);
95-
Node* ComputeIntegerHashForString(Node* context, Node* string_key);
95+
Node* ComputeStringHash(Node* context, Node* string_key);
9696
void SameValueZeroString(Node* context, Node* key_string, Node* candidate_key,
9797
Label* if_same, Label* if_not_same);
9898

@@ -515,8 +515,7 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey(
515515
Node* table, Node* smi_key, Variable* result, Label* entry_found,
516516
Label* not_found) {
517517
Node* const key_untagged = SmiUntag(smi_key);
518-
Node* const hash =
519-
ChangeInt32ToIntPtr(ComputeIntegerHash(key_untagged, Int32Constant(0)));
518+
Node* const hash = ChangeInt32ToIntPtr(ComputeUnseededHash(key_untagged));
520519
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0)));
521520
result->Bind(hash);
522521
FindOrderedHashTableEntry<CollectionType>(
@@ -531,7 +530,7 @@ template <typename CollectionType>
531530
void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey(
532531
Node* context, Node* table, Node* key_tagged, Variable* result,
533532
Label* entry_found, Label* not_found) {
534-
Node* const hash = ComputeIntegerHashForString(context, key_tagged);
533+
Node* const hash = ComputeStringHash(context, key_tagged);
535534
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0)));
536535
result->Bind(hash);
537536
FindOrderedHashTableEntry<CollectionType>(
@@ -573,8 +572,8 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForOtherKey(
573572
result, entry_found, not_found);
574573
}
575574

576-
Node* CollectionsBuiltinsAssembler::ComputeIntegerHashForString(
577-
Node* context, Node* string_key) {
575+
Node* CollectionsBuiltinsAssembler::ComputeStringHash(Node* context,
576+
Node* string_key) {
578577
VARIABLE(var_result, MachineType::PointerRepresentation());
579578

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

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

+27-17
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,6 @@ HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR);
200200
HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST);
201201
#undef HEAP_CONSTANT_TEST
202202

203-
Node* CodeStubAssembler::HashSeed() {
204-
return LoadAndUntagToWord32Root(Heap::kHashSeedRootIndex);
205-
}
206-
207203
Node* CodeStubAssembler::StaleRegisterConstant() {
208204
return LoadRoot(Heap::kStaleRegisterRootIndex);
209205
}
@@ -5389,22 +5385,32 @@ template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>(
53895385
template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
53905386
Node*, Node*, Label*, Variable*, Label*, int, LookupMode);
53915387

5392-
Node* CodeStubAssembler::ComputeIntegerHash(Node* key) {
5393-
return ComputeIntegerHash(key, IntPtrConstant(kZeroHashSeed));
5394-
}
5395-
5396-
Node* CodeStubAssembler::ComputeIntegerHash(Node* key, Node* seed) {
5397-
// See v8::internal::ComputeIntegerHash()
5388+
Node* CodeStubAssembler::ComputeUnseededHash(Node* key) {
5389+
// See v8::internal::ComputeUnseededHash()
53985390
Node* hash = TruncateWordToWord32(key);
5399-
hash = Word32Xor(hash, seed);
5400-
hash = Int32Add(Word32Xor(hash, Int32Constant(0xffffffff)),
5391+
hash = Int32Add(Word32Xor(hash, Int32Constant(0xFFFFFFFF)),
54015392
Word32Shl(hash, Int32Constant(15)));
54025393
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(12)));
54035394
hash = Int32Add(hash, Word32Shl(hash, Int32Constant(2)));
54045395
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(4)));
54055396
hash = Int32Mul(hash, Int32Constant(2057));
54065397
hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
5407-
return Word32And(hash, Int32Constant(0x3fffffff));
5398+
return Word32And(hash, Int32Constant(0x3FFFFFFF));
5399+
}
5400+
5401+
Node* CodeStubAssembler::ComputeSeededHash(Node* key) {
5402+
Node* const function_addr =
5403+
ExternalConstant(ExternalReference::compute_integer_hash(isolate()));
5404+
Node* const isolate_ptr =
5405+
ExternalConstant(ExternalReference::isolate_address(isolate()));
5406+
5407+
MachineType type_ptr = MachineType::Pointer();
5408+
MachineType type_uint32 = MachineType::Uint32();
5409+
5410+
Node* const result =
5411+
CallCFunction2(type_uint32, type_ptr, type_uint32, function_addr,
5412+
isolate_ptr, TruncateWordToWord32(key));
5413+
return result;
54085414
}
54095415

54105416
template <typename Dictionary>
@@ -5420,10 +5426,14 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
54205426
Node* capacity = SmiUntag(GetCapacity<Dictionary>(dictionary));
54215427
Node* mask = IntPtrSub(capacity, IntPtrConstant(1));
54225428

5423-
Node* int32_seed = std::is_same<Dictionary, SeededNumberDictionary>::value
5424-
? HashSeed()
5425-
: Int32Constant(kZeroHashSeed);
5426-
Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed));
5429+
Node* hash;
5430+
5431+
if (std::is_same<Dictionary, SeededNumberDictionary>::value) {
5432+
hash = ChangeUint32ToWord(ComputeSeededHash(intptr_index));
5433+
} else {
5434+
hash = ChangeUint32ToWord(ComputeUnseededHash(intptr_index));
5435+
}
5436+
54275437
Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index);
54285438

54295439
// See Dictionary::FirstProbe().

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
170170
HEAP_CONSTANT_LIST(HEAP_CONSTANT_TEST)
171171
#undef HEAP_CONSTANT_TEST
172172

173-
Node* HashSeed();
174173
Node* StaleRegisterConstant();
175174

176175
Node* IntPtrOrSmiConstant(int value, ParameterMode mode);
@@ -1276,8 +1275,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
12761275
int inlined_probes = kInlinedDictionaryProbes,
12771276
LookupMode mode = kFindExisting);
12781277

1279-
Node* ComputeIntegerHash(Node* key);
1280-
Node* ComputeIntegerHash(Node* key, Node* seed);
1278+
Node* ComputeUnseededHash(Node* key);
1279+
Node* ComputeSeededHash(Node* key);
12811280

12821281
template <typename Dictionary>
12831282
void NumberDictionaryLookup(Node* dictionary, Node* intptr_index,

deps/v8/src/external-reference-table.cc

+2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
232232
"try_internalize_string_function");
233233
Add(ExternalReference::check_object_type(isolate).address(),
234234
"check_object_type");
235+
Add(ExternalReference::compute_integer_hash(isolate).address(),
236+
"ComputeSeededHash");
235237
#ifdef V8_INTL_SUPPORT
236238
Add(ExternalReference::intl_convert_one_byte_to_lower(isolate).address(),
237239
"intl_convert_one_byte_to_lower");

deps/v8/src/flag-definitions.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct MaybeBoolFlag {
160160
FLAG(MAYBE_BOOL, MaybeBoolFlag, nam, {false COMMA false}, cmt)
161161
#define DEFINE_INT(nam, def, cmt) FLAG(INT, int, nam, def, cmt)
162162
#define DEFINE_UINT(nam, def, cmt) FLAG(UINT, unsigned int, nam, def, cmt)
163+
#define DEFINE_UINT64(nam, def, cmt) FLAG(UINT64, uint64_t, nam, def, cmt)
163164
#define DEFINE_FLOAT(nam, def, cmt) FLAG(FLOAT, double, nam, def, cmt)
164165
#define DEFINE_STRING(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt)
165166
#define DEFINE_ARGS(nam, cmt) FLAG(ARGS, JSArguments, nam, {0 COMMA NULL}, cmt)
@@ -914,9 +915,9 @@ DEFINE_BOOL(randomize_hashes, true,
914915
"(with snapshots this option cannot override the baked-in seed)")
915916
DEFINE_BOOL(rehash_snapshot, true,
916917
"rehash strings from the snapshot to override the baked-in seed")
917-
DEFINE_INT(hash_seed, 0,
918-
"Fixed seed to use to hash property keys (0 means random)"
919-
"(with snapshots this option cannot override the baked-in seed)")
918+
DEFINE_UINT64(hash_seed, 0,
919+
"Fixed seed to use to hash property keys (0 means random)"
920+
"(with snapshots this option cannot override the baked-in seed)")
920921
DEFINE_INT(random_seed, 0,
921922
"Default seed for initializing random generator "
922923
"(0, the default, means to use system random).")

deps/v8/src/flags.cc

+39
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_STRING,
4445
TYPE_ARGS
@@ -77,6 +78,11 @@ struct Flag {
7778
return reinterpret_cast<unsigned int*>(valptr_);
7879
}
7980

81+
uint64_t* uint64_variable() const {
82+
DCHECK(type_ == TYPE_UINT64);
83+
return reinterpret_cast<uint64_t*>(valptr_);
84+
}
85+
8086
double* float_variable() const {
8187
DCHECK(type_ == TYPE_FLOAT);
8288
return reinterpret_cast<double*>(valptr_);
@@ -115,6 +121,11 @@ struct Flag {
115121
return *reinterpret_cast<const unsigned int*>(defptr_);
116122
}
117123

124+
uint64_t uint64_default() const {
125+
DCHECK(type_ == TYPE_UINT64);
126+
return *reinterpret_cast<const uint64_t*>(defptr_);
127+
}
128+
118129
double float_default() const {
119130
DCHECK(type_ == TYPE_FLOAT);
120131
return *reinterpret_cast<const double*>(defptr_);
@@ -141,6 +152,8 @@ struct Flag {
141152
return *int_variable() == int_default();
142153
case TYPE_UINT:
143154
return *uint_variable() == uint_default();
155+
case TYPE_UINT64:
156+
return *uint64_variable() == uint64_default();
144157
case TYPE_FLOAT:
145158
return *float_variable() == float_default();
146159
case TYPE_STRING: {
@@ -171,6 +184,9 @@ struct Flag {
171184
case TYPE_UINT:
172185
*uint_variable() = uint_default();
173186
break;
187+
case TYPE_UINT64:
188+
*uint64_variable() = uint64_default();
189+
break;
174190
case TYPE_FLOAT:
175191
*float_variable() = float_default();
176192
break;
@@ -201,6 +217,8 @@ static const char* Type2String(Flag::FlagType type) {
201217
case Flag::TYPE_INT: return "int";
202218
case Flag::TYPE_UINT:
203219
return "uint";
220+
case Flag::TYPE_UINT64:
221+
return "uint64";
204222
case Flag::TYPE_FLOAT: return "float";
205223
case Flag::TYPE_STRING: return "string";
206224
case Flag::TYPE_ARGS: return "arguments";
@@ -225,6 +243,9 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT
225243
case Flag::TYPE_UINT:
226244
os << *flag.uint_variable();
227245
break;
246+
case Flag::TYPE_UINT64:
247+
os << *flag.uint64_variable();
248+
break;
228249
case Flag::TYPE_FLOAT:
229250
os << *flag.float_variable();
230251
break;
@@ -443,6 +464,24 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
443464
*flag->uint_variable() = static_cast<unsigned int>(val);
444465
break;
445466
}
467+
case Flag::TYPE_UINT64: {
468+
// We do not use strtoul because it accepts negative numbers.
469+
int64_t val = static_cast<int64_t>(strtoll(value, &endp, 10));
470+
if (val < 0 || val > std::numeric_limits<unsigned int>::max()) {
471+
PrintF(stderr,
472+
"Error: Value for flag %s of type %s is out of bounds "
473+
"[0-%" PRIu64
474+
"]\n"
475+
"Try --help for options\n",
476+
arg, Type2String(flag->type()),
477+
static_cast<uint64_t>(
478+
std::numeric_limits<unsigned int>::max()));
479+
return_code = j;
480+
break;
481+
}
482+
*flag->uint64_variable() = static_cast<uint64_t>(val);
483+
break;
484+
}
446485
case Flag::TYPE_FLOAT:
447486
*flag->float_variable() = strtod(value, &endp);
448487
break;

deps/v8/src/frames.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,8 @@ InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
21322132
InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
21332133
isolate_->counters()->pc_to_code()->Increment();
21342134
DCHECK(base::bits::IsPowerOfTwo(kInnerPointerToCodeCacheSize));
2135-
uint32_t hash = ComputeIntegerHash(ObjectAddressForHashing(inner_pointer));
2135+
uint32_t hash = ComputeUnseededHash(
2136+
ObjectAddressForHashing(reinterpret_cast<void*>(inner_pointer)));
21362137
uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
21372138
InnerPointerToCodeCacheEntry* entry = cache(index);
21382139
if (entry->inner_pointer == inner_pointer) {

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -614,13 +614,13 @@ Oddball* Heap::ToBoolean(bool condition) {
614614
return condition ? true_value() : false_value();
615615
}
616616

617-
uint32_t Heap::HashSeed() {
618-
uint32_t seed = static_cast<uint32_t>(hash_seed()->value());
617+
uint64_t Heap::HashSeed() {
618+
uint64_t seed;
619+
hash_seed()->copy_out(0, reinterpret_cast<byte*>(&seed), kInt64Size);
619620
DCHECK(FLAG_randomize_hashes || seed == 0);
620621
return seed;
621622
}
622623

623-
624624
int Heap::NextScriptId() {
625625
int last_id = last_script_id()->value();
626626
if (last_id == Smi::kMaxValue) {

0 commit comments

Comments
 (0)