Skip to content

Commit b21dac1

Browse files
leizleizmibrunin
authored andcommitted
[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 <[email protected]> Commit-Queue: Lei Zhang <[email protected]> Reviewed-by: Allan Sandfeld Jensen <[email protected]> Reviewed-by: Michal Klocek <[email protected]>
1 parent 5825fd0 commit b21dac1

File tree

2 files changed

+96
-17
lines changed

2 files changed

+96
-17
lines changed

chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.cpp

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ void CFX_DIBSource::GetOverlapRect(int& dest_left,
863863
int src_height,
864864
int& src_left,
865865
int& src_top,
866-
const CFX_ClipRgn* pClipRgn) {
866+
const CFX_ClipRgn* pClipRgn) const {
867867
if (width == 0 || height == 0)
868868
return;
869869

@@ -873,34 +873,113 @@ void CFX_DIBSource::GetOverlapRect(int& dest_left,
873873
height = 0;
874874
return;
875875
}
876-
int x_offset = dest_left - src_left;
877-
int y_offset = dest_top - src_top;
878-
FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
876+
877+
FX_SAFE_INT32 safe_src_width = src_left;
878+
safe_src_width += width;
879+
if (!safe_src_width.IsValid()) {
880+
width = 0;
881+
height = 0;
882+
return;
883+
}
884+
885+
FX_SAFE_INT32 safe_src_height = src_top;
886+
safe_src_height += height;
887+
if (!safe_src_height.IsValid()) {
888+
width = 0;
889+
height = 0;
890+
return;
891+
}
892+
893+
FX_RECT src_rect(src_left, src_top, safe_src_width.ValueOrDie(),
894+
safe_src_height.ValueOrDie());
879895
FX_RECT src_bound(0, 0, src_width, src_height);
880896
src_rect.Intersect(src_bound);
881-
FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
882-
src_rect.right + x_offset, src_rect.bottom + y_offset);
897+
898+
FX_SAFE_INT32 safe_x_offset = dest_left;
899+
safe_x_offset -= src_left;
900+
if (!safe_x_offset.IsValid()) {
901+
width = 0;
902+
height = 0;
903+
return;
904+
}
905+
906+
FX_SAFE_INT32 safe_y_offset = dest_top;
907+
safe_y_offset -= src_top;
908+
if (!safe_y_offset.IsValid()) {
909+
width = 0;
910+
height = 0;
911+
return;
912+
}
913+
914+
FX_SAFE_INT32 safe_dest_left = safe_x_offset;
915+
safe_dest_left += src_rect.left;
916+
if (!safe_dest_left.IsValid()) {
917+
width = 0;
918+
height = 0;
919+
return;
920+
}
921+
922+
FX_SAFE_INT32 safe_dest_top = safe_y_offset;
923+
safe_dest_top += src_rect.top;
924+
if (!safe_dest_top.IsValid()) {
925+
width = 0;
926+
height = 0;
927+
return;
928+
}
929+
930+
FX_SAFE_INT32 safe_dest_right = safe_x_offset;
931+
safe_dest_right += src_rect.right;
932+
if (!safe_dest_right.IsValid()) {
933+
width = 0;
934+
height = 0;
935+
return;
936+
}
937+
938+
FX_SAFE_INT32 safe_dest_bottom = safe_y_offset;
939+
safe_dest_bottom += src_rect.bottom;
940+
if (!safe_dest_bottom.IsValid()) {
941+
width = 0;
942+
height = 0;
943+
return;
944+
}
945+
946+
FX_RECT dest_rect(safe_dest_left.ValueOrDie(), safe_dest_top.ValueOrDie(),
947+
safe_dest_right.ValueOrDie(),
948+
safe_dest_bottom.ValueOrDie());
883949
FX_RECT dest_bound(0, 0, m_Width, m_Height);
884950
dest_rect.Intersect(dest_bound);
951+
885952
if (pClipRgn)
886953
dest_rect.Intersect(pClipRgn->GetBox());
887954
dest_left = dest_rect.left;
888955
dest_top = dest_rect.top;
889956

890-
pdfium::base::CheckedNumeric<int> safe_src_left = dest_left;
891-
safe_src_left -= x_offset;
892-
if (!safe_src_left.IsValid())
957+
FX_SAFE_INT32 safe_new_src_left = dest_left;
958+
safe_new_src_left -= safe_x_offset;
959+
if (!safe_new_src_left.IsValid()) {
960+
width = 0;
961+
height = 0;
893962
return;
894-
src_left = safe_src_left.ValueOrDie();
963+
}
964+
src_left = safe_new_src_left.ValueOrDie();
895965

896-
pdfium::base::CheckedNumeric<int> safe_src_top = dest_top;
897-
safe_src_top -= y_offset;
898-
if (!safe_src_top.IsValid())
966+
FX_SAFE_INT32 safe_new_src_top = dest_top;
967+
safe_new_src_top -= safe_y_offset;
968+
if (!safe_new_src_top.IsValid()) {
969+
width = 0;
970+
height = 0;
899971
return;
900-
src_top = safe_src_top.ValueOrDie();
972+
}
973+
src_top = safe_new_src_top.ValueOrDie();
974+
975+
if (dest_rect.IsEmpty()) {
976+
width = 0;
977+
height = 0;
978+
return;
979+
}
901980

902-
width = dest_rect.right - dest_rect.left;
903-
height = dest_rect.bottom - dest_rect.top;
981+
width = dest_rect.Width();
982+
height = dest_rect.Height();
904983
}
905984

906985
void CFX_DIBSource::SetPalette(const uint32_t* pSrc) {

chromium/third_party/pdfium/core/fxge/dib/cfx_dibsource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class CFX_DIBSource : public Retainable {
9898
int src_height,
9999
int& src_left,
100100
int& src_top,
101-
const CFX_ClipRgn* pClipRgn);
101+
const CFX_ClipRgn* pClipRgn) const;
102102

103103
#if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
104104
void DebugVerifyBitmapIsPreMultiplied(void* buffer) const;

0 commit comments

Comments
 (0)