Fix unsafe unaligned accesses in the serializer/deserializer.
authoryangguo <yangguo@chromium.org>
Thu, 8 Jan 2015 13:18:45 +0000 (05:18 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 8 Jan 2015 13:18:55 +0000 (13:18 +0000)
R=svenpanne@chromium.org
BUG=v8:3771
LOG=N

Review URL: https://codereview.chromium.org/841943002

Cr-Commit-Position: refs/heads/master@{#25995}

src/serialize.cc
src/serialize.h

index 01c55a1..86348ae 100644 (file)
@@ -614,7 +614,9 @@ void Deserializer::DecodeReservation(
   DCHECK_EQ(0, reservations_[NEW_SPACE].length());
   STATIC_ASSERT(NEW_SPACE == 0);
   int current_space = NEW_SPACE;
-  for (const auto& r : res) {
+  for (int i = 0; i < res.length(); i++) {
+    SerializedData::Reservation r(0);
+    memcpy(&r, res.start() + i, sizeof(r));
     reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
     if (r.is_last()) current_space++;
   }
@@ -860,7 +862,8 @@ void Deserializer::ReadObject(int space_number, Object** write_back) {
   // Fix up strings from serialized user code.
   if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
 
-  *write_back = obj;
+  Object* write_back_obj = obj;
+  UnalignedCopy(write_back, &write_back_obj);
 #ifdef DEBUG
   if (obj->IsCode()) {
     DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE);
@@ -1003,7 +1006,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
         current = reinterpret_cast<Object**>(location_of_branch_data);         \
         current_was_incremented = true;                                        \
       } else {                                                                 \
-        *current = new_object;                                                 \
+        UnalignedCopy(current, &new_object);                                   \
       }                                                                        \
     }                                                                          \
     if (emit_write_barrier && write_barrier_needed) {                          \
@@ -1104,7 +1107,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
         int root_id = RootArrayConstantFromByteCode(data);
         Object* object = isolate->heap()->roots_array_start()[root_id];
         DCHECK(!isolate->heap()->InNewSpace(object));
-        *current++ = object;
+        UnalignedCopy(current++, &object);
         break;
       }
 
@@ -1116,7 +1119,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
             reinterpret_cast<intptr_t>(current) + skip);
         Object* object = isolate->heap()->roots_array_start()[root_id];
         DCHECK(!isolate->heap()->InNewSpace(object));
-        *current++ = object;
+        UnalignedCopy(current++, &object);
         break;
       }
 
@@ -1124,8 +1127,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
         int repeats = source_.GetInt();
         Object* object = current[-1];
         DCHECK(!isolate->heap()->InNewSpace(object));
-        for (int i = 0; i < repeats; i++) current[i] = object;
-        current += repeats;
+        for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
         break;
       }
 
@@ -1139,10 +1141,10 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
       case kFixedRepeat + 13:
       case kFixedRepeat + 14: {
         int repeats = RepeatsForCode(data);
-        Object* object = current[-1];
+        Object* object;
+        UnalignedCopy(&object, current - 1);
         DCHECK(!isolate->heap()->InNewSpace(object));
-        for (int i = 0; i < repeats; i++) current[i] = object;
-        current += repeats;
+        for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
         break;
       }
 
@@ -1254,7 +1256,8 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
             new NativesExternalStringResource(isolate->bootstrapper(),
                                               source_vector.start(),
                                               source_vector.length());
-        *current++ = reinterpret_cast<Object*>(resource);
+        Object* resource_obj = reinterpret_cast<Object*>(resource);
+        UnalignedCopy(current++, &resource_obj);
         break;
       }
 
@@ -1282,8 +1285,9 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
       FOUR_CASES(kHotObject)
       FOUR_CASES(kHotObject + 4) {
         int index = data & kHotObjectIndexMask;
-        *current = hot_objects_.Get(index);
-        if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) {
+        Object* hot_object = hot_objects_.Get(index);
+        UnalignedCopy(current, &hot_object);
+        if (write_barrier_needed && isolate->heap()->InNewSpace(hot_object)) {
           Address current_address = reinterpret_cast<Address>(current);
           isolate->heap()->RecordWrite(
               current_object_address,
index bd0c423..5dc7374 100644 (file)
@@ -482,11 +482,13 @@ class SerializedData {
 
  protected:
   void SetHeaderValue(int offset, int value) {
-    reinterpret_cast<int*>(data_)[offset] = value;
+    memcpy(reinterpret_cast<int*>(data_) + offset, &value, sizeof(value));
   }
 
   int GetHeaderValue(int offset) const {
-    return reinterpret_cast<const int*>(data_)[offset];
+    int value;
+    memcpy(&value, reinterpret_cast<int*>(data_) + offset, sizeof(value));
+    return value;
   }
 
   void AllocateData(int size);
@@ -544,6 +546,10 @@ class Deserializer: public SerializerDeserializer {
 
   bool ReserveSpace();
 
+  void UnalignedCopy(Object** dest, Object** src) {
+    memcpy(dest, src, sizeof(*src));
+  }
+
   // Allocation sites are present in the snapshot, and must be linked into
   // a list at deserialization time.
   void RelinkAllocationSite(AllocationSite* site);