From nobody Tue Jul 29 13:13:27 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4brwlD3Ny6z62ymV; Tue, 29 Jul 2025 13:13:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4brwlD14lzz3t6R; Tue, 29 Jul 2025 13:13:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753794808; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PqbDq1vlFCzZ5mmdx9XB1FQS+TPJDv1SAUvVN5nz0fk=; b=i28QPEI7DTlRCIynzBny9JspFL/KQbW/+XLcBp1ZkqUvVHlz9qCUDVxgf8995vudf1k6ia h/JODf8cavrTsWRwInAl772qdtrgh9qXEjNMZrm9tYUbIQRzgLYRKlf3uK6FsP4bNmk+fz i/xFc0DNVlOe51lSJ9OJ1RhNsDPyjJZV4vZMvBjw+49xegkKKT8X4V/U3/NlEjWqLN5DzK WwN3ZjLjA6CMYbtXD4UJsoA2IX+gt4kDxj/PjuXYshEs3f9H/kfdxRhO9KDj2fNvvhpjyo rBoGM4JWXLYirSuU0YuNCM4ajPIorh0VIoEaCZu0fzYO80v7GoAxzd8tAJfDpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1753794808; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PqbDq1vlFCzZ5mmdx9XB1FQS+TPJDv1SAUvVN5nz0fk=; b=VKMg8zi0qib5E70l/ZCQC/LPFNT07BeK/q1DSvGu6oVOzMz9nSRx/se6t76BPzK7idjuFE DTjCI9h1Mxt4LiL0fCtMsko+OOBRzn/GrYKvEVYwJgJWT3yy9uJoEhTiuR7KGnuRueEGiE IZYify4+izJ+UNnVYfgGTQAa0/CMQ3cuq8vg+9vrlUmO1pdg1qlwaPC5uf+/ZOTl3t4jVz y2kgoT3fde2lBmsfNw/u669zToNSXfphS133+iGy6k5C5ik+HfqXKO8MfwxPcFuTbmhnsi eG3buLAJ+W0RPMlZ1W60+FxcPdZButETnkSJbM/4wjjBL128g+8Al2wFccLgbg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1753794808; a=rsa-sha256; cv=none; b=sWTLa9jgCK55wRABY+yf3c7/splaGt9TJTvKC4GI+yqMyavGu2dF9ohGp3bXWDV8jWK65n DUg7f+gTECEYFJkKcJWO4TZPSm/yraT257YTJ8bXGe4UrUYfXpBEqXXX5uvQleBpxFD1Fh mYIksBF1byUZ7ctAACSFGydbC7oCQKoLJBDVB99gaBIuvTM+Av6PMiflyKnOBgpT2jqjlq uCv5roSdHyT0uIImdacAqqidHAXovEsiRAWBkKdUShrV/NPtdfBRsmbwq8fvv60OG9QiEq O5TMl0EGIUTs1A9sFjGon1aNqQOAnHag/YAIkSF8O4qdkzZVwHFZkMgnTwFLOQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4brwlD0hFpzZ9m; Tue, 29 Jul 2025 13:13:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 56TDDRGD089373; Tue, 29 Jul 2025 13:13:27 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 56TDDReZ089370; Tue, 29 Jul 2025 13:13:27 GMT (envelope-from git) Date: Tue, 29 Jul 2025 13:13:27 GMT Message-Id: <202507291313.56TDDReZ089370@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: e9ca883b12c0 - main - netinet6: Don't return non-IPv6 enabled interfaces from in6_getlinkifnet() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e9ca883b12c0db6210717025f539ef846b986d5b Auto-Submitted: auto-generated The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=e9ca883b12c0db6210717025f539ef846b986d5b commit e9ca883b12c0db6210717025f539ef846b986d5b Author: Kristof Provost AuthorDate: 2025-07-24 14:31:41 +0000 Commit: Kristof Provost CommitDate: 2025-07-29 13:13:10 +0000 netinet6: Don't return non-IPv6 enabled interfaces from in6_getlinkifnet() There are scenarios where we can end up looking up an interface by its scope and turn up an interface that doesn't have IPv6 enabled on it. If that happens we could end up dereferencing a NULL pointer accessing ifp->if_afdata[AF_INET6]. Check for this. One such scenario is if a firewall rewrites a destination address to a link-local address, with an embedded scope for such an interface. Attach a test case which provokes this. PR: 288263 Reported by: Robert Morris Reviewed by: zlei Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51500 --- sys/netinet6/scope6.c | 17 ++++++++++++++++- tests/sys/netpfil/pf/nat64.py | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c index 0987ea7e99ad..08702a2e81ab 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -505,8 +505,23 @@ in6_set_unicast_scopeid(struct in6_addr *in6, uint32_t scopeid) struct ifnet* in6_getlinkifnet(uint32_t zoneid) { + struct ifnet *ifp; - return (ifnet_byindex((u_short)zoneid)); + ifp = ifnet_byindex((u_short)zoneid); + + if (ifp == NULL) + return (NULL); + + /* An interface might not be IPv6 capable. */ + if (ifp->if_afdata[AF_INET6] == NULL) { + log(LOG_NOTICE, + "%s: embedded scope points to an interface without " + "IPv6: %s%%%d.\n", __func__, + if_name(ifp), zoneid); + return (NULL); + } + + return (ifp); } /* diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py index 5cc4713a16cc..a5890fc4a161 100644 --- a/tests/sys/netpfil/pf/nat64.py +++ b/tests/sys/netpfil/pf/nat64.py @@ -33,7 +33,7 @@ from atf_python.sys.net.tools import ToolsHelper from atf_python.sys.net.vnet import VnetTestTemplate class TestNAT64(VnetTestTemplate): - REQUIRED_MODULES = [ "pf" ] + REQUIRED_MODULES = [ "pf", "pflog" ] TOPOLOGY = { "vnet1": {"ifaces": ["if1"]}, "vnet2": {"ifaces": ["if1", "if2"]}, @@ -92,12 +92,15 @@ class TestNAT64(VnetTestTemplate): def vnet2_handler(self, vnet): ifname = vnet.iface_alias_map["if1"].name + ToolsHelper.print_output("/sbin/sysctl net.inet6.ip6.forwarding=1") ToolsHelper.print_output("/sbin/route add default 192.0.2.2") ToolsHelper.print_output("/sbin/pfctl -e") ToolsHelper.pf_rules([ "pass inet6 proto icmp6", "pass in on %s inet6 af-to inet from 192.0.2.1" % ifname]) + vnet.pipe.send(socket.if_nametoindex("pflog0")) + @pytest.mark.require_user("root") @pytest.mark.require_progs(["scapy"]) def test_tcp_rst(self): @@ -287,3 +290,39 @@ class TestNAT64(VnetTestTemplate): reply = sp.sr1(packet, timeout=3) # We don't expect a reply to a corrupted packet assert not reply + + @pytest.mark.require_user("root") + @pytest.mark.require_progs(["scapy"]) + def test_noip6(self): + """ + PR 288263: link-local target address in icmp6 ADVERT can cause NULL deref + """ + ifname = self.vnet.iface_alias_map["if1"].name + gw_mac = self.vnet.iface_alias_map["if1"].epairb.ether + scopeid = self.wait_object(self.vnet_map["vnet2"].pipe) + ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1") + + import scapy.all as sp + + pkt = sp.Ether(dst=gw_mac) \ + / sp.IPv6(dst="64:ff9b::203.0.113.2") \ + / sp.ICMPv6ND_NA(tgt="FFA2:%x:2821:125F:1D27:B3B2:3F6F:C43C" % scopeid) + pkt.show() + sp.hexdump(pkt) + s = DelayedSend(pkt, sendif=ifname) + + packets = sp.sniff(iface=ifname, timeout=5) + for r in packets: + r.show() + + # Try scope id that likely doesn't have an interface at all + pkt = sp.Ether(dst=gw_mac) \ + / sp.IPv6(dst="64:ff9b::203.0.113.2") \ + / sp.ICMPv6ND_NA(tgt="FFA2:%x:2821:125F:1D27:B3B2:3F6F:C43C" % 255) + pkt.show() + sp.hexdump(pkt) + s = DelayedSend(pkt, sendif=ifname) + + packets = sp.sniff(iface=ifname, timeout=5) + for r in packets: + r.show()