From patchwork Mon Mar 13 16:31:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 738272 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vhjzv6WPpz9ryk for ; Tue, 14 Mar 2017 03:31:23 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="mqwCs4pa"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; q=dns; s=default; b= ldudGGZ7f7wu2PSdxBAea71zY700K82vcslMu4gheKToNmfwB2dWLAXr1YqAOO8P cHxfhNjzcpFYf9PTxVtIVOMOz7hSXziBWMxi5Wi+ZSXWz38BT9qm//ayRnRSD897 OWn6+eOqCXR9/kQo0DQmtSspBE7MMfAIJBPofJScGzk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:to:subject:mime-version:content-type :content-transfer-encoding:message-id:from; s=default; bh=GflJPS lFVU9Eq1ebgo9zxTz7MXY=; b=mqwCs4paelkiX/iV2XkYMo+smmj2pPrLz4spVu Lh9XVunGbonX+MjcAmfI3jA7/NrxKo0f6/eI4glOc611uR/tNK5a6wO7tbHsMOYA 05GTeZ8X25088MZhGpSjKaA3ztSb5JQsskFk3IygZvHHG88z87ymTlNYULWUwLGS 20Up4= Received: (qmail 21719 invoked by alias); 13 Mar 2017 16:31:14 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 13419 invoked by uid 89); 13 Mar 2017 16:31:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Response, 1117, CNAME, x12 X-HELO: mx1.redhat.com Date: Mon, 13 Mar 2017 17:31:08 +0100 To: libc-alpha@sourceware.org Subject: [PATCH] support_format_dns_packet: Fix CNAME and multiple RR handling User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20170313163108.A062040196D5E@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) Before this change, the loop iterating over RRs in the answer section stopped at the first CNAME record, never printing them. The CNAME and PTR record contents was extracted from the wrong buffer (whole packet instead RDATA). This desynced the parsing after the first CNAME or PTR record. 2017-03-13 Florian Weimer * support/support_format_dns_packet.c (support_format_dns_packet): Handle CNAME records in the response. Extract RDATA names from rdata, not the whole packet. * support/tst-support_format_dns_packet.c: New file. * support/Makefile (tests): Add tst-support_format_dns_packet. (tst-support_format_dns_packet): Link against libresolv. diff --git a/support/Makefile b/support/Makefile index 2ace559..db7bb13 100644 --- a/support/Makefile +++ b/support/Makefile @@ -111,6 +111,7 @@ endif tests = \ README-testing \ tst-support-namespace \ + tst-support_format_dns_packet \ tst-support_record_failure \ ifeq ($(run-built-tests),yes) @@ -125,4 +126,6 @@ $(objpfx)tst-support_record_failure-2.out: tst-support_record_failure-2.sh \ $(evaluate-test) endif +$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so + include ../Rules diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c index 21fe7e5..d56b820 100644 --- a/support/support_format_dns_packet.c +++ b/support/support_format_dns_packet.c @@ -174,7 +174,7 @@ support_format_dns_packet (const unsigned char *buffer, size_t length) goto out; } /* Skip non-matching record types. */ - if (rtype != qtype || rclass != qclass) + if ((rtype != qtype && rtype != T_CNAME) || rclass != qclass) continue; switch (rtype) { @@ -201,7 +201,7 @@ support_format_dns_packet (const unsigned char *buffer, size_t length) case T_PTR: { struct dname name; - if (extract_name (full, &in, &name)) + if (extract_name (full, &rdata, &name)) fprintf (mem.out, "name: %s\n", name.name); else fprintf (mem.out, "error: malformed CNAME/PTR record\n"); diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c new file mode 100644 index 0000000..eb174e2 --- /dev/null +++ b/support/tst-support_format_dns_packet.c @@ -0,0 +1,62 @@ +/* Tests for the support_format_dns_packet function. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static void +test_multiple_cnames (void) +{ + static const char packet[] = + /* Header: Response with three records. */ + "\x12\x34\x80\x00\x00\x01\x00\x03\x00\x00\x00\x00" + /* Question section. www.example/IN/A. */ + "\x03www\x07""example\x00\x00\x01\x00\x01" + /* Answer section. www.example CNAME www1.example. */ + "\xc0\x0c" + "\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07" + "\x04www1\xc0\x10" + /* www1 CNAME www2. */ + "\x04www1\xc0\x10" + "\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07" + "\x04www2\xc0\x10" + /* www2 A 192.0.2.1. */ + "\x04www2\xc0\x10" + "\x00\x01\x00\x01\x00\x00\x00\x00\x00\x04" + "\xc0\x00\x02\x01"; + + char *formatted = support_format_dns_packet + ((unsigned char *) packet, sizeof (packet) - 1); + puts ("info: test_multiple_cnames output:"); + puts (formatted); + TEST_VERIFY (strcmp (formatted, + "name: www.example\n" + "name: www1.example\n" + "name: www2.example\n" + "address: 192.0.2.1\n") == 0); + free (formatted); +} + +static int +do_test (void) +{ + test_multiple_cnames (); + return 0; +} + +#include