Skip to content

Commit fe9db73

Browse files
srberardlum1n0us
authored andcommitted
test,security: added example code for invalid branch hints
Signed-off-by: Stephen Berard <[email protected]>
1 parent 2a337c4 commit fe9db73

5 files changed

Lines changed: 189 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
cmake_minimum_required (VERSION 3.14)
2+
3+
set (EXE_NAME invalid-branch-hints)
4+
project (${EXE_NAME})
5+
6+
################ runtime settings ################
7+
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
8+
9+
# Reset default linker flags
10+
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
11+
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
12+
13+
# WAMR features switch
14+
set (CMAKE_BUILD_TYPE Debug)
15+
16+
set (WAMR_BUILD_INTERP 1)
17+
set (WAMR_BUILD_AOT 1)
18+
set (WAMR_BUILD_JIT 0)
19+
set (WAMR_BUILD_LIBC_BUILTIN 1)
20+
set (WAMR_BUILD_LIBC_WASI 1)
21+
22+
# Explicitly enable branch hints
23+
add_definitions(-DWASM_ENABLE_BRANCH_HINTS=1)
24+
25+
# linker flags
26+
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
27+
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
28+
endif ()
29+
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
30+
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
31+
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
32+
endif ()
33+
endif ()
34+
35+
# build out vmlib
36+
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
37+
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
38+
39+
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
40+
41+
################ application related ################
42+
add_executable (${EXE_NAME} main.c )
43+
target_link_libraries (${EXE_NAME} vmlib -lm )
44+
45+
60 Bytes
Binary file not shown.
59 Bytes
Binary file not shown.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from pathlib import Path
2+
3+
def u32leb(n):
4+
out = bytearray()
5+
while True:
6+
b = n & 0x7f
7+
n >>= 7
8+
if n:
9+
b |= 0x80
10+
out.append(b)
11+
if not n:
12+
break
13+
return bytes(out)
14+
name = b"metadata.code.branch_hint"
15+
assert len(name) == 25
16+
def build_module(payload_tail, out_path):
17+
payload = b"".join([
18+
u32leb(len(name)),
19+
name,
20+
payload_tail
21+
])
22+
custom_section = b"\x00" + u32leb(len(payload)) + payload
23+
payload_type = u32leb(1) + b"\x60" + u32leb(0) + u32leb(0)
24+
sec_type = b"\x01" + u32leb(len(payload_type)) + payload_type
25+
payload_func = u32leb(1) + u32leb(0)
26+
sec_func = b"\x03" + u32leb(len(payload_func)) + payload_func
27+
body = u32leb(0) + b"\x0b"
28+
payload_code = u32leb(1) + u32leb(len(body)) + body
29+
sec_code = b"\x0a" + u32leb(len(payload_code)) + payload_code
30+
module = b"\x00asm" + b"\x01\x00\x00\x00" + sec_type + sec_func + sec_code + custom_section
31+
Path(out_path).write_bytes(module)
32+
payload_invalid_free = b"".join([
33+
b"\x01", # numFunctionHints
34+
b"\x00", # func_idx
35+
b"\x02", # num_hints
36+
b"\x00", # hint0 offset
37+
b"\x01", # hint0 size
38+
b"\x00", # hint0 data
39+
b"\x00", # hint1 offset
40+
b"\x02", # hint1 size (invalid)
41+
])
42+
build_module(payload_invalid_free, "branch_hint_invalid_free.wasm")
43+
payload_dos = b"".join([
44+
b"\x01",
45+
b"\x00",
46+
b"\xff\xff\xff\xff\x0f",
47+
])
48+
build_module(payload_dos, "branch_hint_null_deref.wasm")

tests/invalid-branch-hints/main.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
#include "wasm_export.h"
6+
7+
static uint8_t *
8+
read_file(const char *path, uint32_t *out_size)
9+
{
10+
FILE *fp = fopen(path, "rb");
11+
long size;
12+
uint8_t *buf;
13+
14+
if (!fp) {
15+
return NULL;
16+
}
17+
18+
if (fseek(fp, 0, SEEK_END) != 0) {
19+
fclose(fp);
20+
return NULL;
21+
}
22+
23+
size = ftell(fp);
24+
if (size < 0) {
25+
fclose(fp);
26+
return NULL;
27+
}
28+
29+
if (fseek(fp, 0, SEEK_SET) != 0) {
30+
fclose(fp);
31+
return NULL;
32+
}
33+
34+
if (size == 0) {
35+
fclose(fp);
36+
return NULL;
37+
}
38+
39+
buf = (uint8_t *)malloc((size_t)size);
40+
if (!buf) {
41+
fclose(fp);
42+
return NULL;
43+
}
44+
45+
if (fread(buf, 1, (size_t)size, fp) != (size_t)size) {
46+
free(buf);
47+
fclose(fp);
48+
return NULL;
49+
}
50+
51+
fclose(fp);
52+
*out_size = (uint32_t)size;
53+
return buf;
54+
}
55+
56+
int
57+
main(int argc, char **argv)
58+
{
59+
RuntimeInitArgs init_args;
60+
wasm_module_t module = NULL;
61+
uint8_t *buffer = NULL;
62+
uint32_t size = 0;
63+
char error_buf[128];
64+
65+
if (argc != 2) {
66+
fprintf(stderr, "usage: %s <wasm-file>\n", argv[0]);
67+
return 1;
68+
}
69+
70+
memset(&init_args, 0, sizeof(init_args));
71+
init_args.mem_alloc_type = Alloc_With_System_Allocator;
72+
73+
if (!wasm_runtime_full_init(&init_args)) {
74+
fprintf(stderr, "wasm_runtime_full_init failed\n");
75+
return 1;
76+
}
77+
78+
buffer = read_file(argv[1], &size);
79+
if (!buffer) {
80+
fprintf(stderr, "read_file failed\n");
81+
wasm_runtime_destroy();
82+
return 1;
83+
}
84+
85+
module = wasm_runtime_load(buffer, size, error_buf, sizeof(error_buf));
86+
if (!module) {
87+
fprintf(stderr, "wasm_runtime_load failed: %s\n", error_buf);
88+
}
89+
else {
90+
wasm_runtime_unload(module);
91+
}
92+
93+
free(buffer);
94+
wasm_runtime_destroy();
95+
return 0;
96+
}

0 commit comments

Comments
 (0)