]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4110. [bug] Address memory leaks / null pointer dereferences
authorMark Andrews <marka@isc.org>
Tue, 28 Apr 2015 17:16:50 +0000 (03:16 +1000)
committerMark Andrews <marka@isc.org>
Tue, 28 Apr 2015 17:16:50 +0000 (03:16 +1000)
                        on out of memory. [RT #39310]

12 files changed:
CHANGES
bin/dig/dighost.c
bin/named/config.c
bin/tests/db_test.c
bin/tests/sock_test.c
bin/tools/mdig.c
lib/dns/include/dns/name.h
lib/dns/name.c
lib/dns/tests/rbt_test.c
lib/isc/include/isc/mem.h
lib/isc/tests/random_test.c
lib/isccfg/parser.c

diff --git a/CHANGES b/CHANGES
index 7633bded324246a3adb8eb670e9ba957f1a2d124..f3d379eb2bea6b0456aca06eac676a1de118199c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4110.  [bug]           Address memory leaks / null pointer dereferences
+                       on out of memory. [RT #39310]
+
 4109.  [port]          linux: support reading the local port range from
                        net.ipv4.ip_local_port_range. [RT # 39379]
 
index 35a86b322310e823d461f3a85d6e57597e9e186c..c2bb8c4b2825b24e1416e4edd803dced633b114b 100644 (file)
@@ -933,6 +933,8 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
        if (lookold->ecs_addr != NULL) {
                size_t len = sizeof(isc_sockaddr_t);
                looknew->ecs_addr = isc_mem_allocate(mctx, len);
+               if (looknew->ecs_addr == NULL)
+                       fatal("out of memory");
                memmove(looknew->ecs_addr, lookold->ecs_addr, len);
        }
 
@@ -1086,6 +1088,8 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
        }
 
        sa = isc_mem_allocate(mctx, sizeof(*sa));
+       if (sa == NULL)
+               fatal("out of memory");
        if (inet_pton(AF_INET6, value, &in6) == 1) {
                isc_sockaddr_fromin6(sa, &in6, 0);
                parsed = ISC_TRUE;
index 6107159c0ec02b2c9d1c2a9ac1141822c3ced212..d4a1f215608a7321b230e7bad06c7bd13763d239 100644 (file)
@@ -465,10 +465,6 @@ ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
        }
 
        if (dscpsp != NULL) {
-               dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
-               if (dscps == NULL)
-                       return (ISC_R_NOMEMORY);
-
                dscpobj = cfg_tuple_get(list, "dscp");
                if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) {
                        if (cfg_obj_asuint32(dscpobj) > 63) {
@@ -479,11 +475,18 @@ ns_config_getiplist(const cfg_obj_t *config, const cfg_obj_t *list,
                        }
                        dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
                }
+
+               dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
+               if (dscps == NULL)
+                       return (ISC_R_NOMEMORY);
        }
 
        addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t));
-       if (addrs == NULL)
+       if (addrs == NULL) {
+               if (dscps != NULL)
+                       isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
                return (ISC_R_NOMEMORY);
+       }
 
        for (element = cfg_list_first(addrlist);
             element != NULL;
@@ -622,7 +625,8 @@ ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
                        cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR,
                                    "dscp value '%u' is out of range",
                                    cfg_obj_asuint32(dscpobj));
-                       return (ISC_R_RANGE);
+                       result = ISC_R_RANGE;
+                       goto cleanup;
                }
                dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
        }
index d3d8b4a54318e9d2cea17ac9c85bcaab3b405036..54ab2075454f687757f50ddad3ec0c7c22bc8df5 100644 (file)
@@ -266,8 +266,10 @@ load(const char *filename, const char *origintext, isc_boolean_t cache) {
        dns_fixedname_init(&forigin);
        origin = dns_fixedname_name(&forigin);
        result = dns_name_fromtext(origin, &source, dns_rootname, 0, NULL);
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
+               isc_mem_put(mctx, dbi, sizeof(*dbi));
                return (result);
+       }
 
        result = dns_db_create(mctx, dbtype, origin,
                               cache ? dns_dbtype_cache : dns_dbtype_zone,
index 6ced499f68909f2cec93982f38b2a41ff04bc866..009ce3cc362e3ab947f87c39fdf1333d43531d12 100644 (file)
@@ -61,7 +61,8 @@ my_send(isc_task_t *task, isc_event_t *event) {
                isc_task_shutdown(task);
        }
 
-       isc_mem_put(mctx, dev->region.base, dev->region.length);
+       if (dev->region.base != NULL)
+               isc_mem_put(mctx, dev->region.base, dev->region.length);
 
        isc_event_free(&event);
 }
@@ -96,8 +97,8 @@ my_recv(isc_task_t *task, isc_event_t *event) {
        if (dev->result != ISC_R_SUCCESS) {
                isc_socket_detach(&sock);
 
-               isc_mem_put(mctx, dev->region.base,
-                           dev->region.length);
+               if (dev->region.base != NULL)
+                       isc_mem_put(mctx, dev->region.base, dev->region.length);
                isc_event_free(&event);
 
                isc_task_shutdown(task);
@@ -112,8 +113,11 @@ my_recv(isc_task_t *task, isc_event_t *event) {
                sprintf(buf, "\r\nReceived: %.*s\r\n\r\n",
                        (int)dev->n, (char *)region.base);
                region.base = isc_mem_get(mctx, strlen(buf) + 1);
-               region.length = strlen(buf) + 1;
-               strcpy((char *)region.base, buf);  /* strcpy is safe */
+               if (region.base != NULL) {
+                       region.length = strlen(buf) + 1;
+                       strcpy((char *)region.base, buf);  /* strcpy is safe */
+               } else
+                       region.length = 0;
                isc_socket_send(sock, &region, task, my_send, event->ev_arg);
        } else {
                region = dev->region;
@@ -143,6 +147,8 @@ my_http_get(isc_task_t *task, isc_event_t *event) {
        if (dev->result != ISC_R_SUCCESS) {
                isc_socket_detach(&sock);
                isc_task_shutdown(task);
+               if (dev->region.base != NULL)
+                       isc_mem_put(mctx, dev->region.base, dev->region.length);
                isc_event_free(&event);
                return;
        }
@@ -179,8 +185,11 @@ my_connect(isc_task_t *task, isc_event_t *event) {
        strcpy(buf, "GET / HTTP/1.1\r\nHost: www.flame.org\r\n"
               "Connection: Close\r\n\r\n");
        region.base = isc_mem_get(mctx, strlen(buf) + 1);
-       region.length = strlen(buf) + 1;
-       strcpy((char *)region.base, buf);  /* This strcpy is safe. */
+       if (region.base != NULL) {
+               region.length = strlen(buf) + 1;
+               strcpy((char *)region.base, buf);  /* This strcpy is safe. */
+       } else
+               region.length = 0;
 
        isc_socket_send(sock, &region, task, my_http_get, event->ev_arg);
 
index bdfa578035d230b9367b981b7e27a9772a85fe6c..9d96e83f2eeeef56f9a5637ea301cb4225080b86 100644 (file)
@@ -908,6 +908,8 @@ parse_netprefix(isc_sockaddr_t **sap, const char *value) {
        }
 
        sa = isc_mem_allocate(mctx, sizeof(*sa));
+       if (sa == NULL)
+               fatal("out of memory");
        if (inet_pton(AF_INET6, value, &in6) == 1) {
                isc_sockaddr_fromin6(sa, &in6, 0);
                parsed = ISC_TRUE;
index 4430d70093ee54871816935e1f2272d24a05e6e2..103128d81eb657b5c02fb8a4ecb362a2cee41ecb 100644 (file)
@@ -1167,6 +1167,7 @@ dns_name_tostring(dns_name_t *source, char **target, isc_mem_t *mctx);
  * Returns:
  *
  *\li  ISC_R_SUCCESS
+ *\li  ISC_R_NOMEMORY
  *
  *\li  Any error that dns_name_totext() can return.
  */
index 09e44abf6485de22c8b54734d92945e38e6a4123..92ddfc860bf1c4fe51ac0c89ab86712fc7703182 100644 (file)
@@ -2428,6 +2428,8 @@ dns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
 
        isc_buffer_usedregion(&buf, &reg);
        p = isc_mem_allocate(mctx, reg.length + 1);
+       if (p == NULL)
+               return (ISC_R_NOMEMORY);
        memmove(p, (char *) reg.base, (int) reg.length);
        p[reg.length] = '\0';
 
index 7b2f42d72273bef11e5bd9969b57a99a4866db87..0d5ea117eaa7b9a38de163b32f1a8d5c6cae5b2a 100644 (file)
@@ -166,6 +166,7 @@ test_context_setup(void) {
        size_t i;
 
        ctx = isc_mem_get(mctx, sizeof(*ctx));
+       ATF_REQUIRE(ctx != NULL);
 
        ctx->rbt = NULL;
        result = dns_rbt_create(mctx, delete_data, NULL, &ctx->rbt);
@@ -1134,6 +1135,8 @@ insert_nodes(dns_rbt_t *mytree, char **names,
                char namebuf[34];
 
                n = isc_mem_get(mctx, sizeof(size_t));
+               ATF_REQUIRE(n != NULL);
+
                *n = i; /* Unused value */
 
                while (1) {
index 671438919741930d0752849dff5e1805f89a317b..ede0327129b584bc1846364e125b9df12a867008 100644 (file)
@@ -49,7 +49,14 @@ typedef void (*isc_memfree_t)(void *, void *);
 /*%
  * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
  * the requested space.  This will increase the size of each allocation.
+ *
+ * If we are performing a Coverity static analysis then ISC_MEM_CHECKOVERRUN
+ * can hide bugs that would otherwise discovered so force to zero.
  */
+#ifdef __COVERITY__
+#undef ISC_MEM_CHECKOVERRUN
+#define ISC_MEM_CHECKOVERRUN 0
+#endif
 #ifndef ISC_MEM_CHECKOVERRUN
 #define ISC_MEM_CHECKOVERRUN 1
 #endif
@@ -59,7 +66,14 @@ typedef void (*isc_memfree_t)(void *, void *);
  * with the byte string '0xbe'.  This helps track down uninitialized pointers
  * and the like.  On freeing memory, the space is filled with '0xde' for
  * the same reasons.
+ *
+ * If we are performing a Coverity static analysis then ISC_MEM_FILL
+ * can hide bugs that would otherwise discovered so force to zero.
  */
+#ifdef __COVERITY__
+#undef ISC_MEM_FILL
+#define ISC_MEM_FILL 0
+#endif
 #ifndef ISC_MEM_FILL
 #define ISC_MEM_FILL 1
 #endif
index ff538508745ec1df4f6bb07176d293948fbf0bee..c8f70ba35f4e9196d129d2944a3945005c25ab86 100644 (file)
@@ -371,7 +371,7 @@ monobit(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
        /* Debug message, not displayed when running via atf-run */
        printf("numbits=%u, scount=%d\n", numbits, scount);
 
-       s_obs = fabs(scount) / sqrt(numbits);
+       s_obs = abs(scount) / sqrt(numbits);
        p_value = erfc(s_obs / sqrt(2.0));
 
        return (p_value);
@@ -484,6 +484,7 @@ blockfrequency(isc_mem_t *mctx, isc_uint16_t *values, size_t length) {
        ATF_REQUIRE(numbits >= (mbits * numblocks));
 
        pi = isc_mem_get(mctx, numblocks * sizeof(double));
+       ATF_REQUIRE(pi != NULL);
 
        cur_word = 0;
        for (i = 0; i < numblocks; i++) {
index fc2777c9b97ea70827b3b60c3aed35a120f69af9..497ab377e4786c9440b35449f61fbdb5c34affce 100644 (file)
@@ -1476,10 +1476,11 @@ parse_any_named_map(cfg_parser_t *pctx, cfg_type_t *nametype, const cfg_type_t *
        CHECK(cfg_parse_obj(pctx, nametype, &idobj));
        CHECK(cfg_parse_map(pctx, type, &mapobj));
        mapobj->value.map.id = idobj;
-       idobj = NULL;
        *ret = mapobj;
+       return (result);
  cleanup:
        CLEANUP_OBJ(idobj);
+       CLEANUP_OBJ(mapobj);
        return (result);
 }