From e9932bde9d39b3441f836560d9cbab87280590d9 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 2 Jul 2026 21:02:31 +0000 Subject: [PATCH] libqcdm: fix heap out-of-bounds read in qcdm_cmd_pilot_sets_result Validate the active, candidate, and neighbor count fields in qcdm_cmd_pilot_sets_result() before parsing the sets. Ensure that the sum of counts does not exceed the size of the static sets array in the response structure, and that the calculated size based on the counts fits within the received buffer len. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1069 Signed-off-by: Aleksander Morgado --- libqcdm/src/commands.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libqcdm/src/commands.c b/libqcdm/src/commands.c index b78c26b7..f182016d 100644 --- a/libqcdm/src/commands.c +++ b/libqcdm/src/commands.c @@ -672,12 +672,24 @@ qcdm_cmd_pilot_sets_result (const char *buf, size_t len, int *out_error) QcdmResult *result = NULL; DMCmdPilotSetsRsp *rsp = (DMCmdPilotSetsRsp *) buf; size_t sets_len; + size_t total_count; qcdm_return_val_if_fail (buf != NULL, NULL); if (!check_command (buf, len, DIAG_CMD_PILOT_SETS, sizeof (DMCmdPilotSetsRsp), out_error)) return NULL; + /* Validate that the modem-supplied counts fit in the fixed sets[] array + * and in the actually-received response. */ + total_count = (size_t) rsp->active_count + rsp->candidate_count + rsp->neighbor_count; + if (total_count > (sizeof (rsp->sets) / sizeof (rsp->sets[0])) || + ((sizeof (*rsp) - sizeof (rsp->sets)) + total_count * sizeof (DMCmdPilotSetsSet)) > len) { + qcdm_err (0, "DM Pilot Sets response counts out of range"); + if (out_error) + *out_error = -QCDM_ERROR_RESPONSE_BAD_LENGTH; + return NULL; + } + result = qcdm_result_new (); sets_len = rsp->active_count * sizeof (DMCmdPilotSetsSet);