mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +00:00
Validate func type in aot loader (#3535)
Fix issue reported by Oss-fuzz test (#69629).
This commit is contained in:
parent
f096b2fa38
commit
c19bc95391
|
@ -1684,6 +1684,9 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
|
|
||||||
func_type->ref_type_map_count = ref_type_map_count;
|
func_type->ref_type_map_count = ref_type_map_count;
|
||||||
|
|
||||||
|
if (!is_valid_func_type(func_type))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
param_cell_num = wasm_get_cell_num(func_type->types, param_count);
|
param_cell_num = wasm_get_cell_num(func_type->types, param_count);
|
||||||
ret_cell_num =
|
ret_cell_num =
|
||||||
wasm_get_cell_num(func_type->types + param_count, result_count);
|
wasm_get_cell_num(func_type->types + param_count, result_count);
|
||||||
|
@ -1988,6 +1991,9 @@ load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
func_types[i]->result_count = (uint16)result_count;
|
func_types[i]->result_count = (uint16)result_count;
|
||||||
read_byte_array(buf, buf_end, func_types[i]->types, (uint32)size1);
|
read_byte_array(buf, buf_end, func_types[i]->types, (uint32)size1);
|
||||||
|
|
||||||
|
if (!is_valid_func_type(func_types[i]))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
param_cell_num = wasm_get_cell_num(func_types[i]->types, param_count);
|
param_cell_num = wasm_get_cell_num(func_types[i]->types, param_count);
|
||||||
ret_cell_num =
|
ret_cell_num =
|
||||||
wasm_get_cell_num(func_types[i]->types + param_count, result_count);
|
wasm_get_cell_num(func_types[i]->types + param_count, result_count);
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
*/
|
*/
|
||||||
#include "wasm_loader_common.h"
|
#include "wasm_loader_common.h"
|
||||||
#include "bh_log.h"
|
#include "bh_log.h"
|
||||||
#include "../interpreter/wasm.h"
|
#if WASM_ENABLE_GC != 0
|
||||||
|
#include "../common/gc/gc_type.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string,
|
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string,
|
||||||
|
@ -56,3 +58,41 @@ wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compare with a bigger type set in `wasm_value_type_size_internal()`,
|
||||||
|
* this function will only cover global value type, function's param
|
||||||
|
* value type and function's result value type.
|
||||||
|
*
|
||||||
|
* please feel free to add more if there are more requirements
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
is_valid_value_type(uint8 type)
|
||||||
|
{
|
||||||
|
if (/* I32/I64/F32/F64, 0x7C to 0x7F */
|
||||||
|
(type >= VALUE_TYPE_F64 && type <= VALUE_TYPE_I32)
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
/* reference types, 0x65 to 0x70 */
|
||||||
|
|| wasm_is_type_reftype(type)
|
||||||
|
#elif WASM_ENABLE_REF_TYPES != 0
|
||||||
|
|| (type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF)
|
||||||
|
#endif
|
||||||
|
#if WASM_ENABLE_SIMD != 0
|
||||||
|
|| type == VALUE_TYPE_V128 /* 0x7B */
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_valid_func_type(const WASMFuncType *func_type)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < func_type->param_count + func_type->result_count; i++) {
|
||||||
|
if (!is_valid_value_type(func_type->types[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define _WASM_LOADER_COMMON_H
|
#define _WASM_LOADER_COMMON_H
|
||||||
|
|
||||||
#include "platform_common.h"
|
#include "platform_common.h"
|
||||||
|
#include "../interpreter/wasm.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -16,6 +17,12 @@ bool
|
||||||
wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
|
wasm_memory_check_flags(const uint8 mem_flag, char *error_buf,
|
||||||
uint32 error_buf_size, bool is_aot);
|
uint32 error_buf_size, bool is_aot);
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_valid_value_type(uint8 value_tpye);
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_valid_func_type(const WASMFuncType *func_type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -323,27 +323,6 @@ is_64bit_type(uint8 type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
is_value_type(uint8 type)
|
|
||||||
{
|
|
||||||
if (/* I32/I64/F32/F64, 0x7C to 0x7F */
|
|
||||||
(type >= VALUE_TYPE_F64 && type <= VALUE_TYPE_I32)
|
|
||||||
#if WASM_ENABLE_GC != 0
|
|
||||||
/* reference types, 0x65 to 0x70 */
|
|
||||||
|| wasm_is_type_reftype(type)
|
|
||||||
#elif WASM_ENABLE_REF_TYPES != 0
|
|
||||||
|| (type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF)
|
|
||||||
#endif
|
|
||||||
#if WASM_ENABLE_SIMD != 0
|
|
||||||
#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0)
|
|
||||||
|| type == VALUE_TYPE_V128 /* 0x7B */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WASM_ENABLE_GC != 0
|
#if WASM_ENABLE_GC != 0
|
||||||
static bool
|
static bool
|
||||||
is_packed_type(uint8 type)
|
is_packed_type(uint8 type)
|
||||||
|
@ -355,7 +334,8 @@ is_packed_type(uint8 type)
|
||||||
static bool
|
static bool
|
||||||
is_byte_a_type(uint8 type)
|
is_byte_a_type(uint8 type)
|
||||||
{
|
{
|
||||||
return (is_value_type(type) || (type == VALUE_TYPE_VOID)) ? true : false;
|
return (is_valid_value_type(type) || (type == VALUE_TYPE_VOID)) ? true
|
||||||
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WASM_ENABLE_SIMD != 0
|
#if WASM_ENABLE_SIMD != 0
|
||||||
|
@ -1462,7 +1442,7 @@ resolve_value_type(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* type which can be represented by one byte */
|
/* type which can be represented by one byte */
|
||||||
if (!is_value_type(type)
|
if (!is_valid_value_type(type)
|
||||||
&& !(allow_packed_type && is_packed_type(type))) {
|
&& !(allow_packed_type && is_packed_type(type))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
||||||
return false;
|
return false;
|
||||||
|
@ -1972,7 +1952,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
type->types[param_count + j] = read_uint8(p);
|
type->types[param_count + j] = read_uint8(p);
|
||||||
}
|
}
|
||||||
for (j = 0; j < param_count + result_count; j++) {
|
for (j = 0; j < param_count + result_count; j++) {
|
||||||
if (!is_value_type(type->types[j])) {
|
if (!is_valid_value_type(type->types[j])) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"unknown value type");
|
"unknown value type");
|
||||||
return false;
|
return false;
|
||||||
|
@ -3061,7 +3041,7 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||||
CHECK_BUF(p, p_end, 2);
|
CHECK_BUF(p, p_end, 2);
|
||||||
/* global type */
|
/* global type */
|
||||||
declare_type = read_uint8(p);
|
declare_type = read_uint8(p);
|
||||||
if (!is_value_type(declare_type)) {
|
if (!is_valid_value_type(declare_type)) {
|
||||||
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3773,7 +3753,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
CHECK_BUF(p_code, buf_code_end, 1);
|
CHECK_BUF(p_code, buf_code_end, 1);
|
||||||
/* 0x7F/0x7E/0x7D/0x7C */
|
/* 0x7F/0x7E/0x7D/0x7C */
|
||||||
type = read_uint8(p_code);
|
type = read_uint8(p_code);
|
||||||
if (!is_value_type(type)) {
|
if (!is_valid_value_type(type)) {
|
||||||
if (type == VALUE_TYPE_V128)
|
if (type == VALUE_TYPE_V128)
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"v128 value type requires simd feature");
|
"v128 value type requires simd feature");
|
||||||
|
@ -4048,7 +4028,7 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
CHECK_BUF(p, p_end, 2);
|
CHECK_BUF(p, p_end, 2);
|
||||||
/* global type */
|
/* global type */
|
||||||
global->type.val_type = read_uint8(p);
|
global->type.val_type = read_uint8(p);
|
||||||
if (!is_value_type(global->type.val_type)) {
|
if (!is_valid_value_type(global->type.val_type)) {
|
||||||
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
set_error_buf(error_buf, error_buf_size, "type mismatch");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -12322,7 +12302,7 @@ re_scan:
|
||||||
#if WASM_ENABLE_GC == 0
|
#if WASM_ENABLE_GC == 0
|
||||||
CHECK_BUF(p, p_end, 1);
|
CHECK_BUF(p, p_end, 1);
|
||||||
type = read_uint8(p);
|
type = read_uint8(p);
|
||||||
if (!is_value_type(type)) {
|
if (!is_valid_value_type(type)) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"unknown value type");
|
"unknown value type");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -88,23 +88,10 @@ is_64bit_type(uint8 type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
is_value_type(uint8 type)
|
|
||||||
{
|
|
||||||
if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_I64
|
|
||||||
|| type == VALUE_TYPE_F32 || type == VALUE_TYPE_F64
|
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
|
||||||
|| type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_byte_a_type(uint8 type)
|
is_byte_a_type(uint8 type)
|
||||||
{
|
{
|
||||||
return is_value_type(type) || (type == VALUE_TYPE_VOID);
|
return is_valid_value_type(type) || (type == VALUE_TYPE_VOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -581,7 +568,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
type->types[param_count + j] = read_uint8(p);
|
type->types[param_count + j] = read_uint8(p);
|
||||||
}
|
}
|
||||||
for (j = 0; j < param_count + result_count; j++) {
|
for (j = 0; j < param_count + result_count; j++) {
|
||||||
bh_assert(is_value_type(type->types[j]));
|
bh_assert(is_valid_value_type(type->types[j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
param_cell_num = wasm_get_cell_num(type->types, param_count);
|
param_cell_num = wasm_get_cell_num(type->types, param_count);
|
||||||
|
@ -1228,7 +1215,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
CHECK_BUF(p_code, buf_code_end, 1);
|
CHECK_BUF(p_code, buf_code_end, 1);
|
||||||
/* 0x7F/0x7E/0x7D/0x7C */
|
/* 0x7F/0x7E/0x7D/0x7C */
|
||||||
type = read_uint8(p_code);
|
type = read_uint8(p_code);
|
||||||
bh_assert(is_value_type(type));
|
bh_assert(is_valid_value_type(type));
|
||||||
for (k = 0; k < sub_local_count; k++) {
|
for (k = 0; k < sub_local_count; k++) {
|
||||||
func->local_types[local_type_index++] = type;
|
func->local_types[local_type_index++] = type;
|
||||||
}
|
}
|
||||||
|
@ -6829,7 +6816,7 @@ re_scan:
|
||||||
|
|
||||||
CHECK_BUF(p, p_end, 1);
|
CHECK_BUF(p, p_end, 1);
|
||||||
ref_type = read_uint8(p);
|
ref_type = read_uint8(p);
|
||||||
if (!is_value_type(ref_type)) {
|
if (!is_valid_value_type(ref_type)) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"unknown value type");
|
"unknown value type");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user