]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4467. [security] It was possible to trigger a assertion when rendering
authorMark Andrews <marka@isc.org>
Fri, 9 Sep 2016 01:29:48 +0000 (11:29 +1000)
committerMark Andrews <marka@isc.org>
Fri, 9 Sep 2016 01:34:04 +0000 (11:34 +1000)
                        a message. [RT #43139]

(cherry picked from commit 2bd0922cf995b9ac205fc83baf7e220b95c6bf12)

CHANGES
lib/dns/message.c

diff --git a/CHANGES b/CHANGES
index a43904178439cb93010e45db8ab53b89b0452543..c70461071fe1a7866e8a89c82332d362cb62394f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4467.  [security]      It was possible to trigger a assertion when rendering
+                       a message. [RT #43139]
+
        --- 9.9.9-P2 released ---
 
 4406.  [bug]           getrrsetbyname with a non absolute name could
index 550058bb018bc340e73e380fbd7d5d05ecbe8d57..869d25823eead313771689cd7f3aec55081c99f0 100644 (file)
@@ -1722,7 +1722,7 @@ dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
        if (r.length < DNS_MESSAGE_HEADERLEN)
                return (ISC_R_NOSPACE);
 
-       if (r.length < msg->reserved)
+       if (r.length - DNS_MESSAGE_HEADERLEN < msg->reserved)
                return (ISC_R_NOSPACE);
 
        /*
@@ -1863,8 +1863,29 @@ norender_rdataset(const dns_rdataset_t *rdataset, unsigned int options,
 
        return (ISC_TRUE);
 }
-
 #endif
+
+static isc_result_t
+renderset(dns_rdataset_t *rdataset, dns_name_t *owner_name,
+         dns_compress_t *cctx, isc_buffer_t *target,
+         unsigned int reserved, unsigned int options, unsigned int *countp)
+{
+       isc_result_t result;
+
+       /*
+        * Shrink the space in the buffer by the reserved amount.
+        */
+       if (target->length - target->used < reserved)
+               return (ISC_R_NOSPACE);
+
+       target->length -= reserved;
+       result = dns_rdataset_towire(rdataset, owner_name,
+                                    cctx, target, options, countp);
+       target->length += reserved;
+
+       return (result);
+}
+
 isc_result_t
 dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
                          unsigned int options)
@@ -1907,6 +1928,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
        /*
         * Shrink the space in the buffer by the reserved amount.
         */
+       if (msg->buffer->length - msg->buffer->used < msg->reserved)
+               return (ISC_R_NOSPACE);
        msg->buffer->length -= msg->reserved;
 
        total = 0;
@@ -2182,9 +2205,8 @@ dns_message_renderend(dns_message_t *msg) {
                 * Render.
                 */
                count = 0;
-               result = dns_rdataset_towire(msg->opt, dns_rootname,
-                                            msg->cctx, msg->buffer, 0,
-                                            &count);
+               result = renderset(msg->opt, dns_rootname, msg->cctx,
+                                  msg->buffer, msg->reserved, 0, &count);
                msg->counts[DNS_SECTION_ADDITIONAL] += count;
                if (result != ISC_R_SUCCESS)
                        return (result);
@@ -2200,9 +2222,8 @@ dns_message_renderend(dns_message_t *msg) {
                if (result != ISC_R_SUCCESS)
                        return (result);
                count = 0;
-               result = dns_rdataset_towire(msg->tsig, msg->tsigname,
-                                            msg->cctx, msg->buffer, 0,
-                                            &count);
+               result = renderset(msg->tsig, msg->tsigname, msg->cctx,
+                                  msg->buffer, msg->reserved, 0, &count);
                msg->counts[DNS_SECTION_ADDITIONAL] += count;
                if (result != ISC_R_SUCCESS)
                        return (result);
@@ -2223,9 +2244,8 @@ dns_message_renderend(dns_message_t *msg) {
                 * the owner name of a SIG(0) is irrelevant, and will not
                 * be set in a message being rendered.
                 */
-               result = dns_rdataset_towire(msg->sig0, dns_rootname,
-                                            msg->cctx, msg->buffer, 0,
-                                            &count);
+               result = renderset(msg->sig0, dns_rootname, msg->cctx,
+                                  msg->buffer, msg->reserved, 0, &count);
                msg->counts[DNS_SECTION_ADDITIONAL] += count;
                if (result != ISC_R_SUCCESS)
                        return (result);