components/bind/patches/013-RT43632.patch
branchs11u3-sru
changeset 7592 12dea84f307b
equal deleted inserted replaced
7591:ba368fc828e6 7592:12dea84f307b
       
     1 This patch was derived from a source code patch provided by ISC to
       
     2 resolve ISC ticket RT #43632. [9.6-ESV-R11-S10]
       
     3 
       
     4 --- old/./CHANGES	Wed Jan 11 14:12:28 2017
       
     5 +++ new/./CHANGES	Wed Jan 11 14:12:28 2017
       
     6 @@ -1,5 +1,9 @@
       
     7  	--- 9.6-ESV-R11-S10 released ---
       
     8  
       
     9 +4517.	[security]	Named could mishandle authority sections that were
       
    10 +			missing RRSIGs triggering an assertion failure.
       
    11 +			(CVE-2016-9444) [RT #43632]
       
    12 +
       
    13  4510.	[security]	Named mishandled some responses where covering RRSIG
       
    14  			records are returned without the requested data
       
    15  			resulting in a assertion failure. (CVE-2016-9147)
       
    16 --- old/lib/dns/api	Wed Jan 11 14:12:28 2017
       
    17 +++ new/lib/dns/api	Wed Jan 11 14:12:28 2017
       
    18 @@ -5,5 +5,5 @@
       
    19  # 9.9: 90-109
       
    20  # 9.9-sub: 130-139
       
    21  LIBINTERFACE = 114
       
    22 -LIBREVISION = 4
       
    23 +LIBREVISION = 5
       
    24  LIBAGE = 1
       
    25 --- old/lib/dns/message.c	Wed Jan 11 14:12:28 2017
       
    26 +++ new/lib/dns/message.c	Wed Jan 11 14:12:28 2017
       
    27 @@ -1169,6 +1169,63 @@
       
    28  	return (ISC_FALSE);
       
    29  }
       
    30  
       
    31 +/*
       
    32 + * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have
       
    33 + * covering RRSIGs.
       
    34 + */
       
    35 +static isc_boolean_t
       
    36 +auth_signed(dns_namelist_t *section) {
       
    37 +	dns_name_t *name;
       
    38 +
       
    39 +	for (name = ISC_LIST_HEAD(*section);
       
    40 +	     name != NULL;
       
    41 +	     name = ISC_LIST_NEXT(name, link))
       
    42 +	{
       
    43 +		int auth_dnssec = 0, auth_rrsig = 0;
       
    44 +		dns_rdataset_t *rds;
       
    45 +
       
    46 +		for (rds = ISC_LIST_HEAD(name->list);
       
    47 +		     rds != NULL;
       
    48 +		     rds = ISC_LIST_NEXT(rds, link))
       
    49 +		{
       
    50 +			switch (rds->type) {
       
    51 +			case dns_rdatatype_ds:
       
    52 +				auth_dnssec |= 0x1;
       
    53 +				break;
       
    54 +			case dns_rdatatype_nsec:
       
    55 +				auth_dnssec |= 0x2;
       
    56 +				break;
       
    57 +			case dns_rdatatype_nsec3:
       
    58 +				auth_dnssec |= 0x4;
       
    59 +				break;
       
    60 +			case dns_rdatatype_rrsig:
       
    61 +				break;
       
    62 +			default:
       
    63 +				continue;
       
    64 +			}
       
    65 +
       
    66 +			switch (rds->covers) {
       
    67 +			case dns_rdatatype_ds:
       
    68 +				auth_rrsig |= 0x1;
       
    69 +				break;
       
    70 +			case dns_rdatatype_nsec:
       
    71 +				auth_rrsig |= 0x2;
       
    72 +				break;
       
    73 +			case dns_rdatatype_nsec3:
       
    74 +				auth_rrsig |= 0x4;
       
    75 +				break;
       
    76 +			default:
       
    77 +				break;
       
    78 +			}
       
    79 +		}
       
    80 +
       
    81 +		if (auth_dnssec != auth_rrsig)
       
    82 +			return (ISC_FALSE);
       
    83 +	}
       
    84 +
       
    85 +	return (ISC_TRUE);
       
    86 +}
       
    87 +
       
    88  static isc_result_t
       
    89  getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
       
    90  	   dns_section_t sectionid, unsigned int options)
       
    91 @@ -1194,12 +1251,12 @@
       
    92  	best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
       
    93  	seen_problem = ISC_FALSE;
       
    94  
       
    95 +	section = &msg->sections[sectionid];
       
    96 +
       
    97  	for (count = 0; count < msg->counts[sectionid]; count++) {
       
    98  		int recstart = source->current;
       
    99  		isc_boolean_t skip_name_search, skip_type_search;
       
   100  
       
   101 -		section = &msg->sections[sectionid];
       
   102 -
       
   103  		skip_name_search = ISC_FALSE;
       
   104  		skip_type_search = ISC_FALSE;
       
   105  		free_rdataset = ISC_FALSE;
       
   106 @@ -1372,7 +1429,7 @@
       
   107  			goto cleanup;
       
   108  		rdata->rdclass = rdclass;
       
   109  		issigzero = ISC_FALSE;
       
   110 -		if (rdtype == dns_rdatatype_rrsig  &&
       
   111 +		if (rdtype == dns_rdatatype_rrsig &&
       
   112  		    rdata->flags == 0) {
       
   113  			covers = dns_rdata_covers(rdata);
       
   114  			if (covers == 0)
       
   115 @@ -1577,6 +1634,19 @@
       
   116  		INSIST(free_rdataset == ISC_FALSE);
       
   117  	}
       
   118  
       
   119 +	/*
       
   120 +	 * If any of DS, NSEC or NSEC3 appeared in the
       
   121 +	 * authority section of a query response without
       
   122 +	 * a covering RRSIG, FORMERR
       
   123 +	 */
       
   124 +	if (sectionid == DNS_SECTION_AUTHORITY &&
       
   125 +	    msg->opcode == dns_opcode_query &&
       
   126 +	    ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) &&
       
   127 +	    ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) &&
       
   128 +	    !preserve_order &&
       
   129 +	    !auth_signed(section))
       
   130 +		DO_FORMERR;
       
   131 +
       
   132  	if (seen_problem)
       
   133  		return (DNS_R_RECOVERABLE);
       
   134  	return (ISC_R_SUCCESS);
       
   135 --- old/lib/dns/resolver.c	Wed Jan 11 14:12:30 2017
       
   136 +++ new/lib/dns/resolver.c	Wed Jan 11 14:12:29 2017
       
   137 @@ -4766,13 +4766,9 @@
       
   138  							      rdataset->type,
       
   139  							      &noqname);
       
   140  					if (tresult == ISC_R_SUCCESS &&
       
   141 -					    noqname != NULL) {
       
   142 -						tresult =
       
   143 -						     dns_rdataset_addnoqname(
       
   144 +					    noqname != NULL)
       
   145 +						(void) dns_rdataset_addnoqname(
       
   146  							    rdataset, noqname);
       
   147 -						RUNTIME_CHECK(tresult ==
       
   148 -							      ISC_R_SUCCESS);
       
   149 -					}
       
   150  				}
       
   151  				addedrdataset = ardataset;
       
   152  				result = dns_db_addrdataset(fctx->cache, node,
       
   153 @@ -4902,11 +4898,9 @@
       
   154  				tresult = findnoqname(fctx, name,
       
   155  						      rdataset->type, &noqname);
       
   156  				if (tresult == ISC_R_SUCCESS &&
       
   157 -				    noqname != NULL) {
       
   158 -					tresult = dns_rdataset_addnoqname(
       
   159 -							    rdataset, noqname);
       
   160 -					RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
       
   161 -				}
       
   162 +				    noqname != NULL)
       
   163 +					(void) dns_rdataset_addnoqname(
       
   164 +						       rdataset, noqname);
       
   165  			}
       
   166  
       
   167  			/*
       
   168 --- old/./version	Wed Jan 11 14:12:30 2017
       
   169 +++ new/./version	Wed Jan 11 14:12:29 2017
       
   170 @@ -10,4 +10,4 @@
       
   171  PATCHVER=
       
   172  RELEASETYPE=-ESV
       
   173  RELEASEVER=-R11
       
   174 -EXTENSIONS=-S9
       
   175 +EXTENSIONS=-S10