summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-02-07 23:28:01 +0000
committerpeter <peter@FreeBSD.org>2001-02-07 23:28:01 +0000
commitc1207542eefdfb96c8a733127ca5fae827a5263e (patch)
treea6b96e709e4f8d480b111ea264d9e8119675b6a1 /sys
parent6ab203b6cab304a5b453d5363ebd316e0c2ead06 (diff)
downloadFreeBSD-src-c1207542eefdfb96c8a733127ca5fae827a5263e.zip
FreeBSD-src-c1207542eefdfb96c8a733127ca5fae827a5263e.tar.gz
The code I picked up from NetBSD in '97 had a nasty bug. It limited
the index of the pollfd array to the number of fd's currently open, not the maximum number of fd's. ie: if you had 0,1,2 open, you could not use pollfd slots higher than 20. The specs say we only have to support OPEN_MAX [64] entries but we allow way more than that.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_generic.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index b6c2bfc..4b2c5d8 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -55,6 +55,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/poll.h>
+#include <sys/resourcevar.h>
#include <sys/selinfo.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
@@ -857,14 +858,21 @@ poll(p, uap)
caddr_t bits;
char smallbits[32 * sizeof(struct pollfd)];
struct timeval atv, rtv, ttv;
- int s, ncoll, error = 0, timo;
+ int s, ncoll, error = 0, timo, lim, nfds;
size_t ni;
- if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) {
- /* forgiving; slightly wrong */
- SCARG(uap, nfds) = p->p_fd->fd_nfiles;
- }
- ni = SCARG(uap, nfds) * sizeof(struct pollfd);
+ nfds = SCARG(uap, nfds);
+ /*
+ * This is kinda bogus. We have fd limits, but that doesn't
+ * map too well to the size of the pfd[] array. Make sure
+ * we let the process use at least FD_SETSIZE entries.
+ * The specs say we only have to support OPEN_MAX entries (64).
+ */
+ lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
+ lim = min(lim, FD_SETSIZE);
+ if (nfds > lim)
+ return (EINVAL);
+ ni = nfds * sizeof(struct pollfd);
if (ni > sizeof(smallbits))
bits = malloc(ni, M_TEMP, M_WAITOK);
else
@@ -891,7 +899,7 @@ retry:
ncoll = nselcoll;
p->p_flag |= P_SELECT;
PROC_UNLOCK(p);
- error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds));
+ error = pollscan(p, (struct pollfd *)bits, nfds);
PROC_LOCK(p);
if (error || p->p_retval[0])
goto done;
OpenPOWER on IntegriCloud