tj3*YUV8(): Fix int overflow w/ huge row alignment
If the align parameter was set to an unreasonably large value, such as 0x2000000, strides[0] * ph0 and strides[1] * ph1 could have overflowed the int datatype and wrapped around when computing (src|dst)Planes[1] and (src|dst)Planes[2] (respectively.) This would have caused (src|dst)Planes[1] and (src|dst)Planes[2] to point to lower addresses in the YUV buffer than expected, so the worst case would have been a visually incorrect output image, not a buffer overrun or other exploitable issue.
This commit is contained in:
13
ChangeLog.md
13
ChangeLog.md
@@ -1,3 +1,16 @@
|
||||
3.0.2
|
||||
=====
|
||||
|
||||
### Significant changes relative to 3.0.1:
|
||||
|
||||
1. Fixed a signed integer overflow in the `tj3CompressFromYUV8()`,
|
||||
`tj3DecodeYUV8()`, `tj3DecompressToYUV8()`, and `tj3EncodeYUV8()` functions,
|
||||
detected by the Clang and GCC undefined behavior sanitizers, that could be
|
||||
triggered by setting the `align` parameter to an unreasonably large value.
|
||||
This issue did not pose a security threat, but removing the warning made it
|
||||
easier to detect actual security issues, should they arise in the future.
|
||||
|
||||
|
||||
3.0.1
|
||||
=====
|
||||
|
||||
|
||||
20
turbojpeg.c
20
turbojpeg.c
@@ -1407,6 +1407,11 @@ DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf,
|
||||
int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp);
|
||||
|
||||
strides[1] = strides[2] = PAD(pw1, align);
|
||||
if ((unsigned long long)strides[0] * (unsigned long long)ph0 >
|
||||
(unsigned long long)INT_MAX ||
|
||||
(unsigned long long)strides[1] * (unsigned long long)ph1 >
|
||||
(unsigned long long)INT_MAX)
|
||||
THROW("Image or row alignment is too large");
|
||||
dstPlanes[1] = dstPlanes[0] + strides[0] * ph0;
|
||||
dstPlanes[2] = dstPlanes[1] + strides[1] * ph1;
|
||||
}
|
||||
@@ -1661,6 +1666,11 @@ DLLEXPORT int tj3CompressFromYUV8(tjhandle handle,
|
||||
int ph1 = tjPlaneHeight(1, height, this->subsamp);
|
||||
|
||||
strides[1] = strides[2] = PAD(pw1, align);
|
||||
if ((unsigned long long)strides[0] * (unsigned long long)ph0 >
|
||||
(unsigned long long)INT_MAX ||
|
||||
(unsigned long long)strides[1] * (unsigned long long)ph1 >
|
||||
(unsigned long long)INT_MAX)
|
||||
THROW("Image or row alignment is too large");
|
||||
srcPlanes[1] = srcPlanes[0] + strides[0] * ph0;
|
||||
srcPlanes[2] = srcPlanes[1] + strides[1] * ph1;
|
||||
}
|
||||
@@ -2242,6 +2252,11 @@ DLLEXPORT int tj3DecodeYUV8(tjhandle handle, const unsigned char *srcBuf,
|
||||
int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp);
|
||||
|
||||
strides[1] = strides[2] = PAD(pw1, align);
|
||||
if ((unsigned long long)strides[0] * (unsigned long long)ph0 >
|
||||
(unsigned long long)INT_MAX ||
|
||||
(unsigned long long)strides[1] * (unsigned long long)ph1 >
|
||||
(unsigned long long)INT_MAX)
|
||||
THROW("Image or row alignment is too large");
|
||||
srcPlanes[1] = srcPlanes[0] + strides[0] * ph0;
|
||||
srcPlanes[2] = srcPlanes[1] + strides[1] * ph1;
|
||||
}
|
||||
@@ -2531,6 +2546,11 @@ DLLEXPORT int tj3DecompressToYUV8(tjhandle handle,
|
||||
int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp);
|
||||
|
||||
strides[1] = strides[2] = PAD(pw1, align);
|
||||
if ((unsigned long long)strides[0] * (unsigned long long)ph0 >
|
||||
(unsigned long long)INT_MAX ||
|
||||
(unsigned long long)strides[1] * (unsigned long long)ph1 >
|
||||
(unsigned long long)INT_MAX)
|
||||
THROW("Image or row alignment is too large");
|
||||
dstPlanes[1] = dstPlanes[0] + strides[0] * ph0;
|
||||
dstPlanes[2] = dstPlanes[1] + strides[1] * ph1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user