diff options
author | Lei Zhang <thestig@chromium.org> | 2020-10-20 19:48:33 +0000 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2021-03-02 15:12:01 +0000 |
commit | b21dac1f27a83d0bb03d256929834ef94ae206c6 (patch) | |
tree | c1e284cf71f0c39ced1db4423e551833e87d8e52 | |
parent | 5825fd01807a7286d3a3dc819cfa67f875192999 (diff) | |
download | qtwebengine-chromium-b21dac1f27a83d0bb03d256929834ef94ae206c6.tar.gz |
[Backport] Security bug 1097499
Manual backport of patch originally reviewed on
https://pdfium-review.googlesource.com/c/pdfium/+/75410:
Prevent undefined behavior in CFX_DIBBase::GetOverlapRect().
Use FX_SAFE_INT32 to prevent integer overflows/underflows. Also mark the
method const.
Bug: chromium:1097499
Change-Id: Ie3809f0cb43cdf9558b40ec2a2e805f535ab749e
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r-- | chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.cpp | 111 | ||||
-rw-r--r-- | chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h | 2 |
2 files changed, 96 insertions, 17 deletions
diff --git a/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.cpp b/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.cpp index cb5115e3929..d6909d9cc68 100644 --- a/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.cpp +++ b/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.cpp @@ -863,7 +863,7 @@ void CFX_DIBSource::GetOverlapRect(int& dest_left, int src_height, int& src_left, int& src_top, - const CFX_ClipRgn* pClipRgn) { + const CFX_ClipRgn* pClipRgn) const { if (width == 0 || height == 0) return; @@ -873,34 +873,113 @@ void CFX_DIBSource::GetOverlapRect(int& dest_left, height = 0; return; } - int x_offset = dest_left - src_left; - int y_offset = dest_top - src_top; - FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height); + + FX_SAFE_INT32 safe_src_width = src_left; + safe_src_width += width; + if (!safe_src_width.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_SAFE_INT32 safe_src_height = src_top; + safe_src_height += height; + if (!safe_src_height.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_RECT src_rect(src_left, src_top, safe_src_width.ValueOrDie(), + safe_src_height.ValueOrDie()); FX_RECT src_bound(0, 0, src_width, src_height); src_rect.Intersect(src_bound); - FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset, - src_rect.right + x_offset, src_rect.bottom + y_offset); + + FX_SAFE_INT32 safe_x_offset = dest_left; + safe_x_offset -= src_left; + if (!safe_x_offset.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_SAFE_INT32 safe_y_offset = dest_top; + safe_y_offset -= src_top; + if (!safe_y_offset.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_SAFE_INT32 safe_dest_left = safe_x_offset; + safe_dest_left += src_rect.left; + if (!safe_dest_left.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_SAFE_INT32 safe_dest_top = safe_y_offset; + safe_dest_top += src_rect.top; + if (!safe_dest_top.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_SAFE_INT32 safe_dest_right = safe_x_offset; + safe_dest_right += src_rect.right; + if (!safe_dest_right.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_SAFE_INT32 safe_dest_bottom = safe_y_offset; + safe_dest_bottom += src_rect.bottom; + if (!safe_dest_bottom.IsValid()) { + width = 0; + height = 0; + return; + } + + FX_RECT dest_rect(safe_dest_left.ValueOrDie(), safe_dest_top.ValueOrDie(), + safe_dest_right.ValueOrDie(), + safe_dest_bottom.ValueOrDie()); FX_RECT dest_bound(0, 0, m_Width, m_Height); dest_rect.Intersect(dest_bound); + if (pClipRgn) dest_rect.Intersect(pClipRgn->GetBox()); dest_left = dest_rect.left; dest_top = dest_rect.top; - pdfium::base::CheckedNumeric<int> safe_src_left = dest_left; - safe_src_left -= x_offset; - if (!safe_src_left.IsValid()) + FX_SAFE_INT32 safe_new_src_left = dest_left; + safe_new_src_left -= safe_x_offset; + if (!safe_new_src_left.IsValid()) { + width = 0; + height = 0; return; - src_left = safe_src_left.ValueOrDie(); + } + src_left = safe_new_src_left.ValueOrDie(); - pdfium::base::CheckedNumeric<int> safe_src_top = dest_top; - safe_src_top -= y_offset; - if (!safe_src_top.IsValid()) + FX_SAFE_INT32 safe_new_src_top = dest_top; + safe_new_src_top -= safe_y_offset; + if (!safe_new_src_top.IsValid()) { + width = 0; + height = 0; return; - src_top = safe_src_top.ValueOrDie(); + } + src_top = safe_new_src_top.ValueOrDie(); + + if (dest_rect.IsEmpty()) { + width = 0; + height = 0; + return; + } - width = dest_rect.right - dest_rect.left; - height = dest_rect.bottom - dest_rect.top; + width = dest_rect.Width(); + height = dest_rect.Height(); } void CFX_DIBSource::SetPalette(const uint32_t* pSrc) { diff --git a/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h b/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h index 0e7fb27dde5..92406a6c2a1 100644 --- a/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h +++ b/chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h @@ -98,7 +98,7 @@ class CFX_DIBSource : public Retainable { int src_height, int& src_left, int& src_top, - const CFX_ClipRgn* pClipRgn); + const CFX_ClipRgn* pClipRgn) const; #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_ void DebugVerifyBitmapIsPreMultiplied(void* buffer) const; |