Index: source/client/client.c =================================================================== --- source/client/client.c.orig +++ source/client/client.c @@ -3061,8 +3061,10 @@ static void readline_callback(void) again: - if (cli->fd == -1) + if (cli->fd < 0 || cli->fd >= FD_SETSIZE) { + errno = EBADF; return; + } FD_ZERO(&fds); FD_SET(cli->fd,&fds); Index: source/lib/readline.c =================================================================== --- source/lib/readline.c.orig +++ source/lib/readline.c @@ -66,6 +66,11 @@ static char *smb_readline_replacement(ch timeout.tv_sec = 5; timeout.tv_usec = 0; + if (fd < 0 || fd >= FD_SETSIZE) { + errno = EBADF; + break; + } + FD_ZERO(&fds); FD_SET(fd,&fds); Index: source/lib/select.c =================================================================== --- source/lib/select.c.orig +++ source/lib/select.c @@ -61,6 +61,11 @@ int sys_select(int maxfd, fd_set *readfd if (initialised != sys_getpid()) { pipe(select_pipe); + if (select_pipe[0] < 0 || select_pipe[0] >= FD_SETSIZE) { + errno = EBADF; + return -1; + } + /* * These next two lines seem to fix a bug with the Linux * 2.0.x kernel (and probably other UNIXes as well) where Index: source/lib/util_sock.c =================================================================== --- source/lib/util_sock.c.orig +++ source/lib/util_sock.c @@ -444,6 +444,12 @@ ssize_t read_socket_with_timeout(int fd, timeout.tv_usec = (long)(1000 * (time_out % 1000)); for (nread=0; nread < mincnt; ) { + if (fd < 0 || fd >= FD_SETSIZE) { + errno = EBADF; + smb_read_error = READ_ERROR; + return -1; + } + FD_ZERO(&fds); FD_SET(fd,&fds); @@ -945,7 +951,7 @@ BOOL open_any_socket_out(struct sockaddr for (i=0; i= FD_SETSIZE) goto done; set_blocking(sockets[i], False); } @@ -990,8 +996,10 @@ BOOL open_any_socket_out(struct sockaddr FD_ZERO(&r_fds); for (i=0; i= FD_SETSIZE) { + /* This cannot happen - ignore if so. */ continue; + } FD_SET(sockets[i], &wr_fds); FD_SET(sockets[i], &r_fds); if (sockets[i]>maxfd) @@ -1011,8 +1019,9 @@ BOOL open_any_socket_out(struct sockaddr for (i=0; i= FD_SETSIZE) { continue; + } /* Stevens, Network Programming says that if there's a * successful connect, the socket is only writable. Upon an Index: source/libsmb/nmblib.c =================================================================== --- source/libsmb/nmblib.c.orig +++ source/libsmb/nmblib.c @@ -1009,6 +1009,11 @@ struct packet_struct *receive_packet(int struct timeval timeout; int ret; + if (fd < 0 || fd >= FD_SETSIZE) { + errno = EBADF; + return NULL; + } + FD_ZERO(&fds); FD_SET(fd,&fds); timeout.tv_sec = t/1000; Index: source/nmbd/nmbd_packets.c =================================================================== --- source/nmbd/nmbd_packets.c.orig +++ source/nmbd/nmbd_packets.c @@ -1671,7 +1671,7 @@ static BOOL create_listen_fdset(fd_set * for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) count++; - if((count*2) + 2 > FD_SETSIZE) { + if((count*2) + 2 >= FD_SETSIZE) { DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \ only use %d.\n", (count*2) + 2, FD_SETSIZE)); return True; @@ -1685,24 +1685,44 @@ only use %d.\n", (count*2) + 2, FD_SETSI FD_ZERO(pset); /* Add in the broadcast socket on 137. */ + if (ClientNMB < 0 || ClientNMB >= FD_SETSIZE) { + errno = EBADF; + SAFE_FREE(pset); + return True; + } + FD_SET(ClientNMB,pset); sock_array[num++] = ClientNMB; *maxfd = MAX( *maxfd, ClientNMB); /* Add in the 137 sockets on all the interfaces. */ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { + if (subrec->nmb_sock < 0 || subrec->nmb_sock >= FD_SETSIZE) { + /* We have to ignore sockets outside FD_SETSIZE. */ + continue; + } FD_SET(subrec->nmb_sock,pset); sock_array[num++] = subrec->nmb_sock; *maxfd = MAX( *maxfd, subrec->nmb_sock); } /* Add in the broadcast socket on 138. */ + if (ClientDGRAM < 0 || ClientDGRAM >= FD_SETSIZE) { + errno = EBADF; + SAFE_FREE(pset); + return True; + } + FD_SET(ClientDGRAM,pset); sock_array[num++] = ClientDGRAM; *maxfd = MAX( *maxfd, ClientDGRAM); /* Add in the 138 sockets on all the interfaces. */ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { + if (subrec->dgram_sock < 0 || subrec->dgram_sock >= FD_SETSIZE) { + /* We have to ignore sockets outside FD_SETSIZE. */ + continue; + } FD_SET(subrec->dgram_sock,pset); sock_array[num++] = subrec->dgram_sock; *maxfd = MAX( *maxfd, subrec->dgram_sock); @@ -1751,7 +1771,7 @@ BOOL listen_for_packets(BOOL run_electio #ifndef SYNC_DNS dns_fd = asyncdns_fd(); - if (dns_fd != -1) { + if (dns_fd != -1 && dns_fd < FD_SETSIZE) { FD_SET(dns_fd, &fds); maxfd = MAX( maxfd, dns_fd); } Index: source/nsswitch/wb_common.c =================================================================== --- source/nsswitch/wb_common.c.orig +++ source/nsswitch/wb_common.c @@ -241,6 +241,12 @@ static int winbind_named_pipe_sock(const switch (errno) { case EINPROGRESS: + + if (fd < 0 || fd >= FD_SETSIZE) { + errno = EBADF; + goto error_out; + } + FD_ZERO(&w_fds); FD_SET(fd, &w_fds); tv.tv_sec = CONNECT_TIMEOUT - wait_time; @@ -358,7 +364,13 @@ int write_sock(void *buffer, int count, while(nwritten < count) { struct timeval tv; fd_set r_fds; - + + if (winbindd_fd < 0 || winbindd_fd >= FD_SETSIZE) { + errno = EBADF; + close_sock(); + return -1; + } + /* Catch pipe close on other end by checking if a read() call would not block by calling select(). */ @@ -410,6 +422,11 @@ static int read_sock(void *buffer, int c int result = 0, nread = 0; int total_time = 0, selret; + if (winbindd_fd < 0 || winbindd_fd >= FD_SETSIZE) { + errno = EBADF; + return -1; + } + /* Read data from socket */ while(nread < count) { struct timeval tv; Index: source/nsswitch/winbindd.c =================================================================== --- source/nsswitch/winbindd.c.orig +++ source/nsswitch/winbindd.c @@ -718,13 +718,17 @@ static void process_loop(void) listen_sock = open_winbindd_socket(); listen_priv_sock = open_winbindd_priv_socket(); - if (listen_sock == -1 || listen_priv_sock == -1) { + if (listen_sock < 0 || listen_sock >= FD_SETSIZE || + listen_priv_sock < 0 || listen_priv_sock >= FD_SETSIZE) { perror("open_winbind_socket"); exit(1); } maxfd = MAX(listen_sock, listen_priv_sock); + /* We check the range for listen_sock and + listen_priv_sock above. */ + FD_ZERO(&r_fds); FD_ZERO(&w_fds); FD_SET(listen_sock, &r_fds); @@ -751,6 +755,12 @@ static void process_loop(void) } for (ev = fd_events; ev; ev = ev->next) { + if (ev->fd < 0 || ev->fd >= FD_SETSIZE) { + /* Ignore here - event_add_to_select_args + should make this impossible. */ + continue; + } + if (ev->flags & EVENT_FD_READ) { FD_SET(ev->fd, &r_fds); maxfd = MAX(ev->fd, maxfd); Index: source/nsswitch/winbindd_dual.c =================================================================== --- source/nsswitch/winbindd_dual.c.orig +++ source/nsswitch/winbindd_dual.c @@ -420,6 +420,12 @@ static BOOL fork_domain_child(struct win return False; } + if (fdpair[0] < 0 || fdpair[0] >= FD_SETSIZE) { + DEBUG(0, ("fork_domain_child: bad fd range (%d)\n", fdpair[0])); + errno = EBADF; + return False; + } + ZERO_STRUCT(state); state.pid = getpid(); Index: source/smbd/oplock_irix.c =================================================================== --- source/smbd/oplock_irix.c.orig +++ source/smbd/oplock_irix.c @@ -268,6 +268,11 @@ struct kernel_oplocks *irix_init_kernel_ return False; } + if (pfd[0] < 0 || pfd[0] >= FD_SETSIZE) { + DEBUG(0,("setup_kernel_oplock_pipe: fd out of range.\n")); + return False; + } + oplock_pipe_read = pfd[0]; oplock_pipe_write = pfd[1]; Index: source/smbd/server.c =================================================================== --- source/smbd/server.c.orig +++ source/smbd/server.c @@ -129,7 +129,13 @@ static BOOL open_sockets_inetd(void) /* Started from inetd. fd 0 is the socket. */ /* We will abort gracefully when the client or remote system goes away */ - smbd_set_server_fd(dup(0)); + int fd = dup(0); + + if (fd < 0 || fd >= FD_SETSIZE) { + return false; + } + + smbd_set_server_fd(fd); /* close our standard file descriptors */ close_low_fds(False); /* Don't close stderr */ @@ -194,6 +200,7 @@ static BOOL open_sockets_smbd(BOOL is_da int maxfd = 0; int i; char *ports; + int fd; if (!is_daemon) { return open_sockets_inetd(); @@ -251,8 +258,9 @@ static BOOL open_sockets_smbd(BOOL is_da continue; } s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True); - if(s == -1) + if (s < 0 || s >= FD_SETSIZE) { return False; + } /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); @@ -291,8 +299,9 @@ static BOOL open_sockets_smbd(BOOL is_da /* open an incoming socket */ s = open_socket_in(SOCK_STREAM, port, 0, interpret_addr(lp_socket_address()),True); - if (s == -1) - return(False); + if (s < 0 || s >= FD_SETSIZE) { + return False; + } /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); @@ -383,17 +392,22 @@ static BOOL open_sockets_smbd(BOOL is_da } } - smbd_set_server_fd(accept(s,&addr,&in_addrlen)); - - if (smbd_server_fd() == -1 && errno == EINTR) + fd = accept(s,&addr,&in_addrlen); + if (fd == -1 && errno == EINTR) continue; - - if (smbd_server_fd() == -1) { + if (fd == -1) { DEBUG(0,("open_sockets_smbd: accept: %s\n", strerror(errno))); continue; } + if (fd < 0 || fd >= FD_SETSIZE) { + DEBUG(2,("open_sockets_smbd: bad fd %d\n", + fd )); + continue; + } + smbd_set_server_fd(fd); + /* Ensure child is set to blocking mode */ set_blocking(smbd_server_fd(),True); Index: source/utils/smbfilter.c =================================================================== --- source/utils/smbfilter.c.orig +++ source/utils/smbfilter.c @@ -133,8 +133,8 @@ static void filter_child(int c, struct i int num; FD_ZERO(&fds); - if (s != -1) FD_SET(s, &fds); - if (c != -1) FD_SET(c, &fds); + if (s >= 0 && s < FD_SETSIZE) FD_SET(s, &fds); + if (c >= 0 && c < FD_SETSIZE) FD_SET(c, &fds); num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL); if (num <= 0) continue; @@ -197,6 +197,10 @@ static void start_filter(char *desthost) struct sockaddr addr; socklen_t in_addrlen = sizeof(addr); + if (s < 0 || s >= FD_SETSIZE) { + break; + } + FD_ZERO(&fds); FD_SET(s, &fds);