From af037da71a15d34c5bd2fd31f686b37e7f9da4fd Mon Sep 17 00:00:00 2001 From: Constantin Dimitrov Date: Fri, 8 Aug 2025 23:08:20 +0200 Subject: [PATCH 1/3] Fix: segfault due to use after free in workers thread NodeDisconnect calls worker.WorkComplete() tells V8 persistent callback to be freed, while the thread is still alive, creating use after free segmentation fault. Fixes https://github.com/Blizzard/node-rdkafka/issues/1057 --- src/workers.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/workers.cc b/src/workers.cc index 55d3dd50..0342b44f 100644 --- a/src/workers.cc +++ b/src/workers.cc @@ -767,7 +767,10 @@ void KafkaConsumerConsumeLoop::HandleMessageCallback(RdKafka::Message* msg, RdKa delete msg; } - callback->Call(argc, argv); + // Don't call after work completed + if (callback && !callback->IsEmpty()) { + callback->Call(argc, argv); + } } void KafkaConsumerConsumeLoop::HandleOKCallback() { From bbcc6fc596f33f1d3c6d3a3b78aecd635dfd0813 Mon Sep 17 00:00:00 2001 From: Constantin Dimitrov Date: Fri, 22 Aug 2025 02:55:26 +0200 Subject: [PATCH 2/3] Fix: segfault due to use after free in workers thread NodeDisconnect calls worker.WorkComplete() which deletes the callback, while the thread is still alive, creating use after free segmentation fault. --- src/workers.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/workers.h b/src/workers.h index d7d5ac8a..06c43adf 100644 --- a/src/workers.h +++ b/src/workers.h @@ -100,7 +100,9 @@ class MessageWorker : public ErrorAwareWorker { } for (unsigned int i = 0; i < message_queue.size(); i++) { - HandleMessageCallback(message_queue[i], RdKafka::ERR_NO_ERROR); + if (callback && !callback->IsEmpty()) { + HandleMessageCallback(message_queue[i], RdKafka::ERR_NO_ERROR); + } // we are done with it. it is about to go out of scope // for the last time so let's just free it up here. can't rely @@ -108,7 +110,9 @@ class MessageWorker : public ErrorAwareWorker { } for (unsigned int i = 0; i < warning_queue.size(); i++) { - HandleMessageCallback(NULL, warning_queue[i]); + if (callback && !callback->IsEmpty()) { + HandleMessageCallback(NULL, warning_queue[i]); + } } } From ac0736ab1b791200794c569ab5b350b06e4acda0 Mon Sep 17 00:00:00 2001 From: Constantin Dimitrov Date: Fri, 22 Aug 2025 03:14:06 +0200 Subject: [PATCH 3/3] Revert changes in workers.cc --- src/workers.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/workers.cc b/src/workers.cc index 0342b44f..55d3dd50 100644 --- a/src/workers.cc +++ b/src/workers.cc @@ -767,10 +767,7 @@ void KafkaConsumerConsumeLoop::HandleMessageCallback(RdKafka::Message* msg, RdKa delete msg; } - // Don't call after work completed - if (callback && !callback->IsEmpty()) { - callback->Call(argc, argv); - } + callback->Call(argc, argv); } void KafkaConsumerConsumeLoop::HandleOKCallback() {