summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>2002-06-26 06:02:54 +0000
committermillert <>2002-06-26 06:02:54 +0000
commit0375e51a80c9a3f6ac5804f1c784f90c8ed7a3c3 (patch)
tree43e53dffa1d2cd6a3c60bdedf574cd5ad04efb78
parent0461b1f9f162975928c9fe60e016b7281276fb0f (diff)
downloadopenbsd-OPENBSD_2_9.tar.gz
openbsd-OPENBSD_2_9.tar.bz2
openbsd-OPENBSD_2_9.zip
avoid remote buffer overrun on hostbuf[]. From: Joost Pol <joost@pine.nl>OPENBSD_2_9
correct bad practice in the code - it uses two changing variables to manage buffer (buf and buflen). we eliminate buflen and use fixed point (ep) as the ending pointer. From: itojun this fix is critical.
-rw-r--r--src/lib/libc/net/gethostnamadr.c57
-rw-r--r--src/lib/libc/net/getnetnamadr.c19
2 files changed, 33 insertions, 43 deletions
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c
index 33c9643f70..c3381a73d0 100644
--- a/src/lib/libc/net/gethostnamadr.c
+++ b/src/lib/libc/net/gethostnamadr.c
@@ -52,7 +52,7 @@
52 */ 52 */
53 53
54#if defined(LIBC_SCCS) && !defined(lint) 54#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.42 2000/07/30 14:07:14 itojun Exp $"; 55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.42.4.1 2002/06/26 06:02:54 millert Exp $";
56#endif /* LIBC_SCCS and not lint */ 56#endif /* LIBC_SCCS and not lint */
57 57
58#include <sys/param.h> 58#include <sys/param.h>
@@ -99,7 +99,7 @@ static FILE *hostf = NULL;
99static int stayopen = 0; 99static int stayopen = 0;
100 100
101static void map_v4v6_address __P((const char *src, char *dst)); 101static void map_v4v6_address __P((const char *src, char *dst));
102static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); 102static void map_v4v6_hostent __P((struct hostent *hp, char **bp, char *));
103 103
104#ifdef RESOLVSORT 104#ifdef RESOLVSORT
105static void addrsort __P((char **, int)); 105static void addrsort __P((char **, int));
@@ -169,8 +169,8 @@ getanswer(answer, anslen, qname, qtype)
169 register const u_char *cp; 169 register const u_char *cp;
170 register int n; 170 register int n;
171 const u_char *eom; 171 const u_char *eom;
172 char *bp, **ap, **hap; 172 char *bp, **ap, **hap, *ep;
173 int type, class, buflen, ancount, qdcount; 173 int type, class, ancount, qdcount;
174 int haveanswer, had_error; 174 int haveanswer, had_error;
175 int toobig = 0; 175 int toobig = 0;
176 char tbuf[MAXDNAME]; 176 char tbuf[MAXDNAME];
@@ -204,13 +204,13 @@ getanswer(answer, anslen, qname, qtype)
204 ancount = ntohs(hp->ancount); 204 ancount = ntohs(hp->ancount);
205 qdcount = ntohs(hp->qdcount); 205 qdcount = ntohs(hp->qdcount);
206 bp = hostbuf; 206 bp = hostbuf;
207 buflen = sizeof hostbuf; 207 ep = hostbuf + sizeof hostbuf;
208 cp = answer->buf + HFIXEDSZ; 208 cp = answer->buf + HFIXEDSZ;
209 if (qdcount != 1) { 209 if (qdcount != 1) {
210 h_errno = NO_RECOVERY; 210 h_errno = NO_RECOVERY;
211 return (NULL); 211 return (NULL);
212 } 212 }
213 n = dn_expand(answer->buf, eom, cp, bp, buflen); 213 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
214 if ((n < 0) || !(*name_ok)(bp)) { 214 if ((n < 0) || !(*name_ok)(bp)) {
215 h_errno = NO_RECOVERY; 215 h_errno = NO_RECOVERY;
216 return (NULL); 216 return (NULL);
@@ -224,7 +224,6 @@ getanswer(answer, anslen, qname, qtype)
224 n = strlen(bp) + 1; /* for the \0 */ 224 n = strlen(bp) + 1; /* for the \0 */
225 host.h_name = bp; 225 host.h_name = bp;
226 bp += n; 226 bp += n;
227 buflen -= n;
228 /* The qname can be abbreviated, but h_name is now absolute. */ 227 /* The qname can be abbreviated, but h_name is now absolute. */
229 qname = host.h_name; 228 qname = host.h_name;
230 } 229 }
@@ -237,7 +236,7 @@ getanswer(answer, anslen, qname, qtype)
237 haveanswer = 0; 236 haveanswer = 0;
238 had_error = 0; 237 had_error = 0;
239 while (ancount-- > 0 && cp < eom && !had_error) { 238 while (ancount-- > 0 && cp < eom && !had_error) {
240 n = dn_expand(answer->buf, eom, cp, bp, buflen); 239 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
241 if ((n < 0) || !(*name_ok)(bp)) { 240 if ((n < 0) || !(*name_ok)(bp)) {
242 had_error++; 241 had_error++;
243 continue; 242 continue;
@@ -272,17 +271,15 @@ getanswer(answer, anslen, qname, qtype)
272 *ap++ = bp; 271 *ap++ = bp;
273 n = strlen(bp) + 1; /* for the \0 */ 272 n = strlen(bp) + 1; /* for the \0 */
274 bp += n; 273 bp += n;
275 buflen -= n;
276 /* Get canonical name. */ 274 /* Get canonical name. */
277 n = strlen(tbuf) + 1; /* for the \0 */ 275 n = strlen(tbuf) + 1; /* for the \0 */
278 if (n > buflen) { 276 if (n > ep - bp) {
279 had_error++; 277 had_error++;
280 continue; 278 continue;
281 } 279 }
282 strcpy(bp, tbuf); 280 strcpy(bp, tbuf);
283 host.h_name = bp; 281 host.h_name = bp;
284 bp += n; 282 bp += n;
285 buflen -= n;
286 continue; 283 continue;
287 } 284 }
288 if (qtype == T_PTR && type == T_CNAME) { 285 if (qtype == T_PTR && type == T_CNAME) {
@@ -298,14 +295,13 @@ getanswer(answer, anslen, qname, qtype)
298 cp += n; 295 cp += n;
299 /* Get canonical name. */ 296 /* Get canonical name. */
300 n = strlen(tbuf) + 1; /* for the \0 */ 297 n = strlen(tbuf) + 1; /* for the \0 */
301 if (n > buflen) { 298 if (n > ep - bp) {
302 had_error++; 299 had_error++;
303 continue; 300 continue;
304 } 301 }
305 strcpy(bp, tbuf); 302 strcpy(bp, tbuf);
306 tname = bp; 303 tname = bp;
307 bp += n; 304 bp += n;
308 buflen -= n;
309 continue; 305 continue;
310 } 306 }
311 if (type != qtype) { 307 if (type != qtype) {
@@ -324,7 +320,7 @@ getanswer(answer, anslen, qname, qtype)
324 cp += n; 320 cp += n;
325 continue; /* XXX - had_error++ ? */ 321 continue; /* XXX - had_error++ ? */
326 } 322 }
327 n = dn_expand(answer->buf, eom, cp, bp, buflen); 323 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
328#ifdef USE_RESOLV_NAME_OK 324#ifdef USE_RESOLV_NAME_OK
329 if ((n < 0) || !res_hnok(bp)) { 325 if ((n < 0) || !res_hnok(bp)) {
330#else 326#else
@@ -344,7 +340,6 @@ getanswer(answer, anslen, qname, qtype)
344 if (n != -1) { 340 if (n != -1) {
345 n = strlen(bp) + 1; /* for the \0 */ 341 n = strlen(bp) + 1; /* for the \0 */
346 bp += n; 342 bp += n;
347 buflen -= n;
348 } 343 }
349 break; 344 break;
350#else 345#else
@@ -352,8 +347,7 @@ getanswer(answer, anslen, qname, qtype)
352 if (_res.options & RES_USE_INET6) { 347 if (_res.options & RES_USE_INET6) {
353 n = strlen(bp) + 1; /* for the \0 */ 348 n = strlen(bp) + 1; /* for the \0 */
354 bp += n; 349 bp += n;
355 buflen -= n; 350 map_v4v6_hostent(&host, &bp, ep);
356 map_v4v6_hostent(&host, &bp, &buflen);
357 } 351 }
358 h_errno = NETDB_SUCCESS; 352 h_errno = NETDB_SUCCESS;
359 return (&host); 353 return (&host);
@@ -376,7 +370,6 @@ getanswer(answer, anslen, qname, qtype)
376 host.h_name = bp; 370 host.h_name = bp;
377 nn = strlen(bp) + 1; /* for the \0 */ 371 nn = strlen(bp) + 1; /* for the \0 */
378 bp += nn; 372 bp += nn;
379 buflen -= nn;
380 } 373 }
381 374
382 bp += sizeof(align) - ((u_long)bp % sizeof(align)); 375 bp += sizeof(align) - ((u_long)bp % sizeof(align));
@@ -400,7 +393,6 @@ getanswer(answer, anslen, qname, qtype)
400 } 393 }
401 bcopy(cp, *hap++ = bp, n); 394 bcopy(cp, *hap++ = bp, n);
402 bp += n; 395 bp += n;
403 buflen -= n;
404 cp += n; 396 cp += n;
405 break; 397 break;
406 } 398 }
@@ -421,15 +413,14 @@ getanswer(answer, anslen, qname, qtype)
421# endif /*RESOLVSORT*/ 413# endif /*RESOLVSORT*/
422 if (!host.h_name) { 414 if (!host.h_name) {
423 n = strlen(qname) + 1; /* for the \0 */ 415 n = strlen(qname) + 1; /* for the \0 */
424 if (n > buflen) 416 if (n > ep - bp)
425 goto try_again; 417 goto try_again;
426 strcpy(bp, qname); 418 strcpy(bp, qname);
427 host.h_name = bp; 419 host.h_name = bp;
428 bp += n; 420 bp += n;
429 buflen -= n;
430 } 421 }
431 if (_res.options & RES_USE_INET6) 422 if (_res.options & RES_USE_INET6)
432 map_v4v6_hostent(&host, &bp, &buflen); 423 map_v4v6_hostent(&host, &bp, ep);
433 h_errno = NETDB_SUCCESS; 424 h_errno = NETDB_SUCCESS;
434 return (&host); 425 return (&host);
435 } 426 }
@@ -521,8 +512,8 @@ gethostbyname2(name, af)
521{ 512{
522 querybuf buf; 513 querybuf buf;
523 register const char *cp; 514 register const char *cp;
524 char *bp; 515 char *bp, *ep;
525 int n, size, type, len, i; 516 int n, size, type, i;
526 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname(); 517 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname();
527 register struct hostent *hp; 518 register struct hostent *hp;
528 char lookups[MAXDNSLUS]; 519 char lookups[MAXDNSLUS];
@@ -577,7 +568,7 @@ gethostbyname2(name, af)
577 strncpy(hostbuf, name, MAXHOSTNAMELEN-1); 568 strncpy(hostbuf, name, MAXHOSTNAMELEN-1);
578 hostbuf[MAXHOSTNAMELEN-1] = '\0'; 569 hostbuf[MAXHOSTNAMELEN-1] = '\0';
579 bp = hostbuf + MAXHOSTNAMELEN; 570 bp = hostbuf + MAXHOSTNAMELEN;
580 len = sizeof hostbuf - MAXHOSTNAMELEN; 571 ep = hostbuf + sizeof(hostbuf);
581 host.h_name = hostbuf; 572 host.h_name = hostbuf;
582 host.h_aliases = host_aliases; 573 host.h_aliases = host_aliases;
583 host_aliases[0] = NULL; 574 host_aliases[0] = NULL;
@@ -585,7 +576,7 @@ gethostbyname2(name, af)
585 h_addr_ptrs[1] = NULL; 576 h_addr_ptrs[1] = NULL;
586 host.h_addr_list = h_addr_ptrs; 577 host.h_addr_list = h_addr_ptrs;
587 if (_res.options & RES_USE_INET6) 578 if (_res.options & RES_USE_INET6)
588 map_v4v6_hostent(&host, &bp, &len); 579 map_v4v6_hostent(&host, &bp, ep);
589 h_errno = NETDB_SUCCESS; 580 h_errno = NETDB_SUCCESS;
590 return (&host); 581 return (&host);
591 } 582 }
@@ -610,7 +601,7 @@ gethostbyname2(name, af)
610 strncpy(hostbuf, name, MAXHOSTNAMELEN-1); 601 strncpy(hostbuf, name, MAXHOSTNAMELEN-1);
611 hostbuf[MAXHOSTNAMELEN-1] = '\0'; 602 hostbuf[MAXHOSTNAMELEN-1] = '\0';
612 bp = hostbuf + MAXHOSTNAMELEN; 603 bp = hostbuf + MAXHOSTNAMELEN;
613 len = sizeof hostbuf - MAXHOSTNAMELEN; 604 ep = hostbuf + sizeof(hostbuf);
614 host.h_name = hostbuf; 605 host.h_name = hostbuf;
615 host.h_aliases = host_aliases; 606 host.h_aliases = host_aliases;
616 host_aliases[0] = NULL; 607 host_aliases[0] = NULL;
@@ -869,9 +860,9 @@ _gethtent()
869 *q = NULL; 860 *q = NULL;
870 if (_res.options & RES_USE_INET6) { 861 if (_res.options & RES_USE_INET6) {
871 char *bp = hostbuf; 862 char *bp = hostbuf;
872 int buflen = sizeof hostbuf; 863 char *ep = hostbuf + sizeof hostbuf;
873 864
874 map_v4v6_hostent(&host, &bp, &buflen); 865 map_v4v6_hostent(&host, &bp, ep);
875 } 866 }
876 h_errno = NETDB_SUCCESS; 867 h_errno = NETDB_SUCCESS;
877 return (&host); 868 return (&host);
@@ -1087,10 +1078,10 @@ map_v4v6_address(src, dst)
1087} 1078}
1088 1079
1089static void 1080static void
1090map_v4v6_hostent(hp, bpp, lenp) 1081map_v4v6_hostent(hp, bpp, ep)
1091 struct hostent *hp; 1082 struct hostent *hp;
1092 char **bpp; 1083 char **bpp;
1093 int *lenp; 1084 char *ep;
1094{ 1085{
1095 char **ap; 1086 char **ap;
1096 1087
@@ -1101,17 +1092,15 @@ map_v4v6_hostent(hp, bpp, lenp)
1101 for (ap = hp->h_addr_list; *ap; ap++) { 1092 for (ap = hp->h_addr_list; *ap; ap++) {
1102 int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); 1093 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1103 1094
1104 if (*lenp < (i + IN6ADDRSZ)) { 1095 if (ep - *bpp < (i + IN6ADDRSZ)) {
1105 /* Out of memory. Truncate address list here. XXX */ 1096 /* Out of memory. Truncate address list here. XXX */
1106 *ap = NULL; 1097 *ap = NULL;
1107 return; 1098 return;
1108 } 1099 }
1109 *bpp += i; 1100 *bpp += i;
1110 *lenp -= i;
1111 map_v4v6_address(*ap, *bpp); 1101 map_v4v6_address(*ap, *bpp);
1112 *ap = *bpp; 1102 *ap = *bpp;
1113 *bpp += IN6ADDRSZ; 1103 *bpp += IN6ADDRSZ;
1114 *lenp -= IN6ADDRSZ;
1115 } 1104 }
1116} 1105}
1117 1106
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
index 0ebc77b656..522332d9b0 100644
--- a/src/lib/libc/net/getnetnamadr.c
+++ b/src/lib/libc/net/getnetnamadr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: getnetnamadr.c,v 1.13 1999/06/04 06:38:10 niklas Exp $ */ 1/* $OpenBSD: getnetnamadr.c,v 1.13.8.1 2002/06/26 06:02:54 millert Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997, Jason Downs. All rights reserved. 4 * Copyright (c) 1997, Jason Downs. All rights reserved.
@@ -77,7 +77,7 @@ static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
77static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; 77static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
78static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; 78static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
79#else 79#else
80static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.13 1999/06/04 06:38:10 niklas Exp $"; 80static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.13.8.1 2002/06/26 06:02:54 millert Exp $";
81#endif 81#endif
82#endif /* LIBC_SCCS and not lint */ 82#endif /* LIBC_SCCS and not lint */
83 83
@@ -133,9 +133,9 @@ getnetanswer(answer, anslen, net_i)
133 register u_char *cp; 133 register u_char *cp;
134 register int n; 134 register int n;
135 u_char *eom; 135 u_char *eom;
136 int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; 136 int type, class, ancount, qdcount, haveanswer, i, nchar;
137 char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN]; 137 char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
138 char *in, *st, *pauxt, *bp, **ap; 138 char *in, *st, *pauxt, *bp, **ap, *ep;
139 char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; 139 char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
140 static struct netent net_entry; 140 static struct netent net_entry;
141 static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; 141 static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
@@ -159,7 +159,7 @@ getnetanswer(answer, anslen, net_i)
159 ancount = ntohs(hp->ancount); /* #/records in the answer section */ 159 ancount = ntohs(hp->ancount); /* #/records in the answer section */
160 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ 160 qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
161 bp = netbuf; 161 bp = netbuf;
162 buflen = sizeof(netbuf); 162 ep = netbuf + sizeof(netbuf);
163 cp = answer->buf + HFIXEDSZ; 163 cp = answer->buf + HFIXEDSZ;
164 if (!qdcount) { 164 if (!qdcount) {
165 if (hp->aa) 165 if (hp->aa)
@@ -175,7 +175,7 @@ getnetanswer(answer, anslen, net_i)
175 net_entry.n_aliases = net_aliases; 175 net_entry.n_aliases = net_aliases;
176 haveanswer = 0; 176 haveanswer = 0;
177 while (--ancount >= 0 && cp < eom) { 177 while (--ancount >= 0 && cp < eom) {
178 n = dn_expand(answer->buf, eom, cp, bp, buflen); 178 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
179#ifdef USE_RESOLV_NAME_OK 179#ifdef USE_RESOLV_NAME_OK
180 if ((n < 0) || !res_dnok(bp)) 180 if ((n < 0) || !res_dnok(bp))
181#else 181#else
@@ -191,12 +191,13 @@ getnetanswer(answer, anslen, net_i)
191 cp += INT32SZ; /* TTL */ 191 cp += INT32SZ; /* TTL */
192 GETSHORT(n, cp); 192 GETSHORT(n, cp);
193 if (class == C_IN && type == T_PTR) { 193 if (class == C_IN && type == T_PTR) {
194 n = dn_expand(answer->buf, eom, cp, bp, buflen); 194 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
195#ifdef USE_RESOLV_NAME_OK 195#ifdef USE_RESOLV_NAME_OK
196 if ((n < 0) || !res_hnok(bp)) { 196 if ((n < 0) || !res_hnok(bp))
197#else 197#else
198 if ((n < 0) || !_hokchar(bp)) { 198 if ((n < 0) || !_hokchar(bp))
199#endif 199#endif
200 {
200 cp += n; 201 cp += n;
201 return (NULL); 202 return (NULL);
202 } 203 }