Commit 8bd7197a authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Primarily this fixes an off-by-one buffer overwrite (rare but still existing).

I also switched from calloc() to malloc() as a minor performance boost since
the rest of the code fills in the structs fine anyway - and they must for the
case when we use the stack-based auto variable array instead of the allocated
one.

I made the loop filling in poll_fds[] break when poll_nfds is reached as a
minor speed improvement.
parent ebb5e1db
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -573,7 +573,7 @@ int Curl_select(int nfds,
  else if (poll_nfds <= SMALL_POLLNFDS)
    poll_fds = small_fds;
  else {
    poll_fds = calloc((size_t)poll_nfds, sizeof(struct pollfd));
    poll_fds = malloc(poll_nfds * sizeof(struct pollfd));
    if (!poll_fds) {
      SET_SOCKERRNO(ENOBUFS);
      return -1;
@@ -581,20 +581,27 @@ int Curl_select(int nfds,
  }

  if (poll_fds) {
    int events;
    ix = 0;
    fd = nfds;
    while (fd--) {
      poll_fds[ix].events = 0;
      events = 0;
      if (fds_read && (0 != FD_ISSET(fd, fds_read)))
        poll_fds[ix].events |= (POLLRDNORM|POLLIN);
        events |= (POLLRDNORM|POLLIN);
      if (fds_write && (0 != FD_ISSET(fd, fds_write)))
        poll_fds[ix].events |= (POLLWRNORM|POLLOUT);
        events |= (POLLWRNORM|POLLOUT);
      if (fds_excep && (0 != FD_ISSET(fd, fds_excep)))
        poll_fds[ix].events |= (POLLRDBAND|POLLPRI);
      if (poll_fds[ix].events) {
        events |= (POLLRDBAND|POLLPRI);
      if (events) {
        poll_fds[ix].events = events;
        poll_fds[ix].fd = fd;
        poll_fds[ix].revents = 0;
        ix++;
        if(ix == poll_nfds)
          /* since we know this is the total amount of descriptors with
             interesting actions, we can skip the rest of the loop at this
             point */
          break;
      }
    }
  }