CVE-2026-112396: Pillow: Heap use-after-free when encoding TIFF to an in-memory buffer

Published Oct 19, 2026
·
Updated

Summary Saving an image as TIFF to an in-memory buffer can trigger a heap use-after-free if libtiff rejects a tag at encode time. When TIFFWriteScanline fails, the encoder frees its output buffer but leaves the libtiff handle open. Later, when the encoder object is torn down, TIFFClose flushes buffered bytes through the write callback and writes into the freed buffer. An application that re-encodes attacker-influenced images to TIFF in memory can be crashed and is a candidate for remote code execution.

Details The failure path in ImagingLibTiffEncode frees clientstate->data for the in-memory case but does not close the TIFF or null clientstate->tiff (the file-descriptor branch just above it does set tiff = NULL):

- src/libImaging/TiffDecode.c:1041-1046

Teardown then calls ImagingLibTiffEncodeCleanup, which runs TIFFClose(tiff) because tiff is still set:

- src/encode.c:99-101 - src/libImaging/TiffDecode.c:955

TIFFClose flushes through tiffWriteProc, which reallocs and memcpys into the freed state->data:

- src/libImaging/TiffDecode.c:103-115

The Predictor tag is a convenient trigger: the floating-point predictor (value 3) is invalid for integer sample data, so libtiff aborts the write.

PoC python import io from PIL import Image

In-memory TIFF re-encode. libtiff rejects Predictor=3 (floating point) on integer data, so TIFFWriteScanline fails. The encoder frees clientstate->data but leaves the TIFF open; cleanup's TIFFClose then writes through the callback into the freed buffer. im = Image.new("L", (64, 64)) buf = io.BytesIO() im.save(buf, format="TIFF", compression="tifflzw", tiffinfo={317: 3}) # 317 = Predictor

Run it: $ python 01poc.py PredictorSetup: Floating point "Predictor" not supported with 1 data format. OSError: encoder error -2 when writing image file Segmentation fault (core dumped)

Observed on a source build of commit 3e2ab96 with libtiff. The process aborts during cleanup after the encoder error. Depending on heap state the same run sometimes reports corrupted double-linked list instead of a segfault; both are the same write into freed memory.

Under AddressSanitizer (build with -fsanitize=address), relevant frames: ==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ef737b48804 WRITE of size 4 at 0x7ef737b48804 thread T0 #1 tiffWriteProc src/libImaging/TiffDecode.c:115 #3 TIFFFlush libtiff.so.6 #5 TIFFClose libtiff.so.6 #6 ImagingLibTiffEncodeCleanup src/libImaging/TiffDecode.c:955 #7 dealloc src/encode.c:100 freed by thread T0 here: #1 ImagingLibTiffEncode src/libImaging/TiffDecode.c:1045 #2 encode src/encode.c:139 previously allocated by thread T0 here: #1 ImagingLibTiffEncodeInit src/libImaging/TiffDecode.c:863 #2 PyImagingLibTiffEncoderNew src/encode.c:757 SUMMARY: AddressSanitizer: heap-use-after-free src/libImaging/TiffDecode.c:115 in tiffWriteProc The buffer allocated in ImagingLibTiffEncodeInit is freed in ImagingLibTiffEncode, then written by tiffWriteProc during the TIFFClose flush that runs from the encoder's dealloc.

Impact Use-after-free in a C extension. Affects any service that converts or thumbnails untrusted images to TIFF in memory (a BytesIO or other non-seekable target). Result is a crash and possible memory corruption leading to code execution.

Other sources

Pillow is a Python imaging library. From 11.3.0 until 13.0.0, Pillow has a heap use-after-free when libtiff rejects a tag while encoding TIFF data to an in-memory buffer. When an application saves attacker-influenced TIFF tags to BytesIO, libtiff can reject a tag during encoding in ImagingLibTiffEncode; the error path then frees the output buffer without closing or clearing the TIFF handle, and later cleanup flushes through the write callback into freed memory, which can crash the process and may enable code execution. This issue is fixed in version 13.0.0.

— NVD

Affected Software

8 affected componentsFixes available
pypi/Pillow>=11.3.0<13.0.0
pip/pillow>=11.3.0<13.0.0
13.0.0
Python Pillow>=11.3.0<13.0.0
ubuntu/pillow-python2*
ubuntu/pillow*
ubuntu/pillow*
IBM App Connect Operator<=CD: 12.1.0 - 12.21.0 12.0 LTS: 12.0.0 - 12.0.28 13 LTS: 13.0.0 - 13.6.0
IBM App Connect EnterpriseCertified Containers Operands<=CD: 12.0.11.1-r1 - 12.0.12.5-r1, 13.0.1.0-r1 - 13.0.6.2-r1 12.0 LTS: 12.0.12-r1 - 12.0.12-r28 13 LTS: 13.0.7.0-r1 - 13.0.9.0-r1

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/pillow to a version that resolves this vulnerability.

    Fixed in 13.0.0
  2. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 13.0.0

Event History

Oct 19, 2026
CVE Published
via MITRE·09:02 PM
Data Sourced
via MITRE·09:02 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·10:17 PM
RemedyDescriptionSeverityWeaknessAffected Software
Oct 21, 2026
Advisory Published
via GitHub·09:24 PM
Data Sourced
via GitHub·09:24 PM
DescriptionSeverityWeaknessAffected Software
Nov 9, 2026
Data Sourced
via IBM·12:00 AM
DescriptionAffected Software
Nov 12, 2026
Data Sourced
via OSV·11:46 PM
Affected Software

Parent advisories

This vulnerability appears in the following advisories.

Frequently Asked Questions

1

Which deployments are exposed to this issue?

Applications using Pillow versions from 11.3.0 up to, but not including, 13.0.0 are affected when they encode TIFF data to an in-memory BytesIO buffer with attacker-influenced TIFF tags.

2

What must an attacker be able to control to trigger the flaw?

The attacker needs to influence TIFF tag data supplied to an application’s TIFF-saving operation. The vulnerable path requires libtiff to reject a tag during encoding to BytesIO.

3

What is the impact if exploitation succeeds?

The use-after-free can crash the affected process. The advisory also states that it may enable code execution.

4

What version remediates the issue?

Upgrade Pillow to version 13.0.0, which contains the fix.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203