fix(housekeeping): unaligned read UB + recv-drop parity; dedup mmsghdr; doc fixes
ci / rust (push) Has been cancelled
ci / rust (push) Has been cancelled
From a bug-hunt + unsafe-audit pass (4 reviewers + adversarial verify). It confirmed ZERO real bugs in the recent batched/paced data-plane work — these are the surfaced cleanups + one genuine soundness fix: - SOUNDNESS (reduce unsafe): inject/gamepad.rs::pump_ff did `ptr::read` of an InputEventRaw (align 8, holds a timeval) out of a 1-aligned [u8; N] buffer — UB per the reference (x86_64 tolerates it, but it can miscompile under LTO). Use ptr::read_unaligned + a SAFETY note. Zero behavior change. - recv parity: recv_batch (recvmmsg) didn't drop an oversized/truncated datagram the way scalar recv does — poll_frame now skips a message whose len fills the buffer (> MAX_DATAGRAM_BYTES), matching recv's `n >= RECV_BUF` drop. (AEAD already rejected these on encrypted sessions; this restores the documented invariant on the batched path.) - dedup unsafe FFI: factor the identical mmsghdr-from-iovec construction out of send_batch + recv_batch into one `mmsghdrs()` helper — the raw-pointer scaffolding + its lifetime SAFETY note now live in one place. - docs: TARGET_SOCKBUF no longer calls paced sending future work (it landed, m3.rs::paced_submit); gamescope.rs input is no longer "(TODO)" (wired + live-validated); the PUNKTFUNK_PERF `wire_mbps` field is renamed `tx_mbps` and noted as attempted/sealed bytes (send_dropped shows what didn't reach the wire). Full suite (35 + loopback round-trip + 6) + clippy + fmt green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -357,7 +357,11 @@ impl VirtualPad {
|
||||
if n != buf.len() as isize {
|
||||
break; // EAGAIN / short read — queue drained
|
||||
}
|
||||
let ev: InputEventRaw = unsafe { std::ptr::read(buf.as_ptr() as *const _) };
|
||||
// SAFETY: `buf` is exactly `size_of::<InputEventRaw>()` bytes and fully written by the
|
||||
// `read` above. `read_unaligned` (not `read`) because the `[u8]` buffer is 1-aligned but
|
||||
// `InputEventRaw` needs 8 (it holds a `timeval`) — a plain `ptr::read` would be UB.
|
||||
let ev: InputEventRaw =
|
||||
unsafe { std::ptr::read_unaligned(buf.as_ptr() as *const InputEventRaw) };
|
||||
match (ev.type_, ev.code) {
|
||||
(EV_UINPUT, UI_FF_UPLOAD) => {
|
||||
let mut up: UinputFfUpload = unsafe { std::mem::zeroed() };
|
||||
|
||||
Reference in New Issue
Block a user