summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2019-11-26 21:42:26 +0100
committerAleksander Morgado <aleksander@aleksander.es>2019-11-26 23:01:19 +0100
commitd498e9323ea133de9993d1fba7f4d548e8ca2152 (patch)
treedcd44c187aacba4af74c673e4040e600d69586cb
parent5ddf637c1636c79eaf69dee6fb5223fea9766927 (diff)
libmbim-glib,message: reading IPv6 array may fail
-rw-r--r--build-aux/mbim-codegen/Message.py9
-rw-r--r--src/libmbim-glib/mbim-message-private.h9
-rw-r--r--src/libmbim-glib/mbim-message.c43
3 files changed, 44 insertions, 17 deletions
diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py
index 76b71a9..2488538 100644
--- a/build-aux/mbim-codegen/Message.py
+++ b/build-aux/mbim-codegen/Message.py
@@ -892,9 +892,10 @@ class Message:
' goto out;\n'
' offset += 4;\n')
elif field['format'] == 'ipv6-array':
+ count_early_outs += 1
inner_template += (
- ' if (out_${field} != NULL)\n'
- ' _${field} = _mbim_message_read_ipv6_array (message, _${array_size_field}, offset);\n'
+ ' if ((out_${field} != NULL) && !_mbim_message_read_ipv6_array (message, _${array_size_field}, offset, &_${field}, error))\n'
+ ' goto out;\n'
' offset += 4;\n')
inner_template += (
@@ -999,6 +1000,7 @@ class Message:
field['format'] == 'ipv4-array' or \
field['format'] == 'ipv6' or \
field['format'] == 'ref-ipv6' or \
+ field['format'] == 'ipv6-array' or \
field['format'] == 'uuid' or \
field['format'] == 'struct-array' or \
field['format'] == 'ref-struct-array' or \
@@ -1298,7 +1300,8 @@ class Message:
elif field['format'] == 'ipv6-array':
inner_template += (
' array_size = _${array_size_field};\n'
- ' tmp = _mbim_message_read_ipv6_array (message, _${array_size_field}, offset);\n'
+ ' if (!_mbim_message_read_ipv6_array (message, _${array_size_field}, offset, &tmp, &inner_error))\n'
+ ' goto out;\n'
' offset += 4;\n')
inner_template += (
diff --git a/src/libmbim-glib/mbim-message-private.h b/src/libmbim-glib/mbim-message-private.h
index 341c257..467e356 100644
--- a/src/libmbim-glib/mbim-message-private.h
+++ b/src/libmbim-glib/mbim-message-private.h
@@ -308,10 +308,11 @@ gboolean _mbim_message_read_ipv6 (const MbimMessage *self,
gboolean ref,
const MbimIPv6 **ipv6,
GError **error);
-
-MbimIPv6 *_mbim_message_read_ipv6_array (const MbimMessage *self,
- guint32 array_size,
- guint32 relative_offset_array_start);
+gboolean _mbim_message_read_ipv6_array (const MbimMessage *self,
+ guint32 array_size,
+ guint32 relative_offset_array_start,
+ MbimIPv6 **array,
+ GError **error);
G_END_DECLS
diff --git a/src/libmbim-glib/mbim-message.c b/src/libmbim-glib/mbim-message.c
index a4dcb4c..bda5650 100644
--- a/src/libmbim-glib/mbim-message.c
+++ b/src/libmbim-glib/mbim-message.c
@@ -712,34 +712,57 @@ _mbim_message_read_ipv6 (const MbimMessage *self,
return TRUE;
}
-MbimIPv6 *
-_mbim_message_read_ipv6_array (const MbimMessage *self,
- guint32 array_size,
- guint32 relative_offset_array_start)
+gboolean
+_mbim_message_read_ipv6_array (const MbimMessage *self,
+ guint32 array_size,
+ guint32 relative_offset_array_start,
+ MbimIPv6 **array,
+ GError **error)
{
- MbimIPv6 *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 (MbimIPv6, 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 IPv6 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 + (16 * array_size);
+ if (self->len < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read IPv6 array data (%u bytes) (%u < %u)",
+ (16 * array_size), self->len, required_size);
+ return FALSE;
+ }
+
+ *array = g_new (MbimIPv6, array_size);
for (i = 0; i < array_size; i++, offset += 16) {
- memcpy (&array[i],
+ memcpy (&((*array)[i]),
G_STRUCT_MEMBER_P (self->data,
(information_buffer_offset + offset)),
16);
}
- return array;
+ return TRUE;
}
/*****************************************************************************/