fix(net): canonicalize v4-mapped IPv6 destinations before policy checks#151
Open
congwang-mk wants to merge 1 commit into
Open
fix(net): canonicalize v4-mapped IPv6 destinations before policy checks#151congwang-mk wants to merge 1 commit into
congwang-mk wants to merge 1 commit into
Conversation
Signed-off-by: Cong Wang <cwang@multikernel.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Network policy matching is family-exact, but a dual-stack
AF_INET6socket that connects to the v4-mapped form::ffff:a.b.c.dreachesa.b.c.dover IPv4. The mapped spelling therefore matched neither v4 CIDR rules nor theis_loopback()gates:--net-deny 169.254.169.254was bypassable viaconnect(::ffff:169.254.169.254)(fails open).--net-allowtarget rejected the same destination written in mapped form (fails closed).::ffff:127.0.0.1was treated as non-loopback by the connect supervision and port-remap gates.Fix
Canonicalize v4-mapped destinations to their V4 form before any policy decision:
parse_ip_from_sockaddr(the parse-phase choke point for connect/sendto/sendmsg/sendmmsg) now returnsIpv6Addr::to_canonical(), so every downstream consumer sees the real destination.NetworkPolicy::allowscanonicalizes at entry as defense in depth, keeping the pure matcher safe regardless of caller.read_sockaddr_for_eventnow reuses the shared materialize parsers (dropping its duplicated hand-rolled parsing), so policy_fn callbacks judge the same canonical address the enforcement path does.Sockaddr rewrites must keep following the socket's family, not the canonical IP's family, so the proxy-redirect plan and the
record_orig_destlocal-bind probe now use a newsockaddr_is_ipv6helper that reads the family field directly. A v6 socket connecting to a mapped destination is still redirected with anAF_INET6sockaddr.Testing
NetworkPolicy::allows(deny and allow sides),parse_ip_from_sockaddrcanonicalization, and aplan_connect_targetregression guard for the redirect family. All were written first and failed on the pre-fix code.sandlock run --net-deny 169.254.169.254now refusesconnect(::ffff:169.254.169.254)instantly withECONNREFUSED, while a control run denying an unrelated IP proceeds to the wire and times out.Known remaining wart (out of scope here): a rule literal written in mapped form, e.g.
--net-deny '::ffff:1.2.3.4', still parses as a V6 host and will never match a canonical destination. Canonicalizing single-host mapped literals inIpCidr::parsewould be a small follow-up.