From 9936872190450a1de1b0bfb763098bd3922b83b1 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 22 Apr 2023 14:11:53 +0100 Subject: [PATCH] Stack corruption with large number of arguments. Fixes #665 --- NEWS.md | 1 + src/jit/jit-irgen.c | 12 +++++++++++- src/jit/jit-priv.h | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3e813234..1e583665 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ - Fix elaboration errors with recursive entity instantiation (#668). - Updated to latest GtkWave FST writer library. - Fix crash when an external name is used in a wait expression (#674). +- Fix stack corruption when passing large numbers of arguments (#665). ## Version 1.9.1 - 2023-04-15 - Fix build errors and warnings on MSYS2 Clang x64 environment. diff --git a/src/jit/jit-irgen.c b/src/jit/jit-irgen.c index 51893b58..f327a942 100644 --- a/src/jit/jit-irgen.c +++ b/src/jit/jit-irgen.c @@ -314,6 +314,7 @@ static void irgen_patch_label(jit_irgen_t *g, jit_ir_t *ir, irgen_label_t *l) static jit_value_t j_recv(jit_irgen_t *g, int pos) { + assert(pos < JIT_MAX_ARGS); jit_reg_t r = irgen_alloc_reg(g); irgen_emit_unary(g, J_RECV, JIT_SZ_UNSPEC, JIT_CC_NONE, r, jit_value_from_int64(pos)); @@ -322,6 +323,7 @@ static jit_value_t j_recv(jit_irgen_t *g, int pos) static void j_send(jit_irgen_t *g, int pos, jit_value_t value) { + assert(pos < JIT_MAX_ARGS); irgen_emit_binary(g, J_SEND, JIT_SZ_UNSPEC, JIT_CC_NONE, JIT_REG_INVALID, jit_value_from_int64(pos), value); } @@ -1195,7 +1197,10 @@ static void irgen_send_args(jit_irgen_t *g, int op, int first) for (int i = 0, pslot = first; i < nargs; i++) { vcode_reg_t vreg = vcode_get_arg(op, i); int slots = irgen_slots_for_type(vcode_reg_type(vreg)); - if (slots > 1) { + if (unlikely(pslot + slots >= JIT_MAX_ARGS)) + fatal("call to %s requires more than the maximum supported " + "%d arguments", istr(vcode_get_func(op)), JIT_MAX_ARGS); + else if (slots > 1) { jit_reg_t base = jit_value_as_reg(irgen_get_value(g, vreg)); for (int j = 0; j < slots; j++) j_send(g, pslot++, jit_value_from_reg(base + j)); @@ -3783,6 +3788,11 @@ static void irgen_params(jit_irgen_t *g, int first) vcode_reg_t preg = vcode_param_reg(i); vcode_type_t vtype = vcode_param_type(i); int slots = irgen_slots_for_type(vtype); + + if (unlikely(pslot + slots >= JIT_MAX_ARGS)) + fatal("%s requires more than the maximum supported %d arguments", + istr(g->func->name), JIT_MAX_ARGS); + g->map[preg] = j_recv(g, pslot++); for (int i = 1; i < slots; i++) j_recv(g, pslot++); // Must be contiguous registers diff --git a/src/jit/jit-priv.h b/src/jit/jit-priv.h index 79b42e4e..f84481e4 100644 --- a/src/jit/jit-priv.h +++ b/src/jit/jit-priv.h @@ -329,7 +329,7 @@ typedef struct { typedef struct _pack_writer pack_writer_t; -#define JIT_MAX_ARGS 64 +#define JIT_MAX_ARGS 80 typedef struct _jit_interp jit_interp_t; -- 2.39.2