Skip to content

Use-after-release of Py_buffer in _prepare_lut_table #9681

Description

@Fuyugithub

Bug Description

In src/_imaging.c, _prepare_lut_table releases the buffer via PyBuffer_Release but then continues to read from the released buffer pointer in the subsequent loop.

Location

src/_imaging.c:832-898

Code

table_data = buffer_info.buf;       // save pointer
...
PyBuffer_Release(&buffer_info);     // line 845: buffer invalidated!
...
for (i = 0; i < table_size; i++) {
    memcpy(&htmp, ((char *)table_data) + i * sizeof(htmp), ...);  // lines 866-882: STALE POINTER
}

Impact

Per CPython docs: "After PyBuffer_Release, the buffer is invalid and must not be used." The table_data pointer becomes dangling. If the buffer provider frees underlying memory in releasebuffer (which custom array-like objects may do), this becomes a read-from-freed-memory bug, causing:

  • Garbage data in the LUT table
  • Crash/SIGSEGV
  • Potential information leak

Suggested Fix

Move PyBuffer_Release(&buffer_info) to after the loop at line ~899:

for (i = 0; i < table_size; i++) {
    memcpy(&htmp, ((char *)table_data) + i * sizeof(htmp), ...);
}
PyBuffer_Release(&buffer_info);  // release AFTER use

Environment

  • Pillow version: current main
  • Affected: ImageFilter.Color3DLUT / LUT operations with custom buffer objects

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions