GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — quic: fix UAF in Application::OnTimeout() · nodejs/node@a4db121

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • src/quic
    • application.cc
    • session.cc
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/quic/application.cc‎

Copy file name to clipboardExpand all lines: src/quic/application.cc
+8-6Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,14 @@ void Session::Application::SendPendingData() {
369369
if (closed) return;
370370
// Flush any remaining accumulated packets before updating stats.
371371
flush_batch();
372-
auto& s = session();
373-
if (!s.is_destroyed()) [[likely]] {
374-
s.UpdatePacketTxTime();
375-
s.UpdateTimer();
376-
s.UpdateDataStats();
377-
}
372+
if (session().is_destroyed()) [[unlikely]] return;
373+
374+
// Get a strong pointer to protect against potential destruction during
375+
// updating the time and data stats.
376+
BaseObjectPtr<Session> s(session_);
377+
s->UpdatePacketTxTime();
378+
s->UpdateTimer();
379+
s->UpdateDataStats();
378380
});
379381

380382
// The maximum size of packet to create.
Collapse file

‎src/quic/session.cc‎

Copy file name to clipboardExpand all lines: src/quic/session.cc
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3026,6 +3026,15 @@ void Session::SendConnectionClose() {
30263026
void Session::OnTimeout() {
30273027
if (is_destroyed()) return;
30283028
if (!impl_->application_) return;
3029+
// Hold a strong reference to prevent the Session from being freed during
3030+
// re-entrant calls. SendPendingData's scope guard calls UpdateTimer(),
3031+
// which can synchronously re-enter OnTimeout() when the timer has already
3032+
// expired. That re-entrant path can reach FinishClose → EmitClose →
3033+
// Destroy → impl_.reset() → ~Impl → RemoveSession(), dropping the last
3034+
// BaseObjectPtr from the endpoint map and freeing the Session. Without
3035+
// this guard, the outer OnTimeout / SendPendingData frames would operate
3036+
// on a freed object.
3037+
BaseObjectPtr<Session> ref(this);
30293038
HandleScope scope(env()->isolate());
30303039
int ret;
30313040
{

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.