Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2020-05-07 02:30:36 +0300
committerAnna Henningsen <anna@addaleax.net>2020-05-15 20:36:48 +0300
commite9f293750760d59243020d0376edf242c9a26b67 (patch)
treebfa905e137940a3d530b1008b5b0327f0bd22f7a /src/node_file.h
parent441e703b2851be4c0f924907ff3c20cc4bab8588 (diff)
fs: clean up Dir.read() uv_fs_t data before calling into JS
A call into JS can schedule another operation on the same `uv_dir_t`. In particular, when the handle is closed from the callback for a directory read operation, there previously was a race condition window: 1. A `dir.read()` operation is submitted to libuv 2. The read operation is finished by libuv, calling `AfterDirRead()` 3. We call into JS 4. JS calls dir.close() 5. libuv posts the close request to a thread in the pool 6. The close request runs, destroying the directory handle 7. `AfterDirRead()` is being exited. Exiting the `FSReqAfterScope` in step 7 attempts to destroy the original uv_fs_t` from step 1, which now points to an `uv_dir_t` that has already been destroyed in step 5. By forcing the `FSReqAfterScope` to clean up before we call into JS, we can be sure that no other operations on the same `uv_dir_t` are submitted concurrently. This addresses issues observed when running with ASAN/valgrind. PR-URL: https://github.com/nodejs/node/pull/33274 Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Diffstat (limited to 'src/node_file.h')
-rw-r--r--src/node_file.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/node_file.h b/src/node_file.h
index 7690f272848..39c9034f669 100644
--- a/src/node_file.h
+++ b/src/node_file.h
@@ -184,6 +184,7 @@ class FSReqAfterScope final {
public:
FSReqAfterScope(FSReqBase* wrap, uv_fs_t* req);
~FSReqAfterScope();
+ void Clear();
bool Proceed();
@@ -195,7 +196,7 @@ class FSReqAfterScope final {
FSReqAfterScope& operator=(const FSReqAfterScope&&) = delete;
private:
- FSReqBase* wrap_ = nullptr;
+ BaseObjectPtr<FSReqBase> wrap_;
uv_fs_t* req_ = nullptr;
v8::HandleScope handle_scope_;
v8::Context::Scope context_scope_;