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 <spronovo@microsoft.com>
Co-authored-by: Brenton DeGeer <brdegeer@microsoft.com>
Signed-off-by: Hideyuki Nagase <hideyukn@microsoft.com>
Signed-off-by: Steve Pronovost <spronovo@microsoft.com>
Signed-off-by: Brenton DeGeer <brdegeer@microsoft.com>
This commit is contained in:
Hideyuki Nagase 2022-03-15 16:40:15 -05:00 committed by Derek Foreman
parent 873ec15412
commit 13e62c9d18
2 changed files with 41 additions and 0 deletions

View File

@ -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,

View File

@ -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;