Skip to content

Commit b4b9706

Browse files
author
kalibera
committed
Report error when file descriptor number is too large for select (PR#18634).
git-svn-id: https://svn.r-project.org/R/trunk@85687 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 01dd63b commit b4b9706

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

src/library/parallel/src/fork.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* R : A Computer Language for Statistical Data Analysis
33
* (C) Copyright 2008-2011 Simon Urbanek
4-
* Copyright 2011-2022 R Core Team.
4+
* Copyright 2011-2023 R Core Team.
55
*
66
* This program is free software; you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by
@@ -816,6 +816,8 @@ SEXP mc_send_child_stdin(SEXP sPid, SEXP what)
816816
void fdcopy(fd_set *dst, fd_set *src, int nfds)
817817
{
818818
FD_ZERO(dst);
819+
if (nfds > FD_SETSIZE)
820+
error("file descriptor is too large for select()");
819821
for(int i = 0; i < nfds; i++)
820822
if (FD_ISSET(i, src)) FD_SET(i, dst);
821823
}
@@ -847,7 +849,7 @@ SEXP mc_select_children(SEXP sTimeout, SEXP sWhich)
847849
unsigned int k = 0;
848850
while (k < wlen) {
849851
if (which[k++] == ci->pid) {
850-
if (ci->pfd > FD_SETSIZE)
852+
if (ci->pfd >= FD_SETSIZE)
851853
error("file descriptor is too large for select()");
852854
FD_SET(ci->pfd, &fs);
853855
if (ci->pfd > maxfd) maxfd = ci->pfd;
@@ -860,7 +862,7 @@ SEXP mc_select_children(SEXP sTimeout, SEXP sWhich)
860862
}
861863
} else {
862864
/* not sure if this should be allowed */
863-
if (ci->pfd > FD_SETSIZE)
865+
if (ci->pfd >= FD_SETSIZE)
864866
error("file descriptor is too large for select()");
865867
FD_SET(ci->pfd, &fs);
866868
if (ci->pfd > maxfd) maxfd = ci->pfd;
@@ -1061,7 +1063,11 @@ SEXP mc_read_children(SEXP sTimeout)
10611063
while (ci) {
10621064
if (!ci->detached && ci->ppid == ppid) {
10631065
if (ci->pfd > maxfd) maxfd = ci->pfd;
1064-
if (ci->pfd >= 0) FD_SET(ci->pfd, &fs);
1066+
if (ci->pfd >= 0) {
1067+
if (ci->pfd >= FD_SETSIZE)
1068+
error("file descriptor is too large for select()");
1069+
FD_SET(ci->pfd, &fs);
1070+
}
10651071
}
10661072
ci = ci -> next;
10671073
}

src/unix/sys-std.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ int R_SelectEx(int n, fd_set *readfds, fd_set *writefds,
120120
platforms. If this still turns out to be limiting we will
121121
probably need to rewrite internals to use poll() instead of
122122
select(). LT */
123-
if (n > FD_SETSIZE)
123+
if (n >= FD_SETSIZE)
124124
error("file descriptor is too large for select()");
125125

126126
if (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)
@@ -229,6 +229,8 @@ addInputHandler(InputHandler *handlers, int fd, InputHandlerProc handler,
229229
input = R_Calloc(1, InputHandler);
230230

231231
input->activity = activity;
232+
if (fd >= FD_SETSIZE)
233+
error("file descriptor is too large for select()");
232234
input->fileDescriptor = fd;
233235
input->handler = handler;
234236

@@ -382,8 +384,11 @@ setSelectMask(InputHandler *handlers, fd_set *readMask)
382384
FD_ZERO(readMask);
383385

384386
/* If we are dealing with BasicInputHandler always put stdin */
385-
if(handlers == &BasicInputHandler)
387+
if(handlers == &BasicInputHandler) {
386388
handlers->fileDescriptor = fileno(stdin);
389+
if (handlers->fileDescriptor >= FD_SETSIZE)
390+
error("file descriptor is too large for select()");
391+
}
387392

388393
while(tmp) {
389394
FD_SET(tmp->fileDescriptor, readMask);

0 commit comments

Comments
 (0)