mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-11-13 03:37:15 +00:00
python3-pillow: upgrade 12.3.0 -> 13.0.0
Home Assistant 2026.11 pins Pillow 13.0.0. Drop CVE-2026-112393.patch. It backported the upstream fix [1] to 12.3.0. That commit is an ancestor of the 13.0.0 tag, so 13.0.0 contains the fix, and the patch no longer applies. [1] https://github.com/python-pillow/Pillow/commit/78c08bd4d9c08037f77465a61d90633f669013f4 AI-Generated: Claude Code, Claude Opus 5.5 Signed-off-by: Thomas Roos <thomas@roosesweb.de> Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
1 parent
76e0e51b5d
commit
668a51afd4
2 files changed
+1
-126
No files matched your search
@@ -1,124 +0,0 @@
|
||||
From 9b693ea929423da2bebef5523881ae3850c3877e Mon Sep 17 00:00:00 2001
|
||||
From: Jeffrey 'Alex' Clark <aclark@aclark.net>
|
||||
Date: Mon, 12 Oct 2026 21:18:41 -0400
|
||||
Subject: [PATCH] Fix heap buffer overflow in _tiffWriteProc when saving TIFF
|
||||
to BytesIO
|
||||
|
||||
libtiff seeks past the current end of data when writing the directory
|
||||
and writes tag values there. _tiffWriteProc sized its realloc() from
|
||||
state->size + size instead of the write position state->loc + size,
|
||||
so the first out-of-line tag value written after such a seek could
|
||||
overrun the allocation by up to the size of the directory. The bytes
|
||||
skipped by the seek were also never zeroed, leaking stale heap
|
||||
contents into the saved file.
|
||||
|
||||
Size the buffer from the write position and zero the space added by
|
||||
realloc, matching the semantics of writing to a real file. Reject
|
||||
writes where the position is still beyond the buffer for the
|
||||
non-reallocating case.
|
||||
|
||||
Reported-by: carlini
|
||||
Reported-by: Tomer-PL
|
||||
Fixes: GHSA-332p-7hrc-92wf
|
||||
|
||||
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
|
||||
CVE: CVE-2026-112393
|
||||
Upstream-Status: Backport [https://github.com/python-pillow/Pillow/commit/78c08bd4d9c08037f77465a61d90633f669013f4]
|
||||
|
||||
Signed-off-by: Kris Gavvala <kris.gavvala@windriver.com>
|
||||
---
|
||||
Tests/test_file_libtiff.py | 36 ++++++++++++++++++++++++++++++++++++
|
||||
src/libImaging/TiffDecode.c | 15 ++++++++++++++-
|
||||
2 files changed, 50 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Tests/test_file_libtiff.py b/Tests/test_file_libtiff.py
|
||||
index c9849a056..84e4299a1 100644
|
||||
--- a/Tests/test_file_libtiff.py
|
||||
+++ b/Tests/test_file_libtiff.py
|
||||
@@ -757,6 +757,42 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||
save_bytesio("packbits")
|
||||
save_bytesio("tiff_lzw")
|
||||
|
||||
+
|
||||
+ def test_save_bytesio_seek_past_end(self, tmp_path: Path) -> None:
|
||||
+ # When writing the directory, libtiff seeks past the end of the data
|
||||
+ # written so far, and then writes the tag values there. Check that the
|
||||
+ # in-memory write buffer grows to fit, and that the bytes that are
|
||||
+ # skipped over are zero, as they would be when writing to a file.
|
||||
+
|
||||
+ # 7 distinct bytes per row: PackBits emits 8 bytes per row, so the strip
|
||||
+ # plus the header are exactly 64 KiB, the initial size of the buffer
|
||||
+ im = Image.new("L", (7, 8191))
|
||||
+ im.putdata([(i * 37) & 0xFF for i in range(7 * 8191)])
|
||||
+ kwargs: dict[str, Any] = {
|
||||
+ "compression": "packbits",
|
||||
+ "description": "D" * 65535,
|
||||
+ }
|
||||
+
|
||||
+ outfile = tmp_path / "temp.tif"
|
||||
+ im.save(outfile, **kwargs)
|
||||
+ buffer_io = io.BytesIO()
|
||||
+ im.save(buffer_io, format="tiff", **kwargs)
|
||||
+ assert buffer_io.getvalue() == outfile.read_bytes()
|
||||
+
|
||||
+ # odd-length tag values, so that libtiff pads between them. Large enough
|
||||
+ # that the buffer has to be reallocated
|
||||
+ im = hopper().resize((300, 300))
|
||||
+ kwargs = {
|
||||
+ "compression": "tiff_lzw",
|
||||
+ "description": "abcdef",
|
||||
+ "software": "xyz0",
|
||||
+ "tiffinfo": {315: "artist", 33432: "copyright!"},
|
||||
+ }
|
||||
+ im.save(outfile, **kwargs)
|
||||
+ buffer_io = io.BytesIO()
|
||||
+ im.save(buffer_io, format="tiff", **kwargs)
|
||||
+ assert buffer_io.getvalue() == outfile.read_bytes()
|
||||
+
|
||||
def test_save_ycbcr(self, tmp_path: Path) -> None:
|
||||
im = hopper("YCbCr")
|
||||
outfile = tmp_path / "temp.tif"
|
||||
diff --git a/src/libImaging/TiffDecode.c b/src/libImaging/TiffDecode.c
|
||||
index 72e0d7b30..e21327f02 100644
|
||||
--- a/src/libImaging/TiffDecode.c
|
||||
+++ b/src/libImaging/TiffDecode.c
|
||||
@@ -88,10 +88,12 @@ _tiffWriteProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
||||
dump_state(state);
|
||||
|
||||
to_write = min(size, state->size - (tsize_t)state->loc);
|
||||
+ // libtiff may have seeked past the end of the buffer, e.g. when writing the
|
||||
+ // directory, so the required size is based on the current location.
|
||||
if (state->flrealloc && size > to_write) {
|
||||
tdata_t new_data;
|
||||
tsize_t newsize = state->size;
|
||||
- while (newsize < (size + state->size)) {
|
||||
+ while (newsize < (size + (tsize_t)state->loc)) {
|
||||
if (newsize > INT_MAX - 64 * 1024) {
|
||||
return 0;
|
||||
}
|
||||
@@ -105,9 +107,20 @@ _tiffWriteProc(thandle_t hdata, tdata_t buf, tsize_t size) {
|
||||
// fail out
|
||||
return 0;
|
||||
}
|
||||
+ // zero the new space, so that any bytes libtiff seeks over without
|
||||
+ // writing are 0 in the output, as they would be in a file
|
||||
+ memset((UINT8 *)new_data + state->size, 0, newsize - state->size);
|
||||
state->data = new_data;
|
||||
state->size = newsize;
|
||||
to_write = size;
|
||||
+ } else if (to_write < 0) {
|
||||
+ TIFFError(
|
||||
+ "_tiffWriteProc",
|
||||
+ "Invalid Write at loc %" PRIu64 ", size: %" PRIu64,
|
||||
+ state->loc,
|
||||
+ (toff_t)state->size
|
||||
+ );
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
TRACE(("to_write: %d\n", (int)to_write));
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Reference in new issue
Block a user