From 6de77d3f091cd3da3b7608e6a8f87fa7161dac09 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Tue, 24 Dec 2019 10:30:46 -0500 Subject: [PATCH] deps: uvwasi: cherry-pick 75b389c Original commit message: This commit changes the memory management in uvwasi_fd_table_init() such that ENOMEM errors can be handled better in uvwasi_fd_table_free(). PR-URL: https://github.com/nodejs/node/pull/31076 Reviewed-By: Jiawen Geng Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Chengzhong Wu Reviewed-By: Rich Trott --- deps/uvwasi/src/fd_table.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c index aad40e7407b259..f3855d4da54dbe 100644 --- a/deps/uvwasi/src/fd_table.c +++ b/deps/uvwasi/src/fd_table.c @@ -291,19 +291,25 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, return UVWASI_EINVAL; table->fds = NULL; - r = uv_rwlock_init(&table->rwlock); - if (r != 0) - return uvwasi__translate_uv_error(r); - table->used = 0; table->size = init_size; table->fds = uvwasi__calloc(uvwasi, init_size, sizeof(struct uvwasi_fd_wrap_t*)); - if (table->fds == NULL) { - err = UVWASI_ENOMEM; - goto error_exit; + if (table->fds == NULL) + return UVWASI_ENOMEM; + + r = uv_rwlock_init(&table->rwlock); + if (r != 0) { + err = uvwasi__translate_uv_error(r); + /* Free table->fds and set it to NULL here. This is done explicitly instead + of jumping to error_exit because uvwasi_fd_table_free() relies on fds + being NULL to know whether or not to destroy the rwlock. + */ + uvwasi__free(uvwasi, table->fds); + table->fds = NULL; + return err; } /* Create the stdio FDs. */ @@ -358,13 +364,6 @@ void uvwasi_fd_table_free(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table) { } if (table->fds != NULL) { - /* It's fine to call uvwasi__free() multiple times on table->fds. However, - it is not fine to call uv_rwlock_destroy() multiple times. Guard against - that by ensuring that table->fds is not NULL. Technically, it's possible - that uvwasi_fd_table_init() initialized the rwlock successfully, but - failed to initialize fds. However, the only way that's possible is if - the application already ran out of memory. - */ uvwasi__free(uvwasi, table->fds); table->fds = NULL; table->size = 0;