Fix node:http UAF (#18485)

Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
This commit is contained in:
Kai Tamkun
2025-03-25 23:31:04 -07:00
committed by GitHub
parent 8ee962d79f
commit ee8a839500
8 changed files with 90 additions and 21 deletions

View File

@@ -25,6 +25,8 @@
extern "C" uint64_t uws_res_get_remote_address_info(void* res, const char** dest, int* port, bool* is_ipv6);
extern "C" uint64_t uws_res_get_local_address_info(void* res, const char** dest, int* port, bool* is_ipv6);
extern "C" void Bun__NodeHTTPResponse_setClosed(void* zigResponse);
namespace Bun {
using namespace JSC;
@@ -121,9 +123,7 @@ public:
static void clearSocketData(us_socket_t* socket)
{
auto* httpResponseData = (uWS::HttpResponseData<SSL>*)us_socket_ext(SSL, socket);
if (httpResponseData->socketData) {
httpResponseData->socketData = nullptr;
}
httpResponseData->socketData = nullptr;
}
void close()
@@ -187,6 +187,9 @@ public:
{
this->socket = nullptr;
this->m_duplex.clear();
if (auto* res = this->currentResponseObject.get(); res != nullptr && res->m_ctx != nullptr) {
Bun__NodeHTTPResponse_setClosed(res->m_ctx);
}
this->currentResponseObject.clear();
// This function can be called during GC!
@@ -200,20 +203,18 @@ public:
WebCore::ScriptExecutionContext* scriptExecutionContext = globalObject->scriptExecutionContext();
if (scriptExecutionContext) {
JSC::gcProtect(this);
scriptExecutionContext->postTask([self = this](ScriptExecutionContext& context) {
WTF::NakedPtr<JSC::Exception> exception;
auto* globalObject = defaultGlobalObject(context.globalObject());
auto* thisObject = self;
auto* callbackObject = thisObject->functionToCallOnClose.get();
if (!callbackObject) {
JSC::gcUnprotect(self);
self->strongThis.clear();
return;
}
auto callData = JSC::getCallData(callbackObject);
MarkedArgumentBuffer args;
EnsureStillAliveScope ensureStillAlive(self);
JSC::gcUnprotect(self);
if (globalObject->scriptExecutionStatus(globalObject, thisObject) == ScriptExecutionStatus::Running) {
profiledCall(globalObject, JSC::ProfilingReason::API, callbackObject, callData, thisObject, args, exception);
@@ -223,10 +224,9 @@ public:
globalObject->reportUncaughtExceptionAtEventLoop(globalObject, ptr);
}
}
self->strongThis.clear();
});
}
this->strongThis.clear();
}
static Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)