[BUGFIX][IOTUC-18] Library fixes

This commit adds mostly integer (and buffer) overflow checks for the
current buffer index (`result` variable).
pull/11051/head
Bogdan Marinescu 2018-03-22 18:47:39 +02:00
parent de7024f7ab
commit a5f07166f9
1 changed files with 256 additions and 250 deletions

View File

@ -17,6 +17,7 @@
#include "mbed_printf_implementation.h"
#include <stdbool.h>
#include <limits.h>
/***************************/
/* MBED */
@ -126,9 +127,9 @@ typedef enum {
static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, int* result, MBED_SIGNED_STORAGE value);
static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value);
static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value);
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, void* value);
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, const void* value);
static void mbed_minimal_formatted_string_character(char* buffer, size_t length, int* result, char character);
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, char* string);
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, const char* string);
/**
* @brief Print signed integer.
@ -141,7 +142,7 @@ static void mbed_minimal_formatted_string_string(char* buffer, size_t length, in
static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, int* result, MBED_SIGNED_STORAGE value)
{
/* only continue if buffer can fit at least 1 characters */
if ((size_t)(*result + 1) <= length)
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
{
MBED_UNSIGNED_STORAGE new_value = 0;
@ -184,7 +185,7 @@ static void mbed_minimal_formatted_string_signed(char* buffer, size_t length, in
static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length, int* result, MBED_UNSIGNED_STORAGE value)
{
/* only continue if buffer can fit at least 1 characters */
if ((size_t)(*result + 1) <= length)
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
{
/* treat 0 as a corner case */
if (value == 0)
@ -218,7 +219,7 @@ static void mbed_minimal_formatted_string_unsigned(char* buffer, size_t length,
}
/* write scratch pad to buffer or output */
for ( ; ((size_t)*result < length) && (index > 0); index--)
for ( ; (*result <= INT_MAX- 1) && ((size_t)*result < length) && (index > 0); index--)
{
if (buffer)
{
@ -248,7 +249,7 @@ static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t lengt
bool print_leading_zero = false;
/* only continue each loop if buffer can fit at least 2 characters */
for (int index = 7; (((size_t)(*result + 2) <= length)) && (index >= 0); index--)
for (int index = 7; (*result >= 0) && (*result <= INT_MAX - 2) && ((size_t)*result + 2 <= length) && (index >= 0); index--)
{
/* get most significant byte */
uint8_t output = value >> (8 * index);
@ -290,10 +291,11 @@ static void mbed_minimal_formatted_string_hexadecimal(char* buffer, size_t lengt
* @param result The current output location.
* @param[in] value The pointer to be printed.
*/
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, void* value)
static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t length, int* result, const void* value)
{
/* only continue if buffer can fit '0x' and twice the size of a void* */
if ((*result + 2 + 2 * sizeof(void*)) <= length)
size_t needed = 2 + 2 * sizeof(void*);
if ((*result >= 0) && ((size_t)*result <= INT_MAX - needed) && ((size_t)*result + needed <= length))
{
/* write leading 0x */
if (buffer)
@ -326,7 +328,7 @@ static void mbed_minimal_formatted_string_void_pointer(char* buffer, size_t leng
static void mbed_minimal_formatted_string_double(char* buffer, size_t length, int* result, double value)
{
/* only continue if buffer can fit at least 1 characters */
if ((size_t)(*result + 1) <= length)
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
{
/* get integer part */
MBED_SIGNED_STORAGE integer = value;
@ -385,7 +387,7 @@ static void mbed_minimal_formatted_string_double(char* buffer, size_t length, in
static void mbed_minimal_formatted_string_character(char* buffer, size_t length, int* result, char character)
{
/* only continue if the buffer can fit 1 character */
if ((size_t)(*result + 1) <= length)
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
{
/* write character */
if (buffer)
@ -422,10 +424,10 @@ static void mbed_minimal_formatted_string_character(char* buffer, size_t length,
* @param result The current output location.
* @param[in] value The string to be printed.
*/
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, char* string)
static void mbed_minimal_formatted_string_string(char* buffer, size_t length, int* result, const char* string)
{
/* only continue if the buffer can fit at least 1 character */
if ((size_t)(*result + 1) <= length)
if ((*result >= 0) && (*result <= INT_MAX - 1) && ((size_t)*result + 1 <= length))
{
/* count characters in string */
size_t remaining = length - *result;
@ -440,6 +442,11 @@ static void mbed_minimal_formatted_string_string(char* buffer, size_t length, in
/* copy string to buffer */
if (buffer)
{
/* ensure that the value of "result" doesn't overflow */
if (string_length + *result > INT_MAX)
{
string_length = (size_t)INT_MAX - *result;
}
for (size_t index = 0; index < string_length; index++)
{
buffer[*result + index] = string[index];
@ -476,12 +483,10 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
int result = 0;
/* if writing to buffer, reserve space for NULL termination */
if (buffer)
/* ensure that function wasn't called with an empty buffer, or with
a buffer size that is larger than the maximum 'int' value */
if (length > 0 && length <= INT_MAX)
{
length--;
}
/* parse string */
for (size_t index = 0; format[index] != '\0'; index++)
{
@ -490,8 +495,8 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
{
size_t next_index = index + 1;
/* while there is room in buffer and format string is not empty */
while ((next_index < length) && (format[next_index] != '\0') &&
/* while format string is not empty */
while ((format[next_index] != '\0') &&
/* skip all flags and precision modifiers */
(((format[next_index] >= '0') && (format[next_index] <= '9')) ||
(format[next_index] == '-') ||
@ -744,10 +749,11 @@ int mbed_minimal_formatted_string(char* buffer, size_t length, const char* forma
}
/* if writing to buffer, NULL terminate string in reserved space*/
if (buffer)
if (buffer && ((size_t)result < length))
{
buffer[result] = '\0';
}
}
return result;
}