Merge 3 CLs to M53.
R=thestig@chromium.org
Add bounds checks to CWeightTable::Calc() and friends.
BUG=624514
Review-Url: https://codereview.chromium.org/2204773003
(cherry picked from commit 766901f5ec79b3c3ccd1e872f699642d771a89c5)
openjpeg: Prevent overflows when using opj_aligned_malloc()
BUG=628304
Review-Url: https://codereview.chromium.org/2218783002
(cherry picked from commit b20ab6c7acb3be1393461eb650ca8fa4660c937e)
openjpeg: Prevent integer overflows during calculation of |l_nb_code_blocks_size|
BUG=628890
Review-Url: https://codereview.chromium.org/2212973002
(cherry picked from commit ff74356915d4c7f7c6eb16de1e9f403da4ecb6d5)
Review URL: https://codereview.chromium.org/2227743004 .
diff --git a/AUTHORS b/AUTHORS
index 7336dfd..7daf4dd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,6 +15,7 @@
Chris Palmer <palmer@chromium.org>
Dan Sinclair <dsinclair@chromium.org>
Finnur Thorarinsson <finnur@chromium.org>
+GiWan Go <gogil@stealien.com>
Jiang Jiang <jiangj@opera.com>
Jochen Eisinger <jochen@chromium.org>
John Abd-El-Malek <jam@chromium.org>
diff --git a/core/fxge/dib/dib_int.h b/core/fxge/dib/dib_int.h
index 415362d..ff2828c 100644
--- a/core/fxge/dib/dib_int.h
+++ b/core/fxge/dib/dib_int.h
@@ -40,25 +40,27 @@
int m_SrcEnd;
int m_Weights[1];
};
+
class CWeightTable {
public:
- CWeightTable() { m_pWeightTables = nullptr; }
- ~CWeightTable() {
- FX_Free(m_pWeightTables);
- m_pWeightTables = nullptr;
- }
- void Calc(int dest_len,
+ CWeightTable();
+ ~CWeightTable();
+
+ bool Calc(int dest_len,
int dest_min,
int dest_max,
int src_len,
int src_min,
int src_max,
int flags);
- PixelWeight* GetPixelWeight(int pixel) {
- return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize);
- }
- int m_DestMin, m_ItemSize;
+ PixelWeight* GetPixelWeight(int pixel) const;
+ int* GetValueFromPixelWeight(PixelWeight* pWeight, int index) const;
+
+ private:
+ int m_DestMin;
+ int m_ItemSize;
uint8_t* m_pWeightTables;
+ size_t m_dwWeightTablesSize;
};
class CStretchEngine {
public:
diff --git a/core/fxge/dib/fx_dib_engine.cpp b/core/fxge/dib/fx_dib_engine.cpp
index 6df51d2..1480b3b 100644
--- a/core/fxge/dib/fx_dib_engine.cpp
+++ b/core/fxge/dib/fx_dib_engine.cpp
@@ -32,7 +32,17 @@
} // namespace
-void CWeightTable::Calc(int dest_len,
+CWeightTable::CWeightTable()
+ : m_DestMin(0),
+ m_ItemSize(0),
+ m_pWeightTables(nullptr),
+ m_dwWeightTablesSize(0) {}
+
+CWeightTable::~CWeightTable() {
+ FX_Free(m_pWeightTables);
+}
+
+bool CWeightTable::Calc(int dest_len,
int dest_min,
int dest_max,
int src_len,
@@ -41,26 +51,22 @@
int flags) {
FX_Free(m_pWeightTables);
m_pWeightTables = nullptr;
- double scale, base;
- scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len;
- if (dest_len < 0) {
- base = (FX_FLOAT)(src_len);
- } else {
- base = 0;
- }
- int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1;
+ m_dwWeightTablesSize = 0;
+ const double scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len;
+ const double base = dest_len < 0 ? (FX_FLOAT)(src_len) : 0;
+ const int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1;
m_ItemSize =
sizeof(int) * 2 +
(int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size));
m_DestMin = dest_min;
- if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) {
- return;
- }
- m_pWeightTables =
- FX_TryAlloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4);
- if (!m_pWeightTables) {
- return;
- }
+ if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize)
+ return false;
+
+ m_dwWeightTablesSize = (dest_max - dest_min) * m_ItemSize + 4;
+ m_pWeightTables = FX_TryAlloc(uint8_t, m_dwWeightTablesSize);
+ if (!m_pWeightTables)
+ return false;
+
if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
@@ -179,8 +185,9 @@
pixel_weights.m_Weights[0] = 65536;
}
}
- return;
+ return true;
}
+
for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) {
PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
double src_start = dest_pixel * scale + base;
@@ -228,10 +235,28 @@
pixel_weights.m_SrcEnd--;
break;
}
- pixel_weights.m_Weights[j - start_i] =
- FXSYS_round((FX_FLOAT)(weight * 65536));
+ size_t idx = j - start_i;
+ if (idx >= m_dwWeightTablesSize)
+ return false;
+ pixel_weights.m_Weights[idx] = FXSYS_round((FX_FLOAT)(weight * 65536));
}
}
+ return true;
+}
+
+PixelWeight* CWeightTable::GetPixelWeight(int pixel) const {
+ ASSERT(pixel >= m_DestMin);
+ return reinterpret_cast<PixelWeight*>(m_pWeightTables +
+ (pixel - m_DestMin) * m_ItemSize);
+}
+
+int* CWeightTable::GetValueFromPixelWeight(PixelWeight* pWeight,
+ int index) const {
+ if (index < pWeight->m_SrcStart)
+ return nullptr;
+
+ size_t idx = index - pWeight->m_SrcStart;
+ return idx < m_dwWeightTablesSize ? &pWeight->m_Weights[idx] : nullptr;
}
CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap,
FXDIB_Format dest_format,
@@ -379,11 +404,12 @@
return FALSE;
}
}
- m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth,
- m_SrcClip.left, m_SrcClip.right, m_Flags);
- if (!m_WeightTable.m_pWeightTables) {
+ bool ret =
+ m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right,
+ m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags);
+ if (!ret)
return FALSE;
- }
+
m_CurRow = m_SrcClip.top;
m_State = 1;
return TRUE;
@@ -423,8 +449,12 @@
int dest_a = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
if (src_scan[j / 8] & (1 << (7 - j % 8))) {
dest_a += pixel_weight * 255;
}
@@ -442,8 +472,12 @@
int dest_a = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
dest_a += pixel_weight * src_scan[j];
}
if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
@@ -459,8 +493,12 @@
int dest_a = 0, dest_r = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
pixel_weight = pixel_weight * src_scan_mask[j] / 255;
dest_r += pixel_weight * src_scan[j];
dest_a += pixel_weight;
@@ -480,8 +518,12 @@
int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]];
if (m_DestFormat == FXDIB_Rgb) {
dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16);
@@ -513,8 +555,12 @@
int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
pixel_weight = pixel_weight * src_scan_mask[j] / 255;
unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]];
if (m_DestFormat == FXDIB_Rgba) {
@@ -550,8 +596,12 @@
int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
const uint8_t* src_pixel = src_scan + j * Bpp;
dest_b_c += pixel_weight * (*src_pixel++);
dest_g_m += pixel_weight * (*src_pixel++);
@@ -578,8 +628,12 @@
int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight =
+ m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return FALSE;
+
+ int pixel_weight = *pWeight;
const uint8_t* src_pixel = src_scan + j * Bpp;
if (m_DestFormat == FXDIB_Argb) {
pixel_weight = pixel_weight * src_pixel[3] / 255;
@@ -623,15 +677,15 @@
return;
}
CWeightTable table;
- table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight,
- m_SrcClip.top, m_SrcClip.bottom, m_Flags);
- if (!table.m_pWeightTables) {
+ bool ret = table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom,
+ m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags);
+ if (!ret)
return;
- }
- int DestBpp = m_DestBpp / 8;
+
+ const int DestBpp = m_DestBpp / 8;
for (int row = m_DestClip.top; row < m_DestClip.bottom; row++) {
unsigned char* dest_scan = m_pDestScanline;
- unsigned char* dest_sacn_mask = m_pDestMaskScanline;
+ unsigned char* dest_scan_mask = m_pDestMaskScanline;
PixelWeight* pPixelWeights = table.GetPixelWeight(row);
switch (m_TransMethod) {
case 1:
@@ -643,8 +697,11 @@
int dest_a = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return;
+
+ int pixel_weight = *pWeight;
dest_a +=
pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
}
@@ -665,8 +722,11 @@
int dest_a = 0, dest_k = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return;
+
+ int pixel_weight = *pWeight;
dest_k +=
pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
dest_a += pixel_weight *
@@ -678,7 +738,7 @@
}
*dest_scan = (uint8_t)(dest_k >> 16);
dest_scan += DestBpp;
- *dest_sacn_mask++ = (uint8_t)(dest_a >> 16);
+ *dest_scan_mask++ = (uint8_t)(dest_a >> 16);
}
break;
}
@@ -690,8 +750,11 @@
int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return;
+
+ int pixel_weight = *pWeight;
const uint8_t* src_pixel =
src_scan + (j - m_SrcClip.top) * m_InterPitch;
dest_b_c += pixel_weight * (*src_pixel++);
@@ -725,8 +788,11 @@
int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd;
j++) {
- int pixel_weight =
- pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j);
+ if (!pWeight)
+ return;
+
+ int pixel_weight = *pWeight;
const uint8_t* src_pixel =
src_scan + (j - m_SrcClip.top) * m_InterPitch;
int mask_v = 255;
@@ -762,11 +828,11 @@
if (m_DestFormat == FXDIB_Argb) {
dest_scan[3] = (uint8_t)((dest_a) >> 16);
} else {
- *dest_sacn_mask = (uint8_t)((dest_a) >> 16);
+ *dest_scan_mask = (uint8_t)((dest_a) >> 16);
}
dest_scan += DestBpp;
- if (dest_sacn_mask) {
- dest_sacn_mask++;
+ if (dest_scan_mask) {
+ dest_scan_mask++;
}
}
break;
diff --git a/third_party/libopenjpeg20/0019-tcd_init_tile.patch b/third_party/libopenjpeg20/0019-tcd_init_tile.patch
new file mode 100644
index 0000000..d8e18fa
--- /dev/null
+++ b/third_party/libopenjpeg20/0019-tcd_init_tile.patch
@@ -0,0 +1,30 @@
+diff --git a/third_party/libopenjpeg20/README.pdfium b/third_party/libopenjpeg20/README.pdfium
+index a9e289d..b1012af 100644
+--- a/third_party/libopenjpeg20/README.pdfium
++++ b/third_party/libopenjpeg20/README.pdfium
+@@ -28,4 +28,5 @@ Local Modifications:
+ 0016-read_SQcd_SQcc_overflow.patch: Prevent a buffer overflow in opj_j2k_read_SQcd_SQcc.
+ 0017-tcd_init_tile.patch: Prevent integer overflows during calculation of |l_nb_precinct_size|.
+ 0018-tcd_get_decoded_tile_size.patch: Fix an integer overflow in opj_tcd_get_decoded_tile_size.
++0019-tcd_init_tile.patch: Prevent integer overflows during calculation of |l_nb_code_blocks_size|.
+ TODO(thestig): List all the other patches.
+diff --git a/third_party/libopenjpeg20/tcd.c b/third_party/libopenjpeg20/tcd.c
+index cd1c439..9270efe 100644
+--- a/third_party/libopenjpeg20/tcd.c
++++ b/third_party/libopenjpeg20/tcd.c
+@@ -939,8 +939,15 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
+ l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn);
+ l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn);
+
++ if (l_current_precinct->cw && ((OPJ_UINT32)-1) / l_current_precinct->cw < l_current_precinct->ch) {
++ return OPJ_FALSE;
++ }
+ l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;
+ /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */
++
++ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof_block < l_nb_code_blocks) {
++ return OPJ_FALSE;
++ }
+ l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block;
+
+ if (! l_current_precinct->cblks.blocks) {
diff --git a/third_party/libopenjpeg20/0020-opj_aligned_malloc.patch b/third_party/libopenjpeg20/0020-opj_aligned_malloc.patch
new file mode 100644
index 0000000..7de6e96
--- /dev/null
+++ b/third_party/libopenjpeg20/0020-opj_aligned_malloc.patch
@@ -0,0 +1,67 @@
+diff --git a/third_party/libopenjpeg20/README.pdfium b/third_party/libopenjpeg20/README.pdfium
+index b1012af..a40ed7b 100644
+--- a/third_party/libopenjpeg20/README.pdfium
++++ b/third_party/libopenjpeg20/README.pdfium
+@@ -29,4 +29,5 @@ Local Modifications:
+ 0017-tcd_init_tile.patch: Prevent integer overflows during calculation of |l_nb_precinct_size|.
+ 0018-tcd_get_decoded_tile_size.patch: Fix an integer overflow in opj_tcd_get_decoded_tile_size.
+ 0019-tcd_init_tile.patch: Prevent integer overflows during calculation of |l_nb_code_blocks_size|.
++0020-opj_aligned_malloc.patch: Prevent overflows when using opj_aligned_malloc().
+ TODO(thestig): List all the other patches.
+diff --git a/third_party/libopenjpeg20/dwt.c b/third_party/libopenjpeg20/dwt.c
+index 3b92bdf..a666d1c 100644
+--- a/third_party/libopenjpeg20/dwt.c
++++ b/third_party/libopenjpeg20/dwt.c
+@@ -576,6 +576,9 @@ static OPJ_BOOL opj_dwt_decode_tile(const opj_tcd_tilecomp_t* tilec, OPJ_UINT32
+ OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+ h.mem_count = opj_dwt_max_resolution(tr, numres);
++ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_INT32) < (OPJ_UINT32)h.mem_count) {
++ return OPJ_FALSE;
++ }
+ h.mem = (OPJ_INT32*)opj_aligned_malloc(h.mem_count * sizeof(OPJ_INT32));
+ if (! h.mem){
+ /* FIXME event manager error callback */
+@@ -850,7 +853,17 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numr
+
+ OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
+
+- h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t));
++ OPJ_UINT32 mr = opj_dwt_max_resolution(res, numres);
++
++ if (mr >= ((OPJ_UINT32)-5)) {
++ return OPJ_FALSE;
++ }
++ mr += 5;
++
++ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(opj_v4_t) < mr) {
++ return OPJ_FALSE;
++ }
++ h.wavelet = (opj_v4_t*) opj_aligned_malloc(mr * sizeof(opj_v4_t));
+ if (!h.wavelet) {
+ /* FIXME event manager error callback */
+ return OPJ_FALSE;
+diff --git a/third_party/libopenjpeg20/t1.c b/third_party/libopenjpeg20/t1.c
+index 108ce78..a119db1 100644
+--- a/third_party/libopenjpeg20/t1.c
++++ b/third_party/libopenjpeg20/t1.c
+@@ -1173,6 +1173,9 @@ static OPJ_BOOL opj_t1_allocate_buffers(
+ if (!t1->encoder) {
+ if(datasize > t1->datasize){
+ opj_aligned_free(t1->data);
++ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_INT32) < datasize) {
++ return OPJ_FALSE;
++ }
+ t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32));
+ if(!t1->data){
+ /* FIXME event manager error callback */
+@@ -1187,6 +1190,9 @@ static OPJ_BOOL opj_t1_allocate_buffers(
+
+ if(flagssize > t1->flagssize){
+ opj_aligned_free(t1->flags);
++ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(opj_flag_t) < flagssize) {
++ return OPJ_FALSE;
++ }
+ t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(opj_flag_t));
+ if(!t1->flags){
+ /* FIXME event manager error callback */
diff --git a/third_party/libopenjpeg20/README.pdfium b/third_party/libopenjpeg20/README.pdfium
index a9e289d..a40ed7b 100644
--- a/third_party/libopenjpeg20/README.pdfium
+++ b/third_party/libopenjpeg20/README.pdfium
@@ -28,4 +28,6 @@
0016-read_SQcd_SQcc_overflow.patch: Prevent a buffer overflow in opj_j2k_read_SQcd_SQcc.
0017-tcd_init_tile.patch: Prevent integer overflows during calculation of |l_nb_precinct_size|.
0018-tcd_get_decoded_tile_size.patch: Fix an integer overflow in opj_tcd_get_decoded_tile_size.
+0019-tcd_init_tile.patch: Prevent integer overflows during calculation of |l_nb_code_blocks_size|.
+0020-opj_aligned_malloc.patch: Prevent overflows when using opj_aligned_malloc().
TODO(thestig): List all the other patches.
diff --git a/third_party/libopenjpeg20/dwt.c b/third_party/libopenjpeg20/dwt.c
index 3b92bdf..1bcb108 100644
--- a/third_party/libopenjpeg20/dwt.c
+++ b/third_party/libopenjpeg20/dwt.c
@@ -576,6 +576,9 @@
OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
h.mem_count = opj_dwt_max_resolution(tr, numres);
+ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_INT32) < (OPJ_UINT32)h.mem_count) {
+ return OPJ_FALSE;
+ }
h.mem = (OPJ_INT32*)opj_aligned_malloc(h.mem_count * sizeof(OPJ_INT32));
if (! h.mem){
/* FIXME event manager error callback */
@@ -850,7 +853,17 @@
OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
- h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t));
+ OPJ_UINT32 mr = opj_dwt_max_resolution(res, numres);
+
+ if (mr >= ((OPJ_UINT32)-5)) {
+ return OPJ_FALSE;
+ }
+ mr += 5;
+
+ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(opj_v4_t) < mr) {
+ return OPJ_FALSE;
+ }
+ h.wavelet = (opj_v4_t*) opj_aligned_malloc(mr * sizeof(opj_v4_t));
if (!h.wavelet) {
/* FIXME event manager error callback */
return OPJ_FALSE;
diff --git a/third_party/libopenjpeg20/t1.c b/third_party/libopenjpeg20/t1.c
index 108ce78..a119db1 100644
--- a/third_party/libopenjpeg20/t1.c
+++ b/third_party/libopenjpeg20/t1.c
@@ -1173,6 +1173,9 @@
if (!t1->encoder) {
if(datasize > t1->datasize){
opj_aligned_free(t1->data);
+ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(OPJ_INT32) < datasize) {
+ return OPJ_FALSE;
+ }
t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32));
if(!t1->data){
/* FIXME event manager error callback */
@@ -1187,6 +1190,9 @@
if(flagssize > t1->flagssize){
opj_aligned_free(t1->flags);
+ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof(opj_flag_t) < flagssize) {
+ return OPJ_FALSE;
+ }
t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(opj_flag_t));
if(!t1->flags){
/* FIXME event manager error callback */
diff --git a/third_party/libopenjpeg20/tcd.c b/third_party/libopenjpeg20/tcd.c
index cd1c439..9270efe 100644
--- a/third_party/libopenjpeg20/tcd.c
+++ b/third_party/libopenjpeg20/tcd.c
@@ -939,8 +939,15 @@
l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn);
l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn);
+ if (l_current_precinct->cw && ((OPJ_UINT32)-1) / l_current_precinct->cw < l_current_precinct->ch) {
+ return OPJ_FALSE;
+ }
l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch;
/*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */
+
+ if (((OPJ_UINT32)-1) / (OPJ_UINT32)sizeof_block < l_nb_code_blocks) {
+ return OPJ_FALSE;
+ }
l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof_block;
if (! l_current_precinct->cblks.blocks) {