diff --git a/CHANGES b/CHANGES index c0c9ee4db4..6a9053aa4d 100644 --- 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] diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index fb1fd58cc1..bf64a5b8c1 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -1011,7 +1011,6 @@ parse_bits(char *arg, const char *desc, isc_uint32_t max) { return (tmp); } - /* * Parse HMAC algorithm specification */ diff --git a/bin/tests/db_test.c b/bin/tests/db_test.c index d3d8b4a543..54ab207545 100644 --- a/bin/tests/db_test.c +++ b/bin/tests/db_test.c @@ -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, diff --git a/bin/tests/sock_test.c b/bin/tests/sock_test.c index 6ced499f68..009ce3cc36 100644 --- a/bin/tests/sock_test.c +++ b/bin/tests/sock_test.c @@ -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, ®ion, 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, ®ion, task, my_http_get, event->ev_arg); diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index 1a88e53264..7de4ad70ca 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -1161,6 +1161,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. */ diff --git a/lib/dns/name.c b/lib/dns/name.c index 3b7ff3f962..6398fe628b 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -2387,6 +2387,8 @@ dns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) { isc_buffer_usedregion(&buf, ®); 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'; diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index 603267c972..45a4fa1312 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -48,7 +48,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 @@ -58,7 +65,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 diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index f14c5d6221..4a2c53c4fd 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -1442,10 +1442,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); }