webmcp

changeset 142:a686ed2ce967

Protect json.import(...) against Lua stack overflows (or integer overflows) due to too many nested levels
author jbe
date Wed Jul 30 02:01:24 2014 +0200 (2014-07-30)
parents ca27aae3f1a1
children 6f723e60acdc
files libraries/json/json.c
line diff
     1.1 --- a/libraries/json/json.c	Wed Jul 30 01:47:01 2014 +0200
     1.2 +++ b/libraries/json/json.c	Wed Jul 30 02:01:24 2014 +0200
     1.3 @@ -3,6 +3,8 @@
     1.4  #include <stdlib.h>
     1.5  #include <string.h>
     1.6  
     1.7 +#define JSON_MAXDEPTH 100
     1.8 +
     1.9  #define JSON_REGENT static char
    1.10  #define JSON_REGREF void *
    1.11  
    1.12 @@ -118,8 +120,6 @@
    1.13      // if a JSON object is not expected here, then return an error:
    1.14      if (mode != JSON_STATE_VALUE && mode != JSON_STATE_OBJECT_VALUE && mode != JSON_STATE_ARRAY_VALUE)
    1.15        goto json_import_syntax_error;
    1.16 -    // consume input character:
    1.17 -    pos++;
    1.18      // create JSON object on stack:
    1.19      lua_newtable(L);
    1.20      // set metatable of JSON object:
    1.21 @@ -131,18 +131,14 @@
    1.22      lua_pushvalue(L, -2);
    1.23      lua_pushvalue(L, -2);
    1.24      lua_rawset(L, json_import_shadowtbl_idx);
    1.25 -    // increment level:
    1.26 -    level++;
    1.27      // expect object key (or end of object) and continue with loop:
    1.28      mode = JSON_STATE_OBJECT_KEY;
    1.29 -    goto json_import_loop;
    1.30 +    goto json_import_open;
    1.31    // new JSON array:
    1.32    case '[':
    1.33      // if a JSON array is not expected here, then return an error:
    1.34      if (mode != JSON_STATE_VALUE && mode != JSON_STATE_OBJECT_VALUE && mode != JSON_STATE_ARRAY_VALUE)
    1.35        goto json_import_syntax_error;
    1.36 -    // consume input character:
    1.37 -    pos++;
    1.38      // create JSON array on stack:
    1.39      lua_newtable(L);
    1.40      // set metatable of JSON array:
    1.41 @@ -156,10 +152,24 @@
    1.42      lua_rawset(L, json_import_shadowtbl_idx);
    1.43      // add nil as key (needed to keep stack balance) and as magic to detect arrays:
    1.44      lua_pushnil(L);
    1.45 +    // expect array value (or end of array) and continue with loop:
    1.46 +    mode = JSON_STATE_ARRAY_VALUE;
    1.47 +    // continue with common code for opening JSON object and JSON array:
    1.48 +  // commn code for opening JSON object or JSON array:
    1.49 +  json_import_open:
    1.50 +    // limit nested levels:
    1.51 +    if (level >= JSON_MAXDEPTH) {
    1.52 +      lua_pushnil(L);
    1.53 +      lua_pushliteral(L, "Too many nested JSON levels");
    1.54 +      return 2;
    1.55 +    }
    1.56 +    // additional buffer overflow protection:
    1.57 +    if (!lua_checkstack(L, LUA_MINSTACK))
    1.58 +      return luaL_error(L, "Caught stack overflow in JSON import function (too many nested levels and stack size too small)");
    1.59      // increment level:
    1.60      level++;
    1.61 -    // expect array value (or end of array) and continue with loop:
    1.62 -    mode = JSON_STATE_ARRAY_VALUE;
    1.63 +    // consume input character:
    1.64 +    pos++;
    1.65      goto json_import_loop;
    1.66    // end of JSON object:
    1.67    case '}':

Impressum / About Us