diff options
author | millert <> | 2002-06-26 06:03:31 +0000 |
---|---|---|
committer | millert <> | 2002-06-26 06:03:31 +0000 |
commit | b88d7a5cb2b7d6387d1028751a707f2097b0269c (patch) | |
tree | e7eda0368471d0c1dc979139a81e28a49589c79d /src/lib/libc/net | |
parent | 62efc4ddcbdcc8c9f4f29b7b5ae76aa66f0b96e2 (diff) | |
download | openbsd-b88d7a5cb2b7d6387d1028751a707f2097b0269c.tar.gz openbsd-b88d7a5cb2b7d6387d1028751a707f2097b0269c.tar.bz2 openbsd-b88d7a5cb2b7d6387d1028751a707f2097b0269c.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. From: itojun
this fix is critical.
Diffstat (limited to 'src/lib/libc/net')
-rw-r--r-- | src/lib/libc/net/gethostnamadr.c | 57 | ||||
-rw-r--r-- | src/lib/libc/net/getnetnamadr.c | 19 |
2 files changed, 33 insertions, 43 deletions
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c index d7d6c621cf..cb6e00d31a 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) |
55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.43 2001/06/27 00:58:55 lebel Exp $"; | 55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.43.2.1 2002/06/26 06:03:31 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; | |||
99 | static int stayopen = 0; | 99 | static int stayopen = 0; |
100 | 100 | ||
101 | static void map_v4v6_address __P((const char *src, char *dst)); | 101 | static void map_v4v6_address __P((const char *src, char *dst)); |
102 | static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len)); | 102 | static void map_v4v6_hostent __P((struct hostent *hp, char **bp, char *)); |
103 | 103 | ||
104 | #ifdef RESOLVSORT | 104 | #ifdef RESOLVSORT |
105 | static void addrsort __P((char **, int)); | 105 | static 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]; |
@@ -576,7 +567,7 @@ gethostbyname2(name, af) | |||
576 | } | 567 | } |
577 | strlcpy(hostbuf, name, MAXHOSTNAMELEN); | 568 | strlcpy(hostbuf, name, MAXHOSTNAMELEN); |
578 | bp = hostbuf + MAXHOSTNAMELEN; | 569 | bp = hostbuf + MAXHOSTNAMELEN; |
579 | len = sizeof hostbuf - MAXHOSTNAMELEN; | 570 | ep = hostbuf + sizeof(hostbuf); |
580 | host.h_name = hostbuf; | 571 | host.h_name = hostbuf; |
581 | host.h_aliases = host_aliases; | 572 | host.h_aliases = host_aliases; |
582 | host_aliases[0] = NULL; | 573 | host_aliases[0] = NULL; |
@@ -584,7 +575,7 @@ gethostbyname2(name, af) | |||
584 | h_addr_ptrs[1] = NULL; | 575 | h_addr_ptrs[1] = NULL; |
585 | host.h_addr_list = h_addr_ptrs; | 576 | host.h_addr_list = h_addr_ptrs; |
586 | if (_res.options & RES_USE_INET6) | 577 | if (_res.options & RES_USE_INET6) |
587 | map_v4v6_hostent(&host, &bp, &len); | 578 | map_v4v6_hostent(&host, &bp, ep); |
588 | h_errno = NETDB_SUCCESS; | 579 | h_errno = NETDB_SUCCESS; |
589 | return (&host); | 580 | return (&host); |
590 | } | 581 | } |
@@ -608,7 +599,7 @@ gethostbyname2(name, af) | |||
608 | } | 599 | } |
609 | strlcpy(hostbuf, name, MAXHOSTNAMELEN); | 600 | strlcpy(hostbuf, name, MAXHOSTNAMELEN); |
610 | bp = hostbuf + MAXHOSTNAMELEN; | 601 | bp = hostbuf + MAXHOSTNAMELEN; |
611 | len = sizeof hostbuf - MAXHOSTNAMELEN; | 602 | ep = hostbuf + sizeof(hostbuf); |
612 | host.h_name = hostbuf; | 603 | host.h_name = hostbuf; |
613 | host.h_aliases = host_aliases; | 604 | host.h_aliases = host_aliases; |
614 | host_aliases[0] = NULL; | 605 | host_aliases[0] = NULL; |
@@ -867,9 +858,9 @@ _gethtent() | |||
867 | *q = NULL; | 858 | *q = NULL; |
868 | if (_res.options & RES_USE_INET6) { | 859 | if (_res.options & RES_USE_INET6) { |
869 | char *bp = hostbuf; | 860 | char *bp = hostbuf; |
870 | int buflen = sizeof hostbuf; | 861 | char *ep = hostbuf + sizeof hostbuf; |
871 | 862 | ||
872 | map_v4v6_hostent(&host, &bp, &buflen); | 863 | map_v4v6_hostent(&host, &bp, ep); |
873 | } | 864 | } |
874 | h_errno = NETDB_SUCCESS; | 865 | h_errno = NETDB_SUCCESS; |
875 | return (&host); | 866 | return (&host); |
@@ -1085,10 +1076,10 @@ map_v4v6_address(src, dst) | |||
1085 | } | 1076 | } |
1086 | 1077 | ||
1087 | static void | 1078 | static void |
1088 | map_v4v6_hostent(hp, bpp, lenp) | 1079 | map_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 f755cd9b14..685434791a 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.14 2001/06/27 00:58:55 lebel Exp $ */ | 1 | /* $OpenBSD: getnetnamadr.c,v 1.14.2.1 2002/06/26 06:03:31 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"; | |||
77 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; | 77 | static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; |
78 | static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; | 78 | static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $"; |
79 | #else | 79 | #else |
80 | static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.14 2001/06/27 00:58:55 lebel Exp $"; | 80 | static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.14.2.1 2002/06/26 06:03:31 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 |
@@ -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 | } |