diff options
author | Gatis Paeglis <gatis.paeglis@qt.io> | 2017-03-01 14:29:25 +0100 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@qt.io> | 2017-03-08 12:39:01 +0000 |
commit | b4fc5b71e907163e075ff39cab5297c9b9bafd0d (patch) | |
tree | 65c230ae52475beaa6e92d51739eb862ce8aa84b | |
parent | 6891d2377993f189863688271fc7db0a06e2dc69 (diff) |
xcb: fix misuse of xcb_send_event
This fixes the following Valgrind warning:
"Syscall param writev(vector[...]) points to uninitialised byte(s)
Uninitialised value was created by a stack allocation"
The xcb_send_event() requires all events to have 32 bytes.
It calls memcpy() on the passed in event. If the passed in
event is less than 32 bytes, memcpy() reaches into unrelated
memory. And as it turns out, this behavior is actually
described in the xcb_send_event function's documentation.
This patch adds a macro that declares an event for safe
usage with xcb_send_event.
The cherry picked change contains one minor adjustment to
support older compilers:
q_padded_xcb_event<event_type> store = {};
was replaced with:
q_padded_xcb_event<event_type> store = q_padded_xcb_event<event_type>();
Change-Id: Id0cfc2b1ae9e105e8b4328fdaba03300cb718840
Done-with: Uli Schlachter
Task-number: QTBUG-56518
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
(cherry picked from commit 1a5deb7e0ea9a129d4ebc59677893c7477ad5a3a)
-rw-r--r-- | src/plugins/platforms/xcb/qxcbclipboard.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 13 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 2 |
4 files changed, 16 insertions, 3 deletions
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 40abef4e50..0291ef0580 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -601,7 +601,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req) return; } - xcb_selection_notify_event_t event; + Q_DECLARE_XCB_EVENT(event, xcb_selection_notify_event_t); event.response_type = XCB_SELECTION_NOTIFY; event.requestor = req->requestor; event.selection = req->selection; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index e7c3722c2e..6668393c44 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -705,6 +705,19 @@ private: QXcbConnection *m_connection; }; +template <typename T> +union q_padded_xcb_event { + T event; + char padding[32]; +}; + +// The xcb_send_event() requires all events to have 32 bytes. It calls memcpy() on the +// passed in event. If the passed in event is less than 32 bytes, memcpy() reaches into +// unrelated memory. +#define Q_DECLARE_XCB_EVENT(event_var, event_type) \ + q_padded_xcb_event<event_type> store = q_padded_xcb_event<event_type>(); \ + auto &event_var = store.event; + #ifdef Q_XCB_DEBUG template <typename cookie_t> cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index acfb580b94..b3aac6960b 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1126,7 +1126,7 @@ static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window) void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event) { - xcb_selection_notify_event_t notify; + Q_DECLARE_XCB_EVENT(notify, xcb_selection_notify_event_t); notify.response_type = XCB_SELECTION_NOTIFY; notify.requestor = event->requestor; notify.selection = event->selection; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 25a8b41195..b30bf5d502 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -879,7 +879,7 @@ void QXcbWindow::hide() Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window)); // send synthetic UnmapNotify event according to icccm 4.1.4 - xcb_unmap_notify_event_t event; + Q_DECLARE_XCB_EVENT(event, xcb_unmap_notify_event_t); event.response_type = XCB_UNMAP_NOTIFY; event.event = xcbScreen()->root(); event.window = m_window; |