diff --git a/wasm-build/sdk_port-wasi/sdk_port-wasi-dlfcn.c b/wasm-build/sdk_port-wasi/sdk_port-wasi-dlfcn.c index 44dac9e5e3cd2..034651dacf2b1 100644 --- a/wasm-build/sdk_port-wasi/sdk_port-wasi-dlfcn.c +++ b/wasm-build/sdk_port-wasi/sdk_port-wasi-dlfcn.c @@ -81,7 +81,16 @@ ends_with(const char *str, const char *suffix) // dlfcn.h -volatile dict_t* dltab[]; +/* dltab was a tentative (1-element) array indexed past its end, and slot + * 0 was never assigned: the first library landed at dltab[1] while the + * lookup loop read dltab[0..dltab_index), so every lookup dereferenced a + * NULL dict — i.e. guest address 0. That is harmless while address 0 + * holds zeros, but the CMA wire channel places live request bytes at the + * bottom of memory, turning the NULL-dict read into wild loads and traps + * (observed as a crash on the first CREATE EXTENSION over CMA). Use a + * real array and keep every slot initialized. */ +#define DLTAB_MAX 64 +static dict_t dltab[DLTAB_MAX]; volatile int dltab_index = 0; void * @@ -132,8 +141,8 @@ dlopen(const char *filename, int flags) { dict_t tab = NULL; fprintf(stderr,"void *dlopen(const char *filename = %s, int flags=%d)\n", filename, flags); for (int i=0; i< dltab_index; i++) { - if ( dict_find_index(dltab[i], filename) > 0 ) - return (void *)i; + if ( dltab[i] && dict_find_index(dltab[i], filename) >= 0 ) + return (void *)(i + 1); } printf("dlopen: new lib '%s'\n", filename ); if ( ends_with(filename,"/plpgsql.so") ){ @@ -141,9 +150,11 @@ dlopen(const char *filename, int flags) { _PG_init(); } + if (dltab_index >= DLTAB_MAX) + return NULL; tab = dict_new(); - dict_add(tab, filename, dltab_index++ ); - dltab[dltab_index] = tab; + dict_add(tab, filename, dltab_index); + dltab[dltab_index++] = tab; return (void *)dltab_index; }