Fix null pointer deref in gif_io.
@akuegel 
Hi! Could you review this PR please? > @akuegel Hi! Could you review this PR please?

I am not familiar with this code. From a quick look, I am not 100% sure whether this is the right fix. Maybe @cantonios can help? > I am not 100% sure whether this is the right fix.

The other way is to fix `gif` library code, because they increase image counter before buffers allocation, which may lead to such cases. But without fixing `gif` library I think that's the only way.
Anyway, if `gif` returned error while parsing, why shouldn't we return an error as well? Hmm, so the reason we try to continue if we have at least one image is that the gif library was failing to parse some non-standard GIF extensions found in some publicly available training datasets, after the image itself was loaded.  This was causing training to crash on some common image models.

But if the image counter is not reliable (increases without actually successfully parsing an image), then I guess we can't do that anymore. @cantonios 
I can send the PR to the `gif` library as well to try to fix the logic of increasing image counter before successfully parsing the image.

But in the current case yes, we cannot rely on image counter. @cantonios 
I've added the check for the raster bits buffer of the last image. We need to check only the last one, because if there are more images, then all of the previous images were loaded successfully.
Now I'm working on the PR for gif library. @cantonios 
I've sent the patch to the gif library: https://sourceforge.net/p/giflib/patches/32/
But it seems like it wasn't updated since 2019, so I've also attached the patch here to apply it during TF build.
It fixes the crash Reviewing the internal version of this, I see a tidy error:

```
  //tensorflow/core/lib/gif/gif_io.cc:84 ClangTidy: use nullptr
```

Let's hold on this change until we know if that is blocking submit
Hi! We've been fuzzing tensorflow and found the error of null pointer
dereference at `gif_io.cc:178`.

### Environment

OS: ubuntu20.04
TF version: 4601e74cdcd86e6d229ec1d98ff08ba8e147c092

### Detailed description

The error of null pointer occurs, because `RasterBits` buffer at 178 line in `gif_io.cc` occurs to be nullptr.

In gif library in `DGifSlurp` function, which is called from `Decode` function of tensorflow core at `gif_io.cc:78`, at `gif/dgif_lib.c:1144` `DGifGetRecordType` function is called, where new element for `SavedImages` buffer is allocated, `RasterBits` field of the corresponding element in buffer is set to `NULL`, and `ImageCount` is increased.

After that, before the memory for `RasterBits` is allocated, there is a check in `DGifSlurp` function at `dgif_lib.c:1149` for image sizes to prevent potential overflow. If they are incorrect, `GIF_ERROR` is returned before the allocation of `RasterBits`.

In TensorFlow at `gif_io.cc:78` there is a check for the result, which leads to returning `nullptr` only in case `ImageCount <= 0`. But `ImageCount` is incremented in gif library before the allocation of inner buffers, so returning `nullptr` only in case of `ImageCount <= 0` can lead to the following errors of null pointer dereference.

To prevent this error, we suggest just to remove this check `ImageCount <= 0` and return `nullptr` in any case when `DGifSlurp` returns `GIF_ERROR`.

### How to reproduce

Build Docker container from [here](https://github.com/ispras/oss-sydr-fuzz/tree/master/projects/tensorflow):

```bash
$ sudo docker build -t oss-sydr-fuzz-tensorflow .
```

Run container:

```bash
sudo docker run --rm -v `pwd`:/fuzz -it oss-sydr-fuzz-tensorflow /bin/bash
```

Run target on the crash input [crash](https://github.com/tensorflow/tensorflow/assets/75036757/34f2f803-b4cc-47d1-a989-1d143838e220):


```bash
/fuzzer/decode_png -rss_limit_mb=0 /fuzz/crash
```

You will see the following output:

```
==1749952==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000259030dd bp 0x7fff67a64090 sp 0x7fff67a63640 T254)
==1749952==The signal is caused by a READ memory access.
==1749952==Hint: address points to the zero page.
    #0 0x259030dd in tensorflow::gif::Decode(void const*, int, std::function<unsigned char* (int, int, int, int)> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool) /proc/self/cwd/tensorflow/core/lib/gif/gif_io.cc:178:13
    #1 0x247743ca in tensorflow::(anonymous namespace)::DecodeImageV2Op::DecodeGifV2(tensorflow::OpKernelContext*, std::basic_string_view<char, std::char_traits<char> >) /proc/self/cwd/tensorflow/core/kernels/image/decode_image_op.cc:462:21
    #2 0x247743ca in tensorflow::(anonymous namespace)::DecodeImageV2Op::Compute(tensorflow::OpKernelContext*) /proc/self/cwd/tensorflow/core/kernels/image/decode_image_op.cc:216:9
    #3 0x48e86ff7 in tensorflow::ThreadPoolDevice::Compute(tensorflow::OpKernel*, tensorflow::OpKernelContext*) /proc/self/cwd/tensorflow/core/common_runtime/threadpool_device.cc:184:14
    #4 0x492f72ea in tensorflow::(anonymous namespace)::ExecutorState<tensorflow::SimplePropagatorState>::ProcessSync(tensorflow::NodeItem const&, tensorflow::OpKernelContext::Params*, absl::lts_20230125::InlinedVector<tensorflow::Entry, 4ul, std::allocator<tensorflow::Entry> >*, tensorflow::NodeExecStatsInterface*) /proc/self/cwd/tensorflow/core/common_runtime/executor.cc:604:13
    #5 0x492f72ea in tensorflow::(anonymous namespace)::ExecutorState<tensorflow::SimplePropagatorState>::ProcessInline(tensorflow::SimplePropagatorState::TaggedNodeReadyQueue*, long) /proc/self/cwd/tensorflow/core/common_runtime/executor.cc:896:13
    #6 0x492eaeaa in tensorflow::(anonymous namespace)::ExecutorState<tensorflow::SimplePropagatorState>::Process(tensorflow::SimplePropagatorState::TaggedNode const&, long) /proc/self/cwd/tensorflow/core/common_runtime/executor.cc:704:10
    #7 0x4b57a771 in tsl::thread::EigenEnvironment::ExecuteTask(tsl::thread::EigenEnvironment::Task const&) /proc/self/cwd/tensorflow/tsl/platform/threadpool.cc:94:5
    #8 0x4b578c61 in Eigen::ThreadPoolTempl<tsl::thread::EigenEnvironment>::WorkerLoop(int) /proc/self/cwd/external/eigen_archive/Eigen/src/ThreadPool/NonBlockingThreadPool.h:330:16
    #9 0x4b576cf6 in tsl::thread::EigenEnvironment::CreateThread(std::function<void ()>)::'lambda'()::operator()() const /proc/self/cwd/tensorflow/tsl/platform/threadpool.cc:71:7
    #10 0x4b529b9e in tsl::(anonymous namespace)::PThread::ThreadFn(void*) /proc/self/cwd/tensorflow/tsl/platform/default/env.cc:93:5
    #11 0x7ffff7e47608 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x8608) (BuildId: 7b4536f41cdaa5888408e82d0836e33dcf436466)
    #12 0x7ffff7b63132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /proc/self/cwd/tensorflow/core/lib/gif/gif_io.cc:178:13 in tensorflow::gif::Decode(void const*, int, std::function<unsigned char* (int, int, int, int)> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool)
Thread T254 created by T0 here:
    #0 0x18e4d5ac in pthread_create /llvm-project-llvmorg-14.0.6/compiler-rt/lib/asan/asan_interceptors.cpp:208:3
    #1 0x4b527904 in tsl::(anonymous namespace)::PThread::PThread(tsl::ThreadOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, absl::lts_20230125::AnyInvocable<void ()>) /proc/self/cwd/tensorflow/tsl/platform/default/env.cc:72:15
    #2 0x4b527904 in tsl::(anonymous namespace)::PosixEnv::StartThread(tsl::ThreadOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, absl::lts_20230125::AnyInvocable<void ()>) /proc/self/cwd/tensorflow/tsl/platform/default/env.cc:137:16
    #3 0x4b57299f in tsl::thread::EigenEnvironment::CreateThread(std::function<void ()>) /proc/self/cwd/tensorflow/tsl/platform/threadpool.cc:63:18
    #4 0x4b56d255 in Eigen::ThreadPoolTempl<tsl::thread::EigenEnvironment>::ThreadPoolTempl(int, bool, tsl::thread::EigenEnvironment) /proc/self/cwd/external/eigen_archive/Eigen/src/ThreadPool/NonBlockingThreadPool.h:60:16
    #5 0x4b56be71 in tsl::thread::ThreadPool::ThreadPool(tsl::Env*, tsl::ThreadOptions const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool, Eigen::Allocator*) /proc/self/cwd/tensorflow/tsl/platform/threadpool.cc:116:31
    #6 0x491fb8d8 in tensorflow::NewThreadPoolFromSessionOptions(tensorflow::SessionOptions const&, int) /proc/self/cwd/tensorflow/core/common_runtime/process_util.cc:162:14
    #7 0x45643d53 in tensorflow::(anonymous namespace)::GlobalThreadPool(tensorflow::SessionOptions const&, int) /proc/self/cwd/tensorflow/core/common_runtime/direct_session.cc:147:7
    #8 0x45643d53 in tensorflow::DirectSession::DirectSession(tensorflow::SessionOptions const&, tensorflow::DeviceMgr const*, tensorflow::DirectSessionFactory*) /proc/self/cwd/tensorflow/core/common_runtime/direct_session.cc:358:9
    #9 0x45681552 in tensorflow::DirectSessionFactory::NewSession(tensorflow::SessionOptions const&, tensorflow::Session**) /proc/self/cwd/tensorflow/core/common_runtime/direct_session.cc:202:34
    #10 0x48e7518c in tensorflow::NewSession(tensorflow::SessionOptions const&, tensorflow::Session**) /proc/self/cwd/tensorflow/core/common_runtime/session.cc:90:16
    #11 0x48e74b46 in tensorflow::NewSession(tensorflow::SessionOptions const&) /proc/self/cwd/tensorflow/core/common_runtime/session.cc:70:14
    #12 0x18e9c7bc in tensorflow::fuzzing::FuzzSession::InitIfNeeded() /proc/self/cwd/./tensorflow/core/kernels/fuzzing/fuzz_session.h:92:41
    #13 0x18e953d4 in tensorflow::fuzzing::FuzzSession::Fuzz(unsigned char const*, unsigned long) /proc/self/cwd/./tensorflow/core/kernels/fuzzing/fuzz_session.h:127:21
    #14 0x4c0df4ed in ExecuteFilesOnyByOne /AFLplusplus/utils/aflpp_driver/aflpp_driver.c:255:7

==1749952==ABORTING
```