Skip to content

Commit 30865c9

Browse files
authored
Use safe math in message.c (#452)
1 parent 1603acf commit 30865c9

File tree

1 file changed

+127
-81
lines changed

1 file changed

+127
-81
lines changed

Diff for: src/message.c

+127-81
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "azure_macro_utils/macro_utils.h"
88
#include "azure_c_shared_utility/gballoc.h"
99
#include "azure_c_shared_utility/xlogging.h"
10+
#include "azure_c_shared_utility/safe_math.h"
1011
#include "azure_uamqp_c/amqp_definitions.h"
1112
#include "azure_uamqp_c/message.h"
1213
#include "azure_uamqp_c/amqpvalue.h"
@@ -232,78 +233,100 @@ MESSAGE_HANDLE message_clone(MESSAGE_HANDLE source_message)
232233

233234
if ((result != NULL) && (source_message->body_amqp_data_count > 0))
234235
{
235-
size_t i;
236+
size_t calloc_size = safe_multiply_size_t(source_message->body_amqp_data_count, sizeof(BODY_AMQP_DATA));
236237

237-
result->body_amqp_data_items = (BODY_AMQP_DATA*)calloc(1, (source_message->body_amqp_data_count * sizeof(BODY_AMQP_DATA)));
238-
if (result->body_amqp_data_items == NULL)
238+
if (calloc_size == SIZE_MAX)
239239
{
240-
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
241-
LogError("Cannot allocate memory for body data sections");
242-
message_destroy(result);
240+
LogError("Invalid size for body_amqp_data_items");
243241
result = NULL;
244242
}
245243
else
246244
{
247-
for (i = 0; i < source_message->body_amqp_data_count; i++)
245+
result->body_amqp_data_items = (BODY_AMQP_DATA*)calloc(1, calloc_size);
246+
247+
if (result->body_amqp_data_items == NULL)
248248
{
249-
result->body_amqp_data_items[i].body_data_section_length = source_message->body_amqp_data_items[i].body_data_section_length;
249+
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
250+
LogError("Cannot allocate memory for body data sections");
251+
message_destroy(result);
252+
result = NULL;
253+
}
254+
else
255+
{
256+
size_t i;
250257

251-
/* Codes_SRS_MESSAGE_01_011: [If an AMQP data has been set as message body on the source message it shall be cloned by allocating memory for the binary payload.] */
252-
result->body_amqp_data_items[i].body_data_section_bytes = (unsigned char*)malloc(source_message->body_amqp_data_items[i].body_data_section_length);
253-
if (result->body_amqp_data_items[i].body_data_section_bytes == NULL)
258+
for (i = 0; i < source_message->body_amqp_data_count; i++)
254259
{
255-
LogError("Cannot allocate memory for body data section %u", (unsigned int)i);
256-
break;
260+
result->body_amqp_data_items[i].body_data_section_length = source_message->body_amqp_data_items[i].body_data_section_length;
261+
262+
/* Codes_SRS_MESSAGE_01_011: [If an AMQP data has been set as message body on the source message it shall be cloned by allocating memory for the binary payload.] */
263+
result->body_amqp_data_items[i].body_data_section_bytes = (unsigned char*)malloc(source_message->body_amqp_data_items[i].body_data_section_length);
264+
if (result->body_amqp_data_items[i].body_data_section_bytes == NULL)
265+
{
266+
LogError("Cannot allocate memory for body data section %u", (unsigned int)i);
267+
break;
268+
}
269+
else
270+
{
271+
(void)memcpy(result->body_amqp_data_items[i].body_data_section_bytes, source_message->body_amqp_data_items[i].body_data_section_bytes, result->body_amqp_data_items[i].body_data_section_length);
272+
}
257273
}
258-
else
274+
275+
result->body_amqp_data_count = i;
276+
if (i < source_message->body_amqp_data_count)
259277
{
260-
(void)memcpy(result->body_amqp_data_items[i].body_data_section_bytes, source_message->body_amqp_data_items[i].body_data_section_bytes, result->body_amqp_data_items[i].body_data_section_length);
278+
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
279+
message_destroy(result);
280+
result = NULL;
261281
}
262282
}
263-
264-
result->body_amqp_data_count = i;
265-
if (i < source_message->body_amqp_data_count)
266-
{
267-
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
268-
message_destroy(result);
269-
result = NULL;
270-
}
271283
}
272284
}
273285

274286
if ((result != NULL) && (source_message->body_amqp_sequence_count > 0))
275287
{
276-
size_t i;
288+
size_t calloc_size = safe_multiply_size_t(source_message->body_amqp_sequence_count, sizeof(AMQP_VALUE));
277289

278-
result->body_amqp_sequence_items = (AMQP_VALUE*)calloc(1, (source_message->body_amqp_sequence_count * sizeof(AMQP_VALUE)));
279-
if (result->body_amqp_sequence_items == NULL)
290+
if (calloc_size == SIZE_MAX)
280291
{
281-
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
282-
LogError("Cannot allocate memory for body AMQP sequences");
292+
LogError("Invalid size for body_amqp_sequence_items");
283293
message_destroy(result);
284294
result = NULL;
285295
}
286296
else
287297
{
288-
for (i = 0; i < source_message->body_amqp_sequence_count; i++)
289-
{
290-
/* Codes_SRS_MESSAGE_01_160: [ If AMQP sequences are set as AMQP body they shall be cloned by calling `amqpvalue_clone`. ] */
291-
result->body_amqp_sequence_items[i] = amqpvalue_clone(source_message->body_amqp_sequence_items[i]);
292-
if (result->body_amqp_sequence_items[i] == NULL)
293-
{
294-
LogError("Cannot clone AMQP sequence %u", (unsigned int)i);
295-
break;
296-
}
297-
}
298-
299-
result->body_amqp_sequence_count = i;
300-
if (i < source_message->body_amqp_sequence_count)
298+
result->body_amqp_sequence_items = (AMQP_VALUE*)calloc(1, calloc_size);
299+
if (result->body_amqp_sequence_items == NULL)
301300
{
302301
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
302+
LogError("Cannot allocate memory for body AMQP sequences");
303303
message_destroy(result);
304304
result = NULL;
305305
}
306-
}
306+
else
307+
{
308+
size_t i;
309+
310+
for (i = 0; i < source_message->body_amqp_sequence_count; i++)
311+
{
312+
/* Codes_SRS_MESSAGE_01_160: [ If AMQP sequences are set as AMQP body they shall be cloned by calling `amqpvalue_clone`. ] */
313+
result->body_amqp_sequence_items[i] = amqpvalue_clone(source_message->body_amqp_sequence_items[i]);
314+
if (result->body_amqp_sequence_items[i] == NULL)
315+
{
316+
LogError("Cannot clone AMQP sequence %u", (unsigned int)i);
317+
break;
318+
}
319+
}
320+
321+
result->body_amqp_sequence_count = i;
322+
if (i < source_message->body_amqp_sequence_count)
323+
{
324+
/* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/
325+
message_destroy(result);
326+
result = NULL;
327+
}
328+
}
329+
}
307330
}
308331

309332
if ((result != NULL) && (source_message->body_amqp_value != NULL))
@@ -1017,45 +1040,56 @@ int message_add_body_amqp_data(MESSAGE_HANDLE message, BINARY_DATA amqp_data)
10171040
}
10181041
else
10191042
{
1020-
/* Codes_SRS_MESSAGE_01_086: [ `message_add_body_amqp_data` shall add the contents of `amqp_data` to the list of AMQP data values for the body of the message identified by `message`. ]*/
1021-
BODY_AMQP_DATA* new_body_amqp_data_items = (BODY_AMQP_DATA*)realloc(message->body_amqp_data_items, sizeof(BODY_AMQP_DATA) * (message->body_amqp_data_count + 1));
1022-
if (new_body_amqp_data_items == NULL)
1043+
size_t realloc_size = safe_add_size_t(message->body_amqp_data_count, 1);
1044+
realloc_size = safe_multiply_size_t(sizeof(BODY_AMQP_DATA), realloc_size);
1045+
1046+
if (realloc_size == SIZE_MAX)
10231047
{
1024-
/* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/
1025-
LogError("Cannot allocate memory for body AMQP data items");
1048+
LogError("Invalid size for new_body_amqp_data_items");
10261049
result = MU_FAILURE;
10271050
}
10281051
else
10291052
{
1030-
message->body_amqp_data_items = new_body_amqp_data_items;
1031-
1032-
if (amqp_data.length == 0)
1053+
/* Codes_SRS_MESSAGE_01_086: [ `message_add_body_amqp_data` shall add the contents of `amqp_data` to the list of AMQP data values for the body of the message identified by `message`. ]*/
1054+
BODY_AMQP_DATA* new_body_amqp_data_items = (BODY_AMQP_DATA*)realloc(message->body_amqp_data_items, realloc_size);
1055+
if (new_body_amqp_data_items == NULL)
10331056
{
1034-
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = NULL;
1035-
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = 0;
1036-
message->body_amqp_data_count++;
1037-
1038-
/* Codes_SRS_MESSAGE_01_087: [ On success it shall return 0. ]*/
1039-
result = 0;
1057+
/* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/
1058+
LogError("Cannot allocate memory for body AMQP data items");
1059+
result = MU_FAILURE;
10401060
}
10411061
else
10421062
{
1043-
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = (unsigned char*)malloc(amqp_data.length);
1044-
if (message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes == NULL)
1045-
{
1046-
/* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/
1047-
LogError("Cannot allocate memory for body AMQP data to be added");
1048-
result = MU_FAILURE;
1049-
}
1050-
else
1063+
message->body_amqp_data_items = new_body_amqp_data_items;
1064+
1065+
if (amqp_data.length == 0)
10511066
{
1052-
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = amqp_data.length;
1053-
(void)memcpy(message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes, amqp_data.bytes, amqp_data.length);
1067+
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = NULL;
1068+
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = 0;
10541069
message->body_amqp_data_count++;
10551070

10561071
/* Codes_SRS_MESSAGE_01_087: [ On success it shall return 0. ]*/
10571072
result = 0;
10581073
}
1074+
else
1075+
{
1076+
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = (unsigned char*)malloc(amqp_data.length);
1077+
if (message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes == NULL)
1078+
{
1079+
/* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/
1080+
LogError("Cannot allocate memory for body AMQP data to be added");
1081+
result = MU_FAILURE;
1082+
}
1083+
else
1084+
{
1085+
message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = amqp_data.length;
1086+
(void)memcpy(message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes, amqp_data.bytes, amqp_data.length);
1087+
message->body_amqp_data_count++;
1088+
1089+
/* Codes_SRS_MESSAGE_01_087: [ On success it shall return 0. ]*/
1090+
result = 0;
1091+
}
1092+
}
10591093
}
10601094
}
10611095
}
@@ -1250,33 +1284,45 @@ int message_add_body_amqp_sequence(MESSAGE_HANDLE message, AMQP_VALUE sequence_l
12501284
}
12511285
else
12521286
{
1253-
AMQP_VALUE* new_body_amqp_sequence_items = (AMQP_VALUE*)realloc(message->body_amqp_sequence_items, sizeof(AMQP_VALUE) * (message->body_amqp_sequence_count + 1));
1254-
if (new_body_amqp_sequence_items == NULL)
1287+
size_t realloc_size = safe_add_size_t(message->body_amqp_sequence_count, 1);
1288+
realloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), realloc_size);
1289+
1290+
if (realloc_size == SIZE_MAX)
12551291
{
1256-
/* Codes_SRS_MESSAGE_01_158: [ If allocating memory in order to store the sequence fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/
1257-
LogError("Cannot allocate enough memory for sequence items");
1292+
LogError("Invalid size for new_body_amqp_sequence_items");
12581293
result = MU_FAILURE;
12591294
}
12601295
else
12611296
{
1262-
message->body_amqp_sequence_items = new_body_amqp_sequence_items;
1297+
AMQP_VALUE* new_body_amqp_sequence_items = (AMQP_VALUE*)realloc(message->body_amqp_sequence_items, realloc_size);
12631298

1264-
/* Codes_SRS_MESSAGE_01_110: [ `message_add_body_amqp_sequence` shall add the contents of `sequence` to the list of AMQP sequences for the body of the message identified by `message`. ]*/
1265-
/* Codes_SRS_MESSAGE_01_156: [ The AMQP sequence shall be cloned by calling `amqpvalue_clone`. ]*/
1266-
message->body_amqp_sequence_items[message->body_amqp_sequence_count] = amqpvalue_clone(sequence_list);
1267-
if (message->body_amqp_sequence_items[message->body_amqp_sequence_count] == NULL)
1299+
if (new_body_amqp_sequence_items == NULL)
12681300
{
1269-
/* Codes_SRS_MESSAGE_01_157: [ If `amqpvalue_clone` fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/
1270-
LogError("Cloning sequence failed");
1301+
/* Codes_SRS_MESSAGE_01_158: [ If allocating memory in order to store the sequence fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/
1302+
LogError("Cannot allocate enough memory for sequence items");
12711303
result = MU_FAILURE;
12721304
}
12731305
else
12741306
{
1275-
/* Codes_SRS_MESSAGE_01_114: [ If adding the AMQP sequence fails, the previous value shall be preserved. ]*/
1276-
message->body_amqp_sequence_count++;
1307+
message->body_amqp_sequence_items = new_body_amqp_sequence_items;
12771308

1278-
/* Codes_SRS_MESSAGE_01_111: [ On success it shall return 0. ]*/
1279-
result = 0;
1309+
/* Codes_SRS_MESSAGE_01_110: [ `message_add_body_amqp_sequence` shall add the contents of `sequence` to the list of AMQP sequences for the body of the message identified by `message`. ]*/
1310+
/* Codes_SRS_MESSAGE_01_156: [ The AMQP sequence shall be cloned by calling `amqpvalue_clone`. ]*/
1311+
message->body_amqp_sequence_items[message->body_amqp_sequence_count] = amqpvalue_clone(sequence_list);
1312+
if (message->body_amqp_sequence_items[message->body_amqp_sequence_count] == NULL)
1313+
{
1314+
/* Codes_SRS_MESSAGE_01_157: [ If `amqpvalue_clone` fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/
1315+
LogError("Cloning sequence failed");
1316+
result = MU_FAILURE;
1317+
}
1318+
else
1319+
{
1320+
/* Codes_SRS_MESSAGE_01_114: [ If adding the AMQP sequence fails, the previous value shall be preserved. ]*/
1321+
message->body_amqp_sequence_count++;
1322+
1323+
/* Codes_SRS_MESSAGE_01_111: [ On success it shall return 0. ]*/
1324+
result = 0;
1325+
}
12801326
}
12811327
}
12821328
}

0 commit comments

Comments
 (0)