epee: fix stack overflow on crafted input

This commit is contained in:
moneromooo-monero 2018-08-05 08:42:52 +00:00
parent c7bca47b69
commit f61cd54465
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

View File

@ -30,6 +30,8 @@
#include "parserse_base_utils.h" #include "parserse_base_utils.h"
#include "file_io_utils.h" #include "file_io_utils.h"
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100
namespace epee namespace epee
{ {
using namespace misc_utils::parse; using namespace misc_utils::parse;
@ -44,8 +46,9 @@ namespace epee
ASSERT_MES_AND_THROW("json parse error"); ASSERT_MES_AND_THROW("json parse error");
}*/ }*/
template<class t_storage> template<class t_storage>
inline void run_handler(typename t_storage::hsection current_section, std::string::const_iterator& sec_buf_begin, std::string::const_iterator buf_end, t_storage& stg) inline void run_handler(typename t_storage::hsection current_section, std::string::const_iterator& sec_buf_begin, std::string::const_iterator buf_end, t_storage& stg, unsigned int recursion)
{ {
CHECK_AND_ASSERT_THROW_MES(recursion < EPEE_JSON_RECURSION_LIMIT_INTERNAL, "Wrong JSON data: recursion limitation (" << EPEE_JSON_RECURSION_LIMIT_INTERNAL << ") exceeded");
std::string::const_iterator sub_element_start; std::string::const_iterator sub_element_start;
std::string name; std::string name;
@ -157,7 +160,7 @@ namespace epee
//sub section here //sub section here
typename t_storage::hsection new_sec = stg.open_section(name, current_section, true); typename t_storage::hsection new_sec = stg.open_section(name, current_section, true);
CHECK_AND_ASSERT_THROW_MES(new_sec, "Failed to insert new section in json: " << std::string(it, buf_end)); CHECK_AND_ASSERT_THROW_MES(new_sec, "Failed to insert new section in json: " << std::string(it, buf_end));
run_handler(new_sec, it, buf_end, stg); run_handler(new_sec, it, buf_end, stg, recursion + 1);
state = match_state_wonder_after_value; state = match_state_wonder_after_value;
}else if(*it == '[') }else if(*it == '[')
{//array of something {//array of something
@ -186,7 +189,7 @@ namespace epee
typename t_storage::hsection new_sec = nullptr; typename t_storage::hsection new_sec = nullptr;
h_array = stg.insert_first_section(name, new_sec, current_section); h_array = stg.insert_first_section(name, new_sec, current_section);
CHECK_AND_ASSERT_THROW_MES(h_array&&new_sec, "failed to create new section"); CHECK_AND_ASSERT_THROW_MES(h_array&&new_sec, "failed to create new section");
run_handler(new_sec, it, buf_end, stg); run_handler(new_sec, it, buf_end, stg, recursion + 1);
state = match_state_array_after_value; state = match_state_array_after_value;
array_md = array_mode_sections; array_md = array_mode_sections;
}else if(*it == '"') }else if(*it == '"')
@ -260,7 +263,7 @@ namespace epee
typename t_storage::hsection new_sec = NULL; typename t_storage::hsection new_sec = NULL;
bool res = stg.insert_next_section(h_array, new_sec); bool res = stg.insert_next_section(h_array, new_sec);
CHECK_AND_ASSERT_THROW_MES(res&&new_sec, "failed to insert next section"); CHECK_AND_ASSERT_THROW_MES(res&&new_sec, "failed to insert next section");
run_handler(new_sec, it, buf_end, stg); run_handler(new_sec, it, buf_end, stg, recursion + 1);
state = match_state_array_after_value; state = match_state_array_after_value;
}else CHECK_ISSPACE(); }else CHECK_ISSPACE();
break; break;
@ -362,7 +365,7 @@ namespace epee
std::string::const_iterator sec_buf_begin = buff_json.begin(); std::string::const_iterator sec_buf_begin = buff_json.begin();
try try
{ {
run_handler(nullptr, sec_buf_begin, buff_json.end(), stg); run_handler(nullptr, sec_buf_begin, buff_json.end(), stg, 0);
return true; return true;
} }
catch(const std::exception& ex) catch(const std::exception& ex)