Hi,
In Bionic C, if we invokes gethostbyname from the thread first time, _res_thread_get actually invokes res_ninit twice (one in _res_thread_alloc and another in the function itself) which would result in malloc twice in
__res_vinit, /platform/bionic/libc/netbsd/resolv/res_init.c:269 and memory leaks.
I have a draft fix as following, where I moved the conditional check above preinit block, so res_ndestroy could be executed first if __res_vinit is entered second time, and free the memory chunk allocated in the previous call. Please kindly review it, thanks.
==============================================
diff --git a/libc/netbsd/resolv/res_init.c b/libc/netbsd/resolv/res_init.c
index 751603d..2c80b28 100644
--- a/libc/netbsd/resolv/res_init.c
+++ b/libc/netbsd/resolv/res_init.c
@@ -223,6 +223,9 @@ __res_vinit(res_state statp, int preinit) {
char dnsProperty[PROP_VALUE_MAX];
#endif
+ if ((statp->options & RES_INIT) != 0U)
+ res_ndestroy(statp);+ if (!preinit) {
statp->retrans = RES_TIMEOUT;
statp->retry = RES_DFLRETRY;
@@ -230,9 +233,6 @@ __res_vinit(res_state statp, int preinit) {
statp->id = res_randomid();
}
- if ((statp->options & RES_INIT) != 0U)
- res_ndestroy(statp);- memset(u, 0, sizeof(u));
#ifdef USELOOPBACK
u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
diff --git a/libc/netbsd/resolv/res_state.c b/libc/netbsd/resolv/res_state.c
index 3a2301d..92bfab3 100644
--- a/libc/netbsd/resolv/res_state.c
+++ b/libc/netbsd/resolv/res_state.c
@@ -53,6 +53,7 @@ static _res_thread*
_res_thread_alloc(void)
{
_res_thread* rt = malloc(sizeof(*rt));
+ memset(rt, 0, sizeof(*rt));
if (rt) {
rt->_h_errno = 0;
Or maybe I can simply remove below two statements from _res_thread_get to avoid res_ninit twice? Which one is better? Personally I would prefer the first one as it also works when res_ninit invoked multiple times somewhere else.
===============
diff --git a/libc/netbsd/resolv/res_state.c b/libc/netbsd/resolv/res_state.c
index 92bfab3..8d33ea4 100644
--- a/libc/netbsd/resolv/res_state.c
+++ b/libc/netbsd/resolv/res_state.c
@@ -113,8 +113,6 @@ _res_thread_get(void)
if ((rt = _res_thread_alloc()) == NULL) {
return NULL;
}
- rt->_h_errno = 0;- rt->_serial = 0;
pthread_setspecific( _res_key, rt );
}
/* Check the serial value for any chanes to net.* properties. */==
BTW: I submitted the issue
6134 several days ago but seems no feedback there, so I re-post the issue here:)
-Freepine