# HG changeset patch # User michen # Date 1164662224 28800 # Node ID a38e922f22b04277b56d27cc895dc6808c0b1d62 # Parent 5903f61aa150605692ee60a64e7bcfe97d60c473 6495346 memory leak in nss_dns.so.1/_nss_dns_gethost_withttl 6495347 getexecuser/getexecprof leak memory in nss_nis.so and nss_nisplus.so diff -r 5903f61aa150 -r a38e922f22b0 usr/src/lib/nsswitch/dns/common/dns_common.c --- a/usr/src/lib/nsswitch/dns/common/dns_common.c Mon Nov 27 12:42:57 2006 -0800 +++ b/usr/src/lib/nsswitch/dns/common/dns_common.c Mon Nov 27 13:17:04 2006 -0800 @@ -263,6 +263,18 @@ return ((nss_backend_t *)be); } +/* + * __res_ndestroy is a simplified version of the non-public function + * res_ndestroy in libresolv.so.2. Before res_ndestroy can be made + * public, __res_ndestroy will be used to make sure the memory pointed + * by statp->_u._ext.ext is freed after res_nclose() is called. + */ +static void +__res_ndestroy(res_state statp) { + res_nclose(statp); + if (statp->_u._ext.ext != NULL) + free(statp->_u._ext.ext); +} /* * nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) @@ -343,14 +355,14 @@ blen = 0; sret = nss_packed_getkey(buffer, bufsize, &dbname, &dbop, &arg); if (sret != NSS_SUCCESS) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } if (ipnode) { /* initially only handle the simple cases */ if (arg.key.ipnode.flags != 0) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } name = arg.key.ipnode.name; @@ -368,11 +380,11 @@ pbuf->p_herrno = HOST_NOT_FOUND; pbuf->p_status = NSS_NOTFOUND; pbuf->data_len = 0; - res_nclose(statp); + __res_ndestroy(statp); return (NSS_NOTFOUND); } /* else lookup error - handle in general code */ - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } @@ -385,25 +397,25 @@ qdcount = ntohs(hp->qdcount); cp += HFIXEDSZ; if (qdcount != 1) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } n = dn_expand(bom, eom, cp, host, MAXHOSTNAMELEN); if (n < 0) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } else hlen = strlen(host); cp += n + QFIXEDSZ; if (cp > eom) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } while (ancount-- > 0 && cp < eom && blen < bsize) { n = dn_expand(bom, eom, cp, ans, MAXHOSTNAMELEN); if (n > 0) { if (strncasecmp(host, ans, hlen) != 0) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); /* spoof? */ } } @@ -435,8 +447,10 @@ * attempted buffer overflow exploit * generic code will do a syslog */ - if (alen + len + 2 > NS_MAXMSG) + if (alen + len + 2 > NS_MAXMSG) { + __res_ndestroy(statp); return (NSS_ERROR); + } *apc++ = ' '; alen++; (void) strlcpy(apc, aname, len + 1); @@ -460,7 +474,7 @@ af = (type == T_A ? AF_INET : AF_INET6); np = inet_ntop(af, (void *)cp, nbuf, INET6_ADDRSTRLEN); if (np == NULL) { - res_nclose(statp); + __res_ndestroy(statp); return (NSS_ERROR); } cp += n; @@ -470,8 +484,10 @@ len = iplen + 2 + hlen + alen; if (alen > 0) len++; - if (blen + len > bsize) + if (blen + len > bsize) { + __res_ndestroy(statp); return (NSS_ERROR); + } (void) strlcpy(bptr, np, bsize - blen); blen += iplen; bptr += iplen; @@ -495,6 +511,7 @@ /* still room? */ if (len + sizeof (nssuint_t) > pbuf->data_len) { /* sigh, no, what happened? */ + __res_ndestroy(statp); return (NSS_ERROR); } pbuf->ext_off = pbuf->data_off + len; @@ -502,6 +519,6 @@ pbuf->data_len = blen; pttl = (nssuint_t *)((void *)((char *)pbuf + pbuf->ext_off)); *pttl = ttl; - res_nclose(statp); + __res_ndestroy(statp); return (NSS_SUCCESS); } diff -r 5903f61aa150 -r a38e922f22b0 usr/src/lib/nsswitch/nis/common/getexecattr.c --- a/usr/src/lib/nsswitch/nis/common/getexecattr.c Mon Nov 27 12:42:57 2006 -0800 +++ b/usr/src/lib/nsswitch/nis/common/getexecattr.c Mon Nov 27 13:17:04 2006 -0800 @@ -282,9 +282,12 @@ res = ypres; break; } else { + char *val_save = val; + massage_netdb((const char **)&val, &vallen); res = _exec_nis_parse((const char *)val, vallen, argp, check_policy); + free(val_save); break; } } while (res == NSS_SUCCESS); @@ -339,13 +342,13 @@ static nss_status_t get_wild(nis_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) { - char *orig_id = NULL; + const char *orig_id; char *old_id = NULL; char *wild_id = NULL; nss_status_t res = NSS_NOTFOUND; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); - orig_id = strdup(_priv_exec->id); + orig_id = _priv_exec->id; old_id = strdup(_priv_exec->id); wild_id = old_id; while ((wild_id = _exec_wild_id(wild_id, _priv_exec->type)) != NULL) { diff -r 5903f61aa150 -r a38e922f22b0 usr/src/lib/nsswitch/nisplus/common/getexecattr.c --- a/usr/src/lib/nsswitch/nisplus/common/getexecattr.c Mon Nov 27 12:42:57 2006 -0800 +++ b/usr/src/lib/nsswitch/nisplus/common/getexecattr.c Mon Nov 27 13:17:04 2006 -0800 @@ -336,13 +336,13 @@ static nss_status_t get_wild(nisplus_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) { - char *orig_id = NULL; + const char *orig_id = NULL; char *old_id = NULL; char *wild_id = NULL; nss_status_t res = NSS_NOTFOUND; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); - orig_id = strdup(_priv_exec->id); + orig_id = _priv_exec->id; old_id = strdup(_priv_exec->id); wild_id = old_id; while ((wild_id = _exec_wild_id(wild_id, _priv_exec->type)) != NULL) {