mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-16 14:56:00 +00:00
Fixed bug 2330 - Debian bug report: SDL2 X11 driver buffer overflow with large X11 file descriptor
manuel.montezelo Original bug report (note that it was against 2.0.0, it might have been fixed in between): http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=733015 -------------------------------------------------------- Package: libsdl2-2.0-0 Version: 2.0.0+dfsg1-3 Severity: normal Tags: patch I have occasional crashes here caused by the X11 backend of SDL2. It seems to be caused by the X11_Pending function trying to add a high number (> 1024) file descriptor to a fd_set before doing a select on it to avoid busy waiting on X11 events. This causes a buffer overflow because the file descriptor is larger (or equal) than the limit FD_SETSIZE. Attached is a possible workaround patch. Please also keep in mind that fd_set are also used in following files which may have similar problems. src/audio/bsd/SDL_bsdaudio.c src/audio/paudio/SDL_paudio.c src/audio/qsa/SDL_qsa_audio.c src/audio/sun/SDL_sunaudio.c src/joystick/linux/SDL_sysjoystick.c -------------------------------------------------------- On Tuesday 24 December 2013 00:43:13 Sven Eckelmann wrote: > I have occasional crashes here caused by the X11 backend of SDL2. It seems > to be caused by the X11_Pending function trying to add a high number (> > 1024) file descriptor to a fd_set before doing a select on it to avoid busy > waiting on X11 events. This causes a buffer overflow because the file > descriptor is larger (or equal) than the limit FD_SETSIZE. I personally experienced this problem while hacking on the python bindings package for SDL2 [1] (while doing make runtest). But it easier to reproduce in a smaller, synthetic testcase.
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_assert.h"
|
||||
#include "../../core/unix/SDL_poll.h"
|
||||
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylanddatamanager.h"
|
||||
@@ -46,16 +47,8 @@ write_pipe(int fd, const void* buffer, size_t total_length, size_t *pos)
|
||||
sigset_t sig_set;
|
||||
sigset_t old_sig_set;
|
||||
struct timespec zerotime = {0};
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(fd, &set);
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
ready = select(fd + 1, NULL, &set, NULL, &timeout);
|
||||
ready = SDL_IOReady(fd, SDL_TRUE, 1 * 1000);
|
||||
|
||||
sigemptyset(&sig_set);
|
||||
sigaddset(&sig_set, SIGPIPE);
|
||||
@@ -92,16 +85,7 @@ read_pipe(int fd, void** buffer, size_t* total_length, SDL_bool null_terminate)
|
||||
ssize_t bytes_read = 0;
|
||||
size_t pos = 0;
|
||||
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(fd, &set);
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
ready = select(fd + 1, &set, NULL, NULL, &timeout);
|
||||
ready = SDL_IOReady(fd, SDL_FALSE, 1 * 1000);
|
||||
|
||||
if (ready == 0) {
|
||||
bytes_read = SDL_SetError("Pipe timeout");
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_log.h"
|
||||
|
||||
#include "../../core/unix/SDL_poll.h"
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/scancodes_xfree86.h"
|
||||
@@ -74,16 +75,14 @@ void
|
||||
Wayland_PumpEvents(_THIS)
|
||||
{
|
||||
SDL_VideoData *d = _this->driverdata;
|
||||
struct pollfd pfd[1];
|
||||
|
||||
pfd[0].fd = WAYLAND_wl_display_get_fd(d->display);
|
||||
pfd[0].events = POLLIN;
|
||||
poll(pfd, 1, 0);
|
||||
|
||||
if (pfd[0].revents & POLLIN)
|
||||
if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_FALSE, 0)) {
|
||||
WAYLAND_wl_display_dispatch(d->display);
|
||||
}
|
||||
else
|
||||
{
|
||||
WAYLAND_wl_display_dispatch_pending(d->display);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "SDL_x11video.h"
|
||||
#include "SDL_x11touch.h"
|
||||
#include "SDL_x11xinput2.h"
|
||||
#include "../../core/unix/SDL_poll.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../events/SDL_touch_c.h"
|
||||
@@ -1409,17 +1410,8 @@ 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;
|
||||
|
||||
x11_fd = ConnectionNumber(display);
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(x11_fd, &fdset);
|
||||
if (select(x11_fd + 1, &fdset, NULL, NULL, &zero_time) == 1) {
|
||||
return (X11_XPending(display));
|
||||
}
|
||||
if (SDL_IOReady(ConnectionNumber(display), SDL_FALSE, 0)) {
|
||||
return (X11_XPending(display));
|
||||
}
|
||||
|
||||
/* Oh well, nothing is ready .. */
|
||||
|
Reference in New Issue
Block a user