File glibc-CVE-2015-7547-patch_2of3_res_query.c.diff of Package glibc.4601

diff -rNU 20 ../glibc-2.18-orig/resolv/res_query.c ./resolv/res_query.c
--- ../glibc-2.18-orig/resolv/res_query.c	2013-08-11 00:52:55.000000000 +0200
+++ ./resolv/res_query.c	2016-02-17 19:13:16.000000000 +0100
@@ -374,80 +374,82 @@
 	 * Also, query 'as is', if there is a trailing dot in the name.
 	 */
 	saved_herrno = -1;
 	if (dots >= statp->ndots || trailing_dot) {
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
 					      answer, anslen, answerp,
 					      answerp2, nanswerp2, resplen2);
 		if (ret > 0 || trailing_dot)
 			return (ret);
 		saved_herrno = h_errno;
 		tried_as_is++;
 		if (answerp && *answerp != answer) {
 			answer = *answerp;
 			anslen = MAXPACKET;
 		}
 		if (answerp2
 		    && (*answerp2 < answer || *answerp2 >= answer + anslen))
 		  {
 		    free (*answerp2);
 		    *answerp2 = NULL;
+		    *nanswerp2 = 0;
 		  }
 	}
 
 	/*
 	 * We do at least one level of search if
 	 *	- there is no dot and RES_DEFNAME is set, or
 	 *	- there is at least one dot, there is no trailing dot,
 	 *	  and RES_DNSRCH is set.
 	 */
 	if ((!dots && (statp->options & RES_DEFNAMES) != 0) ||
 	    (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0)) {
 		int done = 0;
 
 		for (domain = (const char * const *)statp->dnsrch;
 		     *domain && !done;
 		     domain++) {
 			searched = 1;
 
 			if (domain[0][0] == '\0' ||
 			    (domain[0][0] == '.' && domain[0][1] == '\0'))
 				root_on_list++;
 
 			ret = __libc_res_nquerydomain(statp, name, *domain,
 						      class, type,
 						      answer, anslen, answerp,
 						      answerp2, nanswerp2,
 						      resplen2);
 			if (ret > 0)
 				return (ret);
 
 			if (answerp && *answerp != answer) {
 				answer = *answerp;
 				anslen = MAXPACKET;
 			}
 			if (answerp2
 			    && (*answerp2 < answer
 				|| *answerp2 >= answer + anslen))
 			  {
 			    free (*answerp2);
 			    *answerp2 = NULL;
+			    *nanswerp2 = 0;
 			  }
 
 			/*
 			 * If no server present, give up.
 			 * If name isn't found in this domain,
 			 * keep trying higher domains in the search list
 			 * (if that's enabled).
 			 * On a NO_DATA error, keep trying, otherwise
 			 * a wildcard entry of another type could keep us
 			 * from finding this entry higher in the domain.
 			 * If we get some other error (negative answer or
 			 * server failure), then stop searching up,
 			 * but try the input name below in case it's
 			 * fully-qualified.
 			 */
 			if (errno == ECONNREFUSED) {
 				RES_SET_H_ERRNO(statp, TRY_AGAIN);
 				return (-1);
 			}
 
@@ -485,40 +487,41 @@
 	if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0)
 	    && !(tried_as_is || root_on_list)) {
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
 					      answer, anslen, answerp,
 					      answerp2, nanswerp2, resplen2);
 		if (ret > 0)
 			return (ret);
 	}
 
 	/* if we got here, we didn't satisfy the search.
 	 * if we did an initial full query, return that query's H_ERRNO
 	 * (note that we wouldn't be here if that query had succeeded).
 	 * else if we ever got a nodata, send that back as the reason.
 	 * else send back meaningless H_ERRNO, that being the one from
 	 * the last DNSRCH we did.
 	 */
 	if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
 	  {
 	    free (*answerp2);
 	    *answerp2 = NULL;
+	    *nanswerp2 = 0;
 	  }
 	if (saved_herrno != -1)
 		RES_SET_H_ERRNO(statp, saved_herrno);
 	else if (got_nodata)
 		RES_SET_H_ERRNO(statp, NO_DATA);
 	else if (got_servfail)
 		RES_SET_H_ERRNO(statp, TRY_AGAIN);
 	return (-1);
 }
 libresolv_hidden_def (__libc_res_nsearch)
 
 int
 res_nsearch(res_state statp,
 	    const char *name,	/* domain name */
 	    int class, int type,	/* class and type of query */
 	    u_char *answer,	/* buffer to put answer */
 	    int anslen)		/* size of answer */
 {
 	return __libc_res_nsearch(statp, name, class, type, answer,
 				  anslen, NULL, NULL, NULL, NULL);
openSUSE Build Service is sponsored by