diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-11-26 20:17:06 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-11-26 23:01:19 +0100 |
commit | f39f22bd173b27b925b8aaa76650d92ea72584c0 (patch) | |
tree | d3ded8e822bcb4741945de07b6bcee13eaa34f6b | |
parent | 91568c1a79790754eecaaeaf0cf53c27c6494c49 (diff) |
libmbim-glib,message: reading IPv4 array may fail
-rw-r--r-- | build-aux/mbim-codegen/Message.py | 9 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-message-private.h | 8 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-message.c | 42 |
3 files changed, 43 insertions, 16 deletions
diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py index cdca58f..19ec2a2 100644 --- a/build-aux/mbim-codegen/Message.py +++ b/build-aux/mbim-codegen/Message.py @@ -874,9 +874,10 @@ class Message: ' goto out;\n' ' offset += 4;\n') elif field['format'] == 'ipv4-array': + count_early_outs += 1 inner_template += ( - ' if (out_${field} != NULL)\n' - ' _${field} = _mbim_message_read_ipv4_array (message, _${array_size_field}, offset);\n' + ' if ((out_${field} != NULL) && !_mbim_message_read_ipv4_array (message, _${array_size_field}, offset, &_${field}, error))\n' + ' goto out;\n' ' offset += 4;\n') elif field['format'] == 'ipv6': inner_template += ( @@ -993,6 +994,7 @@ class Message: field['format'] == 'string-array' or \ field['format'] == 'ipv4' or \ field['format'] == 'ref-ipv4' or \ + field['format'] == 'ipv4-array' or \ field['format'] == 'uuid' or \ field['format'] == 'struct-array' or \ field['format'] == 'ref-struct-array' or \ @@ -1274,7 +1276,8 @@ class Message: elif field['format'] == 'ipv4-array': inner_template += ( ' array_size = _${array_size_field};\n' - ' tmp = _mbim_message_read_ipv4_array (message, _${array_size_field}, offset);\n' + ' if (!_mbim_message_read_ipv4_array (message, _${array_size_field}, offset, &tmp, &inner_error))\n' + ' goto out;\n' ' offset += 4;\n') elif field['format'] == 'ipv6': inner_template += ( diff --git a/src/libmbim-glib/mbim-message-private.h b/src/libmbim-glib/mbim-message-private.h index c938580..ef8d43a 100644 --- a/src/libmbim-glib/mbim-message-private.h +++ b/src/libmbim-glib/mbim-message-private.h @@ -298,10 +298,12 @@ gboolean _mbim_message_read_ipv4 (const MbimMessage *self, gboolean ref, const MbimIPv4 **ipv4, GError **error); +gboolean _mbim_message_read_ipv4_array (const MbimMessage *self, + guint32 array_size, + guint32 relative_offset_array_start, + MbimIPv4 **array, + GError **error); -MbimIPv4 *_mbim_message_read_ipv4_array (const MbimMessage *self, - guint32 array_size, - guint32 relative_offset_array_start); const MbimIPv6 *_mbim_message_read_ipv6 (const MbimMessage *self, guint32 relative_offset, gboolean ref); diff --git a/src/libmbim-glib/mbim-message.c b/src/libmbim-glib/mbim-message.c index 4809a1a..48005bc 100644 --- a/src/libmbim-glib/mbim-message.c +++ b/src/libmbim-glib/mbim-message.c @@ -612,35 +612,57 @@ _mbim_message_read_ipv4 (const MbimMessage *self, return TRUE; } -MbimIPv4 * -_mbim_message_read_ipv4_array (const MbimMessage *self, - guint32 array_size, - guint32 relative_offset_array_start) +gboolean +_mbim_message_read_ipv4_array (const MbimMessage *self, + guint32 array_size, + guint32 relative_offset_array_start, + MbimIPv4 **array, + GError **error) { - MbimIPv4 *array; + guint32 required_size; guint32 offset; guint32 i; guint32 information_buffer_offset; - if (!array_size) - return NULL; + g_assert (array != NULL); + + if (!array_size) { + *array = NULL; + return TRUE; + } information_buffer_offset = _mbim_message_get_information_buffer_offset (self); - array = g_new (MbimIPv4, array_size); + required_size = information_buffer_offset + relative_offset_array_start + 4; + if (self->len < required_size) { + g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE, + "cannot read IPv4 array offset (4 bytes) (%u < %u)", + self->len, required_size); + return FALSE; + } + offset = GUINT32_FROM_LE (G_STRUCT_MEMBER ( guint32, self->data, (information_buffer_offset + relative_offset_array_start))); + required_size = information_buffer_offset + offset + (4 * array_size); + if (self->len < required_size) { + g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE, + "cannot read IPv4 array data (%u bytes) (%u < %u)", + (4 * array_size), self->len, required_size); + return FALSE; + } + + *array = g_new (MbimIPv4, array_size); for (i = 0; i < array_size; i++, offset += 4) { - memcpy (&array[i], + memcpy (&((*array)[i]), G_STRUCT_MEMBER_P (self->data, (information_buffer_offset + offset)), 4); } - return array; + return TRUE; } const MbimIPv6 * |