Skip to content

heif_list_compatible_brands() requires 3,909,617,969 bytes of memory given 16-bytes of input data #1633

Closed

Description

@bobfriesenhahn

While testing GraphicsMagick, oss-fuzz issue 462978646 reports excessive memory usage for some inputs.

The heif_list_compatible_brands() function is using enormous amounts of memory before finally returning an error.

This is the block of GraphicsMagick source code used while testing:

    {
      char
        fourcc[5];

      {
        /* Log main brand */
        (void) memset(fourcc,0,sizeof(fourcc));
        heif_brand_to_fourcc(heif_read_main_brand(in_buf, in_len), fourcc);
        fourcc[4]=0;
        if (fourcc[0] == 0)
          {
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                                  "Failed to read main brand!");
          }
        else
          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                                "HEIF Brand: \"%s\"", fourcc);
      }
      {
        /* Log compatible brands */
        heif_brand2* brands = NULL;
        int nBrands = 0;
        heif_status = heif_list_compatible_brands(in_buf, in_len, &brands, &nBrands);
        if (heif_status.code == heif_error_Ok)
          {
            char
              *compatible_brands;

            const size_t
              compatible_brands_alloc = 6*(nBrands+1);

            compatible_brands=MagickAllocateClearedMemory(char *,compatible_brands_alloc);
            if (compatible_brands == (char *) NULL)
              ThrowHEIFReaderException(ResourceLimitError,MemoryAllocationFailed,image);
            {
              int
                i;

              for (i = 0; i < nBrands; i++)
                {
                  heif_brand_to_fourcc(brands[i], fourcc);
                  fourcc[4]=0;
                  if (i > 0)
                    (void) strlcat(compatible_brands,", ",compatible_brands_alloc);
                  (void) strlcat(compatible_brands,fourcc,compatible_brands_alloc);
                }
            }
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                                  "Compatible HEIF brands: %s", compatible_brands);
            MagickFreeMemory(compatible_brands);
          }
        else
          {
            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                                  "Failed to read compatible HEIF brands!");
          }
        heif_free_list_of_compatible_brands(brands);
      }

The testing is done with these additional security limits applied:

max-memory-block-size = 268435456
max-total-memory = 268435456
max_image_size_pixels = 4194304

I tested using GraphicsMagick under Ubuntu 22.04LTS like this:

LD_PRELOAD=/lib/x86_64-linux-gnu/libmemusage.so
MAGICK_LIMIT_DISK=0
MAGICK_LIMIT_MEMORY=268435456
MAGICK_LIMIT_WIDTH=2048
MAGICK_LIMIT_HEIGHT=2048
MAGICK_LIMIT_READ=900000
gm convert -debug coder,exception HEIC:clusterfuzz-testcase-minimized-coder_HEIC_fuzzer-4839101758242816.gz info:-

This is the resulting output from the memory usage report:

Memory usage summary: heap total: 3909727070, heap peak: 3909620036, stack peak: 19216
total calls total memory failed calls
malloc| 324 3909721404 0
realloc| 2 1152 0 (nomove:0, dec:0, free:0)
calloc| 6 4514 0
free| 181 3909337014
Histogram for block sizes:
0-15 43 12% =======================
16-31 91 27% ==================================================
32-47 76 22% =========================================
48-63 35 10% ===================
64-79 9 2% ====
80-95 4 1% ==
96-111 5 1% ==
112-127 2 <1% =
128-143 5 1% ==
144-159 2 <1% =
160-175 1 <1%
176-191 3 <1% =
208-223 6 1% ===
224-239 2 <1% =
240-255 1 <1%
256-271 3 <1% =
304-319 2 <1% =
352-367 1 <1%
400-415 2 <1% =
416-431 1 <1%
464-479 3 <1% =
512-527 2 <1% =
784-799 1 <1%
912-927 1 <1%
1024-1039 1 <1%
1248-1263 1 <1%
1280-1295 2 <1% =
1328-1343 1 <1%
1600-1615 1 <1%
2064-2079 1 <1%
2224-2239 1 <1%
2304-2319 2 <1% =
2512-2527 1 <1%
4096-4111 3 <1% =
6864-6879 2 <1% =
7152-7167 1 <1%
8000-8015 1 <1%
8192-8207 1 <1%
8224-8239 1 <1%
8528-8543 2 <1% =
11296-11311 1 <1%
16384-16399 3 <1% =
32816-32831 1 <1%
33600-33615 1 <1%
large 3 <1% =

I have attached a sample input file.

clusterfuzz-testcase-minimized-coder_HEIC_fuzzer-4839101758242816.gz

Activity

  1. bobfriesenhahn commented on Nov 26, 2025

    @bobfriesenhahn
    Author

    This is a more complete reporting of the libheif security limits settings during the oss-fuzz testing since it now includes the values produced as default by libheif:

    06:48:29 0:0.000788 0.000u 1242055 heif.c/apply_security_limits/572/Coder:
    security limits: max_memory_block_size = 268435456
    06:48:29 0:0.000792 0.000u 1242055 heif.c/apply_security_limits/576/Coder:
    security limits: max_total_memory = 268435456
    06:48:29 0:0.000797 0.000u 1242055 heif.c/apply_security_limits/593/Coder:
    security limits: max_image_size_pixels = 4194304
    06:48:29 0:0.000802 0.000u 1242055 heif.c/apply_security_limits/626/Coder:
    security limits: max_image_size_pixels = 4194304
    06:48:29 0:0.000807 0.000u 1242055 heif.c/apply_security_limits/633/Coder:
    security limits: max_number_of_tiles = 16777216
    06:48:29 0:0.000811 0.000u 1242055 heif.c/apply_security_limits/640/Coder:
    security limits: max_bayer_pattern_pixels = 256
    06:48:29 0:0.000816 0.000u 1242055 heif.c/apply_security_limits/647/Coder:
    security limits: max_items = 1000
    06:48:29 0:0.000820 0.000u 1242055 heif.c/apply_security_limits/654/Coder:
    security limits: max_color_profile_size = 104857600
    06:48:29 0:0.000824 0.000u 1242055 heif.c/apply_security_limits/661/Coder:
    security limits: max_memory_block_size = 268435456
    06:48:29 0:0.000829 0.000u 1242055 heif.c/apply_security_limits/668/Coder:
    security limits: max_components = 256
    06:48:29 0:0.000833 0.000u 1242055 heif.c/apply_security_limits/675/Coder:
    security limits: max_iloc_extents_per_item = 32
    06:48:29 0:0.000838 0.000u 1242055 heif.c/apply_security_limits/682/Coder:
    security limits: max_size_entity_group = 64
    06:48:29 0:0.000842 0.000u 1242055 heif.c/apply_security_limits/689/Coder:
    security limits: max_children_per_box = 100
    06:48:29 0:0.000847 0.000u 1242055 heif.c/apply_security_limits/699/Coder:
    security limits: max_total_memory = 268435456
    06:48:29 0:0.000851 0.000u 1242055 heif.c/apply_security_limits/707/Coder:
    security limits: max_sample_description_box_entries = 1024
    06:48:29 0:0.000856 0.000u 1242055 heif.c/apply_security_limits/715/Coder:
    security limits: max_sample_group_description_box_entries = 1024

  2. farindk commented on Nov 29, 2025

    @farindk
    Member

    Thank you.
    I've added a check that the input really starts with a proper 'ftyp' box. That should fix this. Please close when confirmed.

  3. added a commit that references this issue on Nov 29, 2025
    720cad2
  4. bobfriesenhahn commented on Dec 1, 2025

    @bobfriesenhahn
    Author

    Oss-fuzz issue 462978646 is indicated as closed so the fix must be good.

  5. farindk commented on Dec 1, 2025

    @farindk
    Member

    Thanks for the confirmation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions