Skip to content

Commit 80b10b4

Browse files
committed
src: fix use-after-free in inspector agent
uv_close() is an asynchronous operation. Calling it on a data member inside the destructor is unsound because its memory is about to be reclaimed but libuv is not done with it yet. PR-URL: #7907 Reviewed-By: Ali Ijaz Sheikh <[email protected]> Reviewed-By: Eugene Ostroukhov <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 75c6d9d commit 80b10b4

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

src/inspector_agent.cc

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ class AgentImpl {
209209
State state_;
210210
node::Environment* parent_env_;
211211

212-
uv_async_t data_written_;
212+
uv_async_t* data_written_;
213213
uv_async_t io_thread_req_;
214214
inspector_socket_t* client_socket_;
215215
blink::V8Inspector* inspector_;
@@ -317,31 +317,34 @@ AgentImpl::AgentImpl(Environment* env) : port_(0),
317317
shutting_down_(false),
318318
state_(State::kNew),
319319
parent_env_(env),
320+
data_written_(new uv_async_t()),
320321
client_socket_(nullptr),
321322
inspector_(nullptr),
322323
platform_(nullptr),
323324
dispatching_messages_(false),
324325
frontend_session_id_(0),
325326
backend_session_id_(0) {
326327
CHECK_EQ(0, uv_sem_init(&start_sem_, 0));
327-
memset(&data_written_, 0, sizeof(data_written_));
328328
memset(&io_thread_req_, 0, sizeof(io_thread_req_));
329+
CHECK_EQ(0, uv_async_init(env->event_loop(), data_written_, nullptr));
330+
uv_unref(reinterpret_cast<uv_handle_t*>(data_written_));
329331
}
330332

331333
AgentImpl::~AgentImpl() {
332-
if (!inspector_)
333-
return;
334-
uv_close(reinterpret_cast<uv_handle_t*>(&data_written_), nullptr);
334+
auto close_cb = [](uv_handle_t* handle) {
335+
delete reinterpret_cast<uv_async_t*>(handle);
336+
};
337+
uv_close(reinterpret_cast<uv_handle_t*>(data_written_), close_cb);
338+
data_written_ = nullptr;
335339
}
336340

337341
bool AgentImpl::Start(v8::Platform* platform, int port, bool wait) {
338342
auto env = parent_env_;
339343
inspector_ = new V8NodeInspector(this, env, platform);
340344
platform_ = platform;
341-
int err = uv_async_init(env->event_loop(), &data_written_, nullptr);
342-
CHECK_EQ(err, 0);
343345

344-
uv_unref(reinterpret_cast<uv_handle_t*>(&data_written_));
346+
int err = uv_loop_init(&child_loop_);
347+
CHECK_EQ(err, 0);
345348

346349
port_ = port;
347350
wait_ = wait;
@@ -517,7 +520,7 @@ void AgentImpl::PostIncomingMessage(const String16& message) {
517520
platform_->CallOnForegroundThread(isolate,
518521
new DispatchOnInspectorBackendTask(this));
519522
isolate->RequestInterrupt(InterruptCallback, this);
520-
uv_async_send(&data_written_);
523+
uv_async_send(data_written_);
521524
}
522525

523526
void AgentImpl::OnInspectorConnectionIO(inspector_socket_t* socket) {
@@ -559,7 +562,7 @@ void AgentImpl::DispatchMessages() {
559562
inspector_->dispatchMessageFromFrontend(message);
560563
}
561564
}
562-
uv_async_send(&data_written_);
565+
uv_async_send(data_written_);
563566
dispatching_messages_ = false;
564567
}
565568

0 commit comments

Comments
 (0)