[PATCH v5 08/10] mbim: Add support for nested fixed arrays in arrays/structs In some arrays, a nested array can be a fixed array coupled with an OL-pair, which breaks the existing assumptions of arrays and structs, leading to wrong data being parsed. Or the parent array can have no OL-pair in this condition.
Muhammad Asif <[email protected]> Thu, 27 Nov 2025 22:49:42 +0500
| Newsgroups | dev.linux.lists.ofono |
|---|---|
| Message-ID | <[email protected]> |
For example: The UICC low-level access data has a struct array, but the array itself has no OL-pair, instead the OL-pair is of the struct, so the position is no longer incremented in the array parser so the nested struct can parse its OL-pair properly. The method for detecting a fixed array is also flawed, because a nested array can be fixed, e.g. in the example above, the AID array inside the struct array is a fixed array, but parsing fails due to it being treated as a variable array. Introduce a new argument type to parse fixed nested arrays in order to solve this. Also remove out_n_elem for arrays, since it can be a separate field away from the array itself. Signed-off-by: Muhammad Asif <[email protected]> --- drivers/mbimmodem/gprs.c | 2 +- drivers/mbimmodem/mbim-message.c | 29 +++++++++++++++++++++-------- drivers/mbimmodem/sms.c | 5 +++-- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/mbimmodem/gprs.c b/drivers/mbimmodem/gprs.c index 06a50f3d..23953faf 100644 --- a/drivers/mbimmodem/gprs.c +++ b/drivers/mbimmodem/gprs.c @@ -175,7 +175,7 @@ static void provisioned_contexts_query_cb(struct mbim_m= essage *message, =09if (mbim_message_get_error(message) !=3D 0) =09=09return; =20 -=09if (!mbim_message_get_arguments(message, "a(u16ysssuu)", +=09if (!mbim_message_get_arguments(message, "ua(u16ysssuu)", =09=09=09=09=09=09&n_contexts, &contexts)) =09=09return; =20 diff --git a/drivers/mbimmodem/mbim-message.c b/drivers/mbimmodem/mbim-mess= age.c index ecb4f689..637c2cf8 100644 --- a/drivers/mbimmodem/mbim-message.c +++ b/drivers/mbimmodem/mbim-message.c @@ -309,7 +309,8 @@ static bool _iter_next_entry_basic(struct mbim_message_= iter *iter, } =20 static bool _iter_enter_array(struct mbim_message_iter *iter, -=09=09=09=09=09struct mbim_message_iter *array) +=09=09=09=09=09struct mbim_message_iter *array, +=09=09=09=09=09bool fixed_array) { =09size_t pos; =09uint32_t n_elem; @@ -322,7 +323,7 @@ static bool _iter_enter_array(struct mbim_message_iter = *iter, =09if (iter->container_type =3D=3D CONTAINER_TYPE_ARRAY && !iter->n_elem) =09=09return false; =20 -=09if (iter->sig_start[iter->sig_pos] !=3D 'a') +=09if (iter->sig_start[iter->sig_pos] !=3D 'a' && iter->sig_start[iter->si= g_pos] !=3D 'A') =09=09return false; =20 =09sig_start =3D iter->sig_start + iter->sig_pos + 1; @@ -335,7 +336,7 @@ static bool _iter_enter_array(struct mbim_message_iter = *iter, =09 */ =09fixed =3D is_fixed_size(sig_start, sig_end); =20 -=09if (fixed) { +=09if (fixed || fixed_array) { =09=09pos =3D align_len(iter->pos, 4); =09=09if (pos + 4 > iter->len) =09=09=09return false; @@ -351,12 +352,15 @@ static bool _iter_enter_array(struct mbim_message_ite= r *iter, =20 =09data =3D _iter_get_data(iter, pos); =09n_elem =3D l_get_le32(data); -=09pos +=3D 4; +=09if (fixed) +=09=09pos +=3D 4; +=09else if (fixed_array) +=09=09iter->pos +=3D 4; =20 =09if (iter->container_type !=3D CONTAINER_TYPE_ARRAY) =09=09iter->sig_pos +=3D sig_end - sig_start + 1; =20 -=09if (fixed) { +=09if (fixed || fixed_array) { _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") =09=09_iter_init_internal(array, CONTAINER_TYPE_ARRAY, @@ -518,13 +522,22 @@ static bool message_iter_next_entry_valist(struct mbi= m_message_iter *orig, =09=09=09=09iter =3D &stack[indent - 1]; =09=09=09break; =09=09case 'a': -=09=09=09out_n_elem =3D va_arg(args, uint32_t *); =09=09=09sub_iter =3D va_arg(args, void *); =20 -=09=09=09if (!_iter_enter_array(iter, sub_iter)) +=09=09=09if (!_iter_enter_array(iter, sub_iter, false)) =09=09=09=09return false; =20 -=09=09=09*out_n_elem =3D sub_iter->n_elem; +=09=09=09end =3D _signature_end(signature + 1); +=09=09=09signature =3D end + 1; +=09=09=09break; +=09=09/* Fixed array with an OL pair list, no element count +=09=09 * TODO: Implement sending fixed arrays to the modem too +=09=09 */ +=09=09case 'A': +=09=09=09sub_iter =3D va_arg(args, void *); + +=09=09=09if (!_iter_enter_array(iter, sub_iter, true)) +=09=09=09=09return false; =20 =09=09=09end =3D _signature_end(signature + 1); =09=09=09signature =3D end + 1; diff --git a/drivers/mbimmodem/sms.c b/drivers/mbimmodem/sms.c index 1f52ef7e..c0610ef3 100644 --- a/drivers/mbimmodem/sms.c +++ b/drivers/mbimmodem/sms.c @@ -211,7 +211,7 @@ static void mbim_parse_sms_read_info(struct mbim_messag= e *message, =09uint32_t status; =09uint32_t pdu_len; =20 -=09if (!mbim_message_get_arguments(message, "ua(uuay)", +=09if (!mbim_message_get_arguments(message, "uua(uuay)", =09=09=09=09=09=09&format, &n_sms, &array)) =09=09return; =20 @@ -219,7 +219,8 @@ static void mbim_parse_sms_read_info(struct mbim_messag= e *message, =09=09return; =20 =09while (mbim_message_iter_next_entry(&array, &index, &status, -=09=09=09=09=09=09=09&pdu_len, &bytes)) { +=09=09=09=09=09=09=09&bytes)) { +=09=09pdu_len =3D bytes.n_elem; =09=09int i =3D 0; =20 =09=09/* Ignore Draft (2) and Sent (3) messages */ --=20 2.52.0