From patchwork Fri Mar 25 18:55:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 602088 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 3qWsvM6D3rz9s9Z for ; Sat, 26 Mar 2016 05:55:43 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=nnessnHd; 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:to:from:subject:message-id:date:mime-version :content-type; q=dns; s=default; b=Kfkrus8nLWjCDB246Gbp0o4wk/I5k +OlXpuFeCwZ9D018UiLGPE2KxGWmKbGANqZasvBF4LO+6x0WG6DTwqF7nV9FJdcN hcg9dtBC70FgxYmmQgHFYerWH87jKMAlcjqdnCC42EwjBNyTE8bLKeVh6SMxOeFA FHUBUY9IabvYmY= 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:to:from:subject:message-id:date:mime-version :content-type; s=default; bh=5Og1y8l2K3qF9RKGz180JIvlOow=; b=nne ssnHd9N8VhLBl9GApEHDnhEyhxZcTII69mD2vASGs7qIj0xM0ECejSgVTQQaOiqD XSAuA7ixTG/vzv+8+qqcr1ATudT/QQgFnPACbQCo9YsnpcbahEN56g/W4f6vLNr+ 07Yd0f+XtHWwflxxJggsN8mst4rqF/dS6uoEe9Ms= Received: (qmail 36770 invoked by alias); 25 Mar 2016 18:55:36 -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 36645 invoked by uid 89); 25 Mar 2016 18:55:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Receive, len2, nsap, 7896 X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: [PATCH] resolv: Always set *resplen2 out parameter in send_vc [BZ #19825] Message-ID: <56F589A2.3030301@redhat.com> Date: Fri, 25 Mar 2016 19:55:30 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In various error scenarios (for example, if the server closes the TCP connection before sending the full response), send_vc can return without resetting the *resplen2 value. This can pass uninitialized or unexpected data to the caller. Florian 2016-03-25 Florian Weimer [BZ #19825] * resolv/res_send.c (send_vc): Remove early *resplen2 initialization. Set *resplen2 on socket error. Call close_and_return_error for other errors. diff --git a/resolv/res_send.c b/resolv/res_send.c index b4efcb6..2c0bae1 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -762,8 +762,6 @@ send_vc(res_state statp, u_short len2; u_char *cp; - if (resplen2 != NULL) - *resplen2 = 0; connreset = 0; same_ns: truncating = 0; @@ -789,6 +787,8 @@ send_vc(res_state statp, if (statp->_vcsock < 0) { *terrno = errno; Perror(statp, stderr, "socket(vc)", errno); + if (resplen2 != NULL) + *resplen2 = 0; return (-1); } __set_errno (0); @@ -798,8 +798,7 @@ send_vc(res_state statp, : sizeof (struct sockaddr_in6)) < 0) { *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, nsap); - __res_iclose(statp, false); - return (0); + return close_and_return_error (statp, resplen2); } statp->_flags |= RES_F_VC; } @@ -822,8 +821,7 @@ send_vc(res_state statp, if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) { *terrno = errno; Perror(statp, stderr, "write failed", errno); - __res_iclose(statp, false); - return (0); + return close_and_return_error (statp, resplen2); } /* * Receive length & response @@ -845,7 +843,6 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read failed", errno); - __res_iclose(statp, false); /* * A long running process might get its TCP * connection reset if the remote server was @@ -855,11 +852,13 @@ send_vc(res_state statp, * instead of failing. We only allow one reset * per query to prevent looping. */ - if (*terrno == ECONNRESET && !connreset) { - connreset = 1; - goto same_ns; - } - return (0); + if (*terrno == ECONNRESET && !connreset) + { + __res_iclose (statp, false); + connreset = 1; + goto same_ns; + } + return close_and_return_error (statp, resplen2); } int rlen = ntohs (rlen16); @@ -891,11 +890,11 @@ send_vc(res_state statp, /* Always allocate MAXPACKET, callers expect this specific size. */ u_char *newp = malloc (MAXPACKET); - if (newp == NULL) { - *terrno = ENOMEM; - __res_iclose(statp, false); - return (0); - } + if (newp == NULL) + { + *terrno = ENOMEM; + return close_and_return_error (statp, resplen2); + } *thisanssizp = MAXPACKET; *thisansp = newp; if (thisansp == ansp2) @@ -922,8 +921,7 @@ send_vc(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len)); *terrno = EMSGSIZE; - __res_iclose(statp, false); - return (0); + return close_and_return_error (statp, resplen2); } cp = *thisansp; @@ -934,8 +932,7 @@ send_vc(res_state statp, if (__glibc_unlikely (n <= 0)) { *terrno = errno; Perror(statp, stderr, "read(vc)", errno); - __res_iclose(statp, false); - return (0); + return close_and_return_error (statp, resplen2); } if (__glibc_unlikely (truncating)) { /*