about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrooks Moses <bmoses@google.com>2015-12-15 10:57:38 -0800
committerBrooks Moses <bmoses@google.com>2015-12-15 10:57:38 -0800
commitfa9a6cbaeaf0ddd6ff6dcbbc09a4dda802cdb15e (patch)
treeda3abd4b81e57ef087a0e42c6f21a36eb453555a
parent587c53b3440b40dc3e6e494171b5a84966f0a6e8 (diff)
downloadglibc-fa9a6cbaeaf0ddd6ff6dcbbc09a4dda802cdb15e.tar.gz
glibc-fa9a6cbaeaf0ddd6ff6dcbbc09a4dda802cdb15e.tar.xz
glibc-fa9a6cbaeaf0ddd6ff6dcbbc09a4dda802cdb15e.zip
For b/25900273, adjust allocations to avoid segfault.
-rw-r--r--README.google3
-rw-r--r--resolv/res_send.c28
2 files changed, 19 insertions, 12 deletions
diff --git a/README.google b/README.google
index 3a13e160c5..3b478f5da7 100644
--- a/README.google
+++ b/README.google
@@ -541,3 +541,6 @@ iconv/gconv_trans.c
   https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8
   (stanshebs, backport)
 
+resolv/res_send.c
+  For b/25900273, adjust allocations to avoid segfault.
+  (bmoses, google-local)
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 704542c730..6d8fb08bcc 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -783,26 +783,26 @@ send_vc(res_state statp,
 		assert (anscp != NULL || ansp2 == NULL);
 		thisresplenp = &resplen;
 	} else {
-		if (*anssizp != MAXPACKET) {
+		if (*anssizp == orig_anssizp) {
 			/* No buffer allocated for the first
 			   reply.  We can try to use the rest
 			   of the user-provided buffer.  */
 #ifdef _STRING_ARCH_unaligned
 			*anssizp2 = orig_anssizp - resplen;
-			*ansp2 = *ansp + resplen;
+			*ansp2 = ans + resplen;
 #else
 			int aligned_resplen
 			  = ((resplen + __alignof__ (HEADER) - 1)
 			     & ~(__alignof__ (HEADER) - 1));
 			*anssizp2 = orig_anssizp - aligned_resplen;
-			*ansp2 = *ansp + aligned_resplen;
+			*ansp2 = ans + aligned_resplen;
 #endif
-		} else {
+		} else if (*ansp2_malloced == 0) {
 			/* The first reply did not fit into the
 			   user-provided buffer.  Maybe the second
 			   answer will.  */
 			*anssizp2 = orig_anssizp;
-			*ansp2 = *ansp;
+			*ansp2 = ans;
 		}
 
 		thisanssizp = anssizp2;
@@ -826,6 +826,8 @@ send_vc(res_state statp,
 			*thisansp = newp;
 			if (thisansp == ansp2)
 			  *ansp2_malloced = 1;
+                        else if (thisansp == anscp)
+                          *ansp = *thisansp;
 			anhp = (HEADER *) newp;
 			len = rlen;
 		} else {
@@ -1201,26 +1203,26 @@ send_dg(res_state statp,
 			assert (anscp != NULL || ansp2 == NULL);
 			thisresplenp = &resplen;
 		} else {
-			if (*anssizp != MAXPACKET) {
+			if (*anssizp == orig_anssizp) {
 				/* No buffer allocated for the first
 				   reply.  We can try to use the rest
 				   of the user-provided buffer.  */
 #ifdef _STRING_ARCH_unaligned
 				*anssizp2 = orig_anssizp - resplen;
-				*ansp2 = *ansp + resplen;
+				*ansp2 = ans + resplen;
 #else
 				int aligned_resplen
 				  = ((resplen + __alignof__ (HEADER) - 1)
 				     & ~(__alignof__ (HEADER) - 1));
 				*anssizp2 = orig_anssizp - aligned_resplen;
-				*ansp2 = *ansp + aligned_resplen;
+				*ansp2 = ans + aligned_resplen;
 #endif
-			} else {
+			} else if (*ansp2_malloced == 0) {
 				/* The first reply did not fit into the
 				   user-provided buffer.  Maybe the second
 				   answer will.  */
 				*anssizp2 = orig_anssizp;
-				*ansp2 = *ansp;
+				*ansp2 = ans;
 			}
 
 			thisanssizp = anssizp2;
@@ -1239,10 +1241,12 @@ send_dg(res_state statp,
                     ) {
 			u_char *newp = malloc (MAXPACKET);
 			if (newp != NULL) {
-				*anssizp = MAXPACKET;
-				*thisansp = ans = newp;
+				*thisanssizp = MAXPACKET;
+				*thisansp = newp;
 				if (thisansp == ansp2)
 				  *ansp2_malloced = 1;
+                                else if (thisansp == anscp)
+                                  *ansp = *thisansp;
 			}
 		}
 		HEADER *anhp = (HEADER *) *thisansp;