fix(esp_local_ctrl): validate payload_case matches msg_type in command dispatcher

The command dispatcher routed handlers based solely on msg_type without
verifying that the protobuf payload_case field matched. A crafted message
with mismatched msg_type and payload_case could cause type confusion,
leading to an out-of-bounds read or NULL pointer dereference.

Add expected_payload_case to the command table and validate it in the
dispatcher before invoking any handler.

Please note that this issue was applicable for authenticated clients
only (with security1/2 scheme) and hence the impact is on lower side.
This commit is contained in:
Mahavir Jain
2026-02-11 13:29:39 +05:30
parent 45961a72c2
commit ae934f038d
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -25,6 +25,7 @@ static const char* TAG = "esp_local_ctrl_handler";
typedef struct esp_local_ctrl_cmd {
int cmd_num;
int expected_payload_case;
esp_err_t (*command_handler)(LocalCtrlMessage *req,
LocalCtrlMessage *resp, void **ctx);
} esp_local_ctrl_cmd_t;
@@ -41,14 +42,17 @@ static esp_err_t cmd_set_prop_vals_handler(LocalCtrlMessage *req,
static esp_local_ctrl_cmd_t cmd_table[] = {
{
.cmd_num = LOCAL_CTRL_MSG_TYPE__TypeCmdGetPropertyCount,
.expected_payload_case = LOCAL_CTRL_MESSAGE__PAYLOAD_CMD_GET_PROP_COUNT,
.command_handler = cmd_get_prop_count_handler
},
{
.cmd_num = LOCAL_CTRL_MSG_TYPE__TypeCmdGetPropertyValues,
.expected_payload_case = LOCAL_CTRL_MESSAGE__PAYLOAD_CMD_GET_PROP_VALS,
.command_handler = cmd_get_prop_vals_handler
},
{
.cmd_num = LOCAL_CTRL_MSG_TYPE__TypeCmdSetPropertyValues,
.expected_payload_case = LOCAL_CTRL_MESSAGE__PAYLOAD_CMD_SET_PROP_VALS,
.command_handler = cmd_set_prop_vals_handler
}
};
@@ -238,6 +242,12 @@ static esp_err_t esp_local_ctrl_command_dispatcher(LocalCtrlMessage *req,
return ESP_ERR_INVALID_ARG;
}
if (req->payload_case != cmd_table[cmd_index].expected_payload_case) {
ESP_LOGE(TAG, "Payload type mismatch: msg_type %d expects payload %d, got %d",
req->msg, cmd_table[cmd_index].expected_payload_case, req->payload_case);
return ESP_ERR_INVALID_ARG;
}
esp_err_t ret = cmd_table[cmd_index].command_handler(req, resp, ctx);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Error executing command handler");