Permalink
Browse files

Add protection against integer overflow

  • Loading branch information...
1 parent c5c8d6d commit 778f9e0c743c7d66a1c5d59d0e0942ff2595e882 James McLaughlin committed Feb 12, 2012
Showing with 28 additions and 8 deletions.
  1. +28 −8 json.c
View
36 json.c
@@ -59,18 +59,24 @@ static unsigned char hex_value (json_char c)
typedef struct
{
json_settings settings;
+ int first_pass;
unsigned long used_memory;
- int first_pass;
+
+ unsigned int uint_max;
+ unsigned long ulong_max;
} json_state;
static void * json_alloc (json_state * state, unsigned long size, int zero)
{
void * mem;
- if (state->settings.max_memory &&
- (state->used_memory += size) > state->settings.max_memory)
+ if ((state->ulong_max - state->used_memory) < size)
+ return 0;
+
+ if (state->settings.max_memory
+ && (state->used_memory += size) > state->settings.max_memory)
{
return 0;
}
@@ -183,19 +189,23 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
json_state state;
int flags;
+ memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
+ memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
+
+ state.uint_max -= 8; /* limit of how much can be added before next check */
+ state.ulong_max -= 8;
+
error[0] = '\0';
memset (&state, 0, sizeof (json_state));
memcpy (&state.settings, settings, sizeof (json_settings));
- state.first_pass = 1;
-
- for (; state.first_pass >= 0; -- state.first_pass)
+ for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass)
{
json_uchar uchar;
unsigned char uc_b1, uc_b2, uc_b3, uc_b4;
json_char * string;
- int string_length;
+ unsigned int string_length;
top = root = 0;
flags = flag_seek_value;
@@ -214,6 +224,9 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
goto e_failed;
}
+ if (string_length > state.uint_max)
+ goto e_overflow;
+
if (flags & flag_escaped)
{
flags &= ~ flag_escaped;
@@ -600,7 +613,9 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
};
}
- ++ top->parent->u.array.length;
+ if ( (++ top->parent->u.array.length) > state.uint_max)
+ goto e_overflow;
+
top = top->parent;
continue;
@@ -622,6 +637,11 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
strcpy (error, "Memory allocation failure");
goto e_failed;
+e_overflow:
+
+ sprintf (error, "%d:%d: Too long (caught overflow)", cur_line, e_off);
+ goto e_failed;
+
e_failed:
strcpy (error_buf, *error ? error : "Unknown error");

0 comments on commit 778f9e0

Please sign in to comment.