Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/compilation_on_android_ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,48 @@ jobs:
ctest --output-on-failure
working-directory: tests/unit

build_array_bounds_warning_check:
needs: [build_llvm_libraries_on_ubuntu_2204]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
include:
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
steps:
- name: checkout
uses: actions/checkout@v6.0.2
with:
submodules: recursive

- name: Get LLVM libraries
id: retrieve_llvm_libs
uses: actions/cache@v5
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}

- name: Quit if cache miss
if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true'
run: echo "::error::can not get prebuilt llvm libraries" && exit 1

- name: Build shared-utils with array-bounds warnings as errors
run: |
mkdir build && cd build
cmake .. \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS="-Werror=array-bounds" \
-DCMAKE_CXX_FLAGS="-Werror=array-bounds"
cmake --build . --target shared_utils_test --parallel 4
working-directory: tests/unit

build_regression_tests:
needs: [build_llvm_libraries_on_ubuntu_2204]
runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ typedef struct AOTFrame {
* currently local's ref flags are stored in AOTModule,
* here we only reserve the padding bytes
*/
uint32 lp[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint32, lp);
} AOTFrame;

#if WASM_ENABLE_STATIC_PGO != 0
Expand Down
4 changes: 2 additions & 2 deletions core/iwasm/common/gc/gc_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ typedef uintptr_t WASMI31ObjectRef;
typedef struct WASMStructObject {
/* Must be pointer of WASMRttObject of struct type */
WASMObjectHeader header;
uint8 field_data[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint8, field_data);
} WASMStructObject, *WASMStructObjectRef;

/* Representation of WASM array objects */
Expand All @@ -89,7 +89,7 @@ typedef struct WASMArrayObject {
* elem_size = 2 ^ (length & 0x3)
*/
uint32 length;
uint8 elem_data[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint8, elem_data);
} WASMArrayObject, *WASMArrayObjectRef;

#define WASM_ARRAY_LENGTH_SHIFT 2
Expand Down
2 changes: 1 addition & 1 deletion core/iwasm/compilation/aot.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ typedef struct AOTTableInitData {
/* Function index count */
uint32 value_count;
/* Function index array */
InitializerExpression init_values[1];
BH_FLEXIBLE_ARRAY_MEMBER(InitializerExpression, init_values);
} AOTTableInitData;

/**
Expand Down
10 changes: 5 additions & 5 deletions core/iwasm/interpreter/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,13 @@ typedef union WASMValue {
typedef struct WASMStructNewInitValues {
uint32 type_idx;
uint32 count;
WASMValue fields[1];
BH_FLEXIBLE_ARRAY_MEMBER(WASMValue, fields);
} WASMStructNewInitValues;

typedef struct WASMArrayNewInitValues {
uint32 type_idx;
uint32 length;
WASMValue elem_data[1];
BH_FLEXIBLE_ARRAY_MEMBER(WASMValue, elem_data);
} WASMArrayNewInitValues;

typedef struct InitializerExpression {
Expand Down Expand Up @@ -444,7 +444,7 @@ typedef struct WASMFuncType {
/* types of params and results, only store the first byte
* of the type, if it cannot be described with one byte,
* then the full type info is stored in ref_type_maps */
uint8 types[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint8, types);
} WASMFuncType;

#if WASM_ENABLE_GC != 0
Expand Down Expand Up @@ -486,7 +486,7 @@ typedef struct WASMStructType {
* the first byte of the field type, if it cannot be described
* with one byte, then the full field type info is stored in
* ref_type_maps */
WASMStructFieldType fields[1];
BH_FLEXIBLE_ARRAY_MEMBER(WASMStructFieldType, fields);
} WASMStructType;

typedef struct WASMArrayType {
Expand Down Expand Up @@ -862,7 +862,7 @@ typedef struct BrTableCache {
/* Address of br_table opcode */
uint8 *br_table_op_addr;
uint32 br_count;
uint32 br_depths[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint32, br_depths);
} BrTableCache;

#if WASM_ENABLE_DEBUG_INTERP != 0
Expand Down
4 changes: 2 additions & 2 deletions core/iwasm/interpreter/wasm_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ typedef struct WASMInterpFrame {
#if WASM_ENABLE_GC != 0
uint8 *frame_ref;
#endif
uint32 operand[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint32, operand);
#else /* else of WASM_ENABLE_FAST_INTERP != 0 */
/* Operand stack top pointer of the current frame. The bottom of
the stack is the next cell after the last local variable. */
Expand All @@ -71,7 +71,7 @@ typedef struct WASMInterpFrame {
* whether each cell in local and stack area is a GC obj
* jit spill cache: only available for fast jit
*/
uint32 lp[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint32, lp);
#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */
} WASMInterpFrame;

Expand Down
4 changes: 3 additions & 1 deletion core/iwasm/interpreter/wasm_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -1328,8 +1328,10 @@ load_init_expr(WASMModule *module, const uint8 **p_buf, const uint8 *buf_end,
goto fail;
}

/* Use offsetof for flexible array members:
sizeof excludes elem_data when it is []. */
size =
sizeof(WASMArrayNewInitValues)
offsetof(WASMArrayNewInitValues, elem_data)
+ sizeof(WASMValue) * (uint64)len_val.i32;
if (!(array_init_values = loader_malloc(
size, error_buf, error_buf_size))) {
Expand Down
2 changes: 1 addition & 1 deletion core/iwasm/interpreter/wasm_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ struct WASMTableInstance {
/* Maximum size */
uint32 max_size;
/* Table elements */
table_elem_type_t elems[1];
BH_FLEXIBLE_ARRAY_MEMBER(table_elem_type_t, elems);
};

struct WASMGlobalInstance {
Expand Down
10 changes: 10 additions & 0 deletions core/shared/platform/include/platform_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ BH_VPRINTF(const char *format, va_list ap);
#endif
#endif

/* Prefer C99 flexible array members for FORTIFY/ASAN compatibility */
#ifndef BH_FLEXIBLE_ARRAY_MEMBER
#if !defined(__cplusplus) && defined(__STDC_VERSION__) \
&& __STDC_VERSION__ >= 199901L
#define BH_FLEXIBLE_ARRAY_MEMBER(type, name) type name[]
#else
#define BH_FLEXIBLE_ARRAY_MEMBER(type, name) type name[1]
#endif
#endif

typedef uint8_t uint8;
typedef int8_t int8;
typedef uint16_t uint16;
Expand Down
2 changes: 1 addition & 1 deletion core/shared/utils/bh_bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ typedef struct bh_bitmap {
uintptr_t end_index;

/* The bitmap. */
uint8 map[1];
BH_FLEXIBLE_ARRAY_MEMBER(uint8, map);
} bh_bitmap;

/**
Expand Down
2 changes: 1 addition & 1 deletion core/shared/utils/bh_hashmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct HashMap {
KeyEqualFunc key_equal_func;
KeyDestroyFunc key_destroy_func;
ValueDestroyFunc value_destroy_func;
HashMapElem *elements[1];
BH_FLEXIBLE_ARRAY_MEMBER(HashMapElem *, elements);
};

HashMap *
Expand Down
30 changes: 28 additions & 2 deletions tests/unit/shared-utils/bh_hashmap_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,27 @@ struct HashMap {
KeyEqualFunc key_equal_func;
KeyDestroyFunc key_destroy_func;
ValueDestroyFunc value_destroy_func;
HashMapElem *elements[1];
BH_FLEXIBLE_ARRAY_MEMBER(HashMapElem *, elements);
};

int DESTROY_NUM = 0;
char TRAVERSE_KEY[] = "key_1";
char TRAVERSE_VAL[] = "val_1";
int TRAVERSE_COMP_RES = 0;

uint32
hash_to_last_bucket(const void *key)
{
(void)key;
return 31;
}

bool
ptr_equal_test(void *key1, void *key2)
{
return key1 == key2;
}

class bh_hashmap_test_suite : public testing::Test
{
protected:
Expand Down Expand Up @@ -108,6 +121,19 @@ TEST_F(bh_hashmap_test_suite, bh_hash_map_insert)
(void *)"val_1"));
}

TEST_F(bh_hashmap_test_suite, bh_hash_map_insert_trailing_bucket)
{
HashMap *test_hash_map = bh_hash_map_create(
32, false, hash_to_last_bucket, ptr_equal_test, nullptr, nullptr);
int key = 0;
int value = 0;

ASSERT_NE((HashMap *)nullptr, test_hash_map);
EXPECT_EQ(true, bh_hash_map_insert(test_hash_map, &key, &value));
EXPECT_EQ(&value, bh_hash_map_find(test_hash_map, &key));
EXPECT_EQ(true, bh_hash_map_destroy(test_hash_map));
}

TEST_F(bh_hashmap_test_suite, bh_hash_map_find)
{
HashMap *test_hash_map = bh_hash_map_create(
Expand Down Expand Up @@ -359,4 +385,4 @@ TEST_F(bh_hashmap_test_suite, bh_hashmap_thread_safety)

EXPECT_EQ(200, COUNT_ELEM);
EXPECT_EQ(true, bh_hash_map_destroy(test_hash_map));
}
}
5 changes: 4 additions & 1 deletion tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ run_aot_tests () {
test_aot="${test_wasm%.wasm}.aot"
test_json="${test_wasm%.wasm}.json"

# This pre-read is redundant: expected is reset below before checking
if [ -f ${test_wasm} ]; then
expected=$(jq .exit_code ${test_json})
fi
Expand Down Expand Up @@ -141,7 +142,9 @@ if [[ $MODE != "aot" ]];then
deactivate
else
target_option=""
if [[ $TARGET == "X86_32" ]];then
if [[ $TARGET == "X86_64" ]]; then
target_option="--target=x86_64 --cpu=x86-64"
elif [[ $TARGET == "X86_32" ]];then
target_option="--target=i386"
fi

Expand Down
Loading