From patchwork Sat Sep 17 11:31:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Quartulli X-Patchwork-Id: 2768 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id 1rGZOyA9JmOCDQAAIUCqbw (envelope-from ) for ; Sat, 17 Sep 2022 17:33:20 -0400 Received: from proxy15.mail.ord1d.rsapps.net ([172.30.191.6]) by director10.mail.ord1d.rsapps.net with LMTP id yCuuOiA9JmMIRgAApN4f7A (envelope-from ) for ; Sat, 17 Sep 2022 17:33:20 -0400 Received: from smtp39.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.ord1d.rsapps.net with LMTPS id GFnHOiA9JmMvMQAAAY1PeQ (envelope-from ) for ; Sat, 17 Sep 2022 17:33:20 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp39.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=unstable.cc; dmarc=none (p=nil; dis=none) header.from=unstable.cc X-Suspicious-Flag: YES X-Classification-ID: 595e071e-36d0-11ed-82e2-525400a97bbc-1-1 Received: from [216.105.38.7] ([216.105.38.7:35730] helo=lists.sourceforge.net) by smtp39.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 51/8F-00899-02D36236; Sat, 17 Sep 2022 17:33:20 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1oZfQE-000057-4d; Sat, 17 Sep 2022 21:32:22 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1oZfQC-00004w-S1 for openvpn-devel@lists.sourceforge.net; Sat, 17 Sep 2022 21:32:20 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=GrVVazv1wIgSjrrPCVsNvVEeKTzGY/LCIEWFtOEu59M=; b=PWOfkBya5VgKk3hZBeZbKbhqxA hw0qZAJgks0rWT9VQ0oPv+IfgTtTLAWnE37RrFKx7dJaGNL2mOG4y/qcasU1riO7h5Sbv7Heka22F Izxpz4haoOYUZfkgWF9FeigNay+baZ4e1hrYXZUs6QJwlniFWTtIDnx6fEhUqcWRvq28=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:Cc:To:From :Sender:Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=GrVVazv1wIgSjrrPCVsNvVEeKTzGY/LCIEWFtOEu59M=; b=l 7cQ77tVwFwUma1F+QIC/RJQpimwVgKAsBuBIRspbgO9RcYjC0v3c9KNURoaHguJWQ8Gas2khBccyX SlNO9/aaGwZJB3YnVr/0Km9EFKuCFf9qZvYfEg63wSd7/2K8XhNm5fdph99Cs65gkhBBr93utZ7cP QwWl9IwPOnBsb0q8=; Received: from mailout-l3b-97.contactoffice.com ([212.3.242.97]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1oZfQ4-00050S-Io for openvpn-devel@lists.sourceforge.net; Sat, 17 Sep 2022 21:32:15 +0000 Received: from smtpauth1.co-bxl (smtpauth1.co-bxl [10.2.0.15]) by mailout-l3b-97.contactoffice.com (Postfix) with ESMTP id 3C4D1158D; Sat, 17 Sep 2022 23:32:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1663450326; s=20220809-q8oc; d=unstable.cc; i=a@unstable.cc; h=From:Cc:Date:Message-Id:MIME-Version:Content-Transfer-Encoding; l=4109; bh=GrVVazv1wIgSjrrPCVsNvVEeKTzGY/LCIEWFtOEu59M=; b=UmlClnklcdJEN4T0hL1U2Xf97v3pShaB6BEifQCDAyOt0nyToTyDqx8Km4gMV7GB k8YxkKn46sbzFVl2IGdkSH+tJqEM4BXLk00VbW5v9z1QMTujcP2FMDdB48h7DJ2Bh9L JuYjf0ludov8Ebiwx7DHFZeZbIVV0+l0pLfFKzZ4k4j0x+OkSVpFkjIwvwPoaZF+qF5 53LnTd4yf2sh1tmL49d2PHXkkPkh5/QYmjvL2Q9IfuLc1vdcub6z0kPcu0GxE4UghKq mJD5QjOZlBapWsl8JurefkBxIWvEn0khmCNzrrmuEjGxcQLUTtffC8h+7Ps8yB2NNb+ sQ/2YFD+Ww== Received: by smtp.mailfence.com with ESMTPSA ; Sat, 17 Sep 2022 23:32:03 +0200 (CEST) From: Antonio Quartulli To: openvpn-devel@lists.sourceforge.net Date: Sat, 17 Sep 2022 23:31:54 +0200 Message-Id: <20220917213154.29285-1-a@unstable.cc> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Spam-Status: No, hits=-2.9 required=4.7 symbols=ALL_TRUSTED, BAYES_00 device=10.2.0.21 X-ContactOffice-Account: com:375058688 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: This patch brings the following improvements: * check that ETH proto and version in IP header are consistent; * check that length of the packet is enough to store the expected IP header (it may be an [...] Content analysis details: (-0.9 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: unstable.cc] -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at https://www.dnswl.org/, low trust [212.3.242.97 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1oZfQ4-00050S-Io Subject: [Openvpn-devel] [PATCH] is_ipv_X: improve packet consistency checks X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox This patch brings the following improvements: * check that ETH proto and version in IP header are consistent; * check that length of the packet is enough to store the expected IP header (it may be an IPv4 or an IPv6 header) * restyle a bit to improve readability; * remove spaces before ')' in invocations. Signed-off-by: Antonio Quartulli --- src/openvpn/proto.c | 91 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/src/openvpn/proto.c b/src/openvpn/proto.c index 88abd199..345df341 100644 --- a/src/openvpn/proto.c +++ b/src/openvpn/proto.c @@ -41,31 +41,40 @@ static bool is_ipv_X(int tunnel_type, struct buffer *buf, int ip_ver) { + uint16_t eth_ip_proto; int offset; - uint16_t proto; - const struct openvpn_iphdr *ih; + + switch (ip_ver) + { + case 4: + eth_ip_proto = OPENVPN_ETH_P_IPV4; + break; + + case 6: + eth_ip_proto = OPENVPN_ETH_P_IPV6; + break; + + default: + /* invalid input provided */ + return false; + } verify_align_4(buf); if (tunnel_type == DEV_TYPE_TUN) { - if (BLEN(buf) < sizeof(struct openvpn_iphdr)) - { - return false; - } offset = 0; } else if (tunnel_type == DEV_TYPE_TAP) { - const struct openvpn_ethhdr *eh; - if (BLEN(buf) < (sizeof(struct openvpn_ethhdr) - + sizeof(struct openvpn_iphdr))) + if (BLEN(buf) < sizeof(struct openvpn_ethhdr)) { return false; } - eh = (const struct openvpn_ethhdr *)BPTR(buf); - /* start by assuming this is a standard Eth fram */ - proto = eh->proto; + /* start by assuming this is a standard Eth frame */ + const struct openvpn_ethhdr *eh; + eh = (const struct openvpn_ethhdr *)BPTR(buf); + uint16_t proto = eh->proto; offset = sizeof(struct openvpn_ethhdr); /* if this is a 802.1q frame, parse the header using the according @@ -74,19 +83,17 @@ is_ipv_X(int tunnel_type, struct buffer *buf, int ip_ver) if (proto == htons(OPENVPN_ETH_P_8021Q)) { const struct openvpn_8021qhdr *evh; - if (BLEN(buf) < (sizeof(struct openvpn_ethhdr) - + sizeof(struct openvpn_iphdr))) + if (BLEN(buf) < sizeof(struct openvpn_8021qhdr)) { return false; } evh = (const struct openvpn_8021qhdr *)BPTR(buf); - proto = evh->proto; offset = sizeof(struct openvpn_8021qhdr); } - if (ntohs(proto) != (ip_ver == 6 ? OPENVPN_ETH_P_IPV6 : OPENVPN_ETH_P_IPV4)) + if (ntohs(proto) != eth_ip_proto) { return false; } @@ -96,28 +103,68 @@ is_ipv_X(int tunnel_type, struct buffer *buf, int ip_ver) return false; } - ih = (const struct openvpn_iphdr *)(BPTR(buf) + offset); + /* ensure that there is enough room for a header of the expected version */ + size_t ih_len = 0; + switch (eth_ip_proto) + { + case OPENVPN_ETH_P_IPV4: + ih_len = sizeof(struct openvpn_iphdr); + break; + + case OPENVPN_ETH_P_IPV6: + ih_len = sizeof(struct openvpn_ipv6hdr); + break; + } + if (BLEN(buf) < (offset + ih_len)) + { + return false; + } /* IP version is stored in the same bits for IPv4 or IPv6 header */ - if (OPENVPN_IPH_GET_VER(ih->version_len) == ip_ver) + const struct openvpn_iphdr *ih; + ih = (const struct openvpn_iphdr *)(BPTR(buf) + offset); + uint8_t hdr_ip_ver = OPENVPN_IPH_GET_VER(ih->version_len); + + if (tunnel_type == DEV_TYPE_TAP) { - return buf_advance(buf, offset); + /* ensure consistency between the version in the IP header and + * the Eth proto that was retrieved previously + */ + switch (eth_ip_proto) + { + case OPENVPN_ETH_P_IPV4: + if (hdr_ip_ver != 4) + { + return false; + } + break; + + case OPENVPN_ETH_P_IPV6: + if (hdr_ip_ver != 6) + { + return false; + } + break; + } } - else + + if (hdr_ip_ver != ip_ver) { return false; } + + return buf_advance(buf, offset); } bool is_ipv4(int tunnel_type, struct buffer *buf) { - return is_ipv_X( tunnel_type, buf, 4 ); + return is_ipv_X(tunnel_type, buf, 4); } bool is_ipv6(int tunnel_type, struct buffer *buf) { - return is_ipv_X( tunnel_type, buf, 6 ); + return is_ipv_X(tunnel_type, buf, 6); }