| From 218e952a2caf6e1e4103e322780922800884b712 Mon Sep 17 00:00:00 2001 |
| From: Denton Gentry <dgentry@google.com> |
| Date: Sat, 19 Dec 2015 15:53:09 -0800 |
| Subject: [PATCH] Fix fault in getaddrinfo. |
| |
| --- |
| resolv/res_send.c | 28 ++++++++++++++++------------ |
| 1 file changed, 16 insertions(+), 12 deletions(-) |
| |
| diff --git a/resolv/res_send.c b/resolv/res_send.c |
| index 7f2e85f..d178dca 100644 |
| --- a/resolv/res_send.c |
| +++ b/resolv/res_send.c |
| @@ -782,26 +782,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 >= ans && *ansp2 < ans + orig_anssizp) { |
| /* 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; |
| @@ -823,6 +823,8 @@ send_vc(res_state statp, |
| } |
| *thisanssizp = MAXPACKET; |
| *thisansp = newp; |
| + if (thisansp == anscp) |
| + *ansp = *thisansp; |
| anhp = (HEADER *) newp; |
| len = rlen; |
| } else { |
| @@ -1198,26 +1200,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 >= ans && *ansp2 < ans + orig_anssizp) { |
| /* 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; |
| @@ -1236,8 +1238,10 @@ send_dg(res_state statp, |
| ) { |
| u_char *newp = malloc (MAXPACKET); |
| if (newp != NULL) { |
| - *anssizp = MAXPACKET; |
| - *thisansp = ans = newp; |
| + *thisanssizp = MAXPACKET; |
| + *thisansp = newp; |
| + if (thisansp == anscp) |
| + *ansp = *thisansp; |
| } |
| } |
| HEADER *anhp = (HEADER *) *thisansp; |
| -- |
| 2.6.0.rc2.230.g3dd15c0 |
| |