{"record":{"id":"92da21594cbad814","repo":"tursodatabase/turso","slug":"mvcc-logical-log-frame-end-overflow","errorCode":null,"errorMessage":"MVCC logical log frame end overflow","messagePattern":"MVCC logical log frame end overflow","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/sync_server.rs","lineNumber":1083,"sourceCode":"            ));\n        }\n        if extension_size > 0 && frame_flags & MVCC_TX_FRAME_FLAG_HAS_EXTENSION_BLOCK == 0 {\n            return Err(anyhow!(\n                \"MVCC logical log extension block missing flag at offset {offset}\"\n            ));\n        }\n        extension_size\n    } else {\n        0\n    };\n    let trailer_start = offset\n        .checked_add(header_size)\n        .and_then(|value| value.checked_add(payload_size))\n        .and_then(|value| value.checked_add(extension_size))\n        .ok_or_else(|| anyhow!(\"MVCC logical log frame offset overflow\"))?;\n    let frame_end = trailer_start\n        .checked_add(MVCC_TX_TRAILER_SIZE)\n        .ok_or_else(|| anyhow!(\"MVCC logical log frame end overflow\"))?;\n    if frame_end > log.len() {\n        return Ok(None);\n    }\n    let expected_crc = crc32c::crc32c_append(running_crc, &log[offset..trailer_start]);\n    let stored_crc = read_u32_le(log, trailer_start)?;\n    if stored_crc != expected_crc {\n        return Err(anyhow!(\n            \"MVCC logical log frame checksum mismatch at offset {offset}\"\n        ));\n    }\n    let end_magic = read_u32_le(log, trailer_start + 4)?;\n    if end_magic != MVCC_TX_END_MAGIC {\n        return Err(anyhow!(\n            \"invalid MVCC logical log frame end magic at offset {offset}\"\n        ));\n    }\n    Ok(Some((frame_end, stored_crc)))\n}","sourceCodeStart":1065,"sourceCodeEnd":1101,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/cli/sync_server.rs#L1065-L1101","documentation":"The final bound computation adds the 8-byte trailer (MVCC_TX_TRAILER_SIZE) to the already-computed trailer_start with checked_add. Overflow requires the previous sum to sit within 8 bytes of usize::MAX, which only corrupted length metadata produces. The guard exists so the subsequent frame_end > log.len() comparison is always done on valid arithmetic.","triggerScenarios":"trailer_start within 8 bytes of usize::MAX after offset + header + payload + extension summed successfully — effectively the same corrupted-length scenario as the offset overflow, shifted by 8 bytes.","commonSituations":"Fuzzed log files engineered to make lengths just under usize::MAX; corrupted u64 length fields on any build; 32-bit builds with sizes near 4 GiB.","solutions":["Re-pull the log; trailer arithmetic overflow indicates corrupted length fields.","Use a 64-bit build for the sync server.","Add a plausibility pre-check bounding payload and extension sizes by the log length."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match scan_mvcc_log(&log) {\n    Ok(snapshot) => { /* serve deltas */ }\n    Err(err) if err.to_string().contains(\"frame end overflow\") => {\n        // same corrupt-length scenario as the offset overflow: re-pull the log\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Apply the same plausibility bounds as for the offset overflow.","Do not attempt to repair a log whose trailer arithmetic overflows; replace it.","Fuzz the scanner with maximal u64 lengths so these guards stay exercised."],"tags":["mvcc","turso","sync","integer-overflow","defensive-check"],"backgroundTag":"untrusted-length-overflow","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}