Moderate severityNVD Advisory· Published Mar 24, 2023· Updated Feb 19, 2025
TensorFlow vulnerable to segfault when opening multiframe gif
CVE-2023-25667
Description
TensorFlow is an open source platform for machine learning. Prior to versions 2.12.0 and 2.11.1, integer overflow occurs when 2^31 <= num_frames * height * width * channels < 2^32, for example Full HD screencast of at least 346 frames. A fix is included in TensorFlow version 2.12.0 and version 2.11.1.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
tensorflowPyPI | < 2.11.1 | 2.11.1 |
tensorflow-cpuPyPI | < 2.11.1 | 2.11.1 |
tensorflow-gpuPyPI | < 2.11.1 | 2.11.1 |
Affected products
1- Range: < 2.11.1
Patches
18dc723fcdd1aFix integer overflow for multiframe gifs.
5 files changed · +13 −11
tensorflow/core/kernels/image/decode_image_op.cc+2 −2 modified@@ -452,12 +452,12 @@ class DecodeImageV2Op : public OpKernel { // allocation til after dtype conversion is done. `gif`::Decode` supports // uint8 only. Tensor* output = nullptr; - int buffer_size = 0; + ptrdiff_t buffer_size = 0; string error_string; uint8* buffer = gif::Decode( input.data(), input.size(), [&](int num_frames, int width, int height, int channels) -> uint8* { - buffer_size = num_frames * height * width * channels; + buffer_size = ptrdiff_t(num_frames) * height * width * channels; Status status; // By the existing API, we support decoding GIF with `decode_jpeg` or
tensorflow/core/lib/gif/gif_io.cc+7 −7 modified@@ -105,7 +105,7 @@ uint8* Decode(const void* srcdata, int datasize, uint8* const dstdata = allocate_output(target_num_frames, width, height, channel); if (!dstdata) return nullptr; - for (int k = 0; k < target_num_frames; k++) { + for (ptrdiff_t k = 0; k < target_num_frames; k++) { uint8* this_dst = dstdata + k * width * channel * height; SavedImage* this_image = &gif_file->SavedImages[k]; @@ -125,10 +125,10 @@ uint8* Decode(const void* srcdata, int datasize, if (k > 0) { uint8* last_dst = dstdata + (k - 1) * width * channel * height; - for (int i = 0; i < height; ++i) { + for (ptrdiff_t i = 0; i < height; ++i) { uint8* p_dst = this_dst + i * width * channel; uint8* l_dst = last_dst + i * width * channel; - for (int j = 0; j < width; ++j) { + for (ptrdiff_t j = 0; j < width; ++j) { p_dst[j * channel + 0] = l_dst[j * channel + 0]; p_dst[j * channel + 1] = l_dst[j * channel + 1]; p_dst[j * channel + 2] = l_dst[j * channel + 2]; @@ -141,9 +141,9 @@ uint8* Decode(const void* srcdata, int datasize, // If the first frame does not fill the entire canvas then fill the // unoccupied canvas with zeros (black). if (k == 0) { - for (int i = 0; i < height; ++i) { + for (ptrdiff_t i = 0; i < height; ++i) { uint8* p_dst = this_dst + i * width * channel; - for (int j = 0; j < width; ++j) { + for (ptrdiff_t j = 0; j < width; ++j) { p_dst[j * channel + 0] = 0; p_dst[j * channel + 1] = 0; p_dst[j * channel + 2] = 0; @@ -165,9 +165,9 @@ uint8* Decode(const void* srcdata, int datasize, return nullptr; } - for (int i = imgTop; i < imgBottom; ++i) { + for (ptrdiff_t i = imgTop; i < imgBottom; ++i) { uint8* p_dst = this_dst + i * width * channel; - for (int j = imgLeft; j < imgRight; ++j) { + for (ptrdiff_t j = imgLeft; j < imgRight; ++j) { GifByteType color_index = this_image->RasterBits[(i - img_desc->Top) * (img_desc->Width) + (j - img_desc->Left)];
tensorflow/core/lib/gif/gif_io_test.cc+3 −2 modified@@ -52,7 +52,7 @@ void TestDecodeGif(Env* env, DecodeGifTestCase testcase) { w = width; h = height; c = channels; - return new uint8[frame_cnt * height * width * channels]; + return new uint8[ptrdiff_t(frame_cnt) * height * width * channels]; }, &error_string)); ASSERT_NE(imgdata, nullptr); @@ -72,7 +72,8 @@ TEST(GifTest, Gif) { {testdata_path + "optimized.gif", 12, 20, 40, 3}, {testdata_path + "red_black.gif", 1, 16, 16, 3}, {testdata_path + "scan.gif", 12, 20, 40, 3}, - {testdata_path + "squares.gif", 2, 16, 16, 3}}); + {testdata_path + "squares.gif", 2, 16, 16, 3}, + {testdata_path + "3g_multiframe.gif", 519, 1920, 1080, 3}}); for (const auto& tc : testcases) { TestDecodeGif(env, tc);
tensorflow/core/lib/gif/testdata/3g_multiframe.gif+0 −0 addedtensorflow/core/lib/gif/testdata/BUILD+1 −0 modified@@ -16,6 +16,7 @@ filegroup( "scan.gif", "red_black.gif", "squares.gif", + "3g_multiframe.gif", "pendulum_sm.gif", # Add groundtruth frames for `pendulum_sm.gif`. # PNG format because it's lossless.
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-fqm2-gh8w-gr68ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-25667ghsaADVISORY
- github.com/tensorflow/tensorflow/commit/8dc723fcdd1a6127d6c970bd2ecb18b019a1a58dghsax_refsource_MISCWEB
- github.com/tensorflow/tensorflow/security/advisories/GHSA-fqm2-gh8w-gr68ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.