diff options
author | Florian Weimer <fweimer@redhat.com> | 2017-04-13 13:09:38 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2017-04-13 13:09:38 +0200 |
commit | e14a27723cc3a154d67f3f26e719d08c0ba9ad25 (patch) | |
tree | c4706acf27f91784a8b592772d03e0c8da0b4731 /resolv/res_query.c | |
parent | c803cb9b24c6cea15698768e4301e963b98e742c (diff) | |
download | glibc-e14a27723cc3a154d67f3f26e719d08c0ba9ad25.tar.gz glibc-e14a27723cc3a154d67f3f26e719d08c0ba9ad25.tar.xz glibc-e14a27723cc3a154d67f3f26e719d08c0ba9ad25.zip |
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.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/resolv/res_query.c b/resolv/res_query.c index 6f3eada143..c3ebcbf6b5 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; } |