Skip to content

Commit

Permalink
fix: use-after-free on environmentdata
Browse files Browse the repository at this point in the history
PR-URL: #174
  • Loading branch information
legendecas authored May 5, 2022
1 parent 859b9ad commit fb56fe6
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 10 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ npm i xprofiler -g
此命令可以对安装并启用了 xprofiler 插件的 node.js 进程进行一些操作,安装后执行 `xprofctl -h` 可以查看其用法:

```bash
xprofctl <action> -p <pid> [-t profiling_time]
xprofctl <action> -p <pid> [-w <thread_id>] [-t profiling_time]

命令:
xprofctl start_cpu_profiling 启动 cpu 采样
Expand All @@ -179,9 +179,10 @@ xprofctl <action> -p <pid> [-t profiling_time]
xprofctl set_config 设置 xprofiler 配置

选项:
-p, --pid 进程 pid [必需]
-h, --help 显示帮助信息 [布尔]
-v, --version 显示版本号 [布尔]
-p, --pid 进程 pid [必需]
-w, --worker_thread_id 线程 id [可选]
-h, --help 显示帮助信息 [布尔]
-v, --version 显示版本号 [布尔]

示例:
xprofctl start_cpu_profiling -p 29156 触发进程 29156 开始进行 cpu 采样
Expand Down
13 changes: 8 additions & 5 deletions src/environment_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,23 @@ void EnvironmentData::AtExit(void* arg) {
env_data->gc_prologue_callbacks_.clear();

uv_close(reinterpret_cast<uv_handle_t*>(&env_data->interrupt_async_),
nullptr);
CloseCallback<&EnvironmentData::interrupt_async_>);
uv_close(reinterpret_cast<uv_handle_t*>(&env_data->statistics_async_),
CloseCallback);
CloseCallback<&EnvironmentData::statistics_async_>);
per_thread::environment_data = nullptr;
// Release the unique_ptr, but delete it in CloseCallback.
env_data.release();
}

// static
template <uv_async_t EnvironmentData::*field>
void EnvironmentData::CloseCallback(uv_handle_t* handle) {
EnvironmentData* env_data =
ContainerOf(&EnvironmentData::statistics_async_,
reinterpret_cast<uv_async_t*>(handle));
delete env_data;
ContainerOf(field, reinterpret_cast<uv_async_t*>(handle));
env_data->closed_handle_count_++;
if (env_data->closed_handle_count_ == kHandleCount) {
delete env_data;
}
}

void EnvironmentData::SendCollectStatistics() {
Expand Down
4 changes: 4 additions & 0 deletions src/environment_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class EnvironmentData {

private:
static void AtExit(void* arg);
template <uv_async_t EnvironmentData::*field>
static void CloseCallback(uv_handle_t* handle);
static void InterruptBusyCallback(v8::Isolate* isolate, void* data);
static void InterruptIdleCallback(uv_async_t* handle);
Expand Down Expand Up @@ -95,6 +96,9 @@ class EnvironmentData {
MemoryStatistics memory_statistics_;
HttpStatistics http_statistics_;
UvHandleStatistics uv_handle_statistics_;

uint32_t closed_handle_count_ = 0;
static const uint32_t kHandleCount = 2;
};

} // namespace xprofiler
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ exports.fork = function fork(filepath, options = {}) {

proc.on('exit', (code, signal) => {
if (code !== 0) {
console.log('process exited with non-zero code: pid(%d), code(%d), signal(%d)', proc.pid, code, signal);
console.log('process exited with non-zero code: pid(%d), code(%s), signal(%s)', proc.pid, code, signal);
console.log('stdout:\n', stdout);
console.log('');
console.log('stderr:\n', stderr);
Expand Down

0 comments on commit fb56fe6

Please sign in to comment.