Commit 49f0e648 authored by jgruber's avatar jgruber Committed by Commit Bot

[builtins] Hash & verify the embedded blob

Embed a hash of the embedded blob at serialization-time, and verify it
when loading the blob.

Drive-by: Keep the size of the blob trimmed, and only page-align for
dynamic page allocation and freeing during mksnapshot.

Bug: v8:6666
Change-Id: I10b6064f4f2847d4cc400f6f1bd6961194985b8f
Reviewed-on: https://chromium-review.googlesource.com/1019144
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52707}
parent 10152d6f
......@@ -69,7 +69,7 @@ void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate,
PageAllocator::kReadExecute));
*data = allocated_bytes;
*size = allocated_size;
*size = d.size();
d.Dispose();
}
......@@ -77,7 +77,8 @@ void InstructionStream::CreateOffHeapInstructionStream(Isolate* isolate,
// static
void InstructionStream::FreeOffHeapInstructionStream(uint8_t* data,
uint32_t size) {
CHECK(FreePages(data, size));
const uint32_t page_size = static_cast<uint32_t>(AllocatePageSize());
CHECK(FreePages(data, RoundUp(size, page_size)));
}
#endif // V8_EMBEDDED_BUILTINS
......
......@@ -94,6 +94,15 @@ void Isolate::SetEmbeddedBlob(const uint8_t* blob, uint32_t blob_size) {
embedded_blob_size_ = blob_size;
current_embedded_blob_.store(blob, std::memory_order_relaxed);
current_embedded_blob_size_.store(blob_size, std::memory_order_relaxed);
#ifdef DEBUG
if (blob != nullptr) {
// Verify that the contents of the embedded blob are unchanged from
// serialization-time, just to ensure the compiler isn't messing with us.
EmbeddedData d = EmbeddedData::FromBlob();
CHECK_EQ(d.Hash(), d.CreateHash());
}
#endif // DEBUG
}
const uint8_t* Isolate::embedded_blob() const { return embedded_blob_; }
......
......@@ -393,7 +393,17 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
code->raw_instruction_size());
}
return {blob, blob_size};
EmbeddedData d(blob, blob_size);
// Hash the blob and store the result.
STATIC_ASSERT(HashSize() == kSizetSize);
const size_t hash = d.CreateHash();
std::memcpy(blob + HashOffset(), &hash, HashSize());
DCHECK_EQ(hash, d.CreateHash());
DCHECK_EQ(hash, d.Hash());
return d;
}
EmbeddedData EmbeddedData::FromBlob() {
......@@ -406,10 +416,10 @@ EmbeddedData EmbeddedData::FromBlob() {
Address EmbeddedData::InstructionStartOfBuiltin(int i) const {
DCHECK(Builtins::IsBuiltinId(i));
const uint32_t* offsets = Offsets();
const uint8_t* result = RawData() + offsets[i];
DCHECK_LT(result, data_ + size_);
DCHECK_LE(result, data_ + size_);
DCHECK_IMPLIES(result == data_ + size_, InstructionSizeOfBuiltin(i) == 0);
return reinterpret_cast<Address>(result);
}
......@@ -418,6 +428,12 @@ uint32_t EmbeddedData::InstructionSizeOfBuiltin(int i) const {
const uint32_t* lengths = Lengths();
return lengths[i];
}
size_t EmbeddedData::CreateHash() const {
STATIC_ASSERT(HashOffset() == 0);
STATIC_ASSERT(HashSize() == kSizetSize);
return base::hash_range(data_ + HashSize(), data_ + size_);
}
#endif
uint32_t Snapshot::ExtractNumContexts(const v8::StartupData* data) {
......
......@@ -100,16 +100,26 @@ class EmbeddedData final {
return RoundUp<kCodeAlignment>(InstructionSizeOfBuiltin(i));
}
size_t CreateHash() const;
size_t Hash() const {
return *reinterpret_cast<const size_t*>(data_ + HashOffset());
}
// The layout of the blob is as follows:
//
// [0] offset of instruction stream 0
// ... offsets
// [N] length of instruction stream 0
// ... lengths
// ... instruction streams
// [0] hash of the remaining blob
// [1] offset of instruction stream 0
// ... offsets
// [N + 1] length of instruction stream 0
// ... lengths
// ... instruction streams
static constexpr uint32_t kTableSize = Builtins::builtin_count;
static constexpr uint32_t OffsetsOffset() { return 0; }
static constexpr uint32_t HashOffset() { return 0; }
static constexpr uint32_t HashSize() { return kSizetSize; }
static constexpr uint32_t OffsetsOffset() {
return HashOffset() + HashSize();
}
static constexpr uint32_t OffsetsSize() { return kUInt32Size * kTableSize; }
static constexpr uint32_t LengthsOffset() {
return OffsetsOffset() + OffsetsSize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment