{"record":{"id":"2f87f005e51b33fa","repo":"astrid-runtime/astrid","slug":"ipc-frame-overflow","errorCode":null,"errorMessage":"IPC frame overflow","messagePattern":"IPC frame overflow","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-uplink/src/native/framing.rs","lineNumber":42,"sourceCode":"    /// completed read are appended before the next await. Recreating this\n    /// future after another `select!` branch wins therefore cannot discard a\n    /// partially received prefix or body.\n    pub(super) async fn read_message(&mut self) -> std::io::Result<Option<IpcMessage>> {\n        loop {\n            if self.buffered.len() >= 4 {\n                let len = u32::from_be_bytes(\n                    self.buffered[..4]\n                        .try_into()\n                        .expect(\"four-byte frame prefix\"),\n                ) as usize;\n                if len > MAX_FRAME_BYTES {\n                    return Err(std::io::Error::new(\n                        std::io::ErrorKind::InvalidData,\n                        format!(\"IPC frame too large: {len} bytes\"),\n                    ));\n                }\n                let frame_len = 4_usize.checked_add(len).ok_or_else(|| {\n                    std::io::Error::new(std::io::ErrorKind::InvalidData, \"IPC frame overflow\")\n                })?;\n                if self.buffered.len() >= frame_len {\n                    let message =\n                        serde_json::from_slice(&self.buffered[4..frame_len]).map_err(|error| {\n                            std::io::Error::new(\n                                std::io::ErrorKind::InvalidData,\n                                format!(\"invalid IPC message: {error}\"),\n                            )\n                        })?;\n                    self.buffered.drain(..frame_len);\n                    return Ok(Some(message));\n                }\n            }\n\n            let mut chunk = [0_u8; 8192];\n            let read = self.reader.read(&mut chunk).await?;\n            if read == 0 {\n                if self.buffered.is_empty() {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-uplink/src/native/framing.rs#L24-L60","documentation":"After the length-prefix size check, read_message computes frame_len = 4 + payload length with checked arithmetic. If that addition overflows usize (only possible on 32-bit targets or near-max values that passed the MAX check via a raised limit), the reader returns InvalidData 'IPC frame overflow' instead of wrapping and allocating a bogus buffer.","triggerScenarios":"read_message decodes a length prefix where 4usize.checked_add(len) returns None — the declared length is at or near usize::MAX, which can only happen with a corrupt/malicious prefix or an improperly configured/absent size cap between peers.","commonSituations":"Corrupted length bytes on a 32-bit platform; a peer sending a deliberately malicious u32::MAX-adjacent prefix when the local MAX_FRAME_BYTES check was weakened; desynced stream interpreting payload as a prefix on a 32-bit build.","solutions":["Restore/enforce MAX_FRAME_BYTES so implausible lengths are rejected by the size check before arithmetic.","Reconnect and resynchronize the stream — a corrupt prefix means framing is already desynced.","If running a 32-bit build, confirm both peers agree on frame limits; consider a 64-bit build for headroom.","Treat this as a protocol violation from the peer: log the offending peer and close the connection."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match framed.read_message().await {\n    Err(e) if e.to_string().contains(\"IPC frame overflow\") => {\n        // protocol violation from peer: log and terminate the connection\n        connection.terminate().await?;\n    }\n    other => other?,\n}","preventionTips":["Keep the MAX_FRAME_BYTES guard intact so absurd prefixes are caught before arithmetic.","On 32-bit targets, double-check both peers' frame limits and prefix encoding.","Reconnect on any framing error; never attempt to continue parsing a desynced stream.","Log the raw prefix bytes for offending frames to diagnose malicious/corrupt peers."],"tags":["ipc","framing","overflow","protocol"],"backgroundTag":"payload-too-large","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}