From patchwork Fri Aug 16 14:31:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dumitru Ceara X-Patchwork-Id: 1148258 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4695PS1mJPz9sND for ; Sat, 17 Aug 2019 00:32:11 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id AC3E0E94; Fri, 16 Aug 2019 14:32:09 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 4C135E85 for ; Fri, 16 Aug 2019 14:32:08 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id E7B7987B for ; Fri, 16 Aug 2019 14:32:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7742B356C5 for ; Fri, 16 Aug 2019 14:32:07 +0000 (UTC) Received: from dceara.remote.csb (ovpn-117-116.ams2.redhat.com [10.36.117.116]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5C6A88F6CE; Fri, 16 Aug 2019 14:32:06 +0000 (UTC) From: Dumitru Ceara To: dev@openvswitch.org Date: Fri, 16 Aug 2019 16:31:28 +0200 Message-Id: <1565965888-30467-1-git-send-email-dceara@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 16 Aug 2019 14:32:07 +0000 (UTC) X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH branch-2.12] pinctrl: Fix DNS packet parsing X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Dumitru Ceara Due to the use of a uint8_t to index inside the DNS payload we could end up in an infinite loop when specific (invalid) DNS packets were processed by ovn-controller. In the infinite loop we keep increasing the query_name dynamic string until running out of memory. One way to replicate the issue is to configure DNS on the logical switch and then inject a manually crafted DNS-like packet. For example, with Scapy: >>> p = IP(dst='10.0.0.2',src='10.0.0.3')/UDP(dport=53)/('a'*364) >>> send(p) Also add a sanity check on minimum L4 size of packets. CC: Numan Siddique Fixes: 16cb4fb8ca49 ("ovn-controller: Add 'dns_lookup' action") Reported-at: https://bugzilla.redhat.com/1740335 Reported-by: Priscila Signed-off-by: Dumitru Ceara Signed-off-by: Numan Siddique (cherry-picked from ovn commit - 7fbdeaade826da299c20c05050627ebea65fe8c2) --- ovn/controller/pinctrl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index e443449..e388bbc 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -1628,6 +1628,12 @@ pinctrl_handle_dns_lookup( goto exit; } + /* Check that the packet stores at least the minimal headers. */ + if (dp_packet_l4_size(pkt_in) < (UDP_HEADER_LEN + DNS_HEADER_LEN)) { + VLOG_WARN_RL(&rl, "truncated dns packet"); + goto exit; + } + /* Extract the DNS header */ struct dns_header const *in_dns_header = dp_packet_get_udp_payload(pkt_in); if (!in_dns_header) { @@ -1652,7 +1658,7 @@ pinctrl_handle_dns_lookup( uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len); uint8_t *in_dns_data = (uint8_t *)(in_dns_header + 1); uint8_t *in_queryname = in_dns_data; - uint8_t idx = 0; + uint16_t idx = 0; struct ds query_name; ds_init(&query_name); /* Extract the query_name. If the query name is - 'www.ovn.org' it would be