aboutsummaryrefslogtreecommitdiff
path: root/resolv/res_query.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-04-13 13:09:38 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-04-13 13:09:38 +0200
commite14a27723cc3a154d67f3f26e719d08c0ba9ad25 (patch)
treec4706acf27f91784a8b592772d03e0c8da0b4731 /resolv/res_query.c
parentc803cb9b24c6cea15698768e4301e963b98e742c (diff)
downloadglibc-e14a27723cc3a154d67f3f26e719d08c0ba9ad25.zip
glibc-e14a27723cc3a154d67f3f26e719d08c0ba9ad25.tar.gz
glibc-e14a27723cc3a154d67f3f26e719d08c0ba9ad25.tar.bz2
resolv: Reduce EDNS payload size to 1200 bytes [BZ #21361]
This hardens the stub resolver against fragmentation-based attacks.
Diffstat (limited to 'resolv/res_query.c')
-rw-r--r--resolv/res_query.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 6f3eada..c3ebcbf 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -78,6 +78,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <resolv/resolv-internal.h>
/* Options. Leave them on. */
/* #undef DEBUG */
@@ -147,7 +148,10 @@ __libc_res_nquery(res_state statp,
if ((oflags & RES_F_EDNS0ERR) == 0
&& (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
{
- n = __res_nopt(statp, n, query1, bufsize, anslen / 2);
+ /* Use RESOLV_EDNS_BUFFER_SIZE because the receive
+ buffer can be reallocated. */
+ n = __res_nopt (statp, n, query1, bufsize,
+ RESOLV_EDNS_BUFFER_SIZE);
if (n < 0)
goto unspec_nomem;
}
@@ -168,8 +172,10 @@ __libc_res_nquery(res_state statp,
if (n > 0
&& (oflags & RES_F_EDNS0ERR) == 0
&& (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
- n = __res_nopt(statp, n, query2, bufsize - nused - n,
- anslen / 2);
+ /* Use RESOLV_EDNS_BUFFER_SIZE because the receive
+ buffer can be reallocated. */
+ n = __res_nopt (statp, n, query2, bufsize,
+ RESOLV_EDNS_BUFFER_SIZE);
nquery2 = n;
}
@@ -183,7 +189,16 @@ __libc_res_nquery(res_state statp,
if (n > 0
&& (oflags & RES_F_EDNS0ERR) == 0
&& (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
- n = __res_nopt(statp, n, query1, bufsize, anslen);
+ {
+ /* Use RESOLV_EDNS_BUFFER_SIZE if the receive buffer
+ can be reallocated. */
+ size_t advertise;
+ if (answerp == NULL)
+ advertise = anslen;
+ else
+ advertise = RESOLV_EDNS_BUFFER_SIZE;
+ n = __res_nopt (statp, n, query1, bufsize, advertise);
+ }
nquery1 = n;
}