
Samsung libimagecodec.quram.so OOB Write PoC
This repository contains conceptual Proof-of-Concept (PoC) files that demonstrate
out-of-bounds (OOB) write vulnerabilities in the Quramsoft image codec library
(libimagecodec.quram.so) used on Samsung Android devices.
| CVE | Format | Type | Severity | CVSS 4.0 | Patched In |
|---|---|---|---|---|---|
| CVE-2026-21045 | TIFF | Out-of-Bounds Write (CWE-787) | Critical | 8.4 | SMR Jul-2026 Release 1 |
| CVE-2026-21048 | DNG | Out-of-Bounds Write (CWE-787) | High | — | SMR Jul-2026 Release 1 |
/system/lib64/libimagecodec.quram.soThe vulnerability resides in the IFD (Image File Directory) tag parsing function
WINKJ_ReadExifField (offset 0x13a0a8 in the 64-bit binary). This function
processes individual TIFF/EXIF IFD entries, each being a 12-byte structure:
Offset Size Field
------ ---- -----
0 2 Tag ID
2 2 Data Type (1=BYTE, 2=ASCII, 3=SHORT, 4=LONG, 5=RATIONAL, etc.)
4 4 Count (number of values)
8 4 Value / Offset to data
When count * element_size > 4, the 4-byte Value field is treated as a file offset
(pointing to where the actual data lives). The code then performs a bounds check
at address 0x13a258:
add w8, w6, w7 ; w8 = value_offset + (count * element_size) [32-bit]
cmp w8, w5 ; compare against remaining buffer size
b.ls ok ; if w8 <= buffer_size, proceed
The vulnerability is a 32-bit unsigned integer overflow in the addition.
If an attacker crafts value_offset and count * element_size such that their
sum wraps around to a small value, the check passes even though the actual memory
access at base + value_offset goes out of bounds.
Example (UNDEFINED type, element_size = 1):
The 32-bit addition 0x17FFF + 0xFFFF0001 = 0x10008000 truncates to 0x8000,
which equals buffer_size. The check passes, but the actual data pointer
(base + 0x17FFF) lies 0x7FFF bytes past the end of the allocated buffer.
TIFFReadDirectory / WINKJ_ReadTiffInfo
└─> WINKJ_ReadTiffIFDInfo (allocates IFD buffer)
└─> for each IFD entry:
└─> WINKJ_ReadExifField (parses entry, reads value data)
└─> Switch on Data Type (jump table at 0x13a15c)
├─ Type 0 (BYTE/ASCII/UNDEFINED): handler at 0x13a15c
├─ Type 3/8 (SHORT/SSHORT): handler at 0x13a1d0
├─ Type 4/9/11 (LONG/SLONG/FLOAT): handler at 0x13a17c
└─ Type 5/10/12 (RATIONAL/SRATIONAL/DOUBLE): handler at 0x13a1ac
Each handler -> reads data at offset -> bounds check at 0x13a258
| File | Description |
|---|---|
cve-2026-21045_tiff_oob_poc.py | Generates poc_crash.tif — malformed TIFF triggering OOB write via ASCII tag with crafted count/offset |
cve-2026-21048_dng_oob_poc.py | Generates poc_crash.dng — malformed DNG triggering OOB write via UNDEFINED tag with crafted count/offset |
# Generate TIFF PoC
python3 cve-2026-21045_tiff_oob_poc.py -o payload.tif
# Generate DNG PoC
python3 cve-2026-21048_dng_oob_poc.py -o payload.dng
# Transfer to device and trigger (e.g., via Gallery/MMS)
adb push payload.tif /sdcard/Download/
adb shell am start -a android.intent.action.VIEW -d file:///sdcard/Download/payload.tif -t image/tiff
On an unpatched device (security patch < July 2026), opening the crafted TIFF/DNG file in Samsung Gallery (or any app using the Quram decoder) should cause a heap memory corruption potentially leading to:
On a patched device (SMR Jul-2026+), the image should either be rejected as invalid or processed safely. A crash on a fully-patched device may indicate a separate unpatched issue.
File: libimagecodec.quram.so (64-bit)
SHA256: (verify against your copy)
NDK: r23c (Android 21)
Built: 2021-12-31 (placeholder date)
Soname: libimagecodec.quram.so
Extracted from WINKJ_ReadExifField:
All types with element_size = 1 (BYTE, ASCII, UNDEFINED) share the same handler
and are equally vulnerable to the integer overflow bypass.
These proofs of concept are provided for educational and security research purposes only. They demonstrate the vulnerability mechanism to help users and developers understand the risk. Do not use them against systems you do not own or have explicit permission to test.
| Field | Value (hex) | Decimal |
|---|
count | 0xFFFF0001 | 4,294,901,761 |
element_size | 1 | 1 |
count * element_size | 0xFFFF0001 ≡ -65535 (mod 2³²) | 4,294,901,761 |
value_offset | 0x00017FFF | 98,303 |
value_offset + count*size | 0x00008000 (overflow!) | 32,768 |
buffer_size | 0x00008000 | 32,768 |
Check result: 0x8000 <= 0x8000 | ✅ PASS | — |
Actual memory access: base + 0x17FFF | 0x7FFF bytes beyond buffer | ❌ OOB |
| Function | Address (64-bit) | Size | Purpose |
|---|
WINKJ_ReadExifField | 0x13a0a8 | 912 | Parses individual IFD entry (vulnerable) |
WINKJ_ReadTiffIFDInfo | 0x139d28 | 896 | Reads all IFD entries |
WINKJ_ReadTiffInfo | 0x139ad4 | 596 | High-level TIFF info parser |
WINKJ_GetTiffInfo | 0x1393fc | 1752 | Main TIFF parsing entry point |
decodeTIFF | 0x1a2adc | 580 | Decodes TIFF image via libtiff |
getTIFFImageInfo | 0x1a2d20 | 508 | Gets TIFF image metadata |
copySubImageBuffer | 0x0b2824 | 324 | Copies sub-image region |
TIFFReadDirectory | 0x1aac78 | 5896 | libtiff 4.6.0 directory reader |
_TIFFMultiply32 | 0x1a2f1c | 56 | Safe 32-bit multiply check |
_TIFFMultiply64 | 0x1a2f58 | 48 | Safe 64-bit multiply check |
| Type | Name | Element Size | Handler Address |
|---|
| 1 | BYTE | 1 | 0x13a15c |
| 2 | ASCII | 1 | 0x13a15c |
| 3 | SHORT | 2 | 0x13a1d0 |
| 4 | LONG | 4 | 0x13a17c |
| 5 | RATIONAL | 8 | 0x13a1ac |
| 6 | SBYTE | 1 | 0x13a15c |
| 7 | UNDEFINED | 1 | 0x13a15c |
| 8 | SSHORT | 2 | 0x13a1d0 |
| 9 | SLONG | 4 | 0x13a17c |
| 10 | SRATIONAL | 8 | 0x13a1ac |
| 11 | FLOAT | 4 | 0x13a17c |
| 12 | DOUBLE | 8 | 0x13a1ac |
| CVE | Description | Status |
|---|
| CVE-2025-58477 | OOB write in IFD tag parsing in libimagecodec.quram.so (SMR Dec-2025) | ✅ Patched |
| CVE-2026-20973 | OOB read in libimagecodec.quram.so (SMR Jan-2026) | ✅ Patched |
| CVE-2026-21045 | OOB write in TIFF parsing in libimagecodec.media.quram.so (SMR Jul-2026) | ⚠️ Unpatched for me |
| CVE-2026-21048 | OOB write in DNG parsing in libimagecodec.media.quram.so (SMR Jul-2026) | ⚠️ Unpatched for me |
| CVE-2026-4775 | Signed integer overflow in libtiff 4.6.0 putcontig8bitYCbCr44tile | ⚠️ Unpatched for me |
| CVE-2024-7006 | NULL dereference in libtiff tif_dirinfo.c | ✅ Fixed in 4.6.1 |