Files
libfreemkv/docs/network-mod.md
T
Matthew Jackson 6e14fc0c0c libfreemkv: 1.7.0 groundwork — sector-recycle soundness + CI hardening
Security
- Remove the unsafe Vec::set_len over recycled sector buffers — UB reachable
  from safe code (GHSA-j8ww-f5fg-9pmh, low). Uses Vec::resize; pooling unchanged.

CI / tooling
- clippy on stable with the MSRV single-sourced from Cargo.toml; cargo-deny
  dependency-audit gate with first-party git sources allowed (#15); audience-based
  comment-guard (#17).

Docs
- README (keydb ownership, BD-J parser count), drive-access transport/reset
  notes, mux timeline module-doc links.
2026-09-02 12:40:55 -07:00

1.8 KiB

src/mux/network.rs — notes

is_blocked_ip / SSRF vetting rationale

validate_network_target (in autorip) vets the host once at settings-save time, but the raw hostname is re-resolved here at rip time — a DNS-rebinding attacker can flip a previously-public name to 127.0.0.1 / 10.x / 169.254.x in that window. Re-checking the actually-resolved address at connect time closes that TOCTOU.

resolve_allowed_addr resolves addr (host:port) and returns the first socket address whose IP is NOT is_blocked_ip. It errors with crate::error::Error::NetworkAddrBlocked if every resolved address is blocked, or propagates the resolver's own error if resolution fails. The returned SocketAddr carries a vetted IP literal, so the subsequent TcpStream::connect cannot be re-pointed by a second DNS lookup (it connects to the IP we vetted, not the name).

accept_from_rejects_stream_without_fmkv_header — flake fix

FLAKE FIXED, not the behaviour under test: this test used to shutdown(Shutdown::Both) the instant the bytes were written. Closing the READ half while the server had not yet read makes the kernel answer the server's in-flight data with an RST, so accept_from came back ConnectionReset instead of the InvalidInput this asserts — rarely when run alone, reproducibly under the loaded concurrent suite, where the server thread is descheduled long enough for the race to open. A logging/protocol assertion that fails at random teaches the next person to re-run until green, which is how a real regression gets waved through.

Half-closing (Shutdown::Write) delivers the same EOF the test needs while leaving the read half open, and blocking on a read until the server drops its end keeps the socket alive for as long as the server is looking at it. The port was already ephemeral (:0), so it was never a port collision.