summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2020-10-20 19:48:33 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2021-03-02 15:12:01 +0000
commitb21dac1f27a83d0bb03d256929834ef94ae206c6 (patch)
treec1e284cf71f0c39ced1db4423e551833e87d8e52
parent5825fd01807a7286d3a3dc819cfa67f875192999 (diff)
downloadqtwebengine-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.cpp111
-rw-r--r--chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h2
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;