From nobody Tue Jan 11 18:18:14 2022 X-Original-To: dev-commits-src-branches@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 53D05194143C; Tue, 11 Jan 2022 18:18:16 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JYJpZ5vXhz4TZK; Tue, 11 Jan 2022 18:18:14 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 4B10D1DDA5; Tue, 11 Jan 2022 18:18:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 20BIIEeW000621; Tue, 11 Jan 2022 18:18:14 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 20BIIEAv000620; Tue, 11 Jan 2022 18:18:14 GMT (envelope-from git) Date: Tue, 11 Jan 2022 18:18:14 GMT Message-Id: <202201111818.20BIIEAv000620@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: 7910632fbd46 - releng/12.3 - Fix fragmented UDP packets handling since rev.360967. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/releng/12.3 X-Git-Reftype: branch X-Git-Commit: 7910632fbd469cda06915cbc84e8b8ff397938c9 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1641925095; 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=m2Pd9M/twJUkO3m+/aWF+BInNAy5z0cz4vhl8P36crc=; b=DLTREUznjvVWme+Rz4VVep06AwehegHnVEw7xZKnapZNRvFrkSq4djWu/tGqUeHIECV9yj LdRdlZoTjBch0AX6q9FIcAgG9IzLOk59kuKpF6/+8mgDerBwrOSTF5YASU6AKeUonsyTg7 WKRsJOdpoK6tjdpK5dDgV2sWxe2hs1Ek3Ad1DjEyx1Fdb/dXTiVc+X+RXua4RBconA56xI dPBEBQD/h8+/OwgI/hhZbzyUpKvSA+XPQf+i5rKvTVCWw9RnB4HAgZhSr599jNvF0J+mU3 tLOWsmcAGWDO2dhVTHQWLGJkZb3iwEB4UJunCdN/8U/EDE60VDN973Mo2LB6pg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1641925095; a=rsa-sha256; cv=none; b=Vd1oRhY88BjEMSH/A2RRNNlro2DtYw/ARWXW6PZzJ0a7uakNDU9Zn8hxA50Cb2zCnMvarf QfCVXMqtZLJ9YcPlaaI6aMu3hkLTA/AQCKskGNdJi4eP8k2AWrFB2uiYhw2bJCuPKyrLLz /9Hyuy+LChbM+Wm0vHxOODt/idSnoel/saW5paXHUMCOFK049Pz4KBXarfzO92QHKzQAV3 kkvNpZIwI36U2PcpNGxTSzgPnYwvaPUqdlXaCUZ4SAfMQB/fD8LB0T2VVID3FMuh+bAEgK cl3K84k4+WEq4/ix3axzC+O9PEOLYJcawIonQwoHEDOuYwHHALp0nFAaF4Bb8A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch releng/12.3 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=7910632fbd469cda06915cbc84e8b8ff397938c9 commit 7910632fbd469cda06915cbc84e8b8ff397938c9 Author: Maxim Sobolev AuthorDate: 2021-10-07 20:41:40 +0000 Commit: Ed Maste CommitDate: 2022-01-10 00:43:33 +0000 Fix fragmented UDP packets handling since rev.360967. Consider IP_MF flag when checking length of the UDP packet to match the declared value. Sponsored by: Sippy Software, Inc. Differential Revision: https://reviews.freebsd.org/D32363 MFC after: 2 weeks (cherry picked from commit 461e6f23db3b9794e6af88b381b066a2c0463d1c) (cherry picked from commit 73c5a2566dbb3ae57970b203d4de6fcf6088701c) Approved by: so Errata: EN-22:06.libalias --- sys/netinet/libalias/alias.c | 225 +++++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 105 deletions(-) diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c index 030177eb622d..3436bb62a406 100644 --- a/sys/netinet/libalias/alias.c +++ b/sys/netinet/libalias/alias.c @@ -720,21 +720,37 @@ ProtoAliasOut(struct libalias *la, struct ip *pip, return (PKT_ALIAS_IGNORED); } +#define MF_ISSET(_pip) (ntohs((_pip)->ip_off) & IP_MF) +#define FRAG_NO_HDR(_pip) (ntohs((_pip)->ip_off) & IP_OFFMASK) + +static struct udphdr * +ValidateUdpLength(struct ip *pip) +{ + struct udphdr *ud; + size_t dlen; + +#ifdef _KERNEL + KASSERT(!FRAG_NO_HDR(pip), ("header-less fragment isn't expected here")); +#endif + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (NULL); + ud = (struct udphdr *)ip_next(pip); + if (!MF_ISSET(pip) && dlen < ntohs(ud->uh_ulen)) + return (NULL); + return (ud); +} + static int UdpAliasIn(struct libalias *la, struct ip *pip) { struct udphdr *ud; struct alias_link *lnk; - size_t dlen; LIBALIAS_LOCK_ASSERT(la); - dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); - if (dlen < sizeof(struct udphdr)) - return (PKT_ALIAS_IGNORED); - - ud = (struct udphdr *)ip_next(pip); - if (dlen < ntohs(ud->uh_ulen)) + ud = ValidateUdpLength(pip); + if (ud == NULL) return (PKT_ALIAS_IGNORED); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, @@ -827,19 +843,14 @@ UdpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create) u_short proxy_server_port; int proxy_type; int error; - size_t dlen; LIBALIAS_LOCK_ASSERT(la); - /* Return if proxy-only mode is enabled and not proxyrule found.*/ - dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); - if (dlen < sizeof(struct udphdr)) - return (PKT_ALIAS_IGNORED); - - ud = (struct udphdr *)ip_next(pip); - if (dlen < ntohs(ud->uh_ulen)) + ud = ValidateUdpLength(pip); + if (ud == NULL) return (PKT_ALIAS_IGNORED); + /* Return if proxy-only mode is enabled and not proxyrule found.*/ proxy_type = ProxyCheck(la, &proxy_server_address, &proxy_server_port, pip->ip_src, pip->ip_dst, ud->uh_dport, pip->ip_p); if (proxy_type == 0 && (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY)) @@ -1338,64 +1349,65 @@ LibAliasInLocked(struct libalias *la, struct ip *pip, int maxpacketsize) goto getout; } + if (FRAG_NO_HDR(pip)) { + iresult = FragmentIn(la, pip->ip_src, pip, pip->ip_id, + &pip->ip_sum); + goto getout; + } + iresult = PKT_ALIAS_IGNORED; - if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { - switch (pip->ip_p) { - case IPPROTO_ICMP: - iresult = IcmpAliasIn(la, pip); - break; - case IPPROTO_UDP: - iresult = UdpAliasIn(la, pip); - break; - case IPPROTO_TCP: - iresult = TcpAliasIn(la, pip); - break; + switch (pip->ip_p) { + case IPPROTO_ICMP: + iresult = IcmpAliasIn(la, pip); + break; + case IPPROTO_UDP: + iresult = UdpAliasIn(la, pip); + break; + case IPPROTO_TCP: + iresult = TcpAliasIn(la, pip); + break; #ifdef _KERNEL - case IPPROTO_SCTP: - iresult = SctpAlias(la, pip, SN_TO_LOCAL); - break; + case IPPROTO_SCTP: + iresult = SctpAlias(la, pip, SN_TO_LOCAL); + break; #endif - case IPPROTO_GRE: { - int error; - struct alias_data ad = { - .lnk = NULL, - .oaddr = NULL, - .aaddr = NULL, - .aport = NULL, - .sport = NULL, - .dport = NULL, - .maxpktsize = 0 - }; - - /* Walk out chain. */ - error = find_handler(IN, IP, la, pip, &ad); - if (error == 0) - iresult = PKT_ALIAS_OK; - else - iresult = ProtoAliasIn(la, pip->ip_src, - pip, pip->ip_p, &pip->ip_sum); - break; - } - default: - iresult = ProtoAliasIn(la, pip->ip_src, pip, - pip->ip_p, &pip->ip_sum); - break; - } + case IPPROTO_GRE: { + int error; + struct alias_data ad = { + .lnk = NULL, + .oaddr = NULL, + .aaddr = NULL, + .aport = NULL, + .sport = NULL, + .dport = NULL, + .maxpktsize = 0 + }; - if (ntohs(pip->ip_off) & IP_MF) { - struct alias_link *lnk; + /* Walk out chain. */ + error = find_handler(IN, IP, la, pip, &ad); + if (error == 0) + iresult = PKT_ALIAS_OK; + else + iresult = ProtoAliasIn(la, pip->ip_src, + pip, pip->ip_p, &pip->ip_sum); + break; + } + default: + iresult = ProtoAliasIn(la, pip->ip_src, pip, + pip->ip_p, &pip->ip_sum); + break; + } - lnk = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id); - if (lnk != NULL) { - iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT; - SetFragmentAddr(lnk, pip->ip_dst); - } else { - iresult = PKT_ALIAS_ERROR; - } + if (MF_ISSET(pip)) { + struct alias_link *lnk; + + lnk = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id); + if (lnk != NULL) { + iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT; + SetFragmentAddr(lnk, pip->ip_dst); + } else { + iresult = PKT_ALIAS_ERROR; } - } else { - iresult = FragmentIn(la, pip->ip_src, pip, pip->ip_id, - &pip->ip_sum); } getout: @@ -1491,52 +1503,55 @@ LibAliasOutLocked(struct libalias *la, } else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) { SetDefaultAliasAddress(la, pip->ip_src); } + + if (FRAG_NO_HDR(pip)) { + iresult = FragmentOut(la, pip, &pip->ip_sum); + goto getout_restore; + } + iresult = PKT_ALIAS_IGNORED; - if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { - switch (pip->ip_p) { - case IPPROTO_ICMP: - iresult = IcmpAliasOut(la, pip, create); - break; - case IPPROTO_UDP: - iresult = UdpAliasOut(la, pip, maxpacketsize, create); - break; - case IPPROTO_TCP: - iresult = TcpAliasOut(la, pip, maxpacketsize, create); - break; + switch (pip->ip_p) { + case IPPROTO_ICMP: + iresult = IcmpAliasOut(la, pip, create); + break; + case IPPROTO_UDP: + iresult = UdpAliasOut(la, pip, maxpacketsize, create); + break; + case IPPROTO_TCP: + iresult = TcpAliasOut(la, pip, maxpacketsize, create); + break; #ifdef _KERNEL - case IPPROTO_SCTP: - iresult = SctpAlias(la, pip, SN_TO_GLOBAL); - break; + case IPPROTO_SCTP: + iresult = SctpAlias(la, pip, SN_TO_GLOBAL); + break; #endif - case IPPROTO_GRE: { - int error; - struct alias_data ad = { - .lnk = NULL, - .oaddr = NULL, - .aaddr = NULL, - .aport = NULL, - .sport = NULL, - .dport = NULL, - .maxpktsize = 0 - }; - /* Walk out chain. */ - error = find_handler(OUT, IP, la, pip, &ad); - if (error == 0) - iresult = PKT_ALIAS_OK; - else - iresult = ProtoAliasOut(la, pip, - pip->ip_dst, pip->ip_p, &pip->ip_sum, create); - break; - } - default: + case IPPROTO_GRE: { + int error; + struct alias_data ad = { + .lnk = NULL, + .oaddr = NULL, + .aaddr = NULL, + .aport = NULL, + .sport = NULL, + .dport = NULL, + .maxpktsize = 0 + }; + /* Walk out chain. */ + error = find_handler(OUT, IP, la, pip, &ad); + if (error == 0) + iresult = PKT_ALIAS_OK; + else iresult = ProtoAliasOut(la, pip, pip->ip_dst, pip->ip_p, &pip->ip_sum, create); - break; + break; } - } else { - iresult = FragmentOut(la, pip, &pip->ip_sum); + default: + iresult = ProtoAliasOut(la, pip, + pip->ip_dst, pip->ip_p, &pip->ip_sum, create); + break; } +getout_restore: SetDefaultAliasAddress(la, addr_save); getout: return (iresult);