diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/interp/linear/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/interp/linear/check.c | 23 | ||||
| -rw-r--r-- | src/interp/linear/load.c | 17 | ||||
| -rw-r--r-- | src/interp/linear/store.c | 16 |
4 files changed, 55 insertions, 2 deletions
diff --git a/src/interp/linear/CMakeLists.txt b/src/interp/linear/CMakeLists.txt index 0f0e056..7ed9e91 100644 --- a/src/interp/linear/CMakeLists.txt +++ b/src/interp/linear/CMakeLists.txt @@ -6,6 +6,7 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. target_sources(${PROJECT_NAME} PRIVATE + check.c load.c store.c ) diff --git a/src/interp/linear/check.c b/src/interp/linear/check.c new file mode 100644 index 0000000..f2bea9a --- /dev/null +++ b/src/interp/linear/check.c @@ -0,0 +1,23 @@ +/* + * nanowasm, a tiny WebAssembly/Wasm interpreter + * Copyright (C) 2023-2025 Xavier Del Campo Romero + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include <nanowasm/nw.h> +#include <nanowasm/linear.h> +#include <nw/interp.h> +#include <nw/mem.h> +#include <nw/log.h> + +int nwp_linear_check(const struct nw_interp *const i, + const unsigned long offset, const size_t n) +{ + const unsigned long pagesize = 64lu << 10lu, + end = i->linear.n_pages * pagesize; + + return offset >= end || n > end || offset >= end - n; +} diff --git a/src/interp/linear/load.c b/src/interp/linear/load.c index afc6154..38294c4 100644 --- a/src/interp/linear/load.c +++ b/src/interp/linear/load.c @@ -9,6 +9,7 @@ #include <nanowasm/nw.h> #include <nanowasm/linear.h> +#include <nw/linear.h> #include <nw/interp.h> #include <nw/mem.h> #include <nw/log.h> @@ -17,7 +18,21 @@ enum nw_state nwp_linear_load(struct nw_interp *const i, struct nw_sm_io *const io, const unsigned long offset) { const struct nw_interp_cfg *const cfg = &i->cfg; - const enum nw_state n = nwp_mem_load(&cfg->linear, io, offset, cfg->user); + enum nw_state n; + + if (nwp_linear_check(i, offset, io->n)) + { + static const char *const exc = "out-of-bounds read access to " + "linear memory"; + +#ifdef NW_LOG + nwp_log("%s, addr=%#lx, sz=%#lx\n", exc, offset, io->n); +#endif + i->exception = exc; + return NW_FATAL; + } + + n = nwp_mem_load(&cfg->linear, io, offset, cfg->user); if (n == NW_FATAL) { diff --git a/src/interp/linear/store.c b/src/interp/linear/store.c index 6edffd9..904b969 100644 --- a/src/interp/linear/store.c +++ b/src/interp/linear/store.c @@ -18,7 +18,21 @@ enum nw_state nwp_linear_store(struct nw_interp *const i, struct nw_sm_io *const io, const unsigned long offset) { const struct nw_interp_cfg *const cfg = &i->cfg; - const enum nw_state n = nwp_mem_store(&cfg->linear, io, offset, cfg->user); + enum nw_state n; + + if (nwp_linear_check(i, offset, io->n)) + { + static const char *const exc = "out-of-bounds write access to " + "linear memory"; + +#ifdef NW_LOG + nwp_log("%s, addr=%#lx, sz=%#lx\n", exc, offset, io->n); +#endif + i->exception = exc; + return NW_FATAL; + } + + n = nwp_mem_store(&cfg->linear, io, offset, cfg->user); if (n == NW_FATAL) { |
