summaryrefslogtreecommitdiff
path: root/usr/src/lib/libresolv2/common/resolv/res_init.c
diff options
context:
space:
mode:
authorsm26363 <none@none>2007-01-04 10:03:42 -0800
committersm26363 <none@none>2007-01-04 10:03:42 -0800
commitc16fc6609d9aa72229802524dc1d8c4ead6e9d2a (patch)
treec658f2b7f88ddae4c9c4b3a25bc5d852963192c2 /usr/src/lib/libresolv2/common/resolv/res_init.c
parent5600110389005ea5ace473e10a15c3e80a3edf97 (diff)
downloadillumos-gate-c16fc6609d9aa72229802524dc1d8c4ead6e9d2a.tar.gz
6248700 Memory leak in libresolv
6337595 core dump - res_nsend() always assumes statp->_u._ext.ext not being NULL 6340650 in.dhcpd: Must initialize statp structure before calling res_ninit() 6487719 libdhcpdu: Must initialize statp structure before calling res_ninit()
Diffstat (limited to 'usr/src/lib/libresolv2/common/resolv/res_init.c')
-rw-r--r--usr/src/lib/libresolv2/common/resolv/res_init.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/usr/src/lib/libresolv2/common/resolv/res_init.c b/usr/src/lib/libresolv2/common/resolv/res_init.c
index e0eac579e4..33ccc9ece7 100644
--- a/usr/src/lib/libresolv2/common/resolv/res_init.c
+++ b/usr/src/lib/libresolv2/common/resolv/res_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -187,6 +187,9 @@ __res_vinit(res_state statp, int preinit) {
int dots;
union res_sockaddr_union u[2];
+ if (statp->_u._ext.ext != NULL)
+ res_ndestroy(statp);
+
if (!preinit) {
statp->retrans = RES_TIMEOUT;
statp->retry = RES_DFLRETRY;
@@ -194,9 +197,6 @@ __res_vinit(res_state statp, int preinit) {
statp->id = res_randomid();
}
- if ((statp->options & RES_INIT) != 0)
- res_ndestroy(statp);
-
memset(u, 0, sizeof(u));
#ifdef USELOOPBACK
u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
@@ -236,7 +236,8 @@ __res_vinit(res_state statp, int preinit) {
statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
- }
+ } else
+ return (-1);
#ifdef RESOLVSORT
statp->nsort = 0;
#endif
@@ -257,13 +258,13 @@ __res_vinit(res_state statp, int preinit) {
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("res_init: socket");
- return (-1);
+ goto freedata;
}
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = LIFC_EXTERNAL_SOURCE;
if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) {
close(s);
- return (-1);
+ goto freedata;
}
if (lifn.lifn_count == 0) {
/*
@@ -277,14 +278,14 @@ __res_vinit(res_state statp, int preinit) {
if ((ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) ||
(lifn.lifn_count < 1)) {
close(s);
- return (-1);
+ goto freedata;
}
buflen = lifn.lifn_count * sizeof (struct lifreq);
buf = (uchar_t *)malloc(buflen);
if (buf == NULL) {
close(s);
- return (-1);
+ goto freedata;
}
lifc.lifc_family = AF_UNSPEC;
@@ -294,7 +295,7 @@ __res_vinit(res_state statp, int preinit) {
if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) {
close(s);
free(buf);
- return (-1);
+ goto freedata;
}
for (i = 0; i < lifn.lifn_count; ++i) {
@@ -306,7 +307,7 @@ __res_vinit(res_state statp, int preinit) {
if (ioctl(s, SIOCGLIFFLAGS, &lreq) < 0) {
close(s);
free(buf);
- return (-1);
+ goto freedata;
}
if ((lreq.lifr_flags & IFF_UP) &&
!(lreq.lifr_flags & IFF_NOLOCAL) &&
@@ -320,7 +321,7 @@ __res_vinit(res_state statp, int preinit) {
if (!int_up) {
close(s);
- return (-1);
+ goto freedata;
}
}
close(s);
@@ -590,6 +591,14 @@ __res_vinit(res_state statp, int preinit) {
res_setoptions(statp, cp, "env");
statp->options |= RES_INIT;
return (0);
+#ifdef SUNW_INITCHKIF
+freedata:
+ if (statp->_u._ext.ext != NULL) {
+ free(statp->_u._ext.ext);
+ statp->_u._ext.ext = NULL;
+ }
+ return (-1);
+#endif /* SUNW_INITCHKIF */
}
static void