summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2019-11-26 20:17:06 +0100
committerAleksander Morgado <aleksander@aleksander.es>2019-11-26 23:01:19 +0100
commitf39f22bd173b27b925b8aaa76650d92ea72584c0 (patch)
treed3ded8e822bcb4741945de07b6bcee13eaa34f6b
parent91568c1a79790754eecaaeaf0cf53c27c6494c49 (diff)
libmbim-glib,message: reading IPv4 array may fail
-rw-r--r--build-aux/mbim-codegen/Message.py9
-rw-r--r--src/libmbim-glib/mbim-message-private.h8
-rw-r--r--src/libmbim-glib/mbim-message.c42
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 *