Fix wasi ctx memory free issue when app heap is corrupted (#455)

This commit is contained in:
Wenyong Huang
2020-11-30 17:00:53 +08:00
committed by GitHub
parent 282831eba5
commit 0700dc9cd4
5 changed files with 112 additions and 203 deletions

View File

@ -45,49 +45,43 @@ typedef struct iovec_app {
} iovec_app_t;
typedef struct WASIContext {
uint32 curfds_offset;
uint32 prestats_offset;
uint32 argv_environ_offset;
uint32 argv_buf_offset;
uint32 argv_offsets_offset;
uint32 env_buf_offset;
uint32 env_offsets_offset;
struct fd_table *curfds;
struct fd_prestats *prestats;
struct argv_environ_values *argv_environ;
char *argv_buf;
char **argv_list;
char *env_buf;
char **env_list;
} *wasi_ctx_t;
wasi_ctx_t
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
static struct fd_table *
static inline struct fd_table *
wasi_ctx_get_curfds(wasm_module_inst_t module_inst,
wasi_ctx_t wasi_ctx)
{
if (!wasi_ctx)
return NULL;
return (struct fd_table *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->curfds_offset);
return wasi_ctx->curfds;
}
static struct argv_environ_values *
static inline struct argv_environ_values *
wasi_ctx_get_argv_environ(wasm_module_inst_t module_inst,
wasi_ctx_t wasi_ctx)
{
if (!wasi_ctx)
return NULL;
return (struct argv_environ_values *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->argv_environ_offset);
return wasi_ctx->argv_environ;
}
static struct fd_prestats *
static inline struct fd_prestats *
wasi_ctx_get_prestats(wasm_module_inst_t module_inst,
wasi_ctx_t wasi_ctx)
{
if (!wasi_ctx)
return NULL;
return (struct fd_prestats *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->prestats_offset);
return wasi_ctx->prestats;
}
static wasi_errno_t
@ -152,9 +146,7 @@ wasi_args_sizes_get(wasm_exec_env_t exec_env,
|| !validate_native_addr(argv_buf_size_app, sizeof(uint32)))
return (wasi_errno_t)-1;
argv_environ = (struct argv_environ_values *)
wasm_runtime_addr_app_to_native(module_inst,
wasi_ctx->argv_environ_offset);
argv_environ = wasi_ctx->argv_environ;
err = wasmtime_ssp_args_sizes_get(argv_environ,
&argc, &argv_buf_size);

View File

@ -2822,7 +2822,7 @@ __wasi_errno_t wasmtime_ssp_args_get(
char *argv_buf
) {
for (size_t i = 0; i < argv_environ->argc; ++i) {
argv[i] = argv_buf + (argv_environ->argv[i] - argv_environ->argv_buf);
argv[i] = argv_buf + (argv_environ->argv_list[i] - argv_environ->argv_buf);
}
argv[argv_environ->argc] = NULL;
bh_memcpy_s(argv_buf, (uint32)argv_environ->argv_buf_size,
@ -2850,7 +2850,7 @@ __wasi_errno_t wasmtime_ssp_environ_get(
char *environ_buf
) {
for (size_t i = 0; i < argv_environ->environ_count; ++i) {
environ[i] = environ_buf + (argv_environ->environ[i] - argv_environ->environ_buf);
environ[i] = environ_buf + (argv_environ->environ_list[i] - argv_environ->environ_buf);
}
environ[argv_environ->environ_count] = NULL;
bh_memcpy_s(environ_buf, (uint32)argv_environ->environ_buf_size,
@ -2871,76 +2871,26 @@ __wasi_errno_t wasmtime_ssp_environ_sizes_get(
}
bool argv_environ_init(struct argv_environ_values *argv_environ,
const size_t *argv_offsets, size_t argv_offsets_len,
const char *argv_buf, size_t argv_buf_len,
const size_t *environ_offsets, size_t environ_offsets_len,
const char *environ_buf, size_t environ_buf_len)
char *argv_buf, size_t argv_buf_size,
char **argv_list, size_t argc,
char *environ_buf, size_t environ_buf_size,
char **environ_list, size_t environ_count)
{
uint64 total_size;
size_t i;
memset(argv_environ, 0, sizeof(struct argv_environ_values));
argv_environ->argc = argv_offsets_len;
argv_environ->argv_buf_size = argv_buf_len;
total_size = sizeof(char *) * (uint64)argv_offsets_len;
if (total_size >= UINT32_MAX
|| !(argv_environ->argv = wasm_runtime_malloc((uint32)total_size)))
return false;
if (argv_buf_len >= UINT32_MAX
|| !(argv_environ->argv_buf = wasm_runtime_malloc((uint32)argv_buf_len)))
goto fail1;
for (i = 0; i < argv_offsets_len; ++i) {
argv_environ->argv[i] = argv_environ->argv_buf + argv_offsets[i];
}
bh_memcpy_s(argv_environ->argv_buf, (uint32)argv_buf_len,
argv_buf, (uint32)argv_buf_len);
argv_environ->environ_count = environ_offsets_len;
argv_environ->environ_buf_size = environ_buf_len;
total_size = sizeof(char *) * (uint64)environ_offsets_len;
if (total_size >= UINT32_MAX
|| !(argv_environ->environ = wasm_runtime_malloc((uint32)total_size)))
goto fail2;
if (environ_buf_len >= UINT32_MAX
|| !(argv_environ->environ_buf = wasm_runtime_malloc((uint32)environ_buf_len)))
goto fail3;
for (i = 0; i < environ_offsets_len; ++i) {
argv_environ->environ[i] = argv_environ->environ_buf + environ_offsets[i];
}
bh_memcpy_s(argv_environ->environ_buf, (uint32)environ_buf_len,
environ_buf, (uint32)environ_buf_len);
argv_environ->argv_buf = argv_buf;
argv_environ->argv_buf_size = argv_buf_size;
argv_environ->argv_list = argv_list;
argv_environ->argc = argc;
argv_environ->environ_buf = environ_buf;
argv_environ->environ_buf_size = environ_buf_size;
argv_environ->environ_list = environ_list;
argv_environ->environ_count = environ_count;
return true;
fail3:
wasm_runtime_free(argv_environ->environ);
fail2:
wasm_runtime_free(argv_environ->argv_buf);
fail1:
wasm_runtime_free(argv_environ->argv);
memset(argv_environ, 0, sizeof(struct argv_environ_values));
return false;
}
void argv_environ_destroy(struct argv_environ_values *argv_environ)
{
if (argv_environ->argv_buf)
wasm_runtime_free(argv_environ->argv_buf);
if (argv_environ->argv)
wasm_runtime_free(argv_environ->argv);
if (argv_environ->environ_buf)
wasm_runtime_free(argv_environ->environ_buf);
if (argv_environ->environ)
wasm_runtime_free(argv_environ->environ);
}
void fd_table_destroy(struct fd_table *ft)

View File

@ -34,25 +34,25 @@ struct fd_prestats {
};
struct argv_environ_values {
size_t argc;
const char *argv_buf;
size_t argv_buf_size;
char **argv;
char *argv_buf;
size_t environ_count;
size_t environ_buf_size;
char **environ;
char **argv_list;
size_t argc;
char *environ_buf;
size_t environ_buf_size;
char **environ_list;
size_t environ_count;
};
bool fd_table_init(struct fd_table *);
bool fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
bool fd_prestats_init(struct fd_prestats *);
bool fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
bool argv_environ_init(struct argv_environ_values *,
const size_t *argv_offsets, size_t argv_offsets_len,
const char *argv_buf, size_t argv_buf_len,
const size_t *environ_offsets, size_t environ_offsets_len,
const char *environ_buf, size_t environ_buf_len);
bool argv_environ_init(struct argv_environ_values *argv_environ,
char *argv_buf, size_t argv_buf_size,
char **argv_list, size_t argc,
char *environ_buf, size_t environ_buf_size,
char **environ_list, size_t environ_count);
void argv_environ_destroy(struct argv_environ_values *argv_environ);
void fd_table_destroy(struct fd_table *ft);
void fd_prestats_destroy(struct fd_prestats *pt);