From 13e62c9d18b7850dfa4e7a15f1dcb02c7d99ee07 Mon Sep 17 00:00:00 2001 From: Hideyuki Nagase Date: Tue, 15 Mar 2022 16:40:15 -0500 Subject: [PATCH] rdp: validate button state Discard and log duplicate release or press events. Log and discard invalid button ids. This prevents buggy clients from causing problems in weston's internal state - like breaking idle inhibition button counting. Co-authored-by: Steve Pronovost Co-authored-by: Brenton DeGeer Signed-off-by: Hideyuki Nagase Signed-off-by: Steve Pronovost Signed-off-by: Brenton DeGeer --- libweston/backend-rdp/rdp.c | 39 +++++++++++++++++++++++++++++++++++++ libweston/backend-rdp/rdp.h | 2 ++ 2 files changed, 41 insertions(+) diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 9f1ccdb5..a7fb59c3 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -979,6 +979,33 @@ dump_mouseinput(RdpPeerContext *peerContext, UINT16 flags, UINT16 x, UINT16 y, b rdp_debug_verbose_continue(b, "\n"); } +static void +rdp_validate_button_state(RdpPeerContext *peerContext, bool pressed, uint32_t *button) +{ + struct rdp_backend *b = peerContext->rdpBackend; + uint32_t index; + + if (*button < BTN_LEFT || *button > BTN_EXTRA) { + weston_log("RDP client posted invalid button event\n"); + goto ignore; + } + + index = *button - BTN_LEFT; + assert(index < ARRAY_LENGTH(peerContext->button_state)); + + if (pressed == peerContext->button_state[index]) { + rdp_debug_verbose(b, "%s: inconsistent button state button:%d (index:%d) pressed:%d\n", + __func__, *button, index, pressed); + goto ignore; + } else { + peerContext->button_state[index] = pressed; + } + return; +ignore: + /* ignore button input */ + *button = 0; +} + static BOOL xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) { @@ -1007,6 +1034,12 @@ xf_mouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) else if (flags & PTR_FLAGS_BUTTON3) button = BTN_MIDDLE; + if (button) { + rdp_validate_button_state(peerContext, + flags & PTR_FLAGS_DOWN ? true : false, + &button); + } + if (button) { weston_compositor_get_time(&time); notify_button(peerContext->item.seat, &time, button, @@ -1062,6 +1095,12 @@ xf_extendedMouseEvent(rdpInput *input, UINT16 flags, UINT16 x, UINT16 y) else if (flags & PTR_XFLAGS_BUTTON2) button = BTN_EXTRA; + if (button) { + rdp_validate_button_state(peerContext, + flags & PTR_XFLAGS_DOWN ? true : false, + &button); + } + if (button) { weston_compositor_get_time(&time); notify_button(peerContext->item.seat, &time, button, diff --git a/libweston/backend-rdp/rdp.h b/libweston/backend-rdp/rdp.h index 2ebf50f6..31e56d96 100644 --- a/libweston/backend-rdp/rdp.h +++ b/libweston/backend-rdp/rdp.h @@ -109,6 +109,8 @@ struct rdp_peer_context { NSC_CONTEXT *nsc_context; struct rdp_peers_item item; + + bool button_state[5]; }; typedef struct rdp_peer_context RdpPeerContext;