diff --git a/src/ripple/app/hook/Enum.h b/src/ripple/app/hook/Enum.h index f80a37a2c..10880caf0 100644 --- a/src/ripple/app/hook/Enum.h +++ b/src/ripple/app/hook/Enum.h @@ -126,7 +126,8 @@ namespace hook WASM_TEST_FAILURE = 78, // the smoke test failed WASM_TOO_BIG = 79, // set hook would exceed maximum hook size WASM_TOO_SMALL = 80, - WASM_VALIDATION = 81, // a generic error while parsing wasm, usually leb128 overflow + WASM_VALIDATION = 81, // a generic error while parsing wasm, usually leb128 overflow + HOOK_CBAK_DIFF_TYPES = 82, // hook and cbak function definitions were different // RH NOTE: only HookSet msgs got log codes, possibly all Hook log lines should get a code? }; }; diff --git a/src/ripple/app/hook/Guard.h b/src/ripple/app/hook/Guard.h index ca066d42a..f82d63d70 100644 --- a/src/ripple/app/hook/Guard.h +++ b/src/ripple/app/hook/Guard.h @@ -754,13 +754,24 @@ validateGuards( int hook_type_idx = func_type_map[*hook_func_idx]; // cbak function is optional so if it exists it has a type otherwise it is skipped in checks - std::optional cbak_type_idx; - if (cbak_func_idx) - cbak_type_idx = func_type_map[*cbak_func_idx]; + if (cbak_func_idx && func_type_map[*cbak_func_idx] != hook_type_idx) + { + GUARDLOG(hook::log::HOOK_CBAK_DIFF_TYPES) + << "Malformed transaction. " + << "Hook and cbak func must have the same type. int64_t (*)(uint32_t).\n"; + return {}; + } int64_t maxInstrCountHook = 0; int64_t maxInstrCountCbak = 0; +/* printf( "hook_func_idx: %d\ncbak_func_idx: %d\n" + "hook_type_idx: %d\ncbak_type_idx: %d\n", + *hook_func_idx, + *cbak_func_idx, + hook_type_idx, *cbak_type_idx); +*/ + // second pass... where we check all the guard function calls follow the guard rules // minimal other validation in this pass because first pass caught most of it for (int i = 8; i < hook.size();) @@ -788,11 +799,19 @@ validateGuards( CHECK_SHORT_HOOK(); int param_count = parseLeb128(hook, i, &i); CHECK_SHORT_HOOK(); + if (j == hook_type_idx && param_count != 1) + { + GUARDLOG(hook::log::PARAM_HOOK_CBAK) + << "Malformed transaction. " + << "hook and cbak function definition must have exactly one parameter (uint32_t)." << "\n"; + return {}; + } + for (int k = 0; k < param_count; ++k) { int param_type = parseLeb128(hook, i, &i); CHECK_SHORT_HOOK(); - if (param_type == 0x7F || param_type == 0x7E || - param_type == 0x7D || param_type == 0x7C) + if (param_type == 0x7FU || param_type == 0x7EU || + param_type == 0x7DU || param_type == 0x7CU) { // pass, this is fine } @@ -812,8 +831,7 @@ validateGuards( j, *hook_func_idx, *cbak_func_idx, param_count, param_type); // hook and cbak parameter check here - if ((j == hook_type_idx || (cbak_type_idx && j == cbak_type_idx)) && - (param_count != 1 || param_type != 0x7F /* i32 */ )) + if (j == hook_type_idx && param_type != 0x7FU /* i32 */) { GUARDLOG(hook::log::PARAM_HOOK_CBAK) << "Malformed transaction. " @@ -860,8 +878,7 @@ validateGuards( j, *hook_func_idx, *cbak_func_idx, result_count, result_type); // hook and cbak return type check here - if ((j == hook_type_idx || (cbak_type_idx && j == cbak_type_idx)) && - (result_count != 1 || result_type != 0x7E /* i64 */ )) + if (j == hook_type_idx && (result_count != 1 || result_type != 0x7E /* i64 */)) { GUARDLOG(hook::log::RETURN_HOOK_CBAK) << "Malformed transaction. "