commit 9d809fc: [Fix] Add concept of uncancellable events to prevent use-after-free

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Aug 25 15:49:04 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-08-25 16:41:47 +0100
URL: https://github.com/rspamd/rspamd/commit/9d809fc59320afe0304d2e7194a5a68067fb60d2 (HEAD -> master)

[Fix] Add concept of uncancellable events to prevent use-after-free

---
 src/libserver/async_session.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/libserver/async_session.c b/src/libserver/async_session.c
index 1bd4c77e9..057604447 100644
--- a/src/libserver/async_session.c
+++ b/src/libserver/async_session.c
@@ -278,20 +278,30 @@ rspamd_session_cleanup (struct rspamd_async_session *session)
 	}
 
 	session->flags |= RSPAMD_SESSION_FLAG_CLEANUP;
+	khash_t(rspamd_events_hash) *uncancellable_events = kh_init(rspamd_events_hash);
 
 	kh_foreach_key (session->events, ev, {
 		/* Call event's finalizer */
-		msg_debug_session ("removed event on destroy: %p, subsystem: %s",
-				ev->user_data,
-				ev->subsystem);
+		int ret;
 
 		if (ev->fin != NULL) {
+			msg_debug_session ("removed event on destroy: %p, subsystem: %s",
+					ev->user_data,
+					ev->subsystem);
 			ev->fin (ev->user_data);
 		}
+		else {
+			msg_debug_session ("NOT removed event on destroy - uncancellable: %p, subsystem: %s",
+					ev->user_data,
+					ev->subsystem);
+			/* Assume an event is uncancellable, move it to a new hash table */
+			kh_put (rspamd_events_hash, uncancellable_events, ev, &ret);
+		}
 	});
 
-	kh_clear (rspamd_events_hash, session->events);
-
+	kh_destroy (rspamd_events_hash, session->events);
+	session->events = uncancellable_events;
+	msg_debug_session ("pending %d uncancellable events", kh_size (uncancellable_events));
 	session->flags &= ~RSPAMD_SESSION_FLAG_CLEANUP;
 }
 


More information about the Commits mailing list