From 9c50fd8bbda861fd23cb7d132d8b7f8b493cc0ac Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 29 Dec 2013 19:50:43 +0100 Subject: [PATCH] Replace select() for X11 messages with poll() in X11_Pending ConnectionNumber in X11_Pending may return a value outside of the range [0, FD_SETSIZE). This value cannot be stored inside a fd_set and will crash the program. This buffer overflow problem occasionally happens when a lot of file descriptors are used. The poll system call can be used instead. It doesn't use a fixed size bit-array to store the file descriptors to wait for and instead depends on an array of descriptors + requested events. This allows file descriptors up to INT_MAX and automatically handles invalid (negative) file descriptors. diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 818ab2e..904632a 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -27,6 +27,7 @@ #include #include #include /* For INT_MAX */ +#include #include "SDL_x11video.h" #include "SDL_x11video.h" @@ -912,14 +913,11 @@ X11_Pending(Display * display) /* More drastic measures are required -- see if X is ready to talk */ { - static struct timeval zero_time; /* static == 0 */ - int x11_fd; - fd_set fdset; + struct pollfd x11poll; - x11_fd = ConnectionNumber(display); - FD_ZERO(&fdset); - FD_SET(x11_fd, &fdset); - if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1) { + x11poll.fd = ConnectionNumber(display); + x11poll.events = POLLIN | POLLPRI; + if (poll(&x11poll, 1, 0) == 1) { return (XPending(display)); } } -- 1.8.5.2