diff options
| author | michen <none@none> | 2006-11-27 13:17:04 -0800 |
|---|---|---|
| committer | michen <none@none> | 2006-11-27 13:17:04 -0800 |
| commit | 458d6ca5b5e480babef7df52f0e5756ba1abe198 (patch) | |
| tree | 7c4bb68dbec56e5ce70a4e9c3398f0dbb631cf24 /usr | |
| parent | 94501b61e12c24a6ea3abf427022ca0d4a302f3b (diff) | |
| download | illumos-joyent-458d6ca5b5e480babef7df52f0e5756ba1abe198.tar.gz | |
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
Diffstat (limited to 'usr')
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/dns_common.c | 41 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/nis/common/getexecattr.c | 7 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/nisplus/common/getexecattr.c | 4 |
3 files changed, 36 insertions, 16 deletions
diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.c b/usr/src/lib/nsswitch/dns/common/dns_common.c index d7254f6202..a30047ac6d 100644 --- a/usr/src/lib/nsswitch/dns/common/dns_common.c +++ b/usr/src/lib/nsswitch/dns/common/dns_common.c @@ -263,6 +263,18 @@ _nss_dns_constr(dns_backend_op_t ops[], int n_ops) 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) * 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) /* 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 @@ _nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) 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 --git a/usr/src/lib/nsswitch/nis/common/getexecattr.c b/usr/src/lib/nsswitch/nis/common/getexecattr.c index 07f8640f0b..9a4ff82dda 100644 --- a/usr/src/lib/nsswitch/nis/common/getexecattr.c +++ b/usr/src/lib/nsswitch/nis/common/getexecattr.c @@ -282,9 +282,12 @@ _exec_nis_lookup(nis_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) 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 @@ _exec_nis_lookup(nis_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) 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 --git a/usr/src/lib/nsswitch/nisplus/common/getexecattr.c b/usr/src/lib/nsswitch/nisplus/common/getexecattr.c index 8a60c77e75..11b8df8ccf 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getexecattr.c +++ b/usr/src/lib/nsswitch/nisplus/common/getexecattr.c @@ -336,13 +336,13 @@ _exec_nisplus_lookup(nisplus_backend_t *be, 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) { |
