summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2019-03-22 13:51:01 +0100
committerMichael BrĂ¼ning <michael.bruning@qt.io>2019-03-27 16:13:36 +0000
commit700a4af1fb50b5b912c8e7b4013d7e3e1f93dfd2 (patch)
tree65cd58412a964c3559866c75a61c967ab9253cd2
parent03c4a4ffb989460f0c07567535892b5f5479df6d (diff)
downloadqtwebengine-chromium-700a4af1fb50b5b912c8e7b4013d7e3e1f93dfd2.tar.gz
[Backport] Security bug 905509 (12/13)
Backport of original patch by Antoine Labour <piman@chromium.org>: Sanitize use of size_t in {Service,Client}FontManager and RasterCHROMIUM Because transfer buffers are 4GB at the max, use uint32_t instead of size_t (or uint64_t) for sizes in font manager serialized data. Bug: 905509 Change-Id: Iafc1e86f2f053eb978103fb02704d3513ac908af Reviewed-on: https://chromium-review.googlesource.com/c/1404390 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/cc/paint/paint_op_buffer_fuzzer.cc2
-rw-r--r--chromium/gpu/command_buffer/client/client_font_manager.cc60
-rw-r--r--chromium/gpu/command_buffer/client/client_font_manager.h2
-rw-r--r--chromium/gpu/command_buffer/client/raster_implementation.cc7
-rw-r--r--chromium/gpu/command_buffer/client/raster_implementation.h2
-rw-r--r--chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt2
-rw-r--r--chromium/gpu/command_buffer/service/raster_decoder.cc8
-rw-r--r--chromium/gpu/command_buffer/service/raster_decoder_autogen.h14
-rw-r--r--chromium/gpu/command_buffer/service/service_font_manager.cc36
-rw-r--r--chromium/gpu/command_buffer/service/service_font_manager.h2
10 files changed, 69 insertions, 66 deletions
diff --git a/chromium/cc/paint/paint_op_buffer_fuzzer.cc b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
index 77070e59cec..7b27f169306 100644
--- a/chromium/cc/paint/paint_op_buffer_fuzzer.cc
+++ b/chromium/cc/paint/paint_op_buffer_fuzzer.cc
@@ -109,7 +109,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::CommandLine::Init(0, nullptr);
// Partition the data to use some bytes for populating the font cache.
- size_t bytes_for_fonts = data[0];
+ uint32_t bytes_for_fonts = data[0];
if (bytes_for_fonts > size)
bytes_for_fonts = size / 2;
diff --git a/chromium/gpu/command_buffer/client/client_font_manager.cc b/chromium/gpu/command_buffer/client/client_font_manager.cc
index 89e6a8151f5..52008dfd76f 100644
--- a/chromium/gpu/command_buffer/client/client_font_manager.cc
+++ b/chromium/gpu/command_buffer/client/client_font_manager.cc
@@ -11,7 +11,7 @@ namespace {
class Serializer {
public:
- Serializer(char* memory, size_t memory_size)
+ Serializer(char* memory, uint32_t memory_size)
: memory_(memory), memory_size_(memory_size) {}
~Serializer() = default;
@@ -21,7 +21,7 @@ class Serializer {
WriteData(val, sizeof(T), alignof(T));
}
- void WriteData(const void* input, size_t bytes, size_t alignment) {
+ void WriteData(const void* input, uint32_t bytes, size_t alignment) {
AlignMemory(bytes, alignment);
if (bytes == 0)
return;
@@ -32,7 +32,7 @@ class Serializer {
}
private:
- void AlignMemory(size_t size, size_t alignment) {
+ void AlignMemory(uint32_t size, size_t alignment) {
// Due to the math below, alignment must be a power of two.
DCHECK_GT(alignment, 0u);
DCHECK_EQ(alignment & (alignment - 1), 0u);
@@ -46,8 +46,8 @@ class Serializer {
}
char* memory_ = nullptr;
- size_t memory_size_ = 0u;
- size_t bytes_written_ = 0u;
+ uint32_t memory_size_ = 0u;
+ uint32_t bytes_written_ = 0u;
};
} // namespace
@@ -96,7 +96,7 @@ void ClientFontManager::Serialize() {
std::vector<uint8_t> strike_data;
strike_server_.writeStrikeData(&strike_data);
- const size_t num_handles_created =
+ const uint32_t num_handles_created =
last_allocated_handle_id_ - last_serialized_handle_id_;
if (strike_data.size() == 0u && num_handles_created == 0u &&
locked_handles_.size() == 0u) {
@@ -104,19 +104,29 @@ void ClientFontManager::Serialize() {
return;
}
- // Size requires for serialization.
- size_t bytes_required =
- // Skia data size.
- +sizeof(size_t) + alignof(size_t) + strike_data.size() +
- alignof(std::max_align_t)
- // num of handles created + SerializableHandles.
- + sizeof(size_t) + alignof(size_t) +
- num_handles_created * sizeof(SerializableSkiaHandle) +
- alignof(SerializableSkiaHandle) +
- // num of handles locked + DiscardableHandleIds.
- +sizeof(size_t) + alignof(size_t) +
- locked_handles_.size() * sizeof(SkDiscardableHandleId) +
- alignof(SkDiscardableHandleId);
+ // Size required for serialization.
+ base::CheckedNumeric<uint32_t> checked_bytes_required = 0;
+ // Skia data size.
+ checked_bytes_required += sizeof(uint32_t) + alignof(uint32_t) + 16;
+ checked_bytes_required += strike_data.size();
+
+ // num of handles created + SerializableHandles.
+ checked_bytes_required +=
+ sizeof(uint32_t) + alignof(uint32_t) + alignof(SerializableSkiaHandle);
+ checked_bytes_required +=
+ base::CheckMul(num_handles_created, sizeof(SerializableSkiaHandle));
+
+ // num of handles locked + DiscardableHandleIds.
+ checked_bytes_required +=
+ sizeof(uint32_t) + alignof(uint32_t) + alignof(SkDiscardableHandleId);
+ checked_bytes_required +=
+ base::CheckMul(locked_handles_.size(), sizeof(SkDiscardableHandleId));
+
+ uint32_t bytes_required = 0;
+ if (!checked_bytes_required.AssignIfValid(&bytes_required)) {
+ DLOG(FATAL) << "ClientFontManager::Serialize: font buffer overflow";
+ return;
+ }
// Allocate memory.
void* memory = client_->MapFontBuffer(bytes_required);
@@ -128,7 +138,7 @@ void ClientFontManager::Serialize() {
Serializer serializer(reinterpret_cast<char*>(memory), bytes_required);
// Serialize all new handles.
- serializer.Write<size_t>(&num_handles_created);
+ serializer.Write<uint32_t>(&num_handles_created);
for (SkDiscardableHandleId handle_id = last_serialized_handle_id_ + 1;
handle_id <= last_allocated_handle_id_; handle_id++) {
auto it = discardable_handle_map_.find(handle_id);
@@ -141,14 +151,16 @@ void ClientFontManager::Serialize() {
}
// Serialize all locked handle ids, so the raster unlocks them when done.
- const size_t num_locked_handles = locked_handles_.size();
- serializer.Write<size_t>(&num_locked_handles);
+ DCHECK(base::IsValueInRangeForNumericType<uint32_t>(locked_handles_.size()));
+ const uint32_t num_locked_handles = locked_handles_.size();
+ serializer.Write<uint32_t>(&num_locked_handles);
for (auto handle_id : locked_handles_)
serializer.Write<SkDiscardableHandleId>(&handle_id);
// Serialize skia data.
- const size_t skia_data_size = strike_data.size();
- serializer.Write<size_t>(&skia_data_size);
+ DCHECK(base::IsValueInRangeForNumericType<uint32_t>(strike_data.size()));
+ const uint32_t skia_data_size = strike_data.size();
+ serializer.Write<uint32_t>(&skia_data_size);
serializer.WriteData(strike_data.data(), strike_data.size(),
alignof(std::max_align_t));
diff --git a/chromium/gpu/command_buffer/client/client_font_manager.h b/chromium/gpu/command_buffer/client/client_font_manager.h
index faf822660dc..2cc4663189d 100644
--- a/chromium/gpu/command_buffer/client/client_font_manager.h
+++ b/chromium/gpu/command_buffer/client/client_font_manager.h
@@ -22,7 +22,7 @@ class RASTER_EXPORT ClientFontManager
public:
virtual ~Client() {}
- virtual void* MapFontBuffer(size_t size) = 0;
+ virtual void* MapFontBuffer(uint32_t size) = 0;
};
ClientFontManager(Client* client, CommandBuffer* command_buffer);
diff --git a/chromium/gpu/command_buffer/client/raster_implementation.cc b/chromium/gpu/command_buffer/client/raster_implementation.cc
index effa86ad402..a116bba0aa7 100644
--- a/chromium/gpu/command_buffer/client/raster_implementation.cc
+++ b/chromium/gpu/command_buffer/client/raster_implementation.cc
@@ -1011,7 +1011,7 @@ void* RasterImplementation::MapRasterCHROMIUM(GLsizeiptr size) {
return raster_mapped_buffer_->address();
}
-void* RasterImplementation::MapFontBuffer(size_t size) {
+void* RasterImplementation::MapFontBuffer(uint32_t size) {
if (size < 0) {
SetGLError(GL_INVALID_VALUE, "glMapFontBufferCHROMIUM", "negative size");
return nullptr;
@@ -1026,11 +1026,6 @@ void* RasterImplementation::MapFontBuffer(size_t size) {
"mapped font buffer with no raster buffer");
return nullptr;
}
- if (size > std::numeric_limits<uint32_t>::max()) {
- SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM",
- "trying to map too large font buffer");
- return nullptr;
- }
font_mapped_buffer_.emplace(size, helper_, mapped_memory_.get());
if (!font_mapped_buffer_->valid()) {
diff --git a/chromium/gpu/command_buffer/client/raster_implementation.h b/chromium/gpu/command_buffer/client/raster_implementation.h
index 3dff8709f51..336599a6c69 100644
--- a/chromium/gpu/command_buffer/client/raster_implementation.h
+++ b/chromium/gpu/command_buffer/client/raster_implementation.h
@@ -167,7 +167,7 @@ class RASTER_EXPORT RasterImplementation : public RasterInterface,
void UnmapRasterCHROMIUM(uint32_t written_size);
// ClientFontManager::Client implementation.
- void* MapFontBuffer(size_t size) override;
+ void* MapFontBuffer(uint32_t size) override;
private:
friend class RasterImplementationTest;
diff --git a/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt b/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt
index 12261645a1c..5702c0358a1 100644
--- a/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt
+++ b/chromium/gpu/command_buffer/raster_cmd_buffer_functions.txt
@@ -34,7 +34,7 @@ GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void);
// Extension CHROMIUM_raster_transport
GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint sk_color, GLuint msaa_sample_count, GLboolean can_use_lcd_text, GLint color_type, GLuint color_space_transfer_cache_id, const GLbyte* mailbox);
-GL_APICALL void GL_APIENTRY glRasterCHROMIUM (GLuint raster_shm_id, GLuint raster_shm_offset, GLsizeiptr raster_shm_size, GLuint font_shm_id, GLuint font_shm_offset, GLsizeiptr font_shm_size);
+GL_APICALL void GL_APIENTRY glRasterCHROMIUM (GLuint raster_shm_id, GLuint raster_shm_offset, GLuint raster_shm_size, GLuint font_shm_id, GLuint font_shm_offset, GLuint font_shm_size);
GL_APICALL void GL_APIENTRY glEndRasterCHROMIUM (void);
GL_APICALL void GL_APIENTRY glCreateTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, GLuint handle_shm_offset, GLuint data_shm_id, GLuint data_shm_offset, GLuint data_size);
GL_APICALL void GL_APIENTRY glDeleteTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id);
diff --git a/chromium/gpu/command_buffer/service/raster_decoder.cc b/chromium/gpu/command_buffer/service/raster_decoder.cc
index ff88ad77e5f..24ad0fc683d 100644
--- a/chromium/gpu/command_buffer/service/raster_decoder.cc
+++ b/chromium/gpu/command_buffer/service/raster_decoder.cc
@@ -657,10 +657,10 @@ class RasterDecoderImpl final : public RasterDecoder,
const volatile GLbyte* key);
void DoRasterCHROMIUM(GLuint raster_shm_id,
GLuint raster_shm_offset,
- GLsizeiptr raster_shm_size,
+ GLuint raster_shm_size,
GLuint font_shm_id,
GLuint font_shm_offset,
- GLsizeiptr font_shm_size);
+ GLuint font_shm_size);
void DoEndRasterCHROMIUM();
void DoCreateTransferCacheEntryINTERNAL(GLuint entry_type,
GLuint entry_id,
@@ -3103,10 +3103,10 @@ scoped_refptr<Buffer> RasterDecoderImpl::GetShmBuffer(uint32_t shm_id) {
void RasterDecoderImpl::DoRasterCHROMIUM(GLuint raster_shm_id,
GLuint raster_shm_offset,
- GLsizeiptr raster_shm_size,
+ GLuint raster_shm_size,
GLuint font_shm_id,
GLuint font_shm_offset,
- GLsizeiptr font_shm_size) {
+ GLuint font_shm_size) {
TRACE_EVENT1("gpu", "RasterDecoderImpl::DoRasterCHROMIUM", "raster_id",
++raster_chromium_id_);
diff --git a/chromium/gpu/command_buffer/service/raster_decoder_autogen.h b/chromium/gpu/command_buffer/service/raster_decoder_autogen.h
index 5ac48410224..d239d6578db 100644
--- a/chromium/gpu/command_buffer/service/raster_decoder_autogen.h
+++ b/chromium/gpu/command_buffer/service/raster_decoder_autogen.h
@@ -241,20 +241,10 @@ error::Error RasterDecoderImpl::HandleRasterCHROMIUM(
GLuint raster_shm_id = static_cast<GLuint>(c.raster_shm_id);
GLuint raster_shm_offset = static_cast<GLuint>(c.raster_shm_offset);
- GLsizeiptr raster_shm_size = static_cast<GLsizeiptr>(c.raster_shm_size);
+ GLuint raster_shm_size = static_cast<GLuint>(c.raster_shm_size);
GLuint font_shm_id = static_cast<GLuint>(c.font_shm_id);
GLuint font_shm_offset = static_cast<GLuint>(c.font_shm_offset);
- GLsizeiptr font_shm_size = static_cast<GLsizeiptr>(c.font_shm_size);
- if (raster_shm_size < 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM",
- "raster_shm_size < 0");
- return error::kNoError;
- }
- if (font_shm_size < 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glRasterCHROMIUM",
- "font_shm_size < 0");
- return error::kNoError;
- }
+ GLuint font_shm_size = static_cast<GLuint>(c.font_shm_size);
DoRasterCHROMIUM(raster_shm_id, raster_shm_offset, raster_shm_size,
font_shm_id, font_shm_offset, font_shm_size);
return error::kNoError;
diff --git a/chromium/gpu/command_buffer/service/service_font_manager.cc b/chromium/gpu/command_buffer/service/service_font_manager.cc
index 21eb859fdf9..5f96284469d 100644
--- a/chromium/gpu/command_buffer/service/service_font_manager.cc
+++ b/chromium/gpu/command_buffer/service/service_font_manager.cc
@@ -14,7 +14,7 @@ namespace gpu {
namespace {
class Deserializer {
public:
- Deserializer(const volatile char* memory, size_t memory_size)
+ Deserializer(const volatile char* memory, uint32_t memory_size)
: memory_(memory), memory_size_(memory_size) {}
~Deserializer() = default;
@@ -32,7 +32,7 @@ class Deserializer {
return true;
}
- bool ReadStrikeData(SkStrikeClient* strike_client, size_t size) {
+ bool ReadStrikeData(SkStrikeClient* strike_client, uint32_t size) {
if (size == 0u)
return true;
@@ -48,14 +48,20 @@ class Deserializer {
}
private:
- bool AlignMemory(size_t size, size_t alignment) {
+ bool AlignMemory(uint32_t size, size_t alignment) {
// Due to the math below, alignment must be a power of two.
DCHECK_GT(alignment, 0u);
DCHECK_EQ(alignment & (alignment - 1), 0u);
uintptr_t memory = reinterpret_cast<uintptr_t>(memory_);
size_t padding = ((memory + alignment - 1) & ~(alignment - 1)) - memory;
- if (bytes_read_ + size + padding > memory_size_)
+
+ base::CheckedNumeric<uint32_t> checked_padded_size = bytes_read_;
+ checked_padded_size += padding;
+ checked_padded_size += size;
+ uint32_t padded_size = 0;
+ if (!checked_padded_size.AssignIfValid(&padded_size) ||
+ padded_size > memory_size_)
return false;
memory_ += padding;
@@ -64,8 +70,8 @@ class Deserializer {
}
const volatile char* memory_;
- size_t memory_size_;
- size_t bytes_read_ = 0u;
+ uint32_t memory_size_;
+ uint32_t bytes_read_ = 0u;
};
} // namespace
@@ -114,18 +120,18 @@ ServiceFontManager::~ServiceFontManager() {
bool ServiceFontManager::Deserialize(
const volatile char* memory,
- size_t memory_size,
+ uint32_t memory_size,
std::vector<SkDiscardableHandleId>* locked_handles) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(locked_handles->empty());
// All new handles.
Deserializer deserializer(memory, memory_size);
- size_t new_handles_created;
- if (!deserializer.Read<size_t>(&new_handles_created))
+ uint32_t new_handles_created;
+ if (!deserializer.Read<uint32_t>(&new_handles_created))
return false;
- for (size_t i = 0; i < new_handles_created; ++i) {
+ for (uint32_t i = 0; i < new_handles_created; ++i) {
SerializableSkiaHandle handle;
if (!deserializer.Read<SerializableSkiaHandle>(&handle))
return false;
@@ -143,19 +149,19 @@ bool ServiceFontManager::Deserialize(
}
// All locked handles
- size_t num_locked_handles;
- if (!deserializer.Read<size_t>(&num_locked_handles))
+ uint32_t num_locked_handles;
+ if (!deserializer.Read<uint32_t>(&num_locked_handles))
return false;
locked_handles->resize(num_locked_handles);
- for (size_t i = 0; i < num_locked_handles; ++i) {
+ for (uint32_t i = 0; i < num_locked_handles; ++i) {
if (!deserializer.Read<SkDiscardableHandleId>(&locked_handles->at(i)))
return false;
}
// Skia font data.
- size_t skia_data_size = 0u;
- if (!deserializer.Read<size_t>(&skia_data_size))
+ uint32_t skia_data_size = 0u;
+ if (!deserializer.Read<uint32_t>(&skia_data_size))
return false;
if (!deserializer.ReadStrikeData(strike_client_.get(), skia_data_size))
diff --git a/chromium/gpu/command_buffer/service/service_font_manager.h b/chromium/gpu/command_buffer/service/service_font_manager.h
index f46e723b837..0870cf11bd0 100644
--- a/chromium/gpu/command_buffer/service/service_font_manager.h
+++ b/chromium/gpu/command_buffer/service/service_font_manager.h
@@ -27,7 +27,7 @@ class GPU_GLES2_EXPORT ServiceFontManager {
~ServiceFontManager();
bool Deserialize(const volatile char* memory,
- size_t memory_size,
+ uint32_t memory_size,
std::vector<SkDiscardableHandleId>* locked_handles);
bool Unlock(const std::vector<SkDiscardableHandleId>& handles);
SkStrikeClient* strike_client() { return strike_client_.get(); }