Commit 455c0848 authored by Mark Andrews's avatar Mark Andrews
Browse files

4322. [security] Duplicate EDNS COOKIE options in a response could

                        trigger an assertion failure. (CVE-2016-2088)
                        [RT #41809]
parent 7f514657
4322. [security] Duplicate EDNS COOKIE options in a response could
trigger an assertion failure. (CVE-2016-2088)
[RT #41809]
4321. [bug] Zones using mapped files containing out-of-zone data
could return SERVFAIL instead of the expected NODATA
or NXDOMAIN results. [RT #41596]
......
......@@ -3536,6 +3536,7 @@ process_opt(dig_lookup_t *l, dns_message_t *msg) {
isc_buffer_t optbuf;
isc_uint16_t optcode, optlen;
dns_rdataset_t *opt = msg->opt;
isc_boolean_t seen_cookie = ISC_FALSE;
result = dns_rdataset_first(opt);
if (result == ISC_R_SUCCESS) {
......@@ -3548,7 +3549,15 @@ process_opt(dig_lookup_t *l, dns_message_t *msg) {
optlen = isc_buffer_getuint16(&optbuf);
switch (optcode) {
case DNS_OPT_COOKIE:
/*
* Only process the first cookie option.
*/
if (seen_cookie) {
isc_buffer_forward(&optbuf, optlen);
break;
}
process_cookie(l, msg, &optbuf, optlen);
seen_cookie = ISC_TRUE;
break;
default:
isc_buffer_forward(&optbuf, optlen);
......
......@@ -122,6 +122,9 @@
#define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */
#define ECS_SIZE 20U /* 2 + 1 + 1 + [0..16] */
#define WANTNSID(x) (((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0)
#define WANTEXPIRE(x) (((x)->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0)
/*% nameserver client manager structure */
struct ns_clientmgr {
/* Unlocked. */
......@@ -1516,7 +1519,7 @@ ns_client_addopt(ns_client_t *client, dns_message_t *message,
flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE;
/* Set EDNS options if applicable */
if ((client->attributes & NS_CLIENTATTR_WANTNSID) != 0 &&
if (WANTNSID(client) &&
(ns_g_server->server_id != NULL ||
ns_g_server->server_usehostname)) {
if (ns_g_server->server_usehostname) {
......@@ -1893,6 +1896,14 @@ process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
isc_netaddr_t caddr;
int i;
/*
* If we have already seen a ECS option skip this ECS option.
*/
if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
isc_buffer_forward(buf, optlen);
return (ISC_R_SUCCESS);
}
/*
* XXXMUKS: Is there any need to repeat these checks here
* (except query's scope length) when they are done in the OPT
......@@ -2028,7 +2039,9 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
optlen = isc_buffer_getuint16(&optbuf);
switch (optcode) {
case DNS_OPT_NSID:
isc_stats_increment(ns_g_server->nsstats,
if (!WANTNSID(client))
isc_stats_increment(
ns_g_server->nsstats,
dns_nsstatscounter_nsidopt);
client->attributes |= NS_CLIENTATTR_WANTNSID;
isc_buffer_forward(&optbuf, optlen);
......@@ -2037,7 +2050,9 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
process_cookie(client, &optbuf, optlen);
break;
case DNS_OPT_EXPIRE:
isc_stats_increment(ns_g_server->nsstats,
if (!WANTEXPIRE(client))
isc_stats_increment(
ns_g_server->nsstats,
dns_nsstatscounter_expireopt);
client->attributes |= NS_CLIENTATTR_WANTEXPIRE;
isc_buffer_forward(&optbuf, optlen);
......
......@@ -42,6 +42,13 @@
<section xml:id="relnotes_security"><info><title>Security Fixes</title></info>
<itemizedlist>
<listitem>
<para>
Duplicate EDNS COOKIE options in a response could trigger
an assertion failure. This flaw is disclosed in CVE-2016-2088.
[RT #41809]
</para>
</listitem>
<listitem>
<para>
Insufficient testing when parsing a message allowed
......
......@@ -7560,6 +7560,8 @@ process_opt(resquery_t *query, dns_rdataset_t *opt) {
unsigned char *optvalue;
dns_adbaddrinfo_t *addrinfo;
unsigned char cookie[8];
isc_boolean_t seen_cookie = ISC_FALSE;
isc_boolean_t seen_nsid = ISC_FALSE;
result = dns_rdataset_first(opt);
if (result == ISC_R_SUCCESS) {
......@@ -7573,13 +7575,22 @@ process_opt(resquery_t *query, dns_rdataset_t *opt) {
INSIST(optlen <= isc_buffer_remaininglength(&optbuf));
switch (optcode) {
case DNS_OPT_NSID:
if (query->options & DNS_FETCHOPT_WANTNSID)
if (!seen_nsid &&
query->options & DNS_FETCHOPT_WANTNSID)
log_nsid(&optbuf, optlen, query,
ISC_LOG_DEBUG(3),
query->fctx->res->mctx);
isc_buffer_forward(&optbuf, optlen);
seen_nsid = ISC_TRUE;
break;
case DNS_OPT_COOKIE:
/*
* Only process the first cookie option.
*/
if (seen_cookie) {
isc_buffer_forward(&optbuf, optlen);
break;
}
optvalue = isc_buffer_current(&optbuf);
compute_cc(query, cookie, sizeof(cookie));
INSIST(query->fctx->rmessage->cc_bad == 0 &&
......@@ -7598,6 +7609,7 @@ process_opt(resquery_t *query, dns_rdataset_t *opt) {
isc_buffer_forward(&optbuf, optlen);
inc_stats(query->fctx->res,
dns_resstatscounter_cookiein);
seen_cookie = ISC_TRUE;
break;
default:
isc_buffer_forward(&optbuf, optlen);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment