From 36a27b8a902331e0dde510f793b22ff84e5b0998 Mon Sep 17 00:00:00 2001 From: Luciano Iam Date: Thu, 16 Apr 2020 14:35:21 +0200 Subject: [PATCH] WebSockets: prevent crashes by validating inbound message addr and val sizes --- libs/surfaces/websockets/dispatcher.cc | 72 +++++++++++++++++++------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/libs/surfaces/websockets/dispatcher.cc b/libs/surfaces/websockets/dispatcher.cc index 62f64268aa..718bfe9430 100644 --- a/libs/surfaces/websockets/dispatcher.cc +++ b/libs/surfaces/websockets/dispatcher.cc @@ -124,8 +124,10 @@ WebsocketsDispatcher::update_all_nodes (Client client) void WebsocketsDispatcher::tempo_handler (Client client, const NodeStateMessage& msg) { - if (msg.is_write ()) { - globals ().set_tempo (msg.state ().nth_val (0)); + const NodeState& state = msg.state (); + + if (msg.is_write () && (state.n_val () > 0)) { + globals ().set_tempo (state.nth_val (0)); } else { update (client, Node::tempo, globals ().tempo ()); } @@ -134,10 +136,16 @@ WebsocketsDispatcher::tempo_handler (Client client, const NodeStateMessage& msg) void WebsocketsDispatcher::strip_gain_handler (Client client, const NodeStateMessage& msg) { - uint32_t strip_id = msg.state ().nth_addr (0); + const NodeState& state = msg.state (); - if (msg.is_write ()) { - strips ().set_strip_gain (strip_id, msg.state ().nth_val (0)); + if (state.n_addr () < 1) { + return; + } + + uint32_t strip_id = state.nth_addr (0); + + if (msg.is_write () && (state.n_val () > 0)) { + strips ().set_strip_gain (strip_id, state.nth_val (0)); } else { update (client, Node::strip_gain, strip_id, strips ().strip_gain (strip_id)); } @@ -146,10 +154,16 @@ WebsocketsDispatcher::strip_gain_handler (Client client, const NodeStateMessage& void WebsocketsDispatcher::strip_pan_handler (Client client, const NodeStateMessage& msg) { - uint32_t strip_id = msg.state ().nth_addr (0); + const NodeState& state = msg.state (); - if (msg.is_write ()) { - strips ().set_strip_pan (strip_id, msg.state ().nth_val (0)); + if (state.n_addr () < 1) { + return; + } + + uint32_t strip_id = state.nth_addr (0); + + if (msg.is_write () && (state.n_val () > 0)) { + strips ().set_strip_pan (strip_id, state.nth_val (0)); } else { update (client, Node::strip_pan, strip_id, strips ().strip_pan (strip_id)); } @@ -158,10 +172,16 @@ WebsocketsDispatcher::strip_pan_handler (Client client, const NodeStateMessage& void WebsocketsDispatcher::strip_mute_handler (Client client, const NodeStateMessage& msg) { - uint32_t strip_id = msg.state ().nth_addr (0); + const NodeState& state = msg.state (); - if (msg.is_write ()) { - strips ().set_strip_mute (strip_id, msg.state ().nth_val (0)); + if (state.n_addr () < 1) { + return; + } + + uint32_t strip_id = state.nth_addr (0); + + if (msg.is_write () && (state.n_val () > 0)) { + strips ().set_strip_mute (strip_id, state.nth_val (0)); } else { update (client, Node::strip_mute, strip_id, strips ().strip_mute (strip_id)); } @@ -170,11 +190,17 @@ WebsocketsDispatcher::strip_mute_handler (Client client, const NodeStateMessage& void WebsocketsDispatcher::strip_plugin_enable_handler (Client client, const NodeStateMessage& msg) { - uint32_t strip_id = msg.state ().nth_addr (0); - uint32_t plugin_id = msg.state ().nth_addr (1); + const NodeState& state = msg.state (); - if (msg.is_write ()) { - strips ().set_strip_plugin_enabled (strip_id, plugin_id, msg.state ().nth_val (0)); + if (state.n_addr () < 2) { + return; + } + + uint32_t strip_id = state.nth_addr (0); + uint32_t plugin_id = state.nth_addr (1); + + if (msg.is_write () && (state.n_val () > 0)) { + strips ().set_strip_plugin_enabled (strip_id, plugin_id, state.nth_val (0)); } else { update (client, Node::strip_plugin_enable, strip_id, plugin_id, strips ().strip_plugin_enabled (strip_id, plugin_id)); @@ -184,13 +210,19 @@ WebsocketsDispatcher::strip_plugin_enable_handler (Client client, const NodeStat void WebsocketsDispatcher::strip_plugin_param_value_handler (Client client, const NodeStateMessage& msg) { - uint32_t strip_id = msg.state ().nth_addr (0); - uint32_t plugin_id = msg.state ().nth_addr (1); - uint32_t param_id = msg.state ().nth_addr (2); + const NodeState& state = msg.state (); - if (msg.is_write ()) { + if (state.n_addr () < 3) { + return; + } + + uint32_t strip_id = state.nth_addr (0); + uint32_t plugin_id = state.nth_addr (1); + uint32_t param_id = state.nth_addr (2); + + if (msg.is_write () && (state.n_val () > 0)) { strips ().set_strip_plugin_param_value (strip_id, plugin_id, param_id, - msg.state ().nth_val (0)); + state.nth_val (0)); } else { TypedValue value = strips ().strip_plugin_param_value (strip_id, plugin_id, param_id); update (client, Node::strip_plugin_param_value, strip_id, plugin_id, param_id, value);