diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2001-01-16 05:01:41 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2001-01-16 05:01:41 +0000 |
commit | cb480112931ae5581d91fe7867b033a7f39384f3 (patch) | |
tree | 4c27836ade8122742364a7bb42ecd31a69a69ad7 /usr.sbin | |
parent | 16c719bebc6ea3163d9ddf789b350b1a6cac9083 (diff) |
fix fd_set overflows
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/pppoe/client.c | 42 | ||||
-rw-r--r-- | usr.sbin/pppoe/server.c | 50 |
2 files changed, 59 insertions, 33 deletions
diff --git a/usr.sbin/pppoe/client.c b/usr.sbin/pppoe/client.c index 65f123ce18a..8ccd2d01f7f 100644 --- a/usr.sbin/pppoe/client.c +++ b/usr.sbin/pppoe/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.6 2001/01/12 06:12:54 jason Exp $ */ +/* $OpenBSD: client.c,v 1.7 2001/01/16 05:01:39 jason Exp $ */ /* * Copyright (c) 2000 Network Security Technologies, Inc. http://www.netsec.net @@ -97,8 +97,8 @@ client_mode(bfd, sysname, srvname, myea) struct ether_addr *myea; { struct ether_addr rmea; - fd_set fds; - int r = 0, max; + fd_set *fdsp = NULL; + int r = 0, max, oldmax = 0; pppfd = -1; client_sessionid = 0xffff; @@ -107,17 +107,29 @@ client_mode(bfd, sysname, srvname, myea) if (r <= 0) return (r); - FD_ZERO(&fds); for (;;) { - FD_SET(bfd, &fds); - max = bfd + 1; - if (pppfd >= 0) { - if (pppfd >= max) - max = pppfd + 1; - FD_SET(pppfd, &fds); + max = bfd; + if (pppfd >= 0 && pppfd >= max) + max = pppfd; + max++; + + if (max > oldmax) { + if (fdsp != NULL) + free(fdsp); + fdsp = (fd_set *)calloc(howmany(max, NFDBITS), + sizeof(fd_mask)); + if (fdsp == NULL) { + r = -1; + break; + } + max = oldmax; } - r = select(max, &fds, NULL, NULL, NULL); + if (pppfd >= 0) + FD_SET(pppfd, fdsp); + FD_SET(bfd, fdsp); + + r = select(max, fdsp, NULL, NULL, NULL); if (r < 0) { if (errno == EINTR) { if (timer_hit()) @@ -126,12 +138,12 @@ client_mode(bfd, sysname, srvname, myea) } break; } - if (FD_ISSET(bfd, &fds)) { + if (FD_ISSET(bfd, fdsp)) { r = getpackets(bfd, srvname, sysname, myea, &rmea); if (r <= 0) break; } - if (pppfd >= 0 && FD_ISSET(pppfd, &fds)) { + if (pppfd >= 0 && FD_ISSET(pppfd, fdsp)) { r = ppp_to_bpf(bfd, pppfd, myea, &rmea, client_sessionid); if (r < 0) @@ -143,6 +155,10 @@ client_mode(bfd, sysname, srvname, myea) send_padt(bfd, myea, &rmea, client_sessionid); pppfd = -1; } + + if (fdsp != NULL) + free(fdsp); + return (r); } diff --git a/usr.sbin/pppoe/server.c b/usr.sbin/pppoe/server.c index d8e478aa6e5..14aba8cc7da 100644 --- a/usr.sbin/pppoe/server.c +++ b/usr.sbin/pppoe/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.2 2000/06/20 04:53:32 jason Exp $ */ +/* $OpenBSD: server.c,v 1.3 2001/01/16 05:01:40 jason Exp $ */ /* * Copyright (c) 2000 Network Security Technologies, Inc. http://www.netsec.net @@ -86,45 +86,53 @@ server_mode(bpffd, sysname, srvname, ea) struct ether_addr *ea; { struct pppoe_session *ses; - fd_set rfds; - int n; + fd_set *fdsp = NULL; + int n, oldmax = 0; key_gen(); while (1) { reselect: - FD_ZERO(&rfds); - FD_SET(bpffd, &rfds); n = bpffd; - ses = LIST_FIRST(&session_master.sm_sessions); - while (ses) { - if (ses->s_fd != -1) { - FD_SET(ses->s_fd, &rfds); - if (ses->s_fd > n) - n = ses->s_fd; - } - ses = LIST_NEXT(ses, s_next); + LIST_FOREACH(ses, &session_master.sm_sessions, s_next) { + if (ses->s_fd != -1 && ses->s_fd > n) + n = ses->s_fd; + } + n++; + + if (n > oldmax) { + if (fdsp != NULL) + free(fdsp); + fdsp = (fd_set *)calloc(howmany(n, NFDBITS), + sizeof(fd_mask)); + if (fdsp == NULL) + break; + oldmax = n; + } + FD_SET(bpffd, fdsp); + LIST_FOREACH(ses, &session_master.sm_sessions, s_next) { + if (ses->s_fd != -1) + FD_SET(ses->s_fd, fdsp); } - n = select(n+1, &rfds, NULL, NULL, NULL); + n = select(n, fdsp, NULL, NULL, NULL); if (n < 0) { if (errno == EINTR) goto reselect; err(EX_IOERR, "select"); - return; + break; } if (n == 0) continue; - if (FD_ISSET(bpffd, &rfds)) { + if (FD_ISSET(bpffd, fdsp)) { n--; getpackets(bpffd, sysname, ea); } if (n == 0) continue; - ses = LIST_FIRST(&session_master.sm_sessions); - while (ses) { - if (ses->s_fd != -1 && FD_ISSET(ses->s_fd, &rfds)) { + LIST_FOREACH(ses, &session_master.sm_sessions, s_next) { + if (ses->s_fd != -1 && FD_ISSET(ses->s_fd, fdsp)) { if (ppp_to_bpf(bpffd, ses->s_fd, ea, &ses->s_ea, ses->s_id) < 0) { send_padt(bpffd, ea, @@ -135,9 +143,11 @@ reselect: if (n == 0) break; } - ses = LIST_NEXT(ses, s_next); } } + + if (fdsp != NULL) + free(fdsp); } void |