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 '}':