summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoritojun <>2002-06-26 06:00:54 +0000
committeritojun <>2002-06-26 06:00:54 +0000
commit2de6ddb6a22feedbcbc44271ca3841ddc526981b (patch)
tree524bd879d83e4a3a441b496c0122e8a2d30eee92 /src
parent403c6466072dcd35f27270cbae14d8ba3baa7a03 (diff)
downloadopenbsd-2de6ddb6a22feedbcbc44271ca3841ddc526981b.tar.gz
openbsd-2de6ddb6a22feedbcbc44271ca3841ddc526981b.tar.bz2
openbsd-2de6ddb6a22feedbcbc44271ca3841ddc526981b.zip
avoid remote buffer overrun on hostbuf[]. From: Joost Pol <joost@pine.nl>
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. this fix is critical.
Diffstat (limited to 'src')
-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 cdc42c4329..3049d576e1 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.47 2002/05/22 04:31:14 deraadt Exp $"; 55static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.48 2002/06/26 06:00:53 itojun 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(const char *src, char *dst); 101static void map_v4v6_address(const char *src, char *dst);
102static void map_v4v6_hostent(struct hostent *hp, char **bp, int *len); 102static void map_v4v6_hostent(struct hostent *hp, char **bp, char *);
103 103
104#ifdef RESOLVSORT 104#ifdef RESOLVSORT
105static void addrsort(char **, int); 105static void addrsort(char **, int);
@@ -168,8 +168,8 @@ getanswer(answer, anslen, qname, qtype)
168 register const u_char *cp; 168 register const u_char *cp;
169 register int n; 169 register int n;
170 const u_char *eom; 170 const u_char *eom;
171 char *bp, **ap, **hap; 171 char *bp, **ap, **hap, *ep;
172 int type, class, buflen, ancount, qdcount; 172 int type, class, ancount, qdcount;
173 int haveanswer, had_error; 173 int haveanswer, had_error;
174 int toobig = 0; 174 int toobig = 0;
175 char tbuf[MAXDNAME]; 175 char tbuf[MAXDNAME];
@@ -203,13 +203,13 @@ getanswer(answer, anslen, qname, qtype)
203 ancount = ntohs(hp->ancount); 203 ancount = ntohs(hp->ancount);
204 qdcount = ntohs(hp->qdcount); 204 qdcount = ntohs(hp->qdcount);
205 bp = hostbuf; 205 bp = hostbuf;
206 buflen = sizeof hostbuf; 206 ep = hostbuf + sizeof hostbuf;
207 cp = answer->buf + HFIXEDSZ; 207 cp = answer->buf + HFIXEDSZ;
208 if (qdcount != 1) { 208 if (qdcount != 1) {
209 h_errno = NO_RECOVERY; 209 h_errno = NO_RECOVERY;
210 return (NULL); 210 return (NULL);
211 } 211 }
212 n = dn_expand(answer->buf, eom, cp, bp, buflen); 212 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
213 if ((n < 0) || !(*name_ok)(bp)) { 213 if ((n < 0) || !(*name_ok)(bp)) {
214 h_errno = NO_RECOVERY; 214 h_errno = NO_RECOVERY;
215 return (NULL); 215 return (NULL);
@@ -223,7 +223,6 @@ getanswer(answer, anslen, qname, qtype)
223 n = strlen(bp) + 1; /* for the \0 */ 223 n = strlen(bp) + 1; /* for the \0 */
224 host.h_name = bp; 224 host.h_name = bp;
225 bp += n; 225 bp += n;
226 buflen -= n;
227 /* The qname can be abbreviated, but h_name is now absolute. */ 226 /* The qname can be abbreviated, but h_name is now absolute. */
228 qname = host.h_name; 227 qname = host.h_name;
229 } 228 }
@@ -236,7 +235,7 @@ getanswer(answer, anslen, qname, qtype)
236 haveanswer = 0; 235 haveanswer = 0;
237 had_error = 0; 236 had_error = 0;
238 while (ancount-- > 0 && cp < eom && !had_error) { 237 while (ancount-- > 0 && cp < eom && !had_error) {
239 n = dn_expand(answer->buf, eom, cp, bp, buflen); 238 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
240 if ((n < 0) || !(*name_ok)(bp)) { 239 if ((n < 0) || !(*name_ok)(bp)) {
241 had_error++; 240 had_error++;
242 continue; 241 continue;
@@ -271,17 +270,15 @@ getanswer(answer, anslen, qname, qtype)
271 *ap++ = bp; 270 *ap++ = bp;
272 n = strlen(bp) + 1; /* for the \0 */ 271 n = strlen(bp) + 1; /* for the \0 */
273 bp += n; 272 bp += n;
274 buflen -= n;
275 /* Get canonical name. */ 273 /* Get canonical name. */
276 n = strlen(tbuf) + 1; /* for the \0 */ 274 n = strlen(tbuf) + 1; /* for the \0 */
277 if (n > buflen) { 275 if (n > ep - bp) {
278 had_error++; 276 had_error++;
279 continue; 277 continue;
280 } 278 }
281 strcpy(bp, tbuf); 279 strcpy(bp, tbuf);
282 host.h_name = bp; 280 host.h_name = bp;
283 bp += n; 281 bp += n;
284 buflen -= n;
285 continue; 282 continue;
286 } 283 }
287 if (qtype == T_PTR && type == T_CNAME) { 284 if (qtype == T_PTR && type == T_CNAME) {
@@ -297,14 +294,13 @@ getanswer(answer, anslen, qname, qtype)
297 cp += n; 294 cp += n;
298 /* Get canonical name. */ 295 /* Get canonical name. */
299 n = strlen(tbuf) + 1; /* for the \0 */ 296 n = strlen(tbuf) + 1; /* for the \0 */
300 if (n > buflen) { 297 if (n > ep - bp) {
301 had_error++; 298 had_error++;
302 continue; 299 continue;
303 } 300 }
304 strcpy(bp, tbuf); 301 strcpy(bp, tbuf);
305 tname = bp; 302 tname = bp;
306 bp += n; 303 bp += n;
307 buflen -= n;
308 continue; 304 continue;
309 } 305 }
310 if (type != qtype) { 306 if (type != qtype) {
@@ -323,7 +319,7 @@ getanswer(answer, anslen, qname, qtype)
323 cp += n; 319 cp += n;
324 continue; /* XXX - had_error++ ? */ 320 continue; /* XXX - had_error++ ? */
325 } 321 }
326 n = dn_expand(answer->buf, eom, cp, bp, buflen); 322 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
327#ifdef USE_RESOLV_NAME_OK 323#ifdef USE_RESOLV_NAME_OK
328 if ((n < 0) || !res_hnok(bp)) { 324 if ((n < 0) || !res_hnok(bp)) {
329#else 325#else
@@ -343,7 +339,6 @@ getanswer(answer, anslen, qname, qtype)
343 if (n != -1) { 339 if (n != -1) {
344 n = strlen(bp) + 1; /* for the \0 */ 340 n = strlen(bp) + 1; /* for the \0 */
345 bp += n; 341 bp += n;
346 buflen -= n;
347 } 342 }
348 break; 343 break;
349#else 344#else
@@ -351,8 +346,7 @@ getanswer(answer, anslen, qname, qtype)
351 if (_res.options & RES_USE_INET6) { 346 if (_res.options & RES_USE_INET6) {
352 n = strlen(bp) + 1; /* for the \0 */ 347 n = strlen(bp) + 1; /* for the \0 */
353 bp += n; 348 bp += n;
354 buflen -= n; 349 map_v4v6_hostent(&host, &bp, ep);
355 map_v4v6_hostent(&host, &bp, &buflen);
356 } 350 }
357 h_errno = NETDB_SUCCESS; 351 h_errno = NETDB_SUCCESS;
358 return (&host); 352 return (&host);
@@ -375,7 +369,6 @@ getanswer(answer, anslen, qname, qtype)
375 host.h_name = bp; 369 host.h_name = bp;
376 nn = strlen(bp) + 1; /* for the \0 */ 370 nn = strlen(bp) + 1; /* for the \0 */
377 bp += nn; 371 bp += nn;
378 buflen -= nn;
379 } 372 }
380 373
381 bp += sizeof(align) - ((u_long)bp % sizeof(align)); 374 bp += sizeof(align) - ((u_long)bp % sizeof(align));
@@ -399,7 +392,6 @@ getanswer(answer, anslen, qname, qtype)
399 } 392 }
400 bcopy(cp, *hap++ = bp, n); 393 bcopy(cp, *hap++ = bp, n);
401 bp += n; 394 bp += n;
402 buflen -= n;
403 cp += n; 395 cp += n;
404 break; 396 break;
405 } 397 }
@@ -420,15 +412,14 @@ getanswer(answer, anslen, qname, qtype)
420# endif /*RESOLVSORT*/ 412# endif /*RESOLVSORT*/
421 if (!host.h_name) { 413 if (!host.h_name) {
422 n = strlen(qname) + 1; /* for the \0 */ 414 n = strlen(qname) + 1; /* for the \0 */
423 if (n > buflen) 415 if (n > ep - bp)
424 goto try_again; 416 goto try_again;
425 strcpy(bp, qname); 417 strcpy(bp, qname);
426 host.h_name = bp; 418 host.h_name = bp;
427 bp += n; 419 bp += n;
428 buflen -= n;
429 } 420 }
430 if (_res.options & RES_USE_INET6) 421 if (_res.options & RES_USE_INET6)
431 map_v4v6_hostent(&host, &bp, &buflen); 422 map_v4v6_hostent(&host, &bp, ep);
432 h_errno = NETDB_SUCCESS; 423 h_errno = NETDB_SUCCESS;
433 return (&host); 424 return (&host);
434 } 425 }
@@ -520,8 +511,8 @@ gethostbyname2(name, af)
520{ 511{
521 querybuf buf; 512 querybuf buf;
522 register const char *cp; 513 register const char *cp;
523 char *bp; 514 char *bp, *ep;
524 int n, size, type, len, i; 515 int n, size, type, i;
525 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname(); 516 extern struct hostent *_gethtbyname2(), *_yp_gethtbyname();
526 register struct hostent *hp; 517 register struct hostent *hp;
527 char lookups[MAXDNSLUS]; 518 char lookups[MAXDNSLUS];
@@ -575,7 +566,7 @@ gethostbyname2(name, af)
575 } 566 }
576 strlcpy(hostbuf, name, MAXHOSTNAMELEN); 567 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
577 bp = hostbuf + MAXHOSTNAMELEN; 568 bp = hostbuf + MAXHOSTNAMELEN;
578 len = sizeof hostbuf - MAXHOSTNAMELEN; 569 ep = hostbuf + sizeof(hostbuf);
579 host.h_name = hostbuf; 570 host.h_name = hostbuf;
580 host.h_aliases = host_aliases; 571 host.h_aliases = host_aliases;
581 host_aliases[0] = NULL; 572 host_aliases[0] = NULL;
@@ -583,7 +574,7 @@ gethostbyname2(name, af)
583 h_addr_ptrs[1] = NULL; 574 h_addr_ptrs[1] = NULL;
584 host.h_addr_list = h_addr_ptrs; 575 host.h_addr_list = h_addr_ptrs;
585 if (_res.options & RES_USE_INET6) 576 if (_res.options & RES_USE_INET6)
586 map_v4v6_hostent(&host, &bp, &len); 577 map_v4v6_hostent(&host, &bp, ep);
587 h_errno = NETDB_SUCCESS; 578 h_errno = NETDB_SUCCESS;
588 return (&host); 579 return (&host);
589 } 580 }
@@ -607,7 +598,7 @@ gethostbyname2(name, af)
607 } 598 }
608 strlcpy(hostbuf, name, MAXHOSTNAMELEN); 599 strlcpy(hostbuf, name, MAXHOSTNAMELEN);
609 bp = hostbuf + MAXHOSTNAMELEN; 600 bp = hostbuf + MAXHOSTNAMELEN;
610 len = sizeof hostbuf - MAXHOSTNAMELEN; 601 ep = hostbuf + sizeof(hostbuf);
611 host.h_name = hostbuf; 602 host.h_name = hostbuf;
612 host.h_aliases = host_aliases; 603 host.h_aliases = host_aliases;
613 host_aliases[0] = NULL; 604 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);
@@ -1085,10 +1076,10 @@ map_v4v6_address(src, dst)
1085} 1076}
1086 1077
1087static void 1078static void
1088map_v4v6_hostent(hp, bpp, lenp) 1079map_v4v6_hostent(hp, bpp, ep)
1089 struct hostent *hp; 1080 struct hostent *hp;
1090 char **bpp; 1081 char **bpp;
1091 int *lenp; 1082 char *ep;
1092{ 1083{
1093 char **ap; 1084 char **ap;
1094 1085
@@ -1099,17 +1090,15 @@ map_v4v6_hostent(hp, bpp, lenp)
1099 for (ap = hp->h_addr_list; *ap; ap++) { 1090 for (ap = hp->h_addr_list; *ap; ap++) {
1100 int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); 1091 int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
1101 1092
1102 if (*lenp < (i + IN6ADDRSZ)) { 1093 if (ep - *bpp < (i + IN6ADDRSZ)) {
1103 /* Out of memory. Truncate address list here. XXX */ 1094 /* Out of memory. Truncate address list here. XXX */
1104 *ap = NULL; 1095 *ap = NULL;
1105 return; 1096 return;
1106 } 1097 }
1107 *bpp += i; 1098 *bpp += i;
1108 *lenp -= i;
1109 map_v4v6_address(*ap, *bpp); 1099 map_v4v6_address(*ap, *bpp);
1110 *ap = *bpp; 1100 *ap = *bpp;
1111 *bpp += IN6ADDRSZ; 1101 *bpp += IN6ADDRSZ;
1112 *lenp -= IN6ADDRSZ;
1113 } 1102 }
1114} 1103}
1115 1104
diff --git a/src/lib/libc/net/getnetnamadr.c b/src/lib/libc/net/getnetnamadr.c
index 834ddf11ae..a5a4200acf 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.15 2002/02/16 21:27:23 millert Exp $ */ 1/* $OpenBSD: getnetnamadr.c,v 1.16 2002/06/26 06:00:54 itojun 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.15 2002/02/16 21:27:23 millert Exp $"; 80static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.16 2002/06/26 06:00:54 itojun 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
@@ -190,12 +190,13 @@ getnetanswer(answer, anslen, net_i)
190 cp += INT32SZ; /* TTL */ 190 cp += INT32SZ; /* TTL */
191 GETSHORT(n, cp); 191 GETSHORT(n, cp);
192 if (class == C_IN && type == T_PTR) { 192 if (class == C_IN && type == T_PTR) {
193 n = dn_expand(answer->buf, eom, cp, bp, buflen); 193 n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
194#ifdef USE_RESOLV_NAME_OK 194#ifdef USE_RESOLV_NAME_OK
195 if ((n < 0) || !res_hnok(bp)) { 195 if ((n < 0) || !res_hnok(bp))
196#else 196#else
197 if ((n < 0) || !_hokchar(bp)) { 197 if ((n < 0) || !_hokchar(bp))
198#endif 198#endif
199 {
199 cp += n; 200 cp += n;
200 return (NULL); 201 return (NULL);
201 } 202 }