]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Do not assert on synthrecord reverse mode with huge prefix 12173/head
authorColin Vidal <colin@isc.org>
Wed, 3 Jun 2026 14:08:57 +0000 (16:08 +0200)
committerColin Vidal <colin@isc.org>
Thu, 4 Jun 2026 11:51:59 +0000 (13:51 +0200)
When using the `synthrecord` plugin in reverse mode, if a very long
prefix is configured by the operator such that there is no room to fit
the reversed IP address into a DNS name, `named` could assert. This has
now been fixed. In such situations, an error is logged so the operator
is aware of the problem, and `NXDOMAIN` is answered.

bin/plugins/synthrecord.c

index 4f7bff17b40fdff0ad82a51914fdd41eb522140f..f586d3f9e07166b1a8a1baa865167c50832e70ab 100644 (file)
@@ -67,7 +67,7 @@ synthrecord_reverseanswer(synthrecord_t *inst, isc_netaddr_t *na,
        REQUIRE(na->family == AF_INET || na->family == AF_INET6);
 
        isc_buffer_init(&b, bdata, sizeof(bdata));
-       isc_buffer_copyregion(&b, &inst->prefix);
+       RETERR(isc_buffer_copyregion(&b, &inst->prefix));
 
        isc_buffer_init(&addrb, addrbdata, sizeof(addrbdata));
        RETERR(isc_netaddr_totext(na, &addrb));
@@ -86,6 +86,9 @@ synthrecord_reverseanswer(synthrecord_t *inst, isc_netaddr_t *na,
                 */
                isc_buffer_peekuint8(&addrb, &c);
                if (c == ':') {
+                       if (isc_buffer_availablelength(&b) == 0) {
+                               return ISC_R_NOSPACE;
+                       }
                        isc_buffer_putuint8(&b, '0');
                }
 
@@ -96,12 +99,15 @@ synthrecord_reverseanswer(synthrecord_t *inst, isc_netaddr_t *na,
                isc_buffer_forward(&addrb, isc_buffer_usedlength(&addrb) - 1);
                isc_buffer_peekuint8(&addrb, &c);
                if (c == ':') {
+                       if (isc_buffer_availablelength(&b) == 0) {
+                               return ISC_R_NOSPACE;
+                       }
                        isc_buffer_putuint8(&addrb, '0');
                }
        }
 
        isc_buffer_usedregion(&addrb, &addrr);
-       isc_buffer_copyregion(&b, &addrr);
+       RETERR(isc_buffer_copyregion(&b, &addrr));
 
        /*
         * Do not attempt to replace anything in the prefix
@@ -214,6 +220,13 @@ synthrecord_parseforward(synthrecord_t *inst, const dns_name_t *name,
 
        isc_buffer_init(&b, bdata, sizeof(bdata));
        dns_name_totext(&label, DNS_NAME_OMITFINALDOT, &b);
+
+       /*
+        * Buffer is `DNS_NAME_FORMATSIZE` which is the maximum length of
+        * `dns_name_totext()` can put in there, plus one byte which we're
+        * setting here. So we know there is at least one remaining byte in the
+        * buffer.
+        */
        isc_buffer_putuint8(&b, 0);
        if (strncmp((const char *)inst->prefix.base, isc_buffer_base(&b),
                    inst->prefix.length) != 0)