]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3663. [bug] Address bugs in dns_rdata_fromstruct and
authorMark Andrews <marka@isc.org>
Fri, 25 Oct 2013 02:06:09 +0000 (13:06 +1100)
committerMark Andrews <marka@isc.org>
Fri, 25 Oct 2013 02:06:38 +0000 (13:06 +1100)
                        dns_rdata_tostruct for WKS and ISDN types. [RT #34910]

CHANGES
lib/dns/rdata/generic/isdn_20.c
lib/dns/rdata/in_1/wks_11.c
lib/dns/tests/rdata_test.c

diff --git a/CHANGES b/CHANGES
index f76c819342931c7c9284382b50af47e85fcefa45..57132be43c0a3dcb420336344ddd60fd258bb153 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3663.  [bug]           Address bugs in dns_rdata_fromstruct and
+                       dns_rdata_tostruct for WKS and ISDN types. [RT #34910]
+
 3662.  [bug]           'host' could die if a UDP query timed out. [RT #34870]
 
 3660.  [cleanup]       Changed the name of "isc-config.sh" to "bind9-config".
index b3a763c45341c567014422ec8a2ad3f0ee20bf06..90142c568ec967dec06ec47ae89908730ce39f39 100644 (file)
@@ -127,6 +127,8 @@ fromstruct_isdn(ARGS_FROMSTRUCT) {
 
        RETERR(uint8_tobuffer(isdn->isdn_len, target));
        RETERR(mem_tobuffer(target, isdn->isdn, isdn->isdn_len));
+       if (isdn->subaddress == NULL && isdn->subaddress_len == 0)
+               return (ISC_R_SUCCESS);
        RETERR(uint8_tobuffer(isdn->subaddress_len, target));
        return (mem_tobuffer(target, isdn->subaddress, isdn->subaddress_len));
 }
@@ -153,11 +155,17 @@ tostruct_isdn(ARGS_TOSTRUCT) {
                return (ISC_R_NOMEMORY);
        isc_region_consume(&r, isdn->isdn_len);
 
-       isdn->subaddress_len = uint8_fromregion(&r);
-       isc_region_consume(&r, 1);
-       isdn->subaddress = mem_maybedup(mctx, r.base, isdn->subaddress_len);
-       if (isdn->subaddress == NULL)
-               goto cleanup;
+       if (r.length == 0) {
+               isdn->subaddress_len = 0;
+               isdn->subaddress = NULL;
+       } else {
+               isdn->subaddress_len = uint8_fromregion(&r);
+               isc_region_consume(&r, 1);
+               isdn->subaddress = mem_maybedup(mctx, r.base,
+                                               isdn->subaddress_len);
+               if (isdn->subaddress == NULL)
+                       goto cleanup;
+       }
 
        isdn->mctx = mctx;
        return (ISC_R_SUCCESS);
index 0804202da62963bbbfca4452d670a0f20051f6ac..e07fc6b14acf5e5b8bc9632bb1c7629098bc6cf0 100644 (file)
@@ -278,7 +278,7 @@ fromstruct_in_wks(ARGS_FROMSTRUCT) {
 
        a = ntohl(wks->in_addr.s_addr);
        RETERR(uint32_tobuffer(a, target));
-       RETERR(uint16_tobuffer(wks->protocol, target));
+       RETERR(uint8_tobuffer(wks->protocol, target));
        return (mem_tobuffer(target, wks->map, wks->map_len));
 }
 
@@ -300,8 +300,8 @@ tostruct_in_wks(ARGS_TOSTRUCT) {
        n = uint32_fromregion(&region);
        wks->in_addr.s_addr = htonl(n);
        isc_region_consume(&region, 4);
-       wks->protocol = uint16_fromregion(&region);
-       isc_region_consume(&region, 2);
+       wks->protocol = uint8_fromregion(&region);
+       isc_region_consume(&region, 1);
        wks->map_len = region.length;
        wks->map = mem_maybedup(mctx, region.base, region.length);
        if (wks->map == NULL)
index 4a4db2a3e935864d0bd269a2102e052b96f442b7..41891ab48b93a628f337506be4c316b994ca9ad1 100644 (file)
@@ -228,12 +228,162 @@ ATF_TC_BODY(edns_client_subnet, tc) {
        }
 }
 
+ATF_TC(wks);
+ATF_TC_HEAD(wks, tc) {
+       atf_tc_set_md_var(tc, "descr", "wks to/from struct");
+}
+ATF_TC_BODY(wks, tc) {
+       struct {
+               unsigned char data[64];
+               size_t len;
+               isc_boolean_t ok;
+       } test_data[] = {
+               {
+                       /* too short */
+                       { 0x00, 0x08, 0x0, 0x00 }, 4, ISC_FALSE
+               },
+               {
+                       /* minimal TCP */
+                       { 0x00, 0x08, 0x0, 0x00, 6 }, 5, ISC_TRUE
+               },
+               {
+                       /* minimal UDP */
+                       { 0x00, 0x08, 0x0, 0x00, 17 }, 5, ISC_TRUE
+               },
+               {
+                       /* minimal other */
+                       { 0x00, 0x08, 0x0, 0x00, 1 }, 5, ISC_TRUE
+               },
+               {
+                       /* sentinal */
+                       { 0x00 }, 0, ISC_FALSE
+               }
+       };
+       unsigned char buf1[1024*1024];
+       unsigned char buf2[1024*1024];
+       isc_buffer_t source, target1, target2;
+       dns_rdata_t rdata;
+       dns_decompress_t dctx;
+       isc_result_t result;
+       size_t i;
+       dns_rdata_in_wks_t wks;
+
+       UNUSED(tc);
+
+       for (i = 0; test_data[i].len != 0; i++) {
+               isc_buffer_init(&source, test_data[i].data, test_data[i].len);
+               isc_buffer_add(&source, test_data[i].len);
+               isc_buffer_setactive(&source, test_data[i].len);
+               isc_buffer_init(&target1, buf1, sizeof(buf1));
+               dns_rdata_init(&rdata);
+               dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
+               result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
+                                           dns_rdatatype_wks, &source,
+                                           &dctx, 0, &target1);
+               dns_decompress_invalidate(&dctx);
+               if (test_data[i].ok)
+                       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+               else
+                       ATF_REQUIRE(result != ISC_R_SUCCESS);
+               if (result != ISC_R_SUCCESS)
+                       continue;
+               result = dns_rdata_tostruct(&rdata, &wks, NULL);
+               ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+               isc_buffer_init(&target2, buf2, sizeof(buf2));
+               dns_rdata_reset(&rdata);
+               result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
+                                             dns_rdatatype_wks, &wks,
+                                             &target2);
+               ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+               ATF_REQUIRE_EQ(isc_buffer_usedlength(&target2),
+                                                    test_data[i].len);
+               ATF_REQUIRE_EQ(memcmp(buf2, test_data[i].data,
+                                     test_data[i].len), 0);
+       }
+}
+
+ATF_TC(isdn);
+ATF_TC_HEAD(isdn, tc) {
+       atf_tc_set_md_var(tc, "descr", "isdn to/from struct");
+}
+ATF_TC_BODY(isdn, tc) {
+       struct {
+               unsigned char data[64];
+               size_t len;
+               isc_boolean_t ok;
+       } test_data[] = {
+               {
+                       /* "" */
+                       { 0x00 }, 1, ISC_TRUE
+               },
+               {
+                       /* "\001" */
+                       { 0x1, 0x01 }, 2, ISC_TRUE
+               },
+               {
+                       /* "\001" "" */
+                       { 0x1, 0x01, 0x00 }, 3, ISC_TRUE
+               },
+               {
+                       /* "\000" "\001" */
+                       { 0x1, 0x01, 0x01, 0x01 }, 4, ISC_TRUE
+               },
+               {
+                       /* sentinal */
+                       { 0x00 }, 0, ISC_FALSE
+               }
+       };
+       unsigned char buf1[1024*1024];
+       unsigned char buf2[1024*1024];
+       isc_buffer_t source, target1, target2;
+       dns_rdata_t rdata;
+       dns_decompress_t dctx;
+       isc_result_t result;
+       size_t i;
+       dns_rdata_isdn_t isdn;
+
+       UNUSED(tc);
+
+       for (i = 0; test_data[i].len != 0; i++) {
+               isc_buffer_init(&source, test_data[i].data, test_data[i].len);
+               isc_buffer_add(&source, test_data[i].len);
+               isc_buffer_setactive(&source, test_data[i].len);
+               isc_buffer_init(&target1, buf1, sizeof(buf1));
+               dns_rdata_init(&rdata);
+               dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
+               result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
+                                           dns_rdatatype_isdn, &source,
+                                           &dctx, 0, &target1);
+               dns_decompress_invalidate(&dctx);
+               if (test_data[i].ok)
+                       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+               else
+                       ATF_REQUIRE(result != ISC_R_SUCCESS);
+               if (result != ISC_R_SUCCESS)
+                       continue;
+               result = dns_rdata_tostruct(&rdata, &isdn, NULL);
+               ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+               isc_buffer_init(&target2, buf2, sizeof(buf2));
+               dns_rdata_reset(&rdata);
+               result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
+                                             dns_rdatatype_isdn, &isdn,
+                                             &target2);
+               ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+               ATF_REQUIRE_EQ(isc_buffer_usedlength(&target2),
+                                                    test_data[i].len);
+               ATF_REQUIRE_EQ(memcmp(buf2, test_data[i].data,
+                                     test_data[i].len), 0);
+       }
+}
+
 /*
  * Main
  */
 ATF_TP_ADD_TCS(tp) {
        ATF_TP_ADD_TC(tp, hip);
        ATF_TP_ADD_TC(tp, edns_client_subnet);
+       ATF_TP_ADD_TC(tp, wks);
+       ATF_TP_ADD_TC(tp, isdn);
 
        return (atf_no_error());
 }