Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: src/serialize.cc

Issue 841943002: Fix unsafe unaligned accesses in the serializer/deserializer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/serialize.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 NameMap address_to_name_map_; 607 NameMap address_to_name_map_;
608 Isolate* isolate_; 608 Isolate* isolate_;
609 }; 609 };
610 610
611 611
612 void Deserializer::DecodeReservation( 612 void Deserializer::DecodeReservation(
613 Vector<const SerializedData::Reservation> res) { 613 Vector<const SerializedData::Reservation> res) {
614 DCHECK_EQ(0, reservations_[NEW_SPACE].length()); 614 DCHECK_EQ(0, reservations_[NEW_SPACE].length());
615 STATIC_ASSERT(NEW_SPACE == 0); 615 STATIC_ASSERT(NEW_SPACE == 0);
616 int current_space = NEW_SPACE; 616 int current_space = NEW_SPACE;
617 for (const auto& r : res) { 617 for (int i = 0; i < res.length(); i++) {
618 SerializedData::Reservation r(0);
619 memcpy(&r, res.start() + i, sizeof(r));
618 reservations_[current_space].Add({r.chunk_size(), NULL, NULL}); 620 reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
619 if (r.is_last()) current_space++; 621 if (r.is_last()) current_space++;
620 } 622 }
621 DCHECK_EQ(kNumberOfSpaces, current_space); 623 DCHECK_EQ(kNumberOfSpaces, current_space);
622 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; 624 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0;
623 } 625 }
624 626
625 627
626 void Deserializer::FlushICacheForNewCodeObjects() { 628 void Deserializer::FlushICacheForNewCodeObjects() {
627 PageIterator it(isolate_->heap()->code_space()); 629 PageIterator it(isolate_->heap()->code_space());
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 ReadData(current, limit, space_number, address); 855 ReadData(current, limit, space_number, address);
854 856
855 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() 857 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
856 // as a (weak) root. If this root is relocated correctly, 858 // as a (weak) root. If this root is relocated correctly,
857 // RelinkAllocationSite() isn't necessary. 859 // RelinkAllocationSite() isn't necessary.
858 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); 860 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
859 861
860 // Fix up strings from serialized user code. 862 // Fix up strings from serialized user code.
861 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); 863 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
862 864
863 *write_back = obj; 865 Object* write_back_obj = obj;
866 UnalignedCopy(write_back, &write_back_obj);
864 #ifdef DEBUG 867 #ifdef DEBUG
865 if (obj->IsCode()) { 868 if (obj->IsCode()) {
866 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); 869 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE);
867 } else { 870 } else {
868 DCHECK(space_number != CODE_SPACE); 871 DCHECK(space_number != CODE_SPACE);
869 } 872 }
870 #endif 873 #endif
871 } 874 }
872 875
873 876
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 if (how == kFromCode) { \ 999 if (how == kFromCode) { \
997 Address location_of_branch_data = reinterpret_cast<Address>(current); \ 1000 Address location_of_branch_data = reinterpret_cast<Address>(current); \
998 Assembler::deserialization_set_special_target_at( \ 1001 Assembler::deserialization_set_special_target_at( \
999 location_of_branch_data, \ 1002 location_of_branch_data, \
1000 Code::cast(HeapObject::FromAddress(current_object_address)), \ 1003 Code::cast(HeapObject::FromAddress(current_object_address)), \
1001 reinterpret_cast<Address>(new_object)); \ 1004 reinterpret_cast<Address>(new_object)); \
1002 location_of_branch_data += Assembler::kSpecialTargetSize; \ 1005 location_of_branch_data += Assembler::kSpecialTargetSize; \
1003 current = reinterpret_cast<Object**>(location_of_branch_data); \ 1006 current = reinterpret_cast<Object**>(location_of_branch_data); \
1004 current_was_incremented = true; \ 1007 current_was_incremented = true; \
1005 } else { \ 1008 } else { \
1006 *current = new_object; \ 1009 UnalignedCopy(current, &new_object); \
1007 } \ 1010 } \
1008 } \ 1011 } \
1009 if (emit_write_barrier && write_barrier_needed) { \ 1012 if (emit_write_barrier && write_barrier_needed) { \
1010 Address current_address = reinterpret_cast<Address>(current); \ 1013 Address current_address = reinterpret_cast<Address>(current); \
1011 isolate->heap()->RecordWrite( \ 1014 isolate->heap()->RecordWrite( \
1012 current_object_address, \ 1015 current_object_address, \
1013 static_cast<int>(current_address - current_object_address)); \ 1016 static_cast<int>(current_address - current_object_address)); \
1014 } \ 1017 } \
1015 if (!current_was_incremented) { \ 1018 if (!current_was_incremented) { \
1016 current++; \ 1019 current++; \
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 byte* raw_data_out = reinterpret_cast<byte*>(current); 1100 byte* raw_data_out = reinterpret_cast<byte*>(current);
1098 source_.CopyRaw(raw_data_out, size); 1101 source_.CopyRaw(raw_data_out, size);
1099 break; 1102 break;
1100 } 1103 }
1101 1104
1102 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) 1105 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance)
1103 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { 1106 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) {
1104 int root_id = RootArrayConstantFromByteCode(data); 1107 int root_id = RootArrayConstantFromByteCode(data);
1105 Object* object = isolate->heap()->roots_array_start()[root_id]; 1108 Object* object = isolate->heap()->roots_array_start()[root_id];
1106 DCHECK(!isolate->heap()->InNewSpace(object)); 1109 DCHECK(!isolate->heap()->InNewSpace(object));
1107 *current++ = object; 1110 UnalignedCopy(current++, &object);
1108 break; 1111 break;
1109 } 1112 }
1110 1113
1111 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) 1114 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
1112 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { 1115 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
1113 int root_id = RootArrayConstantFromByteCode(data); 1116 int root_id = RootArrayConstantFromByteCode(data);
1114 int skip = source_.GetInt(); 1117 int skip = source_.GetInt();
1115 current = reinterpret_cast<Object**>( 1118 current = reinterpret_cast<Object**>(
1116 reinterpret_cast<intptr_t>(current) + skip); 1119 reinterpret_cast<intptr_t>(current) + skip);
1117 Object* object = isolate->heap()->roots_array_start()[root_id]; 1120 Object* object = isolate->heap()->roots_array_start()[root_id];
1118 DCHECK(!isolate->heap()->InNewSpace(object)); 1121 DCHECK(!isolate->heap()->InNewSpace(object));
1119 *current++ = object; 1122 UnalignedCopy(current++, &object);
1120 break; 1123 break;
1121 } 1124 }
1122 1125
1123 case kVariableRepeat: { 1126 case kVariableRepeat: {
1124 int repeats = source_.GetInt(); 1127 int repeats = source_.GetInt();
1125 Object* object = current[-1]; 1128 Object* object = current[-1];
1126 DCHECK(!isolate->heap()->InNewSpace(object)); 1129 DCHECK(!isolate->heap()->InNewSpace(object));
1127 for (int i = 0; i < repeats; i++) current[i] = object; 1130 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
1128 current += repeats;
1129 break; 1131 break;
1130 } 1132 }
1131 1133
1132 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == 1134 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
1133 Heap::kOldSpaceRoots); 1135 Heap::kOldSpaceRoots);
1134 STATIC_ASSERT(kMaxFixedRepeats == 15); 1136 STATIC_ASSERT(kMaxFixedRepeats == 15);
1135 FOUR_CASES(kFixedRepeat) 1137 FOUR_CASES(kFixedRepeat)
1136 FOUR_CASES(kFixedRepeat + 4) 1138 FOUR_CASES(kFixedRepeat + 4)
1137 FOUR_CASES(kFixedRepeat + 8) 1139 FOUR_CASES(kFixedRepeat + 8)
1138 case kFixedRepeat + 12: 1140 case kFixedRepeat + 12:
1139 case kFixedRepeat + 13: 1141 case kFixedRepeat + 13:
1140 case kFixedRepeat + 14: { 1142 case kFixedRepeat + 14: {
1141 int repeats = RepeatsForCode(data); 1143 int repeats = RepeatsForCode(data);
1142 Object* object = current[-1]; 1144 Object* object;
1145 UnalignedCopy(&object, current - 1);
1143 DCHECK(!isolate->heap()->InNewSpace(object)); 1146 DCHECK(!isolate->heap()->InNewSpace(object));
1144 for (int i = 0; i < repeats; i++) current[i] = object; 1147 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
1145 current += repeats;
1146 break; 1148 break;
1147 } 1149 }
1148 1150
1149 // Deserialize a new object and write a pointer to it to the current 1151 // Deserialize a new object and write a pointer to it to the current
1150 // object. 1152 // object.
1151 ALL_SPACES(kNewObject, kPlain, kStartOfObject) 1153 ALL_SPACES(kNewObject, kPlain, kStartOfObject)
1152 // Support for direct instruction pointers in functions. It's an inner 1154 // Support for direct instruction pointers in functions. It's an inner
1153 // pointer because it points at the entry point, not at the start of the 1155 // pointer because it points at the entry point, not at the start of the
1154 // code object. 1156 // code object.
1155 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) 1157 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE)
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 break; 1249 break;
1248 } 1250 }
1249 1251
1250 case kNativesStringResource: { 1252 case kNativesStringResource: {
1251 int index = source_.Get(); 1253 int index = source_.Get();
1252 Vector<const char> source_vector = Natives::GetScriptSource(index); 1254 Vector<const char> source_vector = Natives::GetScriptSource(index);
1253 NativesExternalStringResource* resource = 1255 NativesExternalStringResource* resource =
1254 new NativesExternalStringResource(isolate->bootstrapper(), 1256 new NativesExternalStringResource(isolate->bootstrapper(),
1255 source_vector.start(), 1257 source_vector.start(),
1256 source_vector.length()); 1258 source_vector.length());
1257 *current++ = reinterpret_cast<Object*>(resource); 1259 Object* resource_obj = reinterpret_cast<Object*>(resource);
1260 UnalignedCopy(current++, &resource_obj);
1258 break; 1261 break;
1259 } 1262 }
1260 1263
1261 case kNextChunk: { 1264 case kNextChunk: {
1262 int space = source_.Get(); 1265 int space = source_.Get();
1263 DCHECK(space < kNumberOfPreallocatedSpaces); 1266 DCHECK(space < kNumberOfPreallocatedSpaces);
1264 int chunk_index = current_chunk_[space]; 1267 int chunk_index = current_chunk_[space];
1265 const Heap::Reservation& reservation = reservations_[space]; 1268 const Heap::Reservation& reservation = reservations_[space];
1266 // Make sure the current chunk is indeed exhausted. 1269 // Make sure the current chunk is indeed exhausted.
1267 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); 1270 CHECK_EQ(reservation[chunk_index].end, high_water_[space]);
1268 // Move to next reserved chunk. 1271 // Move to next reserved chunk.
1269 chunk_index = ++current_chunk_[space]; 1272 chunk_index = ++current_chunk_[space];
1270 DCHECK_LT(chunk_index, reservation.length()); 1273 DCHECK_LT(chunk_index, reservation.length());
1271 high_water_[space] = reservation[chunk_index].start; 1274 high_water_[space] = reservation[chunk_index].start;
1272 break; 1275 break;
1273 } 1276 }
1274 1277
1275 FOUR_CASES(kHotObjectWithSkip) 1278 FOUR_CASES(kHotObjectWithSkip)
1276 FOUR_CASES(kHotObjectWithSkip + 4) { 1279 FOUR_CASES(kHotObjectWithSkip + 4) {
1277 int skip = source_.GetInt(); 1280 int skip = source_.GetInt();
1278 current = reinterpret_cast<Object**>( 1281 current = reinterpret_cast<Object**>(
1279 reinterpret_cast<Address>(current) + skip); 1282 reinterpret_cast<Address>(current) + skip);
1280 // Fall through. 1283 // Fall through.
1281 } 1284 }
1282 FOUR_CASES(kHotObject) 1285 FOUR_CASES(kHotObject)
1283 FOUR_CASES(kHotObject + 4) { 1286 FOUR_CASES(kHotObject + 4) {
1284 int index = data & kHotObjectIndexMask; 1287 int index = data & kHotObjectIndexMask;
1285 *current = hot_objects_.Get(index); 1288 Object* hot_object = hot_objects_.Get(index);
1286 if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) { 1289 UnalignedCopy(current, &hot_object);
1290 if (write_barrier_needed && isolate->heap()->InNewSpace(hot_object)) {
1287 Address current_address = reinterpret_cast<Address>(current); 1291 Address current_address = reinterpret_cast<Address>(current);
1288 isolate->heap()->RecordWrite( 1292 isolate->heap()->RecordWrite(
1289 current_object_address, 1293 current_object_address,
1290 static_cast<int>(current_address - current_object_address)); 1294 static_cast<int>(current_address - current_object_address));
1291 } 1295 }
1292 current++; 1296 current++;
1293 break; 1297 break;
1294 } 1298 }
1295 1299
1296 case kSynchronize: { 1300 case kSynchronize: {
(...skipping 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2477 return GetHeaderValue(kNumInternalizedStringsOffset); 2481 return GetHeaderValue(kNumInternalizedStringsOffset);
2478 } 2482 }
2479 2483
2480 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const { 2484 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const {
2481 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; 2485 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2482 const byte* start = data_ + kHeaderSize + reservations_size; 2486 const byte* start = data_ + kHeaderSize + reservations_size;
2483 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), 2487 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
2484 GetHeaderValue(kNumCodeStubKeysOffset)); 2488 GetHeaderValue(kNumCodeStubKeysOffset));
2485 } 2489 }
2486 } } // namespace v8::internal 2490 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698