Browse Source

Merge pull request #219 from rouault/low_heap_robustness_fixes

Fix various potential null ptr deref and int32 overflows
tags/json-c-0.13-20171207
Eric Haszlakiewicz 9 years ago
parent
commit
82bdbdba24
3 changed files with 38 additions and 4 deletions
  1. +13
    -3
      arraylist.c
  2. +5
    -0
      json_object.c
  3. +20
    -1
      json_tokener.c

+ 13
- 3
arraylist.c View File

@@ -11,6 +11,8 @@


#include "config.h" #include "config.h"


#include <limits.h>

#ifdef STDC_HEADERS #ifdef STDC_HEADERS
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>
@@ -62,10 +64,17 @@ static int array_list_expand_internal(struct array_list *arr, int max)
int new_size; int new_size;


if(max < arr->size) return 0; if(max < arr->size) return 0;
new_size = arr->size << 1;
if (new_size < max)
/* Avoid undefined behaviour on int32 overflow */
if( arr->size >= INT_MAX / 2 )
new_size = max; new_size = max;
if(!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
else
{
new_size = arr->size << 1;
if (new_size < max)
new_size = max;
}
if((size_t)new_size > (~((size_t)0)) / sizeof(void*)) return -1;
if(!(t = realloc(arr->array, ((size_t)new_size)*sizeof(void*)))) return -1;
arr->array = (void**)t; arr->array = (void**)t;
(void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*)); (void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*));
arr->size = new_size; arr->size = new_size;
@@ -75,6 +84,7 @@ static int array_list_expand_internal(struct array_list *arr, int max)
int int
array_list_put_idx(struct array_list *arr, int idx, void *data) array_list_put_idx(struct array_list *arr, int idx, void *data)
{ {
if( idx < 0 || idx > INT_MAX - 1 ) return -1;
if(array_list_expand_internal(arr, idx+1)) return -1; if(array_list_expand_internal(arr, idx+1)) return -1;
if(arr->array[idx]) arr->free_fn(arr->array[idx]); if(arr->array[idx]) arr->free_fn(arr->array[idx]);
arr->array[idx] = data; arr->array[idx] = data;


+ 5
- 0
json_object.c View File

@@ -934,6 +934,11 @@ struct json_object* json_object_new_array(void)
jso->_delete = &json_object_array_delete; jso->_delete = &json_object_array_delete;
jso->_to_json_string = &json_object_array_to_json_string; jso->_to_json_string = &json_object_array_to_json_string;
jso->o.c_array = array_list_new(&json_object_array_entry_free); jso->o.c_array = array_list_new(&json_object_array_entry_free);
if(jso->o.c_array == NULL)
{
free(jso);
return NULL;
}
return jso; return jso;
} }




+ 20
- 1
json_tokener.c View File

@@ -286,11 +286,15 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
saved_state = json_tokener_state_object_field_start; saved_state = json_tokener_state_object_field_start;
current = json_object_new_object(); current = json_object_new_object();
if(current == NULL)
goto out;
break; break;
case '[': case '[':
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
saved_state = json_tokener_state_array; saved_state = json_tokener_state_array;
current = json_object_new_array(); current = json_object_new_array();
if(current == NULL)
goto out;
break; break;
case 'I': case 'I':
case 'i': case 'i':
@@ -376,6 +380,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
if (tok->st_pos == json_inf_str_len) if (tok->st_pos == json_inf_str_len)
{ {
current = json_object_new_double(is_negative ? -INFINITY : INFINITY); current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
if(current == NULL)
goto out;
saved_state = json_tokener_state_finish; saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
goto redo_char; goto redo_char;
@@ -413,6 +419,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
if (tok->st_pos == json_nan_str_len) if (tok->st_pos == json_nan_str_len)
{ {
current = json_object_new_double(NAN); current = json_object_new_double(NAN);
if (current == NULL)
goto out;
saved_state = json_tokener_state_finish; saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
goto redo_char; goto redo_char;
@@ -486,6 +494,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
if(c == tok->quote_char) { if(c == tok->quote_char) {
printbuf_memappend_fast(tok->pb, case_start, str-case_start); printbuf_memappend_fast(tok->pb, case_start, str-case_start);
current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos); current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
if(current == NULL)
goto out;
saved_state = json_tokener_state_finish; saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
break; break;
@@ -646,6 +656,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
) { ) {
if(tok->st_pos == json_true_str_len) { if(tok->st_pos == json_true_str_len) {
current = json_object_new_boolean(1); current = json_object_new_boolean(1);
if(current == NULL)
goto out;
saved_state = json_tokener_state_finish; saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
goto redo_char; goto redo_char;
@@ -655,6 +667,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|| (strncmp(json_false_str, tok->pb->buf, size2) == 0)) { || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
if(tok->st_pos == json_false_str_len) { if(tok->st_pos == json_false_str_len) {
current = json_object_new_boolean(0); current = json_object_new_boolean(0);
if(current == NULL)
goto out;
saved_state = json_tokener_state_finish; saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
goto redo_char; goto redo_char;
@@ -737,10 +751,14 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
goto out; goto out;
} }
current = json_object_new_int64(num64); current = json_object_new_int64(num64);
if(current == NULL)
goto out;
} }
else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0) else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
{ {
current = json_object_new_double_s(numd, tok->pb->buf); current = json_object_new_double_s(numd, tok->pb->buf);
if(current == NULL)
goto out;
} else { } else {
tok->err = json_tokener_error_parse_number; tok->err = json_tokener_error_parse_number;
goto out; goto out;
@@ -775,7 +793,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
break; break;


case json_tokener_state_array_add: case json_tokener_state_array_add:
json_object_array_add(current, obj);
if( json_object_array_add(current, obj) != 0 )
goto out;
saved_state = json_tokener_state_array_sep; saved_state = json_tokener_state_array_sep;
state = json_tokener_state_eatws; state = json_tokener_state_eatws;
goto redo_char; goto redo_char;


Loading…
Cancel
Save