Describe the bug
noq-udp panics on the first received packet on any musl target.
cmsg::decode() asserts align_of::<T>() <= align_of::<C>(). musl declares cmsghdr as { socklen_t cmsg_len, c_int __pad1, c_int cmsg_level, c_int cmsg_type } → align 4, whereas glibc uses size_t cmsg_len → align 8. The SCM_TIMESTAMPNS arm decodes libc::timespec (align 8), so the assert fails. Both operands are compile-time constants, so this is deterministic rather than data-dependent, and SO_TIMESTAMPNS is set unconditionally on Linux, so the path is always live.
Introduced by b454d1799 feat(udp): implement kernel receive timestamps on Linux/Android.
This is not memory unsafety: the control buffer is #[repr(align(8))], so the payload really is 8-aligned in practice. The assert compares the declared alignment of cmsghdr rather than the buffer alignment the code deliberately enforces.
Reproduces in noq's own test suite:
docker run --rm -v "$PWD:/w" -w /w rust:alpine \
sh -c 'apk add --no-cache musl-dev >/dev/null; cargo test -p noq-udp'
Relevant Logs
thread 'gso' panicked at noq-udp/src/cmsg/mod.rs:81:5:
assertion failed: align_of::<T>() <= align_of::<C>()
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
basic
basic_src_ip
ecn_v4
ecn_v4_mapped_v6
ecn_v6
ecn_v6_dualstack
gso
recv_survives_icmp_unreachable_from_prior_send
socket_buffers
test result: FAILED. 0 passed; 9 failed; 0 ignored; 0 measured; 0 filtered out
Expected behavior
- Packets are received on musl targets
cargo test -p noq-udp passes
noq
Version: 1.1.0 (also reproduces on main @ 5cf07f4)
noq-udp v1.1.0
├── noq-udp feature "default" (command-line)
├── noq-udp feature "tracing"
│ ├── noq-udp feature "default" (command-line)
│ └── noq-udp feature "tracing-log"
│ └── noq-udp feature "default" (command-line)
└── noq-udp feature "tracing-log" (*)
Platform(s)
Desktop:
- OS: Alpine Linux (Docker
rust:alpine, rustc 1.97.1) reproduced on both aarch64-unknown-linux-musl and x86_64-unknown-linux-musl
- Version 3.24.1
Desktop (also affected):
- OS: Ubuntu x86_64 running the statically-linked musl
iroh-relay build
- Version 24.04.3 LTS
Additional Context / Screenshots / GIFs
Real-world impact: the official iroh-relay v1.0.3 static binary (from the n0computer/iroh-relay:v1.0.3 image) is musl-linked and crash-loops on first traffic. Because the cmsg decode happens before any protocol parsing, a single unauthenticated UDP datagram to the QUIC port is enough to abort the process so no handshake required. I confirmed that with nc against two otherwise-identical hosts, one patched and one not.
lolwut
Describe the bug
noq-udppanics on the first received packet on any musl target.cmsg::decode()assertsalign_of::<T>() <= align_of::<C>(). musl declarescmsghdras{ socklen_t cmsg_len, c_int __pad1, c_int cmsg_level, c_int cmsg_type }→ align 4, whereas glibc usessize_t cmsg_len→ align 8. TheSCM_TIMESTAMPNSarm decodeslibc::timespec(align 8), so the assert fails. Both operands are compile-time constants, so this is deterministic rather than data-dependent, andSO_TIMESTAMPNSis set unconditionally on Linux, so the path is always live.Introduced by
b454d1799feat(udp): implement kernel receive timestamps on Linux/Android.This is not memory unsafety: the control buffer is
#[repr(align(8))], so the payload really is 8-aligned in practice. The assert compares the declared alignment ofcmsghdrrather than the buffer alignment the code deliberately enforces.Reproduces in noq's own test suite:
Relevant Logs
Expected behavior
cargo test -p noq-udppassesnoq
Version: 1.1.0 (also reproduces on main @ 5cf07f4)
Platform(s)
Desktop:
rust:alpine, rustc 1.97.1) reproduced on bothaarch64-unknown-linux-muslandx86_64-unknown-linux-muslDesktop (also affected):
iroh-relaybuildAdditional Context / Screenshots / GIFs
Real-world impact: the official
iroh-relayv1.0.3 static binary (from then0computer/iroh-relay:v1.0.3image) is musl-linked and crash-loops on first traffic. Because the cmsg decode happens before any protocol parsing, a single unauthenticated UDP datagram to the QUIC port is enough to abort the process so no handshake required. I confirmed that withncagainst two otherwise-identical hosts, one patched and one not.lolwut
the issue being reported and wrote this as concisely and clearly
as they could. Taking full responsibility for the issue being
accurate.