Commit b3e70318 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

platforms/drm: Fix potential stack corruption

If the file descriptor of the DRM device is greater than FD_SETSIZE, the
stack will be corrupted. However, it is highly unlikely that we ever hit
this case because DRM devices are opened at startup of kwin, so the file
descriptors should small.

In order to prevent the potential stack corruption, this change replaces
the usage of select() with poll().

Unlike select(), the api of poll() is much more sensible. Back 20 or so
years ago the main argument against poll() was that it's not implemented
by all platforms. But, nowadays, it's supported on all major platforms.
parent fd68cf3f
......@@ -25,6 +25,7 @@
// system
#include <algorithm>
#include <errno.h>
#include <poll.h>
#include <unistd.h>
// drm
#include <xf86drm.h>
......@@ -339,21 +340,21 @@ void DrmGpu::waitIdle()
if (idle) {
break;
}
fd_set set;
FD_ZERO(&set);
FD_SET(m_fd, &set);
timeval timeout;
timeout.tv_sec = 30;
timeout.tv_usec = 0;
const int descriptorCount = select(m_fd + 1, &set, nullptr, nullptr, &timeout);
if (descriptorCount < 0) {
qCWarning(KWIN_DRM) << "select() in DrmGpu::waitIdle failed:" << strerror(errno);
break;
} else if (FD_ISSET(m_fd, &set)) {
dispatchEvents();
} else {
pollfd pfds[1];
pfds[0].fd = m_fd;
pfds[0].events = POLLIN;
const int ready = poll(pfds, 1, 30000);
if (ready < 0) {
if (errno != EINTR) {
qCWarning(KWIN_DRM) << Q_FUNC_INFO << "poll() failed:" << strerror(errno);
break;
}
} else if (ready == 0) {
qCWarning(KWIN_DRM) << "No drm events for gpu" << m_devNode << "within last 30 seconds";
break;
} else {
dispatchEvents();
}
};
m_socketNotifier->setEnabled(true);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment