Blob Blame History Raw
From 493c4210168fa475aa4130c12e8fdff3b7d85c09 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Mon, 7 Mar 2022 13:32:37 -0600
Subject: [PATCH] threadsh1: Avoid heap-use-after-free.

Previously, the Canvas `Close` signal which triggers a call to the local function `close` which
was unconditionally call `Kill` on its associated thread would call it on an already deleted
object if the `TThread` was deleted before the `TCanvas`.

This fix #10015 (detected by using ASAN).
---
 tutorials/legacy/thread/threadsh1.C | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/tutorials/legacy/thread/threadsh1.C b/tutorials/legacy/thread/threadsh1.C
index b819f5d020..d6abc67e36 100644
--- a/tutorials/legacy/thread/threadsh1.C
+++ b/tutorials/legacy/thread/threadsh1.C
@@ -67,7 +67,8 @@ void *joiner(void *)
 void closed(Int_t id)
 {
    // kill the thread matching the canvas being closed
-   t[id]->Kill();
+   if (t[id])
+      t[id]->Kill();
    // and set the canvas pointer to 0
    c[id] = 0;
 }
@@ -142,11 +143,11 @@ void threadsh1()
    t[4]->Join();
    TThread::Ps();
 
-   delete t[0];
-   delete t[1];
-   delete t[2];
-   delete t[3];
-   delete t[4];
+   delete t[0]; t[0] = nullptr; // Prevents after deletion access.
+   delete t[1]; t[1] = nullptr;
+   delete t[2]; t[2] = nullptr;
+   delete t[3]; t[3] = nullptr;
+   delete t[4]; t[4] = nullptr;
 
    delete rng[0];
    delete rng[1];
-- 
2.35.1