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.
This commit is contained in:
parent
fd68cf3ff4
commit
b3e7031893
1 changed files with 14 additions and 13 deletions
|
@ -25,6 +25,7 @@
|
||||||
// system
|
// system
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
// drm
|
// drm
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
@ -339,21 +340,21 @@ void DrmGpu::waitIdle()
|
||||||
if (idle) {
|
if (idle) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd_set set;
|
pollfd pfds[1];
|
||||||
FD_ZERO(&set);
|
pfds[0].fd = m_fd;
|
||||||
FD_SET(m_fd, &set);
|
pfds[0].events = POLLIN;
|
||||||
timeval timeout;
|
|
||||||
timeout.tv_sec = 30;
|
const int ready = poll(pfds, 1, 30000);
|
||||||
timeout.tv_usec = 0;
|
if (ready < 0) {
|
||||||
const int descriptorCount = select(m_fd + 1, &set, nullptr, nullptr, &timeout);
|
if (errno != EINTR) {
|
||||||
if (descriptorCount < 0) {
|
qCWarning(KWIN_DRM) << Q_FUNC_INFO << "poll() failed:" << strerror(errno);
|
||||||
qCWarning(KWIN_DRM) << "select() in DrmGpu::waitIdle failed:" << strerror(errno);
|
break;
|
||||||
break;
|
}
|
||||||
} else if (FD_ISSET(m_fd, &set)) {
|
} else if (ready == 0) {
|
||||||
dispatchEvents();
|
|
||||||
} else {
|
|
||||||
qCWarning(KWIN_DRM) << "No drm events for gpu" << m_devNode << "within last 30 seconds";
|
qCWarning(KWIN_DRM) << "No drm events for gpu" << m_devNode << "within last 30 seconds";
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
dispatchEvents();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
m_socketNotifier->setEnabled(true);
|
m_socketNotifier->setEnabled(true);
|
||||||
|
|
Loading…
Reference in a new issue